/******/
 (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__) {

	/* WEBPACK VAR INJECTION */(function(global) {'use strict';
	
	__webpack_require__(1);
	
	var _utils = __webpack_require__(2);
	
	var _utils2 = _interopRequireDefault(_utils);
	
	var _header = __webpack_require__(93);
	
	var _header2 = _interopRequireDefault(_header);
	
	var _footer = __webpack_require__(115);
	
	var _footer2 = _interopRequireDefault(_footer);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	__webpack_require__(121);
	__webpack_require__(122);
	__webpack_require__(123);
	__webpack_require__(124);
	__webpack_require__(125);
	
	if (!global._babelPolyfill) {
	  __webpack_require__(126);
	}
	
	try {
	  angular.module('templates');
	} catch (e) {
	  angular.module('templates', []);
	}
	
	(0, _utils2.default)(angular.module('utils', ['ui.select', 'angular-table', 'mgcrea.ngStrap', 'ngCookies', 'vcRecaptcha', 'angular-uri', 'templates', 'angulartics', 'angulartics.google.analytics', 'angulartics.igg.theta']).config(['$analyticsProvider', function ($analyticsProvider) {
	  $analyticsProvider.virtualPageviews(false);
	}]));
	
	angular.module('adminBar', []);
	(0, _header2.default)(angular.module('header', ['ngAnimate', 'utils', 'adminBar']));
	
	(0, _footer2.default)(angular.module('footer', ['utils']));
	
	angular.module('lite', ['header', 'footer', 'utils', 'angular-carousel', 'ng.picturefill']);
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 1 */
/***/ function(module, exports) {

	'use strict';
	
	(function () {
	  'use strict';
	
	  angular.module('angulartics.igg.theta', ['angulartics', 'utils']).config(['$analyticsProvider', function ($analyticsProvider) {
	    $analyticsProvider.registerEventTrack(function (action, properties) {
	      this.$inject(function (gogoEvents) {
	
	        var thetaProperties = {};
	
	        // TODO: change back to:
	        // var event_name = properties.name;
	        var event_name = properties.name || action;
	
	        // Google Analytics sends an eventType that is not needed by Theta so we omit it here.
	        properties = _.omit(properties, ['eventType', 'name']);
	
	        // map Angular camelCase properties into snake case
	        // perhaps we should move this to the gogoEvents.captureEvent function
	        _.each(properties, function (value, key) {
	          var newKey = key.replace(/\.?([A-Z]+)/g, function (x, y) {
	            return "_" + y.toLowerCase();
	          }).replace(/^_/, "");
	          thetaProperties[newKey] = value;
	        });
	
	        // Google Analytics also manipulates the properties object and always adds a property.category: 'Event'
	        // if there is none
	
	        gogoEvents.captureEvent(event_name, thetaProperties);
	      });
	    });
	
	    $analyticsProvider.registerSetSuperProperties(function (properties) {
	      this.$inject(function (gogoEvents) {
	        gogoEvents.setSuperProperties(properties);
	      });
	    });
	  }]);
	})();

/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = utilsModule;
	
	var _lodash = __webpack_require__(3);
	
	var _lodash2 = _interopRequireDefault(_lodash);
	
	var _svgSpriteInjector = __webpack_require__(5);
	
	var _svgSpriteInjector2 = _interopRequireDefault(_svgSpriteInjector);
	
	var _iggAffixDirectives = __webpack_require__(6);
	
	var _iggAffixDirectives2 = _interopRequireDefault(_iggAffixDirectives);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	/* global console */
	
	var requireables = [//$ ls ancillary/utils/*service.* | xargs -I {} basename {} '.js'
	'ckeditor-directive', 'cl-file-uploader-directive', 'cl-image-directive', 'cl-uploadable-image-directive', 'clamp-directive', 'compare-to-directive', 'copy-url-directive', 'cute-flash-directive', 'dotdotdot-directive', 'enter-keypress-directive', 'fb-tracking-pixel-directive', 'ga-content-group-directive', 'ga-raw-directive', 'igg-popover-directive', 'igg-project-card-directive', 'individual-avatar-directive', 'info-message-directive', 'konami-directive', 'pagination-directive', 'share-banner-directive', 'share-links-directive', 'shipping-info-directive', 'simple-image-upload-directive', 'split-directive', 'svg-icon-directive', 'browser-factory', 'cache-factory', 'categories-factory', 'cloudinary-factory', 'csrf-token-factory', 'currencies-factory', 'embedly-factory', 'fb-factory', 'flash-factory', 'froogaloop-factory', 'gogo-events-factory', 'gogo-location-factory', 'gplus-factory', 'igg-ckeditor-config-factory', 'igg-external-factory', 'job-status-api-factory', 'job-status-poller-factory', 'project-card-factory', 'regions-factory', 'split-factory', 'signup-factory', 'starts-with-factory', 'strip-tags-factory', 'twitter-factory', 'typeahead-utils-factory', 'user-service-config-factory', 'youtube-factory', 'abbrev-num-fmt-filter', 'char-counter-filter', 'currency-display-filter', 'html-wrapped-filter', 'igg-currency-filter', 'search-expression-filter', 'truncate-filter'];
	
	function configureUtils(utils) {
	  utils.config(['$logProvider', '$httpProvider', function ($logProvider, $httpProvider) {
	    $logProvider.debugEnabled(false); // Set to true to see debug statements
	
	    var csrfToken = $('meta[name=csrf-token]').attr('content');
	    $httpProvider.defaults.headers.post['X-CSRF-Token'] = csrfToken;
	    $httpProvider.defaults.headers.put['X-CSRF-Token'] = csrfToken;
	    $httpProvider.defaults.headers.patch['X-CSRF-Token'] = csrfToken;
	    $httpProvider.defaults.headers.delete = { 'X-CSRF-Token': csrfToken };
	  }]).config(['$httpProvider', function ($httpProvider) {
	    $httpProvider.interceptors.push('cache');
	  }]).run(['$window', 'gon', function ($window, gon) {
	    $window.igg = $window.igg || {};
	    $window.igg.externalService = $window.igg.externalService || function (callback) {
	      callback.apply(this, arguments);
	    };
	    if (gon.domain !== 'generosity') {
	      (function () {
	        var assetUrl = $('link[rel=svg]').attr('href');
	        if (assetUrl) {
	          $window.igg.externalService(function () {
	            return (0, _svgSpriteInjector2.default)(assetUrl);
	          });
	        }
	      })();
	    }
	  }]).constant('lodash', _lodash2.default).constant('_', _lodash2.default).value('gon', window.gon || {}).value('ga', window.ga).value('fbq', function () {
	    window.fbq.apply(this, arguments);
	  }).value('CKEDITOR', window.CKEDITOR).constant('I18nRails', window.I18n).constant('serverHost', window.location.host);
	}
	
	function utilsModule(utils) {
	  configureUtils(utils);
	  var requireContext = __webpack_require__(7);
	  requireables.forEach(function (requireable) {
	    var moduleName = _lodash2.default.camelCase(requireable.replace(/-(service|directive|filter|factory)$/, ''));
	    var invokeMatch = requireable.match(/(service|directive|filter|factory)/);
	    if (!invokeMatch) {
	      console.warn('No service, directory, or factory inferred from ' + requireable);
	    }
	    var invokeFnName = invokeMatch[0];
	    var required = requireContext('./' + requireable + '.js').default;
	    var fn = utils[invokeFnName];
	    fn(moduleName, required);
	  });
	
	  (0, _iggAffixDirectives2.default)(utils);
	
	  utils.factory('i18n', __webpack_require__(50).default).factory('EmailSubscriber', __webpack_require__(32).default).factory('dateService', __webpack_require__(30).default).factory('pledgeShareService', __webpack_require__(68).default).factory('iggCKEditorConfig', __webpack_require__(51).default).service('userService', __webpack_require__(91).default).service('countriesService', __webpack_require__(24).default).service('backupBeforeUnloadService', __webpack_require__(9).default).service('safeGa', __webpack_require__(71).default).directive('gaEventOn', __webpack_require__(45).default).directive('eventOn', __webpack_require__(35).default).directive('i18n', __webpack_require__(49).default).filter('htmlCharCounter', __webpack_require__(47).default).factory('$exceptionHandler', ["$log", "$window", "gon", function ($log, $window, gon) {
	    function shouldLogAirbrakeErrors() {
	      return gon.airbrake_conf && gon.airbrake_conf.javascript_api_key;
	    }
	
	    function setupAirbrake() {
	      var airbrake = new $window.airbrakeJs.Client({
	        projectId: gon.airbrake_conf.javascript_project_id,
	        projectKey: gon.airbrake_conf.javascript_api_key
	      });
	      airbrake.addFilter(function (notice) {
	        notice.context.environment = gon.airbrake_conf.environment;
	        return notice;
	      });
	      return airbrake;
	    }
	
	    return function (exception, cause) {
	      $log.error(exception);
	      if (shouldLogAirbrakeErrors()) {
	        var airbrake = setupAirbrake();
	        airbrake.notify({ error: exception, params: { angular_cause: cause } });
	      } else if ($window.skipExceptions !== true) {
	        throw exception;
	      }
	    };
	  }]);
	}

/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, 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 (true) {
	    // 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.
	    !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	  // 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));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4)(module), (function() { return this; }())))

/***/ },
/* 4 */
/***/ function(module, exports) {

	module.exports = function(module) {
		if(!module.webpackPolyfill) {
			module.deprecate = function() {};
			module.paths = [];
			// module.parent = undefined by default
			module.children = [];
			module.webpackPolyfill = 1;
		}
		return module;
	}


/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	;(function(window, document) {
		'use strict';
	
		var isSvg = document.createElementNS && document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ).createSVGRect;
		var localStorage = 'localStorage' in window && window['localStorage'] !== null ? window.localStorage : false;
	
		function svgSpriteInjector(source, opts) {
			var file;
			opts = opts || {};
	
			if (source instanceof Node) {
				file = source.getAttribute('data-svg-sprite');
				opts.revision = source.getAttribute('data-svg-sprite-revision') || opts.revision;
			} else if (typeof source === 'string') {
				file = source;
			}
	
			if (isSvg) {
				if (file) {
					injector(file, opts);
				} else {
					console.error('svg-sprite-injector: undefined sprite filename!');
				}
			} else {
				console.error('svg-sprite-injector require ie9 or greater!');
			}
		};
	
		function injector(filepath, opts) {
			var name = 'injectedSVGSprite' + filepath,
				revision = opts.revision,
				request;
	
			// localStorage cache
			if (revision !== undefined && localStorage && localStorage[name + 'Rev'] == revision) {
				return injectOnLoad(localStorage[name]);
			}
	
			// Async load
			request = new XMLHttpRequest();
			request.open('GET', filepath, true);
			request.onreadystatechange = function (e) {
				var data;
	
				if (request.readyState === 4 && request.status >= 200 && request.status < 400) {
					injectOnLoad(data = request.responseText);
					if (revision !== undefined && localStorage) {
						localStorage[name] = data;
						localStorage[name + 'Rev'] = revision;
					}
				}
			};
			request.send();
		}
	
		function injectOnLoad(data) {
			if (data) {
				if (document.body) {
					injectData(data);
				} else {
					document.addEventListener('DOMContentLoaded', injectData.bind(null, data));
				}
			}
		}
	
		function injectData(data) {
			var body = document.body;
			body.insertAdjacentHTML('afterbegin', data);
			if (body.firstChild.tagName === 'svg') {
				body.firstChild.style.display = 'none';
			}
		}
	
		if (true) {
			module.exports = svgSpriteInjector;
		} else {
			window.svgSpriteInjector = svgSpriteInjector;
		}
	
	} (window, document));


/***/ },
/* 6 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = iggAffixDirectives;
	function iggAffixDirectives(utilities) {
	  utilities.directive('iggAffixContainer', function () {
	    return {
	      restrict: 'A',
	      controller: ['$scope', '$element', function (scope, element) {
	        this.element = element;
	      }]
	    };
	  });
	
	  utilities.directive('iggAffix', ['$window', '$interval', 'lodash', function ($window, $interval, _) {
	    return {
	      restrict: 'A',
	      scope: {
	        showOnScroll: "@iggAffixShowOnScroll",
	        minParentHeight: "@iggAffixMinParentHeight"
	      },
	      require: '^iggAffixContainer',
	      link: function link(scope, element, attrs, iggAffixContainerCtrl) {
	        var win = angular.element($window),
	            affixed;
	
	        scope.containerEl = iggAffixContainerCtrl.element;
	
	        function checkPosition() {
	          scope.offsetTop = scope.containerEl.offset().top;
	          scope.offsetBottom = scope.offsetTop + scope.containerEl.height();
	
	          var scrollTop = $window.pageYOffset,
	              scrollBottom = scrollTop + element.outerHeight();
	
	          if (scrollTop >= scope.offsetTop && scrollBottom <= scope.offsetBottom) {
	            affixed = true;
	            element.css({ position: 'fixed', top: '0px', bottom: '' });
	          } else if (scrollBottom > scope.offsetBottom) {
	            affixed = true;
	            var bottom = win.height() - (scope.offsetBottom - scrollTop);
	            element.css({ position: 'fixed', bottom: bottom + 'px', top: '' });
	          } else {
	            affixed = false;
	            element.css({ position: '', bottom: '', top: '' });
	          }
	
	          var isParentTallEnough = _.isUndefined(scope.minParentHeight) || scope.containerEl.height() >= scope.minParentHeight;
	
	          element.toggle(isParentTallEnough && (affixed || !scope.showOnScroll));
	          element.toggleClass('igg-affix', affixed);
	        }
	
	        win.bind('resize', checkPosition);
	        win.bind('scroll', checkPosition);
	        win.bind('click', checkPosition);
	
	        $interval(checkPosition, 100);
	      }
	    };
	  }]);
	}

/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {

	var map = {
		"./abbrev-num-fmt-filter.js": 8,
		"./backup-before-unload-service.js": 9,
		"./browser-factory.js": 10,
		"./cache-factory.js": 11,
		"./categories-factory.js": 12,
		"./char-counter-filter.js": 13,
		"./ckeditor-directive.js": 14,
		"./cl-file-uploader-directive.js": 15,
		"./cl-image-directive.js": 16,
		"./cl-uploadable-image-directive.js": 17,
		"./clamp-directive.js": 19,
		"./cloudinary-factory.js": 21,
		"./compare-to-directive.js": 22,
		"./copy-url-directive.js": 23,
		"./countries-service.js": 24,
		"./csrf-token-factory.js": 25,
		"./currencies-factory.js": 26,
		"./currency-display-filter.js": 27,
		"./cute-flash-directive.js": 28,
		"./date-factory.js": 30,
		"./dotdotdot-directive.js": 31,
		"./email-subscriber-factory.js": 32,
		"./embedly-factory.js": 33,
		"./enter-keypress-directive.js": 34,
		"./event-directive.js": 35,
		"./fb-factory.js": 36,
		"./fb-tracking-pixel-directive.js": 37,
		"./flash-factory.js": 39,
		"./froogaloop-factory.js": 40,
		"./ga-content-group-directive.js": 41,
		"./ga-raw-directive.js": 42,
		"./gogo-events-factory.js": 43,
		"./gogo-location-factory.js": 44,
		"./google-analytics-directive.js": 45,
		"./gplus-factory.js": 46,
		"./html-char-counter-filter.js": 47,
		"./html-wrapped-filter.js": 48,
		"./i18n-directive.js": 49,
		"./i18n-factory.js": 50,
		"./igg-ckeditor-config-factory.js": 51,
		"./igg-currency-filter.js": 53,
		"./igg-external-factory.js": 54,
		"./igg-popover-directive.js": 55,
		"./igg-project-card-directive.js": 58,
		"./individual-avatar-directive.js": 59,
		"./info-message-directive.js": 61,
		"./job-status-api-factory.js": 63,
		"./job-status-poller-factory.js": 64,
		"./konami-directive.js": 65,
		"./pagination-directive.js": 66,
		"./pledge-share-service.js": 68,
		"./project-card-factory.js": 69,
		"./regions-factory.js": 70,
		"./safe-ga-service.js": 71,
		"./search-expression-filter.js": 72,
		"./share-banner-directive.js": 73,
		"./share-links-directive.js": 75,
		"./shipping-info-directive.js": 77,
		"./signup-factory.js": 79,
		"./simple-image-upload-directive.js": 80,
		"./split-directive.js": 82,
		"./split-factory.js": 83,
		"./starts-with-factory.js": 84,
		"./strip-tags-factory.js": 85,
		"./svg-icon-directive.js": 86,
		"./truncate-filter.js": 87,
		"./twitter-factory.js": 88,
		"./typeahead-utils-factory.js": 89,
		"./user-service-config-factory.js": 90,
		"./user-service.js": 91,
		"./youtube-factory.js": 92
	};
	function webpackContext(req) {
		return __webpack_require__(webpackContextResolve(req));
	};
	function webpackContextResolve(req) {
		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	};
	webpackContext.keys = function webpackContextKeys() {
		return Object.keys(map);
	};
	webpackContext.resolve = webpackContextResolve;
	module.exports = webpackContext;
	webpackContext.id = 7;


/***/ },
/* 8 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = abbrevNumFmt;
	/*@ngInject*/
	function abbrevNumFmt() {
	  return function (input) {
	    var num_after_decimal = 1;
	    var million = 1000000;
	    var thousand = 1000;
	
	    if (input >= million) {
	      if (input / million >= 100 || input % million < 50000) {
	        num_after_decimal = 0;
	      }
	      return (input / million).toFixed(num_after_decimal) + 'M';
	    } else if (input >= thousand) {
	      if (input / thousand >= 100 || input % 1000 < 50) {
	        num_after_decimal = 0;
	      }
	      return (input / thousand).toFixed(num_after_decimal) + 'k';
	    } else if (input === null) {
	      return '';
	    } else if (input <= 0) {
	      return '0';
	    } else {
	      return '' + input;
	    }
	  };
	}

/***/ },
/* 9 */
/***/ function(module, exports) {

	'use strict';
	
	backupBeforeUnloadService.$inject = ["_", "$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = backupBeforeUnloadService;
	/*@ngInject*/
	function backupBeforeUnloadService(_, $window) {
	  var self = this;
	  var _objects = {};
	  var storageElement = angular.element('#contribution-backup input');
	
	  function setStorageElement(element) {
	    storageElement = element;
	  }
	
	  function saveJson(json) {
	    return storageElement.val(json);
	  }
	
	  function loadJson() {
	    return storageElement.val();
	  }
	
	  function saveState() {
	    var current = {};
	
	    _.each(_.keys(_objects), function (objectName) {
	      var objectToBackup;
	      if (typeof _objects[objectName] === 'function') {
	        objectToBackup = _objects[objectName]();
	      } else {
	        objectToBackup = _objects[objectName];
	      }
	
	      if (!_.isUndefined(objectToBackup.campaign)) {
	        //TODO: make backupservice smart enough to not save certain unwanted attributes.
	        delete objectToBackup.campaign;
	      }
	
	      current[objectName] = objectToBackup;
	    });
	    var json = JSON.stringify(current);
	    self.saveJson(json);
	  }
	
	  function restoreStateIfSaved(objectName, object) {
	    try {
	      var data = JSON.parse(self.loadJson());
	      var objectToRestore = data[objectName];
	      if (!_.isUndefined(objectToRestore.campaign)) {
	        //TODO: make backupservice smart enough to not save certain unwanted attributes.
	        delete objectToRestore.campaign;
	      }
	      _.merge(object, objectToRestore);
	      return true;
	    } catch (e) {
	      return false;
	    }
	  }
	
	  function register(obj) {
	    _.merge(_objects, obj);
	  }
	
	  function pointerRegister(obj) {
	    for (var key in obj) {
	      _objects[key] = obj[key];
	    }
	  }
	
	  _.merge(self, {
	    objects: function objects() {
	      return _objects;
	    },
	    setStorageElement: setStorageElement,
	    saveState: saveState,
	    saveJson: saveJson,
	    loadJson: loadJson,
	    restoreStateIfSaved: restoreStateIfSaved,
	    pointerRegister: pointerRegister,
	    register: register
	  });
	
	  $window.onbeforeunload = function () {
	    self.saveState();
	  };
	}

/***/ },
/* 10 */
/***/ function(module, exports) {

	"use strict";
	
	browser.$inject = ["$window", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = browser;
	/*@ngInject*/
	function browser($window, gon) {
	  return {
	    isDesktopPlus: function isDesktopPlus() {
	      return $window.innerWidth >= 1280;
	    },
	    isDesktop: function isDesktop() {
	      return $window.innerWidth >= 1002;
	    },
	    isTabletPlus: function isTabletPlus() {
	      return $window.innerWidth >= 768;
	    },
	    isMobile: function isMobile() {
	      return $window.innerWidth < 768;
	    },
	    isMobilePortrait: function isMobilePortrait() {
	      return $window.innerWidth < 480;
	    },
	    height: function height() {
	      return $window.innerHeight;
	    },
	    onResize: function onResize(callback) {
	      angular.element($window).on("resize", callback);
	    },
	    onLoad: function onLoad(callback) {
	      angular.element($window).on("load", callback);
	    },
	    isAndroid: function isAndroid() {
	      var ua = $window.navigator.userAgent.toLowerCase();
	      return ua.indexOf("android") > -1;
	    },
	    isIphone: function isIphone() {
	      return !!($window.navigator.userAgent.match(/iPhone|iPod/g) && !$window.navigator.userAgent.match(/iPad/g));
	    },
	    isNativeMobile: function isNativeMobile() {
	      return gon.is_native_mobile;
	    },
	    currentPath: function currentPath() {
	      return $window.location.pathname;
	    },
	    scrollToTop: function scrollToTop(element) {
	      var elementToScroll = element || angular.element('html,body');
	      elementToScroll.animate({ scrollTop: 0 });
	    },
	    currentHref: function currentHref() {
	      return $window.location.href;
	    },
	    redirectTo: function redirectTo(url) {
	      $window.location.href = url;
	    },
	    refreshPage: function refreshPage() {
	      $window.location.reload();
	    },
	    refreshWithoutParams: function refreshWithoutParams() {
	      $window.location = $window.location.pathname;
	    },
	    openTab: function openTab(url) {
	      $window.open(url, '_blank');
	    },
	    openWindow: function openWindow(url, name, options) {
	      options = options || {};
	      var width = options.width || 670;
	      var height = options.height || 400;
	      var size = 'width=' + width + ',height=' + height + ',' + 'top=' + (screen.height / 2 - height / 2) + ',' + 'left=' + (screen.width / 2 - width / 2);
	
	      $window.open(url, name, size);
	    },
	    close: function close() {
	      $window.close();
	    },
	
	    scrollY: function scrollY() {
	      return $window.pageYOffset;
	    },
	
	    onScroll: function onScroll(callback) {
	      angular.element($window).bind("scroll", function () {
	        /* callback with no arguments to prevent exposing the $window directly */
	        callback();
	      });
	    }
	  };
	}

/***/ },
/* 11 */
/***/ function(module, exports) {

	'use strict';
	
	cache.$inject = ["serverHost", "URI", "$cookies", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = cache;
	/*@ngInject*/
	function cache(serverHost, URI, $cookies, i18n) {
	  function isRequestToCurrentServer(requestURL) {
	    var uri = new URI(requestURL);
	    return uri.is("relative") || uri.host() == serverHost;
	  }
	
	  var request = function request(config) {
	    if (isRequestToCurrentServer(config.url)) {
	      if ($cookies.get('has_account') == 'true') {
	        config.headers['X-Has-Account'] = 'true';
	      }
	      config.headers['X-Locale'] = i18n.locale;
	    }
	
	    return config;
	  };
	
	  return {
	    request: request
	  };
	}

/***/ },
/* 12 */
/***/ function(module, exports) {

	'use strict';
	
	categories.$inject = ["gon", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = categories;
	/*@ngInject*/
	function categories(gon, i18n) {
	  function CategoriesService(initialCategories) {
	    var categories;
	
	    this.setCategories = function (cats) {
	      categories = cats;
	      this.initializeI18n();
	    };
	
	    this.getCategories = function () {
	      return categories;
	    };
	
	    this.asOptions = function () {
	      return _.map(categories, function (category) {
	        return { value: category.id, text: category.name };
	      });
	    };
	
	    this.forId = function (id) {
	      return _.findWhere(categories, { id: parseInt(id) });
	    };
	
	    this.initializeI18n = function () {
	      _.each(categories, function (category) {
	        category.label = i18n.t(category.slug);
	
	        if (i18n.locale === 'en') {
	          category.tagline = i18n.t('explorepage.taglines.' + category.slug);
	        } else {
	          category.tagline = i18n.t(category.slug);
	        }
	      });
	    };
	
	    this.setCategories(initialCategories);
	  }
	
	  return new CategoriesService(gon && gon.services && gon.services.categories || []);
	}

/***/ },
/* 13 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = charCounter;
	/*@ngInject*/
	function charCounter() {
	  return function (input, maxLength, delimiter) {
	    delimiter = delimiter ? " " + delimiter + " " : " / ";
	    var charsLeft = input ? maxLength - input.length : maxLength;
	    return charsLeft.toString() + delimiter + maxLength;
	  };
	}

/***/ },
/* 14 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (CKEDITOR, iggCKEditorConfig, $timeout, $q) {
	  return {
	    require: 'ngModel',
	    scope: {
	      onCkReady: '&'
	    },
	
	    /*
	     * most of this is borrowed from the angular-ckeditor project. the most
	     * important change is the actual creation of the editor. this directive
	     * gives us control over the exact configuration data, where the
	     * angular-ckeditor instance required a json object literal to be passed as
	     * an html attribute.
	     */
	    link: function link(scope, element, attrs, controller) {
	      var editor = CKEDITOR.replace(element[0], iggCKEditorConfig.defaultOptions);
	      var ready = $q.defer();
	
	      function editorReady() {
	        return ready.promise;
	      }
	
	      function onCkEvent(event, listener) {
	        editor.on(event, function () {
	          var args = arguments;
	          /*
	           * $timeout ensures that we call $apply in the background, and not
	           * during an active $apply cycle
	           */
	          $timeout(function () {
	            scope.$apply(function () {
	              listener.apply(null, args);
	            });
	          });
	        });
	      }
	
	      // Set editor data when view data change.
	      controller.$render = function () {
	        editorReady().then(function () {
	          editor.setData(controller.$viewValue || '', {
	            noSnapshot: true,
	            callback: function callback() {
	              editor.fire('updateSnapshot');
	            }
	          });
	        });
	      };
	
	      editorReady().then(function () {
	        // manually sync model on certain ckeditor events
	        ['dataReady', 'change', 'blur', 'saveSnapshot'].forEach(function (event) {
	          onCkEvent(event, function () {
	            controller.$setViewValue(editor.getData() || '');
	          });
	        });
	
	        // make ckeditor readonly when the element is readonly
	        editor.setReadOnly(!!attrs.readonly);
	        attrs.$observe('readonly', function (readonly) {
	          editor.setReadOnly(!!readonly);
	        });
	
	        /*
	         * invoke the onCkReady callback referenced in the element attributes
	         * the $timeout trick ensures this happens in the background, and not
	         * during an active $apply cycle
	         */
	        $timeout(function () {
	          iggCKEditorConfig.onReady(editor, scope.onCkReady(scope));
	        });
	      });
	
	      scope.$on('$destroy', function () {
	        editorReady().then(function () {
	          editor.destroy(false);
	        });
	      });
	
	      onCkEvent('instanceReady', function () {
	        ready.resolve(true);
	      });
	    }
	  };
	};

/***/ },
/* 15 */
/***/ function(module, exports) {

	'use strict';
	
	fileUploader.$inject = ["i18n", "cloudinary"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = fileUploader;
	// https://github.com/jbcpollak/cloudinary_angular
	/*@ngInject*/
	function fileUploader(i18n, cloudinary) {
	  return {
	    restrict: 'A',
	    template: '<button type="button" class="i-spin-button i-cta-1 i-cta-1--grey btn-upload">' + '<span class="i-button-spinner fa fa-spinner fa-spin" ng-show="buttonSpinner"></span>' + '<span ng-class="{\'invisible-text\': buttonSpinner}">{{buttonText}}</span>' + '</button>' + '<input class="cloudinary-fileupload" name="file" type="file" data-cloudinary-field="image_id"/>' + '<div class="i-error-text" ng-show="cloudinaryError">{{cloudinaryError}}</div>',
	    scope: {
	      doneCallback: '&',
	      buttonText: '@'
	    },
	    link: function link(scope, element, attr) {
	      scope.cloudinaryError = null;
	      var callback = scope.doneCallback();
	      cloudinary.forFileInput(element.find('.cloudinary-fileupload')).onUploadStart(function () {
	        scope.buttonSpinner = true;
	      }).onUploadComplete(function (result) {
	        if (result) {
	          result.publicId = result.public_id;
	          callback(result);
	          scope.$emit('setFormDirty');
	        }
	        scope.cloudinaryError = null;
	        scope.buttonSpinner = false;
	      }).onUploadFail(function (response) {
	        scope.buttonSpinner = false;
	        if (response) {
	          var fileType = response.files[0].name.split('.').pop();
	          if (fileType && fileType != 'jpg' && fileType != 'png') {
	            scope.cloudinaryError = i18n.t('campaign_editor.misc.error.cloudinary_file_type');
	            return;
	          }
	        }
	        scope.cloudinaryError = i18n.t('campaign_editor.misc.error.cloudinary_generic');
	      });
	
	      //bind the click on the button to trigger clicking on input[type=file]
	      element.find('.btn-upload').bind('click', function () {
	        element.find('.cloudinary-fileupload').trigger('click');
	      });
	    }
	  };
	}

/***/ },
/* 16 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = clImage;
	/*@ngInject*/
	function clImage() {
	  return {
	    restrict: 'A',
	    scope: {
	      publicId: "=",
	      placeholderPath: "@",
	      width: '@',
	      height: '@',
	      crop: '@',
	      background: '@'
	    },
	
	    link: function link(scope, element) {
	      scope.$watch('publicId', function (newPublicId) {
	        if (newPublicId) {
	          element.webpify(_.extend({ 'width': scope.width, 'height': scope.height, 'crop': scope.crop, 'background': scope.background }, { 'src': newPublicId + '.jpg' }, { 'secure': true }));
	        } else if (scope.placeholderPath) {
	          element.attr('src', scope.placeholderPath);
	        }
	      });
	      scope.$on('imageReceived', function (event, imageModel) {
	        element.webpify(_.extend({ width: scope.width,
	          height: scope.height,
	          crop: scope.crop,
	          background: scope.background
	        }, { src: imageModel.public_id + '.jpg' }, { secure: true }));
	      });
	    }
	  };
	}

/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {

	"use strict";
	
	uploadableImage.$inject = ["i18n", "cloudinary", "$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = uploadableImage;
	/*@ngInject*/
	function uploadableImage(i18n, cloudinary, $window) {
	  return {
	    restrict: 'A',
	    scope: {
	      imageModel: "=",
	      missingImagePath: "@",
	      showDelete: '=',
	      showError: '=',
	      showUploadIcon: '=?',
	      dirtyOnUpload: '=',
	      width: '@',
	      height: '@',
	      crop: '@'
	    },
	    template: __webpack_require__(18),
	    link: function link(scope, element) {
	      scope.testOverride = $window.test_override;
	      if (typeof scope.showDelete === 'undefined') {
	        scope.showDelete = true;
	      }
	      if (typeof scope.showUploadIcon === 'undefined') {
	        scope.showUploadIcon = true;
	      }
	      scope.i18n = i18n;
	      scope.showSpinner = false;
	      scope.cloudinaryError = null;
	      scope.triggerFileUpload = function () {
	        element.find('.cloudinary-fileupload').trigger('click');
	      };
	      scope.setImage = function (imageJson) {
	        scope.imageModel = imageJson;
	        if (scope.dirtyOnUpload !== false) {
	          scope.$emit('setFormDirty');
	        }
	      };
	      scope.triggerUploadIfBlankImage = function () {
	        if (scope.imageModel === null) {
	          scope.triggerFileUpload();
	        }
	      };
	      scope.resetImageFile = function (clickEvent) {
	        scope.setImage(null);
	        if (clickEvent) clickEvent.stopPropagation();
	      };
	
	      var $dropZone = element.find("img");
	      cloudinary.forFileInput(element.find('.cloudinary-fileupload'), $dropZone).onUploadStart(function () {
	        scope.showSpinner = true;
	      }).onUploadComplete(function (result) {
	        if (result) {
	          result.publicId = result.public_id;
	          scope.setImage(result);
	          scope.$apply();
	        }
	        scope.cloudinaryError = null;
	        scope.showSpinner = false;
	      }).onUploadFail(function (response) {
	        scope.showSpinner = false;
	        if (response && response.files) {
	          var fileType = response.files[0].name.split('.').pop();
	          if (fileType && fileType != 'jpg' && fileType != 'png') {
	            scope.cloudinaryError = i18n.t('campaign_editor.misc.error.cloudinary_file_type');
	            return;
	          }
	        }
	        scope.cloudinaryError = i18n.t('campaign_editor.misc.error.cloudinary_generic');
	      });
	    }
	  };
	}

/***/ },
/* 18 */
/***/ function(module, exports) {

	module.exports = "<div class=\"image-container\" ng-click=\"triggerUploadIfBlankImage()\"\n     ng-class=\"{'not-empty': imageModel !== null, 'i-field-error': showError || cloudinaryError}\">\n  <div ng-if=\"imageModel == undefined && missingImagePath == undefined\" class=\"clImageUploader-placeholder\"><svg><use xlink:href=\"#icon-icon-create-photo\"></use></svg></div>\n  <img cl-image width=\"{{width}}\" height=\"{{height}}\" crop=\"{{crop}}\"\n       public-id=\"imageModel.publicId\" alt=\"{{i18n.t('upload_an_image')}}\"\n       placeholder-path=\"{{missingImagePath}}\"/>\n\n  <i class=\"i-fa-centered i-fa-gogenta fa fa-spinner fa-4x fa-spin\" ng-show=\"showSpinner\"></i>\n\n  <div ng-if=\"imageModel !== null\">\n    <a ng-if=\"showDelete\" ng-click=\"resetImageFile($event)\" class=\"miniBtnAction miniBtnAction--delete miniBtnTopRight\"><svg><use xlink:href=\"#icon-icon-close\"></use></svg></a>\n    <a ng-if=\"showUploadIcon\" ng-click=\"triggerFileUpload()\" class=\"miniBtnAction miniBtnAction--edit miniBtn2ndFromRight\"><svg><use xlink:href=\"#icon-icon-edit\"></use></svg></a>\n  </div>\n</div>\n\n<div class=\"i-uploader-button\" ng-show=\"imageModel === null || testOverride\">\n  <button type=\"button\" ng-click=\"triggerFileUpload()\" class=\"i-cta-1 i-cta-1--grey btn-upload\">{{::i18n.t('campaign_editor.buttons.upload_an_image')}}</button>\n  <input class=\"cloudinary-fileupload\" name=\"file\" type=\"file\" data-cloudinary-field=\"image_id\"/>\n</div>\n<div class=\"i-error-text\" ng-show=\"cloudinaryError\">{{cloudinaryError}}</div>\n";

/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function () {
	  return {
	    restrict: 'A',
	    scope: {
	      'clamp': '@'
	    },
	    link: function link($scope, elem, attrs) {
	      var lineLimit = $scope.clamp || 'auto';
	      (0, _clampJs2.default)(elem[0], { clamp: lineLimit });
	    }
	  };
	};
	
	var _clampJs = __webpack_require__(20);
	
	var _clampJs2 = _interopRequireDefault(_clampJs);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	 * Clamp.js 0.7.0
	 *
	 * Copyright 2011-2013, Joseph Schmitt http://joe.sh
	 * Released under the WTFPL license
	 * http://sam.zoy.org/wtfpl/
	 */
	
	(function(root, factory) {
	  if (true) {
	    // AMD
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  } else if (typeof exports === 'object') {
	    // Node, CommonJS-like
	    module.exports = factory();
	  } else {
	    // Browser globals
	    root.$clamp = factory();
	  }
	}(this, function() {
	  /**
	   * Clamps a text node.
	   * @param {HTMLElement} element. Element containing the text node to clamp.
	   * @param {Object} options. Options to pass to the clamper.
	   */
	  function clamp(element, options) {
	    options = options || {};
	
	    var self = this,
	      win = window,
	      opt = {
	        clamp: options.clamp || 2,
	        useNativeClamp: typeof(options.useNativeClamp) != 'undefined' ? options.useNativeClamp : true,
	        splitOnChars: options.splitOnChars || ['.', '-', '–', '—', ' '], //Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces).
	        animate: options.animate || false,
	        truncationChar: options.truncationChar || '…',
	        truncationHTML: options.truncationHTML
	      },
	
	      sty = element.style,
	      originalText = element.innerHTML,
	
	      supportsNativeClamp = typeof(element.style.webkitLineClamp) != 'undefined',
	      clampValue = opt.clamp,
	      isCSSValue = clampValue.indexOf && (clampValue.indexOf('px') > -1 || clampValue.indexOf('em') > -1),
	      truncationHTMLContainer;
	
	    if (opt.truncationHTML) {
	      truncationHTMLContainer = document.createElement('span');
	      truncationHTMLContainer.innerHTML = opt.truncationHTML;
	    }
	
	
	    // UTILITY FUNCTIONS __________________________________________________________
	
	    /**
	     * Return the current style for an element.
	     * @param {HTMLElement} elem The element to compute.
	     * @param {string} prop The style property.
	     * @returns {number}
	     */
	    function computeStyle(elem, prop) {
	      if (!win.getComputedStyle) {
	        win.getComputedStyle = function(el, pseudo) {
	          this.el = el;
	          this.getPropertyValue = function(prop) {
	            var re = /(\-([a-z]){1})/g;
	            if (prop == 'float') prop = 'styleFloat';
	            if (re.test(prop)) {
	              prop = prop.replace(re, function() {
	                return arguments[2].toUpperCase();
	              });
	            }
	            return el.currentStyle && el.currentStyle[prop] ? el.currentStyle[prop] : null;
	          };
	          return this;
	        };
	      }
	
	      return win.getComputedStyle(elem, null).getPropertyValue(prop);
	    }
	
	    /**
	     * Returns the maximum number of lines of text that should be rendered based
	     * on the current height of the element and the line-height of the text.
	     */
	    function getMaxLines(height) {
	      var availHeight = height || element.clientHeight,
	        lineHeight = getLineHeight(element);
	
	      return Math.max(Math.floor(availHeight / lineHeight), 0);
	    }
	
	    /**
	     * Returns the maximum height a given element should have based on the line-
	     * height of the text and the given clamp value.
	     */
	    function getMaxHeight(clmp) {
	      var lineHeight = getLineHeight(element);
	      return lineHeight * clmp;
	    }
	
	    /**
	     * Returns the line-height of an element as an integer.
	     */
	    function getLineHeight(elem) {
	      var lh = computeStyle(elem, 'line-height');
	      if (lh == 'normal') {
	        // Normal line heights vary from browser to browser. The spec recommends
	        // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff.
	        lh = parseInt(computeStyle(elem, 'font-size')) * 1.2;
	      }
	      return parseInt(lh);
	    }
	
	
	    // MEAT AND POTATOES (MMMM, POTATOES...) ______________________________________
	    var splitOnChars = opt.splitOnChars.slice(0),
	      splitChar = splitOnChars[0],
	      chunks,
	      lastChunk;
	
	    /**
	     * Gets an element's last child. That may be another node or a node's contents.
	     */
	    function getLastChild(elem) {
	      //Current element has children, need to go deeper and get last child as a text node
	      if (elem.lastChild.children && elem.lastChild.children.length > 0) {
	        return getLastChild(Array.prototype.slice.call(elem.children).pop());
	      }
	      //This is the absolute last child, a text node, but something's wrong with it. Remove it and keep trying
	      else if (!elem.lastChild || !elem.lastChild.nodeValue || elem.lastChild.nodeValue === '' || elem.lastChild.nodeValue == opt.truncationChar) {
	        elem.lastChild.parentNode.removeChild(elem.lastChild);
	        return getLastChild(element);
	      }
	      //This is the last child we want, return it
	      else {
	        return elem.lastChild;
	      }
	    }
	
	    /**
	     * Removes one character at a time from the text until its width or
	     * height is beneath the passed-in max param.
	     */
	    function truncate(target, maxHeight) {
	      if (!maxHeight) {
	        return;
	      }
	
	      /**
	       * Resets global variables.
	       */
	      function reset() {
	        splitOnChars = opt.splitOnChars.slice(0);
	        splitChar = splitOnChars[0];
	        chunks = null;
	        lastChunk = null;
	      }
	
	      var nodeValue = target.nodeValue.replace(opt.truncationChar, '');
	
	      //Grab the next chunks
	      if (!chunks) {
	        //If there are more characters to try, grab the next one
	        if (splitOnChars.length > 0) {
	          splitChar = splitOnChars.shift();
	        }
	        //No characters to chunk by. Go character-by-character
	        else {
	          splitChar = '';
	        }
	
	        chunks = nodeValue.split(splitChar);
	      }
	
	      //If there are chunks left to remove, remove the last one and see if
	      // the nodeValue fits.
	      if (chunks.length > 1) {
	        // console.log('chunks', chunks);
	        lastChunk = chunks.pop();
	        // console.log('lastChunk', lastChunk);
	        applyEllipsis(target, chunks.join(splitChar));
	      }
	      //No more chunks can be removed using this character
	      else {
	        chunks = null;
	      }
	
	      //Insert the custom HTML before the truncation character
	      if (truncationHTMLContainer) {
	        target.nodeValue = target.nodeValue.replace(opt.truncationChar, '');
	        element.innerHTML = target.nodeValue + ' ' + truncationHTMLContainer.innerHTML + opt.truncationChar;
	      }
	
	      //Search produced valid chunks
	      if (chunks) {
	        //It fits
	        if (element.clientHeight <= maxHeight) {
	          //There's still more characters to try splitting on, not quite done yet
	          if (splitOnChars.length >= 0 && splitChar !== '') {
	            applyEllipsis(target, chunks.join(splitChar) + splitChar + lastChunk);
	            chunks = null;
	          }
	          //Finished!
	          else {
	            return element.innerHTML;
	          }
	        }
	      }
	      //No valid chunks produced
	      else {
	        //No valid chunks even when splitting by letter, time to move
	        //on to the next node
	        if (splitChar === '') {
	          applyEllipsis(target, '');
	          target = getLastChild(element);
	
	          reset();
	        }
	      }
	
	      //If you get here it means still too big, let's keep truncating
	      if (opt.animate) {
	        setTimeout(function() {
	          truncate(target, maxHeight);
	        }, opt.animate === true ? 10 : opt.animate);
	      } else {
	        return truncate(target, maxHeight);
	      }
	    }
	
	    function applyEllipsis(elem, str) {
	      elem.nodeValue = str + opt.truncationChar;
	    }
	
	
	    // CONSTRUCTOR ________________________________________________________________
	
	    if (clampValue == 'auto') {
	      clampValue = getMaxLines();
	    } else if (isCSSValue) {
	      clampValue = getMaxLines(parseInt(clampValue));
	    }
	
	    var clampedText;
	    if (supportsNativeClamp && opt.useNativeClamp) {
	      sty.overflow = 'hidden';
	      sty.textOverflow = 'ellipsis';
	      sty.webkitBoxOrient = 'vertical';
	      sty.display = '-webkit-box';
	      sty.webkitLineClamp = clampValue;
	
	      if (isCSSValue) {
	        sty.height = opt.clamp + 'px';
	      }
	    } else {
	      var height = getMaxHeight(clampValue);
	      if (height <= element.clientHeight) {
	        clampedText = truncate(getLastChild(element), height);
	      }
	    }
	
	    return {
	      'original': originalText,
	      'clamped': clampedText
	    };
	  }
	
	  return clamp;
	}));


/***/ },
/* 21 */
/***/ function(module, exports) {

	"use strict";
	
	cloudinary.$inject = ["gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = cloudinary;
	/*@ngInject*/
	function cloudinary(gon) {
	
	  var cloudinaryOptions = {};
	  if (gon && gon.services && gon.services.cloudinary) {
	    cloudinaryOptions = {
	      url: gon.services.cloudinary.data.url,
	      cloudName: gon.services.cloudinary.data.cloud_name,
	      formData: gon.services.cloudinary.data.form_data
	    };
	  }
	
	  return {
	    setCloudinaryOptions: function setCloudinaryOptions(options) {
	      cloudinaryOptions = options;
	    },
	    forFileInput: function forFileInput($fileInput, $dropzone) {
	      $fileInput.cloudinary_fileupload(angular.extend({ headers: { "X-Requested-With": "XMLHttpRequest" }, dropZone: $dropzone, pasteZone: $dropzone }, cloudinaryOptions));
	      return {
	        onUploadStart: function onUploadStart(callback) {
	          $fileInput.on('cloudinarystart', callback);
	          return this;
	        },
	        onUploadComplete: function onUploadComplete(callback) {
	          $fileInput.on('cloudinarydone', function (e, response) {
	            callback(response.result);
	          });
	          return this;
	        },
	        onUploadFail: function onUploadFail(callback) {
	          $fileInput.on('cloudinaryfail', function (e, response) {
	            callback(response);
	          });
	          return this;
	        }
	      };
	    }
	  };
	}

/***/ },
/* 22 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = compareTo;
	/*@ngInject*/
	function compareTo() {
	  return {
	    require: "ngModel",
	    scope: {
	      otherModelValue: "=compareTo"
	    },
	    link: function link(scope, element, attributes, ngModel) {
	
	      ngModel.$validators.compareTo = function (modelValue) {
	        return modelValue == scope.otherModelValue;
	      };
	
	      scope.$watch("otherModelValue", function () {
	        ngModel.$validate();
	      });
	    }
	  };
	}

/***/ },
/* 23 */
/***/ function(module, exports) {

	'use strict';
	
	copyUrl.$inject = ["$http", "gon", "i18n", "fb", "twitter", "gplus", "$timeout", "$window", "browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = copyUrl;
	/*@ngInject*/
	function copyUrl($http, gon, i18n, fb, twitter, gplus, $timeout, $window, browser) {
	
	  return {
	    restrict: 'A',
	    link: function link(scope, element, attrs) {
	      element.on('click', function () {
	        $window.prompt("Copy link, then click OK.", attrs.copyUrl);
	      });
	    }
	  };
	}

/***/ },
/* 24 */
/***/ function(module, exports) {

	"use strict";
	
	countriesService.$inject = ["lodash", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	/*@ngInject*/
	function countriesService(lodash, i18n) {
	  var _ = lodash;
	  var localizedCountries = _.map(countries, function (country) {
	    return {
	      "country_code_alpha_2": country.alpha_2,
	      "country_code": 'CTRY_' + country.alpha_2,
	      "text": country.locales[i18n.locale || 'en'],
	      "common": _.include(country.tags, "common"),
	      "tags": country.tags,
	      "european": _.include(country.tags, "european_union")
	    };
	  });
	  var sortedCountries = _.sortBy(localizedCountries, function (country) {
	    return country.country_code_alpha_2 === 'US' ? '' : country.text;
	  });
	  var commonChoices = _.select(sortedCountries, function (country) {
	    return country.common;
	  });
	  var remainingChoices = _.select(sortedCountries, function (country) {
	    return !country.common;
	  });
	  var europeanCountries = _.select(sortedCountries, function (country) {
	    return country.european;
	  });
	
	  var self = this;
	  var divider = {
	    "country_code_alpha_2": null,
	    "text": "—",
	    ships_to: false,
	    isDisabled: true,
	    tags: ["divider"]
	  };
	
	  function all() {
	    return _.union(commonChoices, remainingChoices);
	  }
	
	  function asUiSelectItems(options) {
	    if (options && options.grouped) {
	      return all();
	    } else {
	      return _.union(commonChoices, [divider], remainingChoices);
	    }
	  }
	
	  function countryGrouping(item) {
	    return item.common ? i18n.t('country_groups.common') : i18n.t('country_groups.other');
	  }
	
	  function findByAlpha2(alpha2) {
	    return _.find(all(), function (country) {
	      return alpha2 === country.country_code_alpha_2;
	    });
	  }
	
	  function findByText(text) {
	    return _.findWhere(all(), { text: text });
	  }
	
	  function findByCode(code) {
	    return _.find(all(), function (country) {
	      return code === 'CTRY_' + country.country_code_alpha_2;
	    });
	  }
	
	  function findByTwoLetterCode(twoLetter) {
	    return findByCode('CTRY_' + twoLetter);
	  }
	
	  function europeanUnion() {
	    return _.map(europeanCountries, function (country) {
	      return country.country_code_alpha_2;
	    });
	  }
	
	  function alpha2InEU(code) {
	    return !!_.contains(this.europeanUnion(), code);
	  }
	
	  function alphabetized() {
	    return _.sortBy(localizedCountries, function (ctry) {
	      return ctry.text;
	    });
	  }
	
	  function zipCodeLabelKey(countryCode) {
	    if (countryCode === '' || countryCode === 'CTRY_US') {
	      return 'zip_code';
	    } else if (countryCode === 'CTRY_CA') {
	      return 'postal_code';
	    } else {
	      var postalCodeOverrides = {
	        CTRY_GB: 'post_code',
	        CTRY_PH: 'zip_code',
	        CTRY_IN: 'pin_code'
	      };
	      return postalCodeOverrides[countryCode] || 'postal_code';
	    }
	  }
	
	  _.merge(self, {
	    all: all,
	    asUiSelectItems: asUiSelectItems,
	    countryGrouping: countryGrouping,
	    findByText: findByText,
	    findByAlpha2: findByAlpha2,
	    findByCode: findByCode,
	    findByTwoLetterCode: findByTwoLetterCode,
	    europeanUnion: europeanUnion,
	    alpha2InEU: alpha2InEU,
	    alphabetized: alphabetized,
	    zipCodeLabelKey: zipCodeLabelKey
	  });
	}
	
	/* To refresh, open up a Rails console and type "puts JSON.pretty_generate(Country.in_order.map(&:as_country_service_json))" */
	var countries = [{
	  "alpha_2": "US",
	  "locales": {
	    "en": "United States",
	    "fr": "Etats-Unis",
	    "de": "Vereinigte Staaten",
	    "es": "Estados Unidos"
	  },
	  "tags": ["common"]
	}, {
	  "alpha_2": "AU",
	  "locales": {
	    "en": "Australia",
	    "fr": "Australie",
	    "de": "Australien",
	    "es": "Australia"
	  },
	  "tags": ["common"]
	}, {
	  "alpha_2": "CA",
	  "locales": {
	    "en": "Canada",
	    "fr": "Canada",
	    "de": "Kanada",
	    "es": "Canadá"
	  },
	  "tags": ["common"]
	}, {
	  "alpha_2": "DE",
	  "locales": {
	    "en": "Germany",
	    "fr": "Allemagne",
	    "de": "Deutschland",
	    "es": "Alemania"
	  },
	  "tags": ["common", "european_union"]
	}, {
	  "alpha_2": "GB",
	  "locales": {
	    "en": "United Kingdom",
	    "fr": "Royaume-Uni",
	    "de": "Großbritannien",
	    "es": "Reino Unido"
	  },
	  "tags": ["common", "european_union"]
	}, {
	  "alpha_2": "AF",
	  "locales": {
	    "en": "Afghanistan",
	    "fr": "Afghanistan",
	    "de": "Afghanistan",
	    "es": "Afganistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AX",
	  "locales": {
	    "en": "Aland Islands",
	    "fr": "Aland",
	    "de": "Alandinseln",
	    "es": "Islas Aland"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AL",
	  "locales": {
	    "en": "Albania",
	    "fr": "Albanie",
	    "de": "Albanien",
	    "es": "Albania"
	  },
	  "tags": []
	}, {
	  "alpha_2": "DZ",
	  "locales": {
	    "en": "Algeria",
	    "fr": "Algérie",
	    "de": "Algerien",
	    "es": "Argelia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AS",
	  "locales": {
	    "en": "American Samoa",
	    "fr": "Samoa américaines",
	    "de": "Amerikanisch-Samoa",
	    "es": "Samoa Americana"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AD",
	  "locales": {
	    "en": "Andorra",
	    "fr": "Andorre",
	    "de": "Andorra",
	    "es": "Andorra"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AO",
	  "locales": {
	    "en": "Angola",
	    "fr": "Angola",
	    "de": "Angola",
	    "es": "Angola"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AI",
	  "locales": {
	    "en": "Anguilla",
	    "fr": "Anguilla",
	    "de": "Anguilla",
	    "es": "Anguila"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AQ",
	  "locales": {
	    "en": "Antarctica",
	    "fr": "Antarctique",
	    "de": "Antarktis",
	    "es": "Antártida"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AG",
	  "locales": {
	    "en": "Antigua and Barbuda",
	    "fr": "Antigua-et-Barbuda",
	    "de": "Antigua und Barbuda",
	    "es": "Antigua y Barbuda"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AR",
	  "locales": {
	    "en": "Argentina",
	    "fr": "Argentine",
	    "de": "Argentinien",
	    "es": "Argentina"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AM",
	  "locales": {
	    "en": "Armenia",
	    "fr": "Arménie",
	    "de": "Armenien",
	    "es": "Armenia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AW",
	  "locales": {
	    "en": "Aruba",
	    "fr": "Aruba",
	    "de": "Aruba",
	    "es": "Aruba"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AT",
	  "locales": {
	    "en": "Austria",
	    "fr": "Autriche",
	    "de": "Österreich",
	    "es": "Austria"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "AZ",
	  "locales": {
	    "en": "Azerbaijan",
	    "fr": "Azerbaïdjan",
	    "de": "Aserbaidschan",
	    "es": "Azerbaiyán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BS",
	  "locales": {
	    "en": "Bahamas",
	    "fr": "Bahams",
	    "de": "Bahamas",
	    "es": "Bahamas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BH",
	  "locales": {
	    "en": "Bahrain",
	    "fr": "Bahreïn",
	    "de": "Bahrain",
	    "es": "Bahréin"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BD",
	  "locales": {
	    "en": "Bangladesh",
	    "fr": "Bangladesh",
	    "de": "Bangladesh",
	    "es": "Bangladesh"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BB",
	  "locales": {
	    "en": "Barbados",
	    "fr": "Barbade",
	    "de": "Barbados",
	    "es": "Barbados"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BY",
	  "locales": {
	    "en": "Belarus",
	    "fr": "Biélorussie",
	    "de": "Belarus",
	    "es": "Belarús"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BE",
	  "locales": {
	    "en": "Belgium",
	    "fr": "Belgique",
	    "de": "Belgien",
	    "es": "Bélgica"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "BZ",
	  "locales": {
	    "en": "Belize",
	    "fr": "Belize",
	    "de": "Belize",
	    "es": "Belice"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BJ",
	  "locales": {
	    "en": "Benin",
	    "fr": "Bénin",
	    "de": "Benin",
	    "es": "Benín"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BM",
	  "locales": {
	    "en": "Bermuda",
	    "fr": "Bermudes",
	    "de": "Bermuda",
	    "es": "Bermudas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BT",
	  "locales": {
	    "en": "Bhutan",
	    "fr": "Bhoutan",
	    "de": "Bhutan",
	    "es": "Bután"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BO",
	  "locales": {
	    "en": "Bolivia",
	    "fr": "Bolivie",
	    "de": "Bolivien",
	    "es": "Bolivia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BA",
	  "locales": {
	    "en": "Bosnia and Herzegovina",
	    "fr": "Bosnie-Herzégovine",
	    "de": "Bosnien-Herzegowina",
	    "es": "Bosnia y Herzegovina"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BW",
	  "locales": {
	    "en": "Botswana",
	    "fr": "Botswana",
	    "de": "Botswana",
	    "es": "Botsuana"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BV",
	  "locales": {
	    "en": "Bouvet Island",
	    "fr": "Île Bouvet",
	    "de": "Bouvetinsel",
	    "es": "Isla Bouvet"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BR",
	  "locales": {
	    "en": "Brazil",
	    "fr": "Brésil",
	    "de": "Brasilien",
	    "es": "Brasil"
	  },
	  "tags": []
	}, {
	  "alpha_2": "IO",
	  "locales": {
	    "en": "British Indian Ocean Territory",
	    "fr": "Territoire britannique de l'océan Indien",
	    "de": "Britisches Territorium im Indischen Ozean",
	    "es": "Territorio Británico del Océano Índico"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BN",
	  "locales": {
	    "en": "Brunei Darussalam",
	    "fr": "Brunei",
	    "de": "Brunei Darussalam",
	    "es": "Brunei Darussalam"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BG",
	  "locales": {
	    "en": "Bulgaria",
	    "fr": "Bulgarie",
	    "de": "Bulgarien",
	    "es": "Bulgaria"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "BF",
	  "locales": {
	    "en": "Burkina Faso",
	    "fr": "Burkina Faso",
	    "de": "Burkina Faso",
	    "es": "Burkina Faso"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BI",
	  "locales": {
	    "en": "Burundi",
	    "fr": "Burundi",
	    "de": "Burundi",
	    "es": "Burundi"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KH",
	  "locales": {
	    "en": "Cambodia",
	    "fr": "Cambodge",
	    "de": "Kambodscha",
	    "es": "Camboya"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CM",
	  "locales": {
	    "en": "Cameroon",
	    "fr": "Cameroun",
	    "de": "Kamerun",
	    "es": "Camerún"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CV",
	  "locales": {
	    "en": "Cape Verde",
	    "fr": "Cap-Vert",
	    "de": "Kap Verde",
	    "es": "Cabo Verde"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KY",
	  "locales": {
	    "en": "Cayman Islands",
	    "fr": "Îles Caïman",
	    "de": "Kaimaninseln",
	    "es": "Islas Caimán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CF",
	  "locales": {
	    "en": "Central African Republic",
	    "fr": "Centrafrique",
	    "de": "Zentralafrikanische Republik",
	    "es": "República Centroafricana"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TD",
	  "locales": {
	    "en": "Chad",
	    "fr": "Tchad",
	    "de": "Tschad",
	    "es": "Chad"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CL",
	  "locales": {
	    "en": "Chile",
	    "fr": "Chili",
	    "de": "Chile",
	    "es": "Chile"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CN",
	  "locales": {
	    "en": "China",
	    "fr": "Chine",
	    "de": "China",
	    "es": "China"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CX",
	  "locales": {
	    "en": "Christmas Island",
	    "fr": "Île Christmas",
	    "de": "Weihnachtsinsel",
	    "es": "Isla de Navidad"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CC",
	  "locales": {
	    "en": "Cocos (Keeling) Islands",
	    "fr": "Îles Cocos",
	    "de": "Cocosinseln",
	    "es": "Islas Cocos (Keeling)"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CO",
	  "locales": {
	    "en": "Colombia",
	    "fr": "Colombie",
	    "de": "Kolumbien",
	    "es": "Colombia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KM",
	  "locales": {
	    "en": "Comoros",
	    "fr": "Comores",
	    "de": "Komoren",
	    "es": "Comoras"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CG",
	  "locales": {
	    "en": "Congo",
	    "fr": "Congo",
	    "de": "Kongo",
	    "es": "Congo"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CD",
	  "locales": {
	    "en": "Congo, the Democratic Republic of the",
	    "fr": "République Démocratique du Congo",
	    "de": "Kongo, demokratische Republik",
	    "es": "República Democrática del Congo"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CK",
	  "locales": {
	    "en": "Cook Islands",
	    "fr": "Îles Cook",
	    "de": "Cookinseln",
	    "es": "Islas Cook"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CR",
	  "locales": {
	    "en": "Costa Rica",
	    "fr": "Costa Rica",
	    "de": "Costa Rica",
	    "es": "Costa Rica"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CI",
	  "locales": {
	    "en": "Cote d'Ivoire",
	    "fr": "Côte d'Ivoire",
	    "de": "Elfenbeinküste",
	    "es": "Costa de Marfil"
	  },
	  "tags": []
	}, {
	  "alpha_2": "HR",
	  "locales": {
	    "en": "Croatia",
	    "fr": "Croatie",
	    "de": "Kroatien",
	    "es": "Croacia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "CW",
	  "locales": {
	    "en": "Curacao",
	    "fr": "Curaçao",
	    "de": "Curacao",
	    "es": "Curacao"
	  },
	  "tags": []
	}, {
	  "alpha_2": "CY",
	  "locales": {
	    "en": "Cyprus",
	    "fr": "Chypre",
	    "de": "Zypern",
	    "es": "Chipre"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "CZ",
	  "locales": {
	    "en": "Czech Republic",
	    "fr": "République Tchèque",
	    "de": "Tschechische Republik",
	    "es": "República Checa"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "DK",
	  "locales": {
	    "en": "Denmark",
	    "fr": "Danemark",
	    "de": "Dänemark",
	    "es": "Dinamarca"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "DJ",
	  "locales": {
	    "en": "Djibouti",
	    "fr": "Djibouti",
	    "de": "Dschibuti",
	    "es": "Yibuti"
	  },
	  "tags": []
	}, {
	  "alpha_2": "DM",
	  "locales": {
	    "en": "Dominica",
	    "fr": "Dominique",
	    "de": "Dominica",
	    "es": "Dominica"
	  },
	  "tags": []
	}, {
	  "alpha_2": "DO",
	  "locales": {
	    "en": "Dominican Republic",
	    "fr": "République Dominicaine",
	    "de": "Dominikanische Republik",
	    "es": "República Dominicana"
	  },
	  "tags": []
	}, {
	  "alpha_2": "EC",
	  "locales": {
	    "en": "Ecuador",
	    "fr": "Equateur",
	    "de": "Ecuador",
	    "es": "Ecuador"
	  },
	  "tags": []
	}, {
	  "alpha_2": "EG",
	  "locales": {
	    "en": "Egypt",
	    "fr": "Egypte",
	    "de": "Ägypten",
	    "es": "Egipto"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SV",
	  "locales": {
	    "en": "El Salvador",
	    "fr": "El Salvador",
	    "de": "El Salvador",
	    "es": "El Salvador"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GQ",
	  "locales": {
	    "en": "Equatorial Guinea",
	    "fr": "Guinée équatoriale",
	    "de": "Äquatorialguinea",
	    "es": "Guinea Ecuatorial"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ER",
	  "locales": {
	    "en": "Eritrea",
	    "fr": "Erythrée",
	    "de": "Eritrea",
	    "es": "Eritrea"
	  },
	  "tags": []
	}, {
	  "alpha_2": "EE",
	  "locales": {
	    "en": "Estonia",
	    "fr": "Estonie",
	    "de": "Estland",
	    "es": "Estonia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "ET",
	  "locales": {
	    "en": "Ethiopia",
	    "fr": "Ethiopie",
	    "de": "Äthiopien",
	    "es": "Etiopía"
	  },
	  "tags": []
	}, {
	  "alpha_2": "FK",
	  "locales": {
	    "en": "Falkland Islands (Malvinas)",
	    "fr": "Îles Falkland (Malouines)",
	    "de": "Falklandinseln (Malwinen)",
	    "es": "Islas Malvinas (Falkland)"
	  },
	  "tags": []
	}, {
	  "alpha_2": "FO",
	  "locales": {
	    "en": "Faroe Islands",
	    "fr": "Îles Faroe",
	    "de": "Färöer Inseln",
	    "es": "Islas Feroe"
	  },
	  "tags": []
	}, {
	  "alpha_2": "FJ",
	  "locales": {
	    "en": "Fiji",
	    "fr": "Fidji",
	    "de": "Fidschi",
	    "es": "Fiji"
	  },
	  "tags": []
	}, {
	  "alpha_2": "FI",
	  "locales": {
	    "en": "Finland",
	    "fr": "Finlande",
	    "de": "Finnland",
	    "es": "Finlandia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "FR",
	  "locales": {
	    "en": "France",
	    "fr": "France",
	    "de": "Frankreich",
	    "es": "Francia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "GF",
	  "locales": {
	    "en": "French Guiana",
	    "fr": "Guyane",
	    "de": "Französisch-Guayana",
	    "es": "Guayana Francesa"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PF",
	  "locales": {
	    "en": "French Polynesia",
	    "fr": "Polynésie française",
	    "de": "Französisch-Polynesien",
	    "es": "Polinesia Francesa"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TF",
	  "locales": {
	    "en": "French Southern Territories",
	    "fr": "Terres australes et antarctiques françaises",
	    "de": "Französische Südpolar-Territorien",
	    "es": "Territorios Australes Franceses"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GA",
	  "locales": {
	    "en": "Gabon",
	    "fr": "Gabon",
	    "de": "Gabun",
	    "es": "Gabón"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GM",
	  "locales": {
	    "en": "Gambia",
	    "fr": "Gambie",
	    "de": "Gambia",
	    "es": "Gambia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GE",
	  "locales": {
	    "en": "Georgia",
	    "fr": "Géorgie",
	    "de": "Georgien",
	    "es": "Georgia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GH",
	  "locales": {
	    "en": "Ghana",
	    "fr": "Ghana",
	    "de": "Ghana",
	    "es": "Ghana"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GI",
	  "locales": {
	    "en": "Gibraltar",
	    "fr": "Gibraltar",
	    "de": "Gibraltar",
	    "es": "Gibraltar"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GR",
	  "locales": {
	    "en": "Greece",
	    "fr": "Grèce",
	    "de": "Griechenland",
	    "es": "Grecia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "GL",
	  "locales": {
	    "en": "Greenland",
	    "fr": "Groenland",
	    "de": "Grönland",
	    "es": "Groenlandia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GD",
	  "locales": {
	    "en": "Grenada",
	    "fr": "Grenade",
	    "de": "Grenada",
	    "es": "Granada"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GP",
	  "locales": {
	    "en": "Guadeloupe",
	    "fr": "Guadeloupe",
	    "de": "Guadeloupe",
	    "es": "Guadalupe"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GU",
	  "locales": {
	    "en": "Guam",
	    "fr": "Guam",
	    "de": "Guam",
	    "es": "Guam"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GT",
	  "locales": {
	    "en": "Guatemala",
	    "fr": "Guatemala",
	    "de": "Guatemala",
	    "es": "Guatemala"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GN",
	  "locales": {
	    "en": "Guinea",
	    "fr": "Guinée",
	    "de": "Guinea",
	    "es": "Guinea"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GW",
	  "locales": {
	    "en": "Guinea-Bissau",
	    "fr": "Guinée-Bissau",
	    "de": "Guinea-Bissau",
	    "es": "Guinea-Bissau"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GY",
	  "locales": {
	    "en": "Guyana",
	    "fr": "Guyana",
	    "de": "Guyana",
	    "es": "Guayana"
	  },
	  "tags": []
	}, {
	  "alpha_2": "HT",
	  "locales": {
	    "en": "Haiti",
	    "fr": "Haïti",
	    "de": "Haiti",
	    "es": "Haití"
	  },
	  "tags": []
	}, {
	  "alpha_2": "HM",
	  "locales": {
	    "en": "Heard Island and McDonald Islands",
	    "fr": "Îles Heard-et-MacDonald",
	    "de": "Heard-Insel und McDonald-Inseln",
	    "es": "Islas Heard y McDonald"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VA",
	  "locales": {
	    "en": "Holy See (Vatican City State)",
	    "fr": "Saint-Siège (Etat du Vatican)",
	    "de": "Vatikanstadt",
	    "es": "Santa Sede (Ciudad del Vaticano)"
	  },
	  "tags": []
	}, {
	  "alpha_2": "HN",
	  "locales": {
	    "en": "Honduras",
	    "fr": "Honduras",
	    "de": "Honduras",
	    "es": "Honduras"
	  },
	  "tags": []
	}, {
	  "alpha_2": "HK",
	  "locales": {
	    "en": "Hong Kong",
	    "fr": "Hong Kong",
	    "de": "Hong Kong",
	    "es": "Hong Kong"
	  },
	  "tags": []
	}, {
	  "alpha_2": "HU",
	  "locales": {
	    "en": "Hungary",
	    "fr": "Hongrie",
	    "de": "Ungarn",
	    "es": "Hungría"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "IS",
	  "locales": {
	    "en": "Iceland",
	    "fr": "Islande",
	    "de": "Island",
	    "es": "Islandia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "IN",
	  "locales": {
	    "en": "India",
	    "fr": "Inde",
	    "de": "Indien",
	    "es": "India"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ID",
	  "locales": {
	    "en": "Indonesia",
	    "fr": "Indonésie",
	    "de": "Indonesien",
	    "es": "Indonesia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "IQ",
	  "locales": {
	    "en": "Iraq",
	    "fr": "Irak",
	    "de": "Irak",
	    "es": "Iraq"
	  },
	  "tags": []
	}, {
	  "alpha_2": "IE",
	  "locales": {
	    "en": "Ireland",
	    "fr": "Irlande",
	    "de": "Irland",
	    "es": "Irlanda"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "IL",
	  "locales": {
	    "en": "Israel",
	    "fr": "Israël",
	    "de": "Israel",
	    "es": "Israel"
	  },
	  "tags": []
	}, {
	  "alpha_2": "IT",
	  "locales": {
	    "en": "Italy",
	    "fr": "Italie",
	    "de": "Italien",
	    "es": "Italia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "JM",
	  "locales": {
	    "en": "Jamaica",
	    "fr": "Jamaïque",
	    "de": "Jamaica",
	    "es": "Jamaica"
	  },
	  "tags": []
	}, {
	  "alpha_2": "JP",
	  "locales": {
	    "en": "Japan",
	    "fr": "Japon",
	    "de": "Japan",
	    "es": "Japón"
	  },
	  "tags": []
	}, {
	  "alpha_2": "JO",
	  "locales": {
	    "en": "Jordan",
	    "fr": "Jordanie",
	    "de": "Jordanien",
	    "es": "Jordania"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KZ",
	  "locales": {
	    "en": "Kazakhstan",
	    "fr": "Kazakhstan",
	    "de": "Kasachstan",
	    "es": "Kazajistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KE",
	  "locales": {
	    "en": "Kenya",
	    "fr": "Kenya",
	    "de": "Kenia",
	    "es": "Kenia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KI",
	  "locales": {
	    "en": "Kiribati",
	    "fr": "Kiribati",
	    "de": "Kiribati",
	    "es": "Kiribati"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KR",
	  "locales": {
	    "en": "Korea, Republic of",
	    "fr": "République de Corée",
	    "de": "Korea, Republik",
	    "es": "República de Corea"
	  },
	  "tags": []
	}, {
	  "alpha_2": "XK",
	  "locales": {
	    "en": "Kosovo",
	    "fr": "Kosovo",
	    "de": "Kosovo",
	    "es": "Kosovo"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KW",
	  "locales": {
	    "en": "Kuwait",
	    "fr": "Koweït",
	    "de": "Kuwait",
	    "es": "Kuwait"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KG",
	  "locales": {
	    "en": "Kyrgyzstan",
	    "fr": "Kirghizistan",
	    "de": "Kirgisistan",
	    "es": "Kirguistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LA",
	  "locales": {
	    "en": "Lao People's Democratic Republic",
	    "fr": "Laos",
	    "de": "Laos",
	    "es": "República Democrática Popular Lao"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LV",
	  "locales": {
	    "en": "Latvia",
	    "fr": "Lettonie",
	    "de": "Lettland",
	    "es": "Letonia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "LB",
	  "locales": {
	    "en": "Lebanon",
	    "fr": "Liban",
	    "de": "Libanon",
	    "es": "Líbano"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LS",
	  "locales": {
	    "en": "Lesotho",
	    "fr": "Lesotho",
	    "de": "Lesotho",
	    "es": "Lesoto"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LR",
	  "locales": {
	    "en": "Liberia",
	    "fr": "Liberia",
	    "de": "Liberien",
	    "es": "Liberia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LY",
	  "locales": {
	    "en": "Libya",
	    "fr": "Libye",
	    "de": "Libyen",
	    "es": "Libia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LI",
	  "locales": {
	    "en": "Liechtenstein",
	    "fr": "Liechtenstein",
	    "de": "Liechtenstein",
	    "es": "Liechtenstein"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LT",
	  "locales": {
	    "en": "Lithuania",
	    "fr": "Lituanie",
	    "de": "Litauen",
	    "es": "Lituania"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "LU",
	  "locales": {
	    "en": "Luxembourg",
	    "fr": "Luxembourg",
	    "de": "Luxembourg",
	    "es": "Luxemburgo"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "MO",
	  "locales": {
	    "en": "Macao",
	    "fr": "Macao",
	    "de": "Macau",
	    "es": "Macao"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MK",
	  "locales": {
	    "en": "Macedonia",
	    "fr": "Macédoine",
	    "de": "Mazedonien",
	    "es": "Macedonia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MG",
	  "locales": {
	    "en": "Madagascar",
	    "fr": "Madagascar",
	    "de": "Madagaskar",
	    "es": "Madagascar"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MW",
	  "locales": {
	    "en": "Malawi",
	    "fr": "Malawi",
	    "de": "Malawi",
	    "es": "Malawi"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MY",
	  "locales": {
	    "en": "Malaysia",
	    "fr": "Malaisie",
	    "de": "Malaysia",
	    "es": "Malasia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MV",
	  "locales": {
	    "en": "Maldives",
	    "fr": "Maldives",
	    "de": "Malediven",
	    "es": "Maldivas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ML",
	  "locales": {
	    "en": "Mali",
	    "fr": "Mali",
	    "de": "Mali",
	    "es": "Mali"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MT",
	  "locales": {
	    "en": "Malta",
	    "fr": "Malte",
	    "de": "Malta",
	    "es": "Malta"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "MH",
	  "locales": {
	    "en": "Marshall Islands",
	    "fr": "Îles Marshall",
	    "de": "Marshallinseln",
	    "es": "Islas Marshall"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MQ",
	  "locales": {
	    "en": "Martinique",
	    "fr": "Martinique",
	    "de": "Martinique",
	    "es": "Martinica"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MR",
	  "locales": {
	    "en": "Mauritania",
	    "fr": "Mauritanie",
	    "de": "Mauritanien",
	    "es": "Mauritania"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MU",
	  "locales": {
	    "en": "Mauritius",
	    "fr": "Île Maurice",
	    "de": "Mauritius",
	    "es": "Mauricio"
	  },
	  "tags": []
	}, {
	  "alpha_2": "YT",
	  "locales": {
	    "en": "Mayotte",
	    "fr": "Mayotte",
	    "de": "Mayotte",
	    "es": "Mayotte"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MX",
	  "locales": {
	    "en": "Mexico",
	    "fr": "Mexique",
	    "de": "Mexiko",
	    "es": "México"
	  },
	  "tags": []
	}, {
	  "alpha_2": "FM",
	  "locales": {
	    "en": "Micronesia, Federated States of",
	    "fr": "Micronésie (Etats fédéraux de)",
	    "de": "Mikronesien",
	    "es": "Estados Federados de Micronesia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MD",
	  "locales": {
	    "en": "Moldova, Republic of",
	    "fr": "Moldavie (République de)",
	    "de": "Moldawien",
	    "es": "Moldavia, República de"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MC",
	  "locales": {
	    "en": "Monaco",
	    "fr": "Monaco",
	    "de": "Monaco",
	    "es": "Mónaco"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MN",
	  "locales": {
	    "en": "Mongolia",
	    "fr": "Mongolie",
	    "de": "Mongolei",
	    "es": "Mongolia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ME",
	  "locales": {
	    "en": "Montenegro",
	    "fr": "Monténégro",
	    "de": "Montenegro",
	    "es": "Montenegro"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MS",
	  "locales": {
	    "en": "Montserrat",
	    "fr": "Montserrat",
	    "de": "Montserrat",
	    "es": "Montserrat"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MA",
	  "locales": {
	    "en": "Morocco",
	    "fr": "Maroc",
	    "de": "Marokko",
	    "es": "Marruecos"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MZ",
	  "locales": {
	    "en": "Mozambique",
	    "fr": "Mozambique",
	    "de": "Mosambik",
	    "es": "Mozambique"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MM",
	  "locales": {
	    "en": "Myanmar",
	    "fr": "Myanmar",
	    "de": "Myanmar",
	    "es": "Birmania"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NA",
	  "locales": {
	    "en": "Namibia",
	    "fr": "Namibie",
	    "de": "Namibia",
	    "es": "Namibia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NR",
	  "locales": {
	    "en": "Nauru",
	    "fr": "Nauru",
	    "de": "Nauru",
	    "es": "Nauru"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NP",
	  "locales": {
	    "en": "Nepal",
	    "fr": "Népal",
	    "de": "Nepal",
	    "es": "Nepal"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NL",
	  "locales": {
	    "en": "Netherlands",
	    "fr": "Pays-Bas",
	    "de": "Niederlande",
	    "es": "Países Bajos"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "AN",
	  "locales": {
	    "en": "Netherlands Antilles",
	    "fr": "Pays-Bas antillais",
	    "de": "Niederländische Antillen",
	    "es": "Antillas Neerlandesas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NC",
	  "locales": {
	    "en": "New Caledonia",
	    "fr": "Nouvelle-Calédonie",
	    "de": "Neukaledonien",
	    "es": "Nueva Caledonia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NZ",
	  "locales": {
	    "en": "New Zealand",
	    "fr": "Nouvelle-Zélande",
	    "de": "Neuseeland",
	    "es": "Nueva Zelandia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NI",
	  "locales": {
	    "en": "Nicaragua",
	    "fr": "Nicaragua",
	    "de": "Nicaragua",
	    "es": "Nicaragua"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NE",
	  "locales": {
	    "en": "Niger",
	    "fr": "Niger",
	    "de": "Niger",
	    "es": "Níger"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NG",
	  "locales": {
	    "en": "Nigeria",
	    "fr": "Nigeria",
	    "de": "Nigeria",
	    "es": "Nigeria"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NU",
	  "locales": {
	    "en": "Niue",
	    "fr": "Niue",
	    "de": "Niue",
	    "es": "Niue"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NF",
	  "locales": {
	    "en": "Norfolk Island",
	    "fr": "Île de Norfolk",
	    "de": "Norfolkinseln",
	    "es": "Isla Norfolk"
	  },
	  "tags": []
	}, {
	  "alpha_2": "MP",
	  "locales": {
	    "en": "Northern Mariana Islands",
	    "fr": "Îles Mariannes du Nord",
	    "de": "Nördliche Marianen",
	    "es": "Islas Marianas del Norte"
	  },
	  "tags": []
	}, {
	  "alpha_2": "NO",
	  "locales": {
	    "en": "Norway",
	    "fr": "Norvège",
	    "de": "Norwegen",
	    "es": "Noruega"
	  },
	  "tags": []
	}, {
	  "alpha_2": "OM",
	  "locales": {
	    "en": "Oman",
	    "fr": "Oman",
	    "de": "Oman",
	    "es": "Omán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PK",
	  "locales": {
	    "en": "Pakistan",
	    "fr": "Pakistan",
	    "de": "Pakistan",
	    "es": "Pakistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PW",
	  "locales": {
	    "en": "Palau",
	    "fr": "Palaos",
	    "de": "Palau",
	    "es": "Palau"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PS",
	  "locales": {
	    "en": "Palestine, State of",
	    "fr": "Etat de Palestine",
	    "de": "Staat Palästina",
	    "es": "Estado de Palestina"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PA",
	  "locales": {
	    "en": "Panama",
	    "fr": "Panama",
	    "de": "Panama",
	    "es": "Panamá"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PG",
	  "locales": {
	    "en": "Papua New Guinea",
	    "fr": "Papouasie-Nouvelle Guinée",
	    "de": "Papua-Neuguinea",
	    "es": "Papúa Nueva Guinea"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PY",
	  "locales": {
	    "en": "Paraguay",
	    "fr": "Paraguay",
	    "de": "Paraguay",
	    "es": "Paraguay"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PE",
	  "locales": {
	    "en": "Peru",
	    "fr": "Pérou",
	    "de": "Peru",
	    "es": "Perú"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PH",
	  "locales": {
	    "en": "Philippines",
	    "fr": "Philippines",
	    "de": "Philippinen",
	    "es": "Filipinas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PN",
	  "locales": {
	    "en": "Pitcairn",
	    "fr": "Île Pitcairn",
	    "de": "Pitcairninseln",
	    "es": "Islas Pitcairn"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PL",
	  "locales": {
	    "en": "Poland",
	    "fr": "Pologne",
	    "de": "Polen",
	    "es": "Polonia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "PT",
	  "locales": {
	    "en": "Portugal",
	    "fr": "Portugal",
	    "de": "Portugal",
	    "es": "Portugal"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "PR",
	  "locales": {
	    "en": "Puerto Rico",
	    "fr": "Porto Rico",
	    "de": "Puerto Rico",
	    "es": "Puerto Rico"
	  },
	  "tags": []
	}, {
	  "alpha_2": "QA",
	  "locales": {
	    "en": "Qatar",
	    "fr": "Qatar",
	    "de": "Katar",
	    "es": "Qatar"
	  },
	  "tags": []
	}, {
	  "alpha_2": "RO",
	  "locales": {
	    "en": "Romania",
	    "fr": "Roumanie",
	    "de": "Rumänien",
	    "es": "Rumania"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "RU",
	  "locales": {
	    "en": "Russian Federation",
	    "fr": "Russie (Fédération de)",
	    "de": "Russische Federation",
	    "es": "Federación Rusa"
	  },
	  "tags": []
	}, {
	  "alpha_2": "RW",
	  "locales": {
	    "en": "Rwanda",
	    "fr": "Rwanda",
	    "de": "Ruanda",
	    "es": "Ruanda"
	  },
	  "tags": []
	}, {
	  "alpha_2": "RE",
	  "locales": {
	    "en": "Réunion",
	    "fr": "La Réunion",
	    "de": "Réunion",
	    "es": "Reunión"
	  },
	  "tags": []
	}, {
	  "alpha_2": "BL",
	  "locales": {
	    "en": "Saint Barthélemy",
	    "fr": "Saint-Barthélemy",
	    "de": "Saint-Barthélemy",
	    "es": "San Bartolomé"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SH",
	  "locales": {
	    "en": "Saint Helena",
	    "fr": "Saint-Hélène",
	    "de": "St. Helena",
	    "es": "Santa Helena"
	  },
	  "tags": []
	}, {
	  "alpha_2": "KN",
	  "locales": {
	    "en": "Saint Kitts and Nevis",
	    "fr": "Saint-Christophe-et-Niévès",
	    "de": "St. Kitts und Nevis",
	    "es": "San Cristóbal y Nieves"
	  },
	  "tags": []
	}, {
	  "alpha_2": "LC",
	  "locales": {
	    "en": "Saint Lucia",
	    "fr": "Sainte-Lucie",
	    "de": "St. Lucia",
	    "es": "Santa Lucía"
	  },
	  "tags": []
	}, {
	  "alpha_2": "PM",
	  "locales": {
	    "en": "Saint Pierre and Miquelon",
	    "fr": "Saint-Pierre-et-Miquelon",
	    "de": "Saint Pierre und Miquelon",
	    "es": "San Pedro y Miquelón"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VC",
	  "locales": {
	    "en": "Saint Vincent and the Grenadines",
	    "fr": "Saint-Vincent-et-les-Grenadines",
	    "de": "St. Vincent und die Grenadinen",
	    "es": "San Vicente y las Granadinas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "WS",
	  "locales": {
	    "en": "Samoa",
	    "fr": "Samoa",
	    "de": "Samoa",
	    "es": "Samoa"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SM",
	  "locales": {
	    "en": "San Marino",
	    "fr": "Saint-Marin",
	    "de": "San Marino",
	    "es": "San Marino"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ST",
	  "locales": {
	    "en": "Sao Tome and Principe",
	    "fr": "Sao Tomé-et-Principe",
	    "de": "Sao Tome und Principe",
	    "es": "Santo Tomé y Príncipe"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SA",
	  "locales": {
	    "en": "Saudi Arabia",
	    "fr": "Arabie Saoudite",
	    "de": "Saudi Arabien",
	    "es": "Arabia Saudita"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SN",
	  "locales": {
	    "en": "Senegal",
	    "fr": "Sénégal",
	    "de": "Senegal",
	    "es": "Senegal"
	  },
	  "tags": []
	}, {
	  "alpha_2": "RS",
	  "locales": {
	    "en": "Serbia",
	    "fr": "Serbie",
	    "de": "Serbien",
	    "es": "Serbia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SC",
	  "locales": {
	    "en": "Seychelles",
	    "fr": "Seychelles",
	    "de": "Seychellen",
	    "es": "Seychelles"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SL",
	  "locales": {
	    "en": "Sierra Leone",
	    "fr": "Sierra Leone",
	    "de": "Sierra Leone",
	    "es": "Sierra Leona"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SG",
	  "locales": {
	    "en": "Singapore",
	    "fr": "Singapour",
	    "de": "Singapur",
	    "es": "Singapur"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SX",
	  "locales": {
	    "en": "Sint Maarten",
	    "fr": "Sint Maarten",
	    "de": "Sint Maarten",
	    "es": "Sint Maarten"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SK",
	  "locales": {
	    "en": "Slovakia",
	    "fr": "Slovaque",
	    "de": "Slowakei",
	    "es": "Eslovaquia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "SI",
	  "locales": {
	    "en": "Slovenia",
	    "fr": "Slovénie",
	    "de": "Slowenien",
	    "es": "Eslovenia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "SB",
	  "locales": {
	    "en": "Solomon Islands",
	    "fr": "Îles Salomon",
	    "de": "Salomoninseln",
	    "es": "Islas Salomón"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SO",
	  "locales": {
	    "en": "Somalia",
	    "fr": "Somalie",
	    "de": "Somalia",
	    "es": "Somalia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ZA",
	  "locales": {
	    "en": "South Africa",
	    "fr": "Afrique du Sud",
	    "de": "Südafrika",
	    "es": "Sudáfrica"
	  },
	  "tags": []
	}, {
	  "alpha_2": "GS",
	  "locales": {
	    "en": "South Georgia and the South Sandwich Islands",
	    "fr": "Géorgie du Sud-et-les Îles Sandwich du Sud",
	    "de": "Süd-Georgien und südliche Sandwichinseln",
	    "es": "Islas Georgia del Sur y Sandwich del Sur"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ES",
	  "locales": {
	    "en": "Spain",
	    "fr": "Espagne",
	    "de": "Spanien",
	    "es": "España"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "LK",
	  "locales": {
	    "en": "Sri Lanka",
	    "fr": "Sri Lanka",
	    "de": "Sri Lanka",
	    "es": "Sri Lanka"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SR",
	  "locales": {
	    "en": "Suriname",
	    "fr": "Surinam",
	    "de": "Suriname",
	    "es": "Surinam"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SJ",
	  "locales": {
	    "en": "Svalbard and Jan Mayen",
	    "fr": "Svalbard et île Jan Mayen",
	    "de": "Svalbard und Jan Mayen Insel",
	    "es": "Svalbard y Jan Mayen"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SZ",
	  "locales": {
	    "en": "Swaziland",
	    "fr": "Swaziland",
	    "de": "Swaziland",
	    "es": "Swazilandia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "SE",
	  "locales": {
	    "en": "Sweden",
	    "fr": "Suède",
	    "de": "Schweden",
	    "es": "Suecia"
	  },
	  "tags": ["european_union"]
	}, {
	  "alpha_2": "CH",
	  "locales": {
	    "en": "Switzerland",
	    "fr": "Suisse",
	    "de": "Schweiz",
	    "es": "Suiza"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TW",
	  "locales": {
	    "en": "Taiwan",
	    "fr": "Taïwan",
	    "de": "Taiwan",
	    "es": "Taiwán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TJ",
	  "locales": {
	    "en": "Tajikistan",
	    "fr": "Tadjikistan",
	    "de": "Tadshikistan",
	    "es": "Tayikistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TZ",
	  "locales": {
	    "en": "Tanzania, United Republic of",
	    "fr": "Tanzanie (République unie de)",
	    "de": "Tansania",
	    "es": "República Unida de Tanzania"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TH",
	  "locales": {
	    "en": "Thailand",
	    "fr": "Thaïlande",
	    "de": "Thailand",
	    "es": "Tailandia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TL",
	  "locales": {
	    "en": "Timor-Leste",
	    "fr": "Timor-Oriental",
	    "de": "Timor-Leste",
	    "es": "Timor Oriental"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TG",
	  "locales": {
	    "en": "Togo",
	    "fr": "Togo",
	    "de": "Togo",
	    "es": "Togo"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TK",
	  "locales": {
	    "en": "Tokelau",
	    "fr": "Tokelau",
	    "de": "Tokelau",
	    "es": "Tokelau"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TO",
	  "locales": {
	    "en": "Tonga",
	    "fr": "Tonga",
	    "de": "Tonga",
	    "es": "Tonga"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TT",
	  "locales": {
	    "en": "Trinidad and Tobago",
	    "fr": "Trinidad-et-Tobago",
	    "de": "Trinidad und Tobago",
	    "es": "Trinidad y Tobago"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TN",
	  "locales": {
	    "en": "Tunisia",
	    "fr": "Tunisie",
	    "de": "Tunesien",
	    "es": "Túnez"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TR",
	  "locales": {
	    "en": "Turkey",
	    "fr": "Turquie",
	    "de": "Türkei",
	    "es": "Turquía"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TM",
	  "locales": {
	    "en": "Turkmenistan",
	    "fr": "Turkménistan",
	    "de": "Turkmenistan",
	    "es": "Turkmenistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TC",
	  "locales": {
	    "en": "Turks and Caicos Islands",
	    "fr": "Îles Turques-et-Caïques",
	    "de": "Turks- und Caicosinseln",
	    "es": "Islas Turcos y Caicos"
	  },
	  "tags": []
	}, {
	  "alpha_2": "TV",
	  "locales": {
	    "en": "Tuvalu",
	    "fr": "Tuvalu",
	    "de": "Tuvalu",
	    "es": "Tuvalu"
	  },
	  "tags": []
	}, {
	  "alpha_2": "UG",
	  "locales": {
	    "en": "Uganda",
	    "fr": "Ouganda",
	    "de": "Uganda",
	    "es": "Uganda"
	  },
	  "tags": []
	}, {
	  "alpha_2": "UA",
	  "locales": {
	    "en": "Ukraine",
	    "fr": "Ukraine",
	    "de": "Ukraine",
	    "es": "Ucrania"
	  },
	  "tags": []
	}, {
	  "alpha_2": "AE",
	  "locales": {
	    "en": "United Arab Emirates",
	    "fr": "Emirats Arabes Unis",
	    "de": "Vereinte Arabische Emirate",
	    "es": "Emiratos Árabes Unidos"
	  },
	  "tags": []
	}, {
	  "alpha_2": "UM",
	  "locales": {
	    "en": "United States Minor Outlying Islands",
	    "fr": "Îles mineures éloignées des Etats-Unis",
	    "de": "Amerikanisch-Ozeanien",
	    "es": "Islas Ultramarinas Menores de Estados Unidos"
	  },
	  "tags": []
	}, {
	  "alpha_2": "UY",
	  "locales": {
	    "en": "Uruguay",
	    "fr": "Uruguay",
	    "de": "Uruguay",
	    "es": "Uruguay"
	  },
	  "tags": []
	}, {
	  "alpha_2": "UZ",
	  "locales": {
	    "en": "Uzbekistan",
	    "fr": "Ouzbékistan",
	    "de": "Usbekistan",
	    "es": "Uzbekistán"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VU",
	  "locales": {
	    "en": "Vanuatu",
	    "fr": "Vanuatu",
	    "de": "Vanuatu",
	    "es": "Vanuatu"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VE",
	  "locales": {
	    "en": "Venezuela",
	    "fr": "Vénézuela",
	    "de": "Venezuela",
	    "es": "Venezuela"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VN",
	  "locales": {
	    "en": "Vietnam",
	    "fr": "Viêtnam",
	    "de": "Vietnam",
	    "es": "Vietnam"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VG",
	  "locales": {
	    "en": "Virgin Islands, British",
	    "fr": "Îles Vierges britanniques",
	    "de": "Britische Jungferninseln",
	    "es": "Islas Vírgenes Británicas"
	  },
	  "tags": []
	}, {
	  "alpha_2": "VI",
	  "locales": {
	    "en": "Virgin Islands, U.S.",
	    "fr": "Îles Vierges américaines",
	    "de": "US-Jungferninseln",
	    "es": "Islas Vírgenes de los EE.UU."
	  },
	  "tags": []
	}, {
	  "alpha_2": "WF",
	  "locales": {
	    "en": "Wallis and Futuna",
	    "fr": "Wallis-et-Futuna",
	    "de": "Wallis und Futuna",
	    "es": "Wallis y Futuna"
	  },
	  "tags": []
	}, {
	  "alpha_2": "EH",
	  "locales": {
	    "en": "Western Sahara",
	    "fr": "Sahara occidental",
	    "de": "Westsahara",
	    "es": "Sahara Occidental"
	  },
	  "tags": []
	}, {
	  "alpha_2": "YE",
	  "locales": {
	    "en": "Yemen",
	    "fr": "Yémen",
	    "de": "Jemen",
	    "es": "Yemen"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ZM",
	  "locales": {
	    "en": "Zambia",
	    "fr": "Zambie",
	    "de": "Sambia",
	    "es": "Zambia"
	  },
	  "tags": []
	}, {
	  "alpha_2": "ZW",
	  "locales": {
	    "en": "Zimbabwe",
	    "fr": "Zimbabwe",
	    "de": "Simbabwe",
	    "es": "Zimbabue"
	  },
	  "tags": []
	}];
	
	exports.default = countriesService;

/***/ },
/* 25 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = csrfToken;
	/*@ngInject*/
	function csrfToken() {
	  var csrfTokenService = {};
	  var _token = $('meta[name=csrf-token]').attr('content');
	
	  csrfTokenService.getToken = function () {
	    return _token;
	  };
	
	  csrfTokenService.headerConfig = function () {
	    return { headers: { 'X-CSRF-Token': _token } };
	  };
	
	  csrfTokenService.setToken = function (newToken) {
	    _token = newToken;
	  };
	
	  return csrfTokenService;
	}

/***/ },
/* 26 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = currencies;
	function currencies() {
	  function CurrenciesService() {
	    /* To refresh, open up a Rails console and type "puts JSON.pretty_generate(Currency.visible_list.map { |cur| CurrencySerializer.new(cur).serializable_hash })" */
	    var currencies = [{
	      "iso_num": 840,
	      "symbol": "$",
	      "iso_code": "USD"
	    }, {
	      "iso_num": 978,
	      "symbol": "€",
	      "iso_code": "EUR"
	    }, {
	      "iso_num": 826,
	      "symbol": "£",
	      "iso_code": "GBP"
	    }, {
	      "iso_num": 124,
	      "symbol": "$",
	      "iso_code": "CAD"
	    }, {
	      "iso_num": 36,
	      "symbol": "$",
	      "iso_code": "AUD"
	    }];
	
	    this.asOptions = function () {
	      return _.map(currencies, function (currency) {
	        return { value: currency.iso_num, text: currency.iso_code };
	      });
	    };
	
	    this.all = function () {
	      return currencies;
	    };
	
	    this.asPartnerOptions = function () {
	      return _.map(currencies, function (currency) {
	        return { value: currency.id, text: currency.iso_code + ' (' + currency.symbol + ')' };
	      });
	    };
	
	    this.asSimpleOptions = function () {
	      return _.select(this.asOptions(), function (currencyOption) {
	        return currencyOption.text === 'USD' || currencyOption.text === 'CAD' || currencyOption.text === 'GBP';
	      });
	    };
	
	    this.forIsoNum = function (isoNum) {
	      return _.findWhere(currencies, { iso_num: parseInt(isoNum) });
	    };
	
	    this.forIsoCode = function (isoCode) {
	      return _.findWhere(currencies, { iso_code: isoCode });
	    };
	  }
	
	  return new CurrenciesService();
	}

/***/ },
/* 27 */
/***/ function(module, exports) {

	'use strict';
	
	currencyDisplay.$inject = ["currencies"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = currencyDisplay;
	/*@ngInject*/
	function currencyDisplay(currencies) {
	  return function (input, property) {
	    var currentCurrency = currencies.forIsoNum(input.currency_iso_num);
	    return currentCurrency[property || 'symbol'];
	  };
	}

/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	cuteFlash.$inject = ["$timeout", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = cuteFlash;
	/*@ngInject*/
	function cuteFlash($timeout, i18n) {
	  return {
	    restrict: 'A',
	    scope: {},
	    template: __webpack_require__(29),
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.showFlash = false;
	      scope.flashSuccess = false;
	      scope.flashMessage = '';
	
	      var DISMISS_TIMEOUT = 3000;
	
	      scope.$on('flash', function (event, args) {
	        scope.showFlash = true;
	
	        scope.flashSuccess = args.status === 'success';
	        scope.flashMessage = args.message;
	
	        $timeout(function () {
	          scope.showFlash = false;
	          scope.flashSuccess = true;
	        }, DISMISS_TIMEOUT);
	      });
	    }
	  };
	}

/***/ },
/* 29 */
/***/ function(module, exports) {

	module.exports = "<div class=\"cute-flash-relative-container am-fade\" ng-if=\"showFlash\">\n  <div class=\"cute-flash-absolute-container\">\n    <div class=\"messageNotification cute-flash\" ng-class=\"{'messageNotification--success': flashSuccess, 'messageNotification--error': !flashSuccess}\">\n      <div class=\"messageNotification-header\">{{flashMessage}}</div>\n    </div>\n  </div>\n</div>\n";

/***/ },
/* 30 */
/***/ function(module, exports) {

	'use strict';
	
	date.$inject = ["$rootScope", "_", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = date;
	/*@ngInject*/
	function date($rootScope, _, i18n) {
	  var today = new Date();
	  var months = [{ id: '', text: i18n.t('campaign_editor.misc.month'), days: 0 }, { id: 0, text: i18n.t('campaign_editor.misc.date_options.january'), days: 31 }, { id: 1, text: i18n.t('campaign_editor.misc.date_options.february'), days: 28 }, { id: 2, text: i18n.t('campaign_editor.misc.date_options.march'), days: 31 }, { id: 3, text: i18n.t('campaign_editor.misc.date_options.april'), days: 30 }, { id: 4, text: i18n.t('campaign_editor.misc.date_options.may'), days: 31 }, { id: 5, text: i18n.t('campaign_editor.misc.date_options.june'), days: 30 }, { id: 6, text: i18n.t('campaign_editor.misc.date_options.july'), days: 31 }, { id: 7, text: i18n.t('campaign_editor.misc.date_options.august'), days: 31 }, { id: 8, text: i18n.t('campaign_editor.misc.date_options.september'), days: 30 }, { id: 9, text: i18n.t('campaign_editor.misc.date_options.october'), days: 31 }, { id: 10, text: i18n.t('campaign_editor.misc.date_options.november'), days: 30 }, { id: 11, text: i18n.t('campaign_editor.misc.date_options.december'), days: 31 }];
	
	  var monthById = function monthById(id) {
	    return _.find(months, function (m) {
	      return m.id === id;
	    });
	  };
	
	  return {
	    today: today,
	    years: function years(range) {
	      var years = [{ id: '', text: i18n.t('campaign_editor.misc.year') }];
	      var startYear = today.getFullYear();
	      var endYear = startYear;
	
	      if (range > 0) endYear += range;else startYear += range;
	
	      for (var i = startYear; i <= endYear; i++) {
	        years.push({ id: i, text: i.toString() });
	      }return years;
	    },
	    months: months,
	    days: function days(month, year) {
	      var days = [{ id: '', text: i18n.t('campaign_editor.misc.day') }];
	      var startOfNextMonth = new Date(year, month + 1, 1);
	      startOfNextMonth.setDate(-1);
	      for (var i = 1; i <= startOfNextMonth.getDate() + 1; i++) {
	        days.push({ id: i, text: i.toString() });
	      }return days;
	    },
	    daysWithoutText: function daysWithoutText(monthId, year) {
	      var month = monthById(monthId);
	
	      var numberOfDays = month && month.days || 31;
	      if (year && year % 4 === 0 && month && month.id === 1) {
	        //leap years
	        numberOfDays++;
	      }
	      return _.range(1, numberOfDays + 1);
	    },
	    isNull: function isNull(option) {
	      return _.isNull(option) || _.isUndefined(option) || option.id === '';
	    },
	    dayById: function dayById(id, days) {
	      return _.find(days, function (d) {
	        return d.id === id;
	      });
	    },
	    dayByDate: function dayByDate(d, days) {
	      return this.dayById(d.getDate(), days);
	    },
	    monthById: monthById,
	    monthByDate: function monthByDate(d) {
	      return this.monthById(d.getMonth());
	    },
	    yearById: function yearById(id, years) {
	      return _.find(years, function (y) {
	        return y.id === id;
	      });
	    },
	    yearByDate: function yearByDate(d, year) {
	      return this.yearById(d.getFullYear(), year);
	    }
	  };
	}

/***/ },
/* 31 */
/***/ function(module, exports) {

	'use strict';
	
	dotdotdot.$inject = ["$timeout"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = dotdotdot;
	/*@ngInject*/
	function dotdotdot($timeout) {
	  return {
	    restrict: 'A',
	    scope: {
	      numLines: '=dotdotdotNumLines'
	    },
	    link: function link(scope, element) {
	      if (typeof scope.numLines === 'undefined') {
	        element.dotdotdot();
	      } else {
	        $timeout(function () {
	          var desiredTotalHeight = parseInt(element.css("line-height")) * scope.numLines;
	          element.dotdotdot({
	            height: desiredTotalHeight,
	            wrap: "letter",
	            watch: "window"
	          });
	        });
	      }
	    }
	  };
	}

/***/ },
/* 32 */
/***/ function(module, exports) {

	'use strict';
	
	emailSubscriber.$inject = ["$rootScope", "$http", "$window", "browser", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = emailSubscriber;
	/*@ngInject*/
	function emailSubscriber($rootScope, $http, $window, browser, i18n) {
	  var campaignSlug = $window.location.pathname.split('/')[2];
	  var baseUrl = '/private_api/campaigns/' + campaignSlug;
	
	  var button_text = i18n.t('email_subscriber.sign_up');
	  var placeholder = i18n.t('email_subscriber.your_email_address');
	
	  function setOptions(options) {
	    button_text = options.button_text || button_text;
	    placeholder = options.placeholder || placeholder;
	    $rootScope.$broadcast('EmailOptionsUpdated');
	  }
	
	  function getOptions() {
	    return {
	      button_text: button_text,
	      placeholder: placeholder
	    };
	  }
	
	  function getEmails() {
	    var csvUrl = baseUrl + '/email_subscribers';
	    browser.redirectTo(csvUrl);
	  }
	
	  function subscribeEmail(subscriber, source) {
	    source = source || 'unknown';
	    subscriber.source = source;
	    return $http.post(baseUrl + '/subscribe', { email_subscriber: subscriber });
	  }
	
	  return {
	    subscribeEmail: subscribeEmail,
	    getEmails: getEmails,
	    setOptions: setOptions,
	    getOptions: getOptions
	  };
	}

/***/ },
/* 33 */
/***/ function(module, exports) {

	'use strict';
	
	embedly.$inject = ["gon", "$http", "$q"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = embedly;
	/*@ngInject*/
	function embedly(gon, $http, $q) {
	
	  var embedlyConf = {
	    apiKey: gon && gon.embedly_conf && gon.embedly_conf.api_key,
	    apiUrl: "https://api.embed.ly/1/oembed"
	  };
	
	  return {
	    fetchVideoHtml: function fetchVideoHtml(videoUrl, width, height) {
	      var params = {
	        'key': embedlyConf.apiKey,
	        'url': videoUrl,
	        'width': width,
	        'height': height
	      };
	
	      var deferred = $q.defer();
	      $http.get(embedlyConf.apiUrl, { params: params }).success(function (response) {
	        if (_.isUndefined(response.html)) {
	          deferred.reject();
	        } else {
	          deferred.resolve(response);
	        }
	      }).error(function () {
	        deferred.reject();
	      });
	      return deferred.promise;
	    }
	  };
	}

/***/ },
/* 34 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = keys;
	/*@ngInject*/
	function keys() {
	  return {
	    restrict: 'A',
	    link: function link(scope, element, attrs) {
	      element.bind("keyup", function (event) {
	        if (event.which === 13) {
	          scope.$apply(function () {
	            scope.$eval(attrs.enterKeypress);
	          });
	          event.preventDefault();
	        }
	      });
	    }
	  };
	}

/***/ },
/* 35 */
/***/ function(module, exports) {

	'use strict';
	
	event.$inject = ["gogoEvents"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = event;
	/*@ngInject*/
	function event(gogoEvents) {
	  function isCommand(element) {
	    return ['a:', 'button:', 'button:button', 'button:submit', 'input:button', 'input:submit'].indexOf(element.tagName.toLowerCase() + ':' + (element.type || '')) >= 0;
	  }
	
	  function inferEventName(element) {
	    if (isCommand(element)) return element.innerText || element.value;
	    return element.id || element.name || element.tagName;
	  }
	
	  function isProperty(name) {
	    return name.substr(0, 5) === 'event' && ['On', 'If', 'Tags', 'Name'].indexOf(name.substr(5)) === -1;
	  }
	
	  function propertyName(name) {
	    var s = name.slice(5); // slice off the 'event' prefix
	    if (typeof s !== 'undefined' && s !== null && s.length > 0) {
	      return camelToUnderscore(s.substring(0, 1).toLowerCase() + s.substring(1));
	    } else {
	      return s;
	    }
	  }
	
	  function camelToUnderscore(str) {
	    return str.replace(/([A-Z])/g, function ($1) {
	      return "_" + $1.toLowerCase();
	    });
	  }
	
	  function eventTrack(action, properties) {
	    gogoEvents.captureEvent(action, properties);
	  }
	
	  return {
	    restrict: 'A',
	    link: function link($scope, $element, $attrs) {
	      var eventType = $attrs.eventOn;
	      var trackingData = {};
	
	      angular.forEach($attrs.$attr, function (attr, name) {
	        if (isProperty(name)) {
	          trackingData[propertyName(name)] = $attrs[name];
	          $attrs.$observe(name, function (value) {
	            trackingData[propertyName(name)] = value;
	          });
	        }
	      });
	
	      angular.element($element[0]).bind(eventType, function ($event) {
	        var eventName = $attrs.eventName || inferEventName($element[0]);
	
	        if ($attrs.eventIf) {
	          if (!$scope.$eval($attrs.eventIf)) {
	            return; // Cancel this event if we don't pass the event-if condition
	          }
	        }
	        // Allow components to pass through an expression that gets merged on to the event properties
	        // eg. event-tags='{{eventTags()}}'
	        if ($attrs.eventTags) {
	          angular.extend(trackingData, $scope.$eval($attrs.eventTags));
	        }
	        eventTrack(eventName, trackingData);
	      });
	    }
	  };
	}

/***/ },
/* 36 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function ($http, $q, gon) {
	  var fb = {
	    shareCount: null
	  };
	
	  var shareCountFetched = false;
	  var shareCountUrl = null;
	
	  fb.setUrls = function (urls) {
	    shareCountUrl = urls.shareCount;
	  };
	
	  fb.login = function (args) {
	    var deferred = $q.defer();
	    FB.login(function (response) {
	      deferred.resolve(response);
	    }, args);
	    return deferred.promise;
	  };
	
	  fb.share = function (uri, options) {
	    options = options || {};
	    var ref = '?ref=gogo__'.concat(options.iggref || 'fblk');
	    ref = options.account_id ? ref.concat('__', options.account_id) : ref;
	    var utms = options.utm_query_string ? '&'.concat(options.utm_query_string) : '';
	    var params = {
	      method: 'share',
	      href: uri + ref + utms,
	      redirect_uri: uri
	    };
	    return fb.ui(params);
	  };
	
	  fb.ui = function (params) {
	    var deferred = $q.defer();
	    FB.ui(params, function (response) {
	      if (response && !response.error_code) {
	        deferred.resolve(response);
	      } else {
	        deferred.reject(response);
	      }
	    });
	    return deferred.promise;
	  };
	
	  fb.fetchShareCount = function () {
	    if (!shareCountFetched) {
	      /* lets remove the gon dependency from this service by allowing
	       * shareCountUrl to be specified from the outside. For now,
	       * fallback to looking on the gon when that's not present
	       */
	      var url = shareCountUrl || gon.urls && gon.urls.fb_share_count_url;
	      $http.get(url).then(function (res) {
	        fb.shareCount = res.data.fb_share_count;
	      });
	    }
	
	    shareCountFetched = true;
	  };
	
	  fb.refreshAllWidgets = function () {
	    try {
	      FB.XFBML.parse();
	    } catch (ex) {}
	  };
	
	  return fb;
	};

/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	function fbTrackingPixel($window, $log, gon) {
	  return {
	    restrict: 'E',
	    scope: {},
	    template: __webpack_require__(38),
	    link: function link(scope, element, attrs) {
	      scope.shouldTrack = gon.tracking_info && gon.tracking_info.fb_pixel_id && (gon.tracking_info.amount || gon.tracking_info.amount === 0) && gon.tracking_info.currency_iso_code;
	
	      angular.element(document).ready(function () {
	        if (scope.shouldTrack) {
	          var _fbq;
	          if (!$window._fbq) {
	            $window._fbq = [];
	          }
	          _fbq = $window._fbq;
	          if (!_fbq.loaded) {
	            var fbds = undefined;
	            fbds = document.createElement('script');
	            fbds.async = true;
	            fbds.src = '//connect.facebook.net/en_US/fbds.js';
	            var s = document.getElementsByTagName('script')[0];
	            s.parentNode.insertBefore(fbds, s);
	            _fbq.loaded = true;
	          }
	          $window._fbq = $window._fbq || [];
	          _fbq.push(['track', gon.tracking_info.fb_pixel_id, {
	            'value': gon.tracking_info.amount,
	            'currency': gon.tracking_info.currency_iso_code
	          }]);
	        } else {
	          $log.debug('fbTrackingPixel directive rendered without required attributes: pixel-id, amount, currencyIsoCode');
	        }
	      });
	
	      scope.fbTrackingPixelUrl = function () {
	        return "https://www.facebook.com/tr?ev=" + gon.tracking_info.fb_pixel_id + "&cd[value]=" + gon.tracking_info.amount + "&cd[currency]=" + gon.tracking_info.currency_iso_code + "&noscript=1";
	      };
	    }
	  };
	}
	fbTrackingPixel.$inject = ['$window', '$log', 'gon'];
	
	exports.default = fbTrackingPixel;

/***/ },
/* 38 */
/***/ function(module, exports) {

	module.exports = "<noscript ng-if=\"shouldTrack\"><img height=\"1\" width=\"1\" alt=\"\" style=\"display:none\" src=\"{{fbTrackingPixelUrl()}}\"></noscript>\n";

/***/ },
/* 39 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (browser, $sce, $rootScope, $window, $cookies) {
	  var flashService = {};
	  flashService.flashes = [];
	
	  flashService.replaceMessage = function (alertLevel, message, options) {
	    _.remove(flashService.flashes, function () {
	      return true;
	    });
	    flashService.addMessage(alertLevel, message, options);
	  };
	
	  flashService.addMessage = function (alertLevel, message, options) {
	    options = _.merge({}, options);
	    if (options.html) {
	      flashService.flashes.push({
	        messageHtml: $sce.trustAsHtml(message),
	        alertLevel: alertLevel
	      });
	    } else {
	      flashService.flashes.push({
	        messageText: message,
	        alertLevel: alertLevel
	      });
	    }
	    if (options.fromOutsideAngular) {
	      $rootScope.$digest();
	    }
	    browser.scrollToTop();
	  };
	
	  flashService.addMessageForAfterRedirect = function (alertLevel, message, options) {
	    $cookies.putObject('flash', { alertLevel: alertLevel, messageText: message, options: options });
	  };
	
	  flashService.getMessageForAfterRedirect = function () {
	    var previousFlash = $cookies.getObject('flash');
	
	    if (previousFlash !== undefined) {
	      $cookies.remove('flash');
	    }
	
	    return previousFlash;
	  };
	
	  $window.showFlashMessage = function (args) {
	    flashService.addMessage(args.alertLevel, args.messageText, { fromOutsideAngular: true, html: args.html });
	  };
	
	  var previousFlash = flashService.getMessageForAfterRedirect();
	
	  if (previousFlash !== undefined) {
	    flashService.addMessage(previousFlash.alertLevel, previousFlash.messageText, previousFlash.options);
	  }
	
	  return flashService;
	};

/***/ },
/* 40 */
/***/ function(module, exports) {

	"use strict";
	
	froogaloop.$inject = ["$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = froogaloop;
	/*@ngInject*/
	function froogaloop($window) {
	  return function (sel) {
	    return $window.$f(sel);
	  };
	}

/***/ },
/* 41 */
/***/ function(module, exports) {

	'use strict';
	
	gaContentGroup.$inject = ["ga"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = gaContentGroup;
	/*@ngInject*/
	function gaContentGroup(ga) {
	  return {
	    scope: {},
	    link: function link(scope, element, attrs) {
	      // TODO EVENTS: id=qua6f fixtype=infra subsystem=analytics . maybe move gaContentGroup to superproperties
	      ga('set', 'contentGroup1', attrs.gaContentGroup);
	    }
	  };
	}

/***/ },
/* 42 */
/***/ function(module, exports) {

	'use strict';
	
	gaRaw.$inject = ["$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = gaRaw;
	/*@ngInject*/
	function gaRaw($window) {
	  return {
	    scope: {
	      'gaRawOn': '@',
	      'gaRaw': '@'
	    },
	    link: function link($scope, $element, $attrs) {
	      $element.on($attrs.gaRawOn || 'click', function () {
	        var args = $scope.$eval($scope.gaRaw);
	        $window.ga.apply(ga, args);
	      });
	    }
	  };
	}

/***/ },
/* 43 */
/***/ function(module, exports) {

	'use strict';
	
	gogoEvents.$inject = ["$http", "$window", "$log", "gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = gogoEvents;
	/*@ngInject*/
	function gogoEvents($http, $window, $log, gon) {
	  var service = {};
	  var defaultAnnotations = ['request_remote_ip', 'request_user_agent', 'request_host', 'source_bot', 'source_locale', 'source_country', 'source_region', 'source_browser', 'source_mobile', 'visitor_id', 'session_id'];
	
	  var defaultEventTags = function defaultEventTags() {
	    return _.clone(gon.default_event_tags) || {};
	  };
	
	  var superProperties = $window.thetaSuperProperties || {};
	
	  service.clearSuperProperties = function () {
	    $window.thetaSuperProperties = superProperties = {};
	  };
	
	  service.setSuperProperties = function (properties) {
	    superProperties = angular.extend(superProperties, properties);
	    $window.thetaSuperProperties = superProperties;
	  };
	
	  service.captureEvent = function (eventName, properties) {
	    if (typeof eventName === 'undefined') {
	      throw new Error('Theta event name is undefined. You must specify an analytics-name on your DOM element.');
	    }
	    var eventProperties = angular.extend(defaultEventTags(), superProperties, properties);
	
	    var data = {
	      event_types: [eventName],
	      event_data: eventProperties,
	      annotations: defaultAnnotations
	    };
	
	    return $http.post('/analytics/events/batch', { events: [data] }).success(function (response) {
	      return true;
	    }).error(function (response) {
	      $log.debug(eventName, "gogoEvent Failure");
	      $log.debug(response);
	      return false;
	    });
	  };
	
	  return service;
	}

/***/ },
/* 44 */
/***/ function(module, exports) {

	"use strict";
	
	gogoLocation.$inject = ["$window"];
	Object.defineProperty(exports, "__esModule", {
	    value: true
	});
	exports.default = gogoLocation;
	/*@ngInject*/
	function gogoLocation($window) {
	    return $window.location;
	}

/***/ },
/* 45 */
/***/ function(module, exports) {

	'use strict';
	
	googleAnalytics.$inject = ["ga"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = googleAnalytics;
	/*@ngInject*/
	function googleAnalytics(ga) {
	  function sendGAEvent(scope, ga, target) {
	    var params = ['category', 'action', 'label', 'value'];
	    var gaArgs = ['send', 'event'];
	
	    var perform = scope.performIf();
	    if (perform === undefined) {
	      // if not present, perform unconditionally
	      perform = true;
	    }
	    if (!perform) {
	      // skip submitting this event because criteria aren't right
	      return;
	    }
	
	    // Add Category, Action, Label, and Value GA parameters, in this order.
	    // Stop looking and proceed when any of the four are not present.
	    for (var i = 0; i < params.length; i++) {
	      var val = scope.$eval(params[i]);
	
	      if (!val) {
	        // skip if parameter not present
	        break;
	      }
	
	      gaArgs.push(val);
	    }
	
	    // only send events that have a category (3rd argument)
	    if (gaArgs.length > 2) {
	      ga.apply(target, gaArgs);
	    }
	  }
	
	  return {
	    restrict: 'A',
	    scope: {
	      category: '@gaEventCategory',
	      action: '@gaEventAction',
	      label: '@gaEventLabel',
	      value: '@gaEventValue',
	      performIf: '&gaEventIf'
	    },
	    link: function link(scope, element, attrs) {
	      // jQuery DOM event like click, blur, hover
	      var onEvent = attrs.gaEventOn.toLowerCase();
	      if (onEvent === 'load') {
	        sendGAEvent(scope, ga, this);
	      } else {
	        element.bind(onEvent, function () {
	          sendGAEvent(scope, ga, this);
	        });
	      }
	    }
	  };
	}

/***/ },
/* 46 */
/***/ function(module, exports) {

	'use strict';
	
	gplus.$inject = ["$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = gplus;
	/*@ngInject*/
	function gplus($window) {
	  return {
	    refreshAllWidgets: function refreshAllWidgets() {
	      var gapi = $window.gapi;
	      if (typeof gapi !== 'undefined') {
	        gapi.plusone.go();
	      }
	    }
	  };
	}

/***/ },
/* 47 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = htmlCharCounter;
	/*@ngInject*/
	function htmlCharCounter() {
	  function stripTags(html) {
	    return $('<div>' + html + '</div>').text().replace(/\t+/g, " ").replace(/\n/g, "").replace(/^\s/g, "");
	  }
	
	  return function (input, maxLength, delimiter) {
	    var charsLeft = maxLength;
	
	    if (input) {
	      charsLeft = maxLength - stripTags(input).length;
	    }
	
	    return charsLeft.toString() + " " + (delimiter ? delimiter : "/") + " " + maxLength;
	  };
	}

/***/ },
/* 48 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = htmlWrapped;
	/*@ngInject*/
	function htmlWrapped() {
	  return function (text, tag) {
	    var tagEl = $(tag);
	    tagEl.text(text);
	    var wrapperEl = $("<div>");
	    wrapperEl.append(tagEl);
	    return wrapperEl.html();
	  };
	}

/***/ },
/* 49 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (i18n) {
	  return {
	    scope: true,
	    link: function link($scope) {
	      $scope.i18n = i18n;
	    }
	  };
	};

/***/ },
/* 50 */
/***/ function(module, exports) {

	'use strict';
	
	i18n.$inject = ["$sce", "gon", "I18nRails", "$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = i18n;
	/*@ngInject*/
	function i18n($sce, gon, I18nRails, $window) {
	  var currentLocale = I18nRails.locale;
	  if ($window.moment) {
	    $window.moment.locale(currentLocale);
	  }
	  var domain = gon.domain;
	
	  function translateAdjustingKeyForGenerosity(key, options) {
	    if (typeof gon !== 'undefined' && domain === 'generosity') {
	      return generosityTranslate(key, options);
	    } else {
	      return translate(key, options);
	    }
	  }
	
	  function generosityTranslate(key, options) {
	    var genKey = 'generosity.' + key;
	    return translate(genKey, options);
	  }
	
	  function localeGlobalSafe(func) {
	    var oldLocale = I18nRails.locale;
	    var returnVal = null;
	    I18nRails.locale = currentLocale;
	    try {
	      returnVal = func();
	    } finally {
	      I18nRails.locale = oldLocale;
	    }
	    return returnVal;
	  }
	
	  function translate(key, options) {
	    return localeGlobalSafe(function () {
	      var translation = I18nRails.t(key, options);
	      if (key.match(/html$/)) {
	        return $sce.trustAsHtml(translation);
	      } else {
	        return translation;
	      }
	    });
	  }
	
	  function strftime(object, format) {
	    return localeGlobalSafe(function () {
	      return I18nRails.strftime(object, format);
	    });
	  }
	
	  function setLocale(newLocale) {
	    currentLocale = newLocale || I18nRails.defaultLocale;
	    this.locale = currentLocale;
	    $window.moment.locale(currentLocale);
	  }
	
	  function localize(date, options) {
	    return localeGlobalSafe(function () {
	      var format = I18nRails.lookup('date.formats.' + options.format);
	      return strftime(date, format);
	    });
	  }
	
	  return {
	    locale: currentLocale,
	    setLocale: setLocale,
	    strftime: strftime,
	    t: translate,
	    l: localize,
	    pt: translateAdjustingKeyForGenerosity
	  };
	}

/***/ },
/* 51 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (CKEDITOR, csrfToken) {
	  return {
	    defaultOptions: {
	      language: 'en',
	      allowedContent: true,
	      entities: false,
	      forcePasteAsPlainText: true,
	      uploadUrl: (0, _legacy.attachmentsUploadCkImagePath)(),
	      filebrowserImageUploadUrl: (0, _legacy.attachmentsUploadCkDialogImagePath)(),
	      removeDialogTabs: 'image:advanced;link:advanced;image:Link'
	    },
	
	    onReady: function onReady(editor, onReadyCallback) {
	      editor.uploadRepository.editor.on('fileUploadRequest', function (event) {
	        event.data.fileLoader.xhr.setRequestHeader('X-CSRF-Token', csrfToken.getToken());
	      });
	
	      CKEDITOR.lang.en.format.tag_p = 'Paragraph';
	      CKEDITOR.lang.en.format.tag_h2 = 'Header 1';
	      CKEDITOR.lang.en.format.tag_h3 = 'Header 2';
	
	      if (onReadyCallback) {
	        onReadyCallback(editor);
	      }
	    }
	  };
	};
	
	var _legacy = __webpack_require__(52);

/***/ },
/* 52 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.accountSessionPath = accountSessionPath;
	exports.attachmentsEmbedPath = attachmentsEmbedPath;
	exports.attachmentsUploadCkDialogImagePath = attachmentsUploadCkDialogImagePath;
	exports.attachmentsUploadCkImagePath = attachmentsUploadCkImagePath;
	exports.attachmentsUploadFilePath = attachmentsUploadFilePath;
	exports.attachmentsUploadImagePath = attachmentsUploadImagePath;
	function accountSessionPath() {
	  return "/accounts/sign_in";
	}
	function attachmentsEmbedPath() {
	  return "/api/attachments/embed";
	}
	function attachmentsUploadCkDialogImagePath() {
	  return "/api/attachments/upload_ck_dialog_image";
	}
	function attachmentsUploadCkImagePath() {
	  return "/api/attachments/upload_ck_image";
	}
	function attachmentsUploadFilePath() {
	  return "/api/attachments/upload_file";
	}
	function attachmentsUploadImagePath() {
	  return "/api/attachments/upload_image";
	}

/***/ },
/* 53 */
/***/ function(module, exports) {

	"use strict";
	
	iggCurrency.$inject = ["currencies", "numberFilter", "$sce"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = iggCurrency;
	/*@ngInject*/
	function iggCurrency(currencies, numberFilter, $sce) {
	  return function (input, isoNumber, optionsString) {
	    var options = (optionsString || '').split(",");
	    var currentCurrency = currencies.forIsoNum(isoNumber);
	
	    var precision = options.indexOf("cents") >= 0 ? 2 : 0;
	    var value = numberFilter(input || 0, precision);
	    var symbolicValue = currentCurrency.symbol + value;
	    var isoCode = currentCurrency.iso_code;
	
	    if (options.indexOf("html") >= 0) {
	      var markup = '<span class="currency"><span>' + symbolicValue + '</span><em>' + isoCode + '</em></span>';
	      return $sce.trustAsHtml(markup);
	    } else if (options.indexOf("separated") >= 0) {
	      return { "symbolicValue": symbolicValue, "isoCode": isoCode };
	    } else if (options.indexOf('noIso') >= 0) {
	      return symbolicValue;
	    } else {
	      return symbolicValue + " " + isoCode;
	    }
	  };
	}

/***/ },
/* 54 */
/***/ function(module, exports) {

	"use strict";
	
	iggExternal.$inject = ["callback"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = iggExternal;
	/*@ngInject*/
	function iggExternal(callback) {
	  callback.apply(this, arguments);
	}

/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	iggPopover.$inject = ["$popover", "$sce", "$compile", "$timeout"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = iggPopover;
	/*@ngInject*/
	function iggPopover($popover, $sce, $compile, $timeout) {
	  return {
	    restrict: 'A',
	    transclude: true,
	    replace: true,
	    template: function template(elem, attrs) {
	      if (attrs.text) {
	        return __webpack_require__(56);
	      } else {
	        return __webpack_require__(57);
	      }
	    },
	    scope: {
	      placement: '@',
	      popoverIcon: '@',
	      text: '@'
	    },
	    link: function link(scope, element, attributes, controller, transclude) {
	      var placement = scope.placement || 'right';
	      scope.iconClass = 'infoBubble';
	      if (scope.popoverIcon) {
	        scope.iconClass = null;
	      }
	      transclude(function (clone) {
	        var ctx = $("<div></div>");
	        clone.appendTo(ctx);
	        var compiledElement = $compile(ctx)(scope);
	        element.show();
	        $timeout(function () {
	          var popoverOptions = {
	            content: $sce.trustAsHtml(compiledElement.html()),
	            trigger: 'hover click',
	            html: true,
	            placement: placement,
	            autoClose: true
	          };
	          if (typeof attributes.closeDelay !== 'undefined') {
	            popoverOptions.delay = { show: 0, hide: 1500 };
	          }
	          $popover(element, popoverOptions);
	        });
	      });
	    }
	  };
	}

/***/ },
/* 56 */
/***/ function(module, exports) {

	module.exports = "<span>{{text}}</span>\n";

/***/ },
/* 57 */
/***/ function(module, exports) {

	module.exports = "<span ng-class=\"iconClass\"><svg-icon icon=\"{{popoverIcon || 'icon-icon-help'}}\"></svg-icon></span>\n";

/***/ },
/* 58 */
/***/ function(module, exports) {

	'use strict';
	
	iggProjectCard.$inject = ["projectCard"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = iggProjectCard;
	/*@ngInject*/
	function iggProjectCard(projectCard) {
	  return {
	    restrict: 'A',
	    link: function link(scope, element) {
	      projectCard.setupDelayedImageLoad(element);
	      projectCard.ellipsizeProjectCardTagline(element);
	    }
	  };
	}

/***/ },
/* 59 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = individualAvatar;
	/*@ngInject*/
	function individualAvatar() {
	  return {
	    scope: {
	      individualAvatar: '@'
	    },
	    template: __webpack_require__(60),
	    restrict: 'A',
	    replace: true,
	    link: function link($scope, $element) {}
	  };
	}

/***/ },
/* 60 */
/***/ function(module, exports) {

	module.exports = "<div class=\"individualAvatar\">\n  <img ng-if=\"individualAvatar\" ng-src=\"{{individualAvatar}}\" />\n  <span class=\"missingAvatar\" ng-if=\"!individualAvatar\"></span>\n</div>\n";

/***/ },
/* 61 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function () {
	  return {
	    scope: {
	      message: '@',
	      linkText: '@',
	      link: '@',
	      onGenerosity: '@'
	    },
	    template: __webpack_require__(62),
	    link: function link(scope, element) {
	      scope.hideMessage = function () {
	        element.addClass('hidden');
	      };
	    }
	  };
	};

/***/ },
/* 62 */
/***/ function(module, exports) {

	module.exports = "<div class=\"container i-info-message-container\">\n  <span class=\"info-message-text i-info-message-text\">\n    <span class=\"info-message-message\">{{::message}}</span> <a ng-href=\"{{::link}}\" class=\"info-message-link i-cta-2--informationBar small-ghost-cta--dark\" ng-if=\"link\">{{::linkText}}</a>\n  </span>\n  <svg-icon icon=\"icon-icon-close\" ng-class=\"{'container': onGenerosity}\" ng-click=\"hideMessage()\"></svg-icon>\n</div>\n";

/***/ },
/* 63 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function ($http, $interpolate) {
	  var urls = { show: null };
	
	  return {
	    setUrls: function setUrls(u) {
	      if (angular.isUndefined(u.show)) {
	        throw new Error('a show url is required');
	      }
	
	      urls.show = u.show;
	    },
	
	    get: function get(jobId) {
	      var url = $interpolate(urls.show)({ id: jobId });
	      return $http.get(url);
	    }
	  };
	};

/***/ },
/* 64 */
/***/ function(module, exports) {

	'use strict';
	
	jobStatusPoller.$inject = ["$timeout", "jobStatusApi"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = jobStatusPoller;
	/*@ngInject*/
	function jobStatusPoller($timeout, jobStatusApi) {
	  var canceled = false;
	
	  return {
	    poll: function poll(uuid, period, callback) {
	      if (typeof callback !== 'function') {
	        throw new Error('a callback function is required');
	      }
	
	      function onSuccess(response) {
	        if (response.data.status === 'queued' || response.data.status === 'working') {
	          $timeout(function () {
	            if (!canceled) {
	              jobStatusApi.get(uuid).then(onSuccess, onFailure);
	            }
	          }, period);
	        }
	        callback(response);
	      }
	
	      function onFailure(response) {
	        callback(null);
	      }
	
	      jobStatusApi.get(uuid).then(onSuccess, onFailure);
	    },
	    cancel: function cancel() {
	      canceled = true;
	    },
	    reset: function reset() {
	      canceled = false;
	    }
	  };
	}

/***/ },
/* 65 */
/***/ function(module, exports) {

	'use strict';
	
	konami.$inject = ["browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = konami;
	/*@ngInject*/
	function konami(browser) {
	  return {
	    restrict: 'A',
	    link: function link(scope, element, attrs) {
	      var konamiSequence = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
	      var sequenceIndex = 0;
	
	      $(element).on('keydown', function (ev) {
	        if (ev.keyCode === konamiSequence[sequenceIndex]) {
	          sequenceIndex += 1;
	          if (sequenceIndex === konamiSequence.length) {
	            browser.redirectTo('https://www.indiegogo.com/explore/gaming');
	          }
	        } else {
	          sequenceIndex = 0;
	        }
	      });
	    }
	  };
	}

/***/ },
/* 66 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	pagination.$inject = ["i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = pagination;
	/*@ngInject*/
	function pagination(i18n) {
	  return {
	    restrict: 'A',
	    scope: {
	      pagination: "="
	    },
	    transclude: false,
	    replace: false,
	    template: __webpack_require__(67),
	    link: function link(scope, element, attrs, nullController, transclude) {
	      scope.i18n = i18n;
	      var MAX_PAGES = 9;
	      var SURROUNDING_PAGES = Math.floor(MAX_PAGES / 2);
	
	      var inMiddle = function inMiddle(pagination) {
	        // there are more than 4 pages to either side of the current page
	        return pagination.data.current - SURROUNDING_PAGES >= 1 && pagination.data.current + SURROUNDING_PAGES <= pagination.data.pages;
	      };
	
	      var morePages = function morePages(pagination) {
	        return pagination.data.pages > MAX_PAGES;
	      };
	
	      var atEnd = function atEnd(pagination) {
	        return pagination.data.current >= pagination.data.pages - SURROUNDING_PAGES;
	      };
	
	      scope.generatePageRange = function (pagination) {
	        if (inMiddle(pagination)) {
	          // the current page can fit comfortably in the middle of all pages
	          // (as defined by SURROUNDING_PAGES, so there need to be 4 pages on either side)
	          var start = pagination.data.current - SURROUNDING_PAGES;
	          var end = pagination.data.current + SURROUNDING_PAGES;
	          return _.range(start, end + 1);
	        } else if (atEnd(pagination) && morePages(pagination)) {
	          return _.range(pagination.data.pages - MAX_PAGES + 1, pagination.data.pages + 1);
	        }
	
	        // the normal case is to just return the number of pages we have, starting at 1.
	        return _.range(1, Math.min(MAX_PAGES, pagination.data.pages) + 1);
	      };
	
	      scope.isCurrentPage = function (pageNumber) {
	        return scope.pagination.data.current === pageNumber;
	      };
	
	      scope.showBeginningPageGap = function (pagination) {
	        return scope.generatePageRange(pagination)[0] != 1;
	      };
	
	      scope.showEndingPageGap = function (pagination) {
	        var range = scope.generatePageRange(pagination);
	        return range[range.length - 1] != pagination.data.pages;
	      };
	    }
	  };
	}

/***/ },
/* 67 */
/***/ function(module, exports) {

	module.exports = "<div class=\"js-pagination-links i-pagination-directive-links\" ng-if=\"pagination.data.pages > 1\">\n  <div class=\"pagination-previous\" ng-if=\"pagination.data.previous\" class=\"pagination-previous\">\n    <a class=\"first-link unselected\" ng-click=\"pagination.getPage({ page: 1 })\">{{i18n.t('will_paginate.first_label')}}</a>\n    <a class=\"previous-link unselected\" ng-click=\"pagination.getPage({ page: pagination.data.previous })\">{{i18n.t('will_paginate.previous_label')}}</a><span class=\"page-gap\" ng-if=\"showBeginningPageGap(pagination)\">{{i18n.t('will_paginate.page_gap')}}</span>\n  </div>\n  <div ng-class=\"{'selected-page-number': isCurrentPage(pageNumber), 'page-number': true}\" ng-repeat=\"pageNumber in generatePageRange(pagination)\">\n    <div ng-if=\"!isCurrentPage(pageNumber)\">\n      <a class=\"page-link page-{{pageNumber}} unselected\" ng-click=\"pagination.getPage({page: pageNumber})\">{{ pageNumber}}</a>\n    </div>\n    <div ng-if=\"isCurrentPage(pageNumber)\">\n      <span class=\"current selected\">{{pageNumber}}</span>\n    </div>\n  </div>\n  <div ng-class=\"{'pagination-next': true, 'i-hidden' : !pagination.data.next}\">\n    <span class=\"page-gap\" ng-if=\"showEndingPageGap(pagination)\">{{i18n.t('will_paginate.page_gap')}}</span>\n    <a class=\"next-link unselected\" ng-click=\"pagination.getPage({page: pagination.data.next})\">{{i18n.t('will_paginate.next_label')}}</a>\n    <a class=\"last-link unselected\" ng-click=\"pagination.getPage({page: pagination.data.pages})\">{{i18n.t('will_paginate.last_label')}}</a>\n  </div>\n</div>\n";

/***/ },
/* 68 */
/***/ function(module, exports) {

	'use strict';
	
	pledgeShareService.$inject = ["gon", "i18n", "fb"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = pledgeShareService;
	/*@ngInject*/
	function pledgeShareService(gon, i18n, fb) {
	  return {
	    postToFacebook: function postToFacebook(options) {
	      var namespaceAction = gon.domain === 'generosity' ? 'donate' : 'contribute';
	      var campaignActionProp = gon.domain === 'generosity' ? 'fundraiser' : 'campaign';
	      var actionProps = {};
	      actionProps[campaignActionProp] = options.url;
	      actionProps.contributor = options.contributor_url;
	
	      var params = {
	        method: 'share_open_graph',
	        display: 'popup',
	        name: i18n.t("help_make_it_happen_for_") + " " + options.title,
	        picture: options.picture_url,
	        caption: options.title,
	        description: options.tagline,
	        action_type: options.namespace + ':' + namespaceAction,
	        action_properties: JSON.stringify(actionProps)
	      };
	      return fb.ui(params);
	    },
	    twitterHref: function twitterHref(project) {
	      if (gon.domain === 'generosity') {
	        return "https://twitter.com/intent/tweet?text=" + encodeURIComponent(i18n.t("generosity.social.twitter", {
	          fundraiser_title: project.title,
	          fundraiser_url: project.url
	        })) + "&counturl=" + encodeURIComponent(project.counturl);
	      } else {
	        return "https://twitter.com/intent/tweet?url=" + encodeURIComponent(project.url) + "&text=" + encodeURIComponent(i18n.t("help_make_it_happen_for_") + " " + project.title) + "&via=indiegogo&related=indiegogo&hashtags=indiegogo&counturl=" + encodeURIComponent(project.counturl);
	      }
	    },
	    emailHref: function emailHref(project) {
	      var body, subject;
	      if (gon.domain === 'generosity') {
	        body = i18n.t('generosity.social.email', {
	          fundraiser_url: project.url,
	          fundraiser_title: project.title
	        });
	        subject = i18n.t('generosity.social.email_subject', { project_title: project.title });
	      } else {
	        body = i18n.t('email_share_body', {
	          project_title: project.title,
	          project_url: project.url
	        });
	        subject = i18n.t('email_share_subject', { project_title: project.title });
	      }
	      return "mailto:?body=" + encodeURIComponent(body) + "&subject=" + encodeURIComponent(subject);
	    }
	  };
	}

/***/ },
/* 69 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = projectCard;
	/*@ngInject*/
	function projectCard() {
	  function setupDelayedImageLoad(element) {
	    var $imgContainer = element.find(".i-img");
	    if ($imgContainer.length > 0) {
	      var $img = $("<img />");
	      $img.attr("src", $imgContainer.data("src"));
	      $imgContainer.replaceWith($img);
	    }
	  }
	
	  function ellipsizeProjectCardTagline(element) {
	    var $content = element.find(".i-content");
	    var $title = $content.find(".i-title");
	    var titleLineHeight = parseInt($title.css("line-height"));
	    $title.dotdotdot({
	      height: titleLineHeight * 3,
	      wrap: "letter",
	      watch: "window"
	    });
	
	    var $tagline = $content.find(".i-tagline");
	    var taglineHeight = $content.height() - $title.height();
	
	    var $partner = $content.find(".i-partner-name");
	    if ($partner.length > 0) {
	      var partnerLineHeight = parseInt($partner.css("line-height"));
	      $partner.dotdotdot({
	        height: partnerLineHeight * 1,
	        watch: "window"
	      });
	      taglineHeight = taglineHeight - $partner.height() - parseInt($partner.css("margin-top"));
	    }
	    $tagline.css("max-height", taglineHeight);
	    $tagline.dotdotdot({
	      watch: 'window'
	    });
	  }
	
	  return {
	    setupDelayedImageLoad: setupDelayedImageLoad,
	    ellipsizeProjectCardTagline: ellipsizeProjectCardTagline
	  };
	}

/***/ },
/* 70 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = regions;
	/*@ngInject*/
	function regions() {
	  function RegionsService() {
	    /* To refresh, open up a Rails console and type "puts JSON.pretty_generate(Code.region_service_json_hash)" */
	    var regions = [{
	      "code": "STTE_CAAB",
	      "text": "Alberta",
	      "two_letter": "AB",
	      "country": "ca"
	    }, {
	      "code": "STTE_CABC",
	      "text": "British Columbia",
	      "two_letter": "BC",
	      "country": "ca"
	    }, {
	      "code": "STTE_CAMB",
	      "text": "Manitoba",
	      "two_letter": "MB",
	      "country": "ca"
	    }, {
	      "code": "STTE_CANB",
	      "text": "New Brunswick",
	      "two_letter": "NB",
	      "country": "ca"
	    }, {
	      "code": "STTE_CANL",
	      "text": "Newfoundland and Labrador",
	      "two_letter": "NL",
	      "country": "ca"
	    }, {
	      "code": "STTE_CANS",
	      "text": "Nova Scotia",
	      "two_letter": "NS",
	      "country": "ca"
	    }, {
	      "code": "STTE_CANT",
	      "text": "Northwest Territories",
	      "two_letter": "NT",
	      "country": "ca"
	    }, {
	      "code": "STTE_CANU",
	      "text": "Nunavut",
	      "two_letter": "NU",
	      "country": "ca"
	    }, {
	      "code": "STTE_CAON",
	      "text": "Ontario",
	      "two_letter": "ON",
	      "country": "ca"
	    }, {
	      "code": "STTE_CAPE",
	      "text": "Prince Edward Island",
	      "two_letter": "PE",
	      "country": "ca"
	    }, {
	      "code": "STTE_CAQC",
	      "text": "Quebec",
	      "two_letter": "QC",
	      "country": "ca"
	    }, {
	      "code": "STTE_CASK",
	      "text": "Saskatchewan",
	      "two_letter": "SK",
	      "country": "ca"
	    }, {
	      "code": "STTE_CAYT",
	      "text": "Yukon",
	      "two_letter": "YT",
	      "country": "ca"
	    }, {
	      "code": "STTE_USAK",
	      "text": "Alaska",
	      "two_letter": "AK",
	      "country": "us"
	    }, {
	      "code": "STTE_USAL",
	      "text": "Alabama",
	      "two_letter": "AL",
	      "country": "us"
	    }, {
	      "code": "STTE_USAR",
	      "text": "Arkansas",
	      "two_letter": "AR",
	      "country": "us"
	    }, {
	      "code": "STTE_USAZ",
	      "text": "Arizona",
	      "two_letter": "AZ",
	      "country": "us"
	    }, {
	      "code": "STTE_USCA",
	      "text": "California",
	      "two_letter": "CA",
	      "country": "us"
	    }, {
	      "code": "STTE_USCO",
	      "text": "Colorado",
	      "two_letter": "CO",
	      "country": "us"
	    }, {
	      "code": "STTE_USCT",
	      "text": "Connecticut",
	      "two_letter": "CT",
	      "country": "us"
	    }, {
	      "code": "STTE_USDC",
	      "text": "District of Columbia",
	      "two_letter": "DC",
	      "country": "us"
	    }, {
	      "code": "STTE_USDE",
	      "text": "Delaware",
	      "two_letter": "DE",
	      "country": "us"
	    }, {
	      "code": "STTE_USFL",
	      "text": "Florida",
	      "two_letter": "FL",
	      "country": "us"
	    }, {
	      "code": "STTE_USGA",
	      "text": "Georgia",
	      "two_letter": "GA",
	      "country": "us"
	    }, {
	      "code": "STTE_USHI",
	      "text": "Hawaii",
	      "two_letter": "HI",
	      "country": "us"
	    }, {
	      "code": "STTE_USIA",
	      "text": "Iowa",
	      "two_letter": "IA",
	      "country": "us"
	    }, {
	      "code": "STTE_USID",
	      "text": "Idaho",
	      "two_letter": "ID",
	      "country": "us"
	    }, {
	      "code": "STTE_USIL",
	      "text": "Illinois",
	      "two_letter": "IL",
	      "country": "us"
	    }, {
	      "code": "STTE_USIN",
	      "text": "Indiana",
	      "two_letter": "IN",
	      "country": "us"
	    }, {
	      "code": "STTE_USKS",
	      "text": "Kansas",
	      "two_letter": "KS",
	      "country": "us"
	    }, {
	      "code": "STTE_USKY",
	      "text": "Kentucky",
	      "two_letter": "KY",
	      "country": "us"
	    }, {
	      "code": "STTE_USLA",
	      "text": "Louisiana",
	      "two_letter": "LA",
	      "country": "us"
	    }, {
	      "code": "STTE_USMA",
	      "text": "Massachusetts",
	      "two_letter": "MA",
	      "country": "us"
	    }, {
	      "code": "STTE_USMD",
	      "text": "Maryland",
	      "two_letter": "MD",
	      "country": "us"
	    }, {
	      "code": "STTE_USME",
	      "text": "Maine",
	      "two_letter": "ME",
	      "country": "us"
	    }, {
	      "code": "STTE_USMI",
	      "text": "Michigan",
	      "two_letter": "MI",
	      "country": "us"
	    }, {
	      "code": "STTE_USMN",
	      "text": "Minnesota",
	      "two_letter": "MN",
	      "country": "us"
	    }, {
	      "code": "STTE_USMO",
	      "text": "Missouri",
	      "two_letter": "MO",
	      "country": "us"
	    }, {
	      "code": "STTE_USMS",
	      "text": "Mississippi",
	      "two_letter": "MS",
	      "country": "us"
	    }, {
	      "code": "STTE_USMT",
	      "text": "Montana",
	      "two_letter": "MT",
	      "country": "us"
	    }, {
	      "code": "STTE_USNC",
	      "text": "North Carolina",
	      "two_letter": "NC",
	      "country": "us"
	    }, {
	      "code": "STTE_USND",
	      "text": "North Dakota",
	      "two_letter": "ND",
	      "country": "us"
	    }, {
	      "code": "STTE_USNE",
	      "text": "Nebraska",
	      "two_letter": "NE",
	      "country": "us"
	    }, {
	      "code": "STTE_USNH",
	      "text": "New Hampshire",
	      "two_letter": "NH",
	      "country": "us"
	    }, {
	      "code": "STTE_USNJ",
	      "text": "New Jersey",
	      "two_letter": "NJ",
	      "country": "us"
	    }, {
	      "code": "STTE_USNM",
	      "text": "New Mexico",
	      "two_letter": "NM",
	      "country": "us"
	    }, {
	      "code": "STTE_USNV",
	      "text": "Nevada",
	      "two_letter": "NV",
	      "country": "us"
	    }, {
	      "code": "STTE_USNY",
	      "text": "New York",
	      "two_letter": "NY",
	      "country": "us"
	    }, {
	      "code": "STTE_USOH",
	      "text": "Ohio",
	      "two_letter": "OH",
	      "country": "us"
	    }, {
	      "code": "STTE_USOK",
	      "text": "Oklahoma",
	      "two_letter": "OK",
	      "country": "us"
	    }, {
	      "code": "STTE_USOR",
	      "text": "Oregon",
	      "two_letter": "OR",
	      "country": "us"
	    }, {
	      "code": "STTE_USPA",
	      "text": "Pennsylvania",
	      "two_letter": "PA",
	      "country": "us"
	    }, {
	      "code": "STTE_USRI",
	      "text": "Rhode Island",
	      "two_letter": "RI",
	      "country": "us"
	    }, {
	      "code": "STTE_USSC",
	      "text": "South Carolina",
	      "two_letter": "SC",
	      "country": "us"
	    }, {
	      "code": "STTE_USSD",
	      "text": "South Dakota",
	      "two_letter": "SD",
	      "country": "us"
	    }, {
	      "code": "STTE_USTN",
	      "text": "Tennessee",
	      "two_letter": "TN",
	      "country": "us"
	    }, {
	      "code": "STTE_USTX",
	      "text": "Texas",
	      "two_letter": "TX",
	      "country": "us"
	    }, {
	      "code": "STTE_USUT",
	      "text": "Utah",
	      "two_letter": "UT",
	      "country": "us"
	    }, {
	      "code": "STTE_USVA",
	      "text": "Virginia",
	      "two_letter": "VA",
	      "country": "us"
	    }, {
	      "code": "STTE_USVT",
	      "text": "Vermont",
	      "two_letter": "VT",
	      "country": "us"
	    }, {
	      "code": "STTE_USWA",
	      "text": "Washington",
	      "two_letter": "WA",
	      "country": "us"
	    }, {
	      "code": "STTE_USWI",
	      "text": "Wisconsin",
	      "two_letter": "WI",
	      "country": "us"
	    }, {
	      "code": "STTE_USWV",
	      "text": "West Virginia",
	      "two_letter": "WV",
	      "country": "us"
	    }, {
	      "code": "STTE_USWY",
	      "text": "Wyoming",
	      "two_letter": "WY",
	      "country": "us"
	    }];
	    var states = _.select(regions, function (region) {
	      return region.country === 'us';
	    });
	    var provinces = _.select(regions, function (region) {
	      return region.country === 'ca';
	    });
	
	    function regionsAsOptions(regions) {
	      return _.map(regions, function (region) {
	        return { value: region.code, text: region.text, two_letter: region.two_letter };
	      });
	    }
	
	    this.all = function () {
	      return regions;
	    };
	
	    this.getStates = function () {
	      return states;
	    };
	
	    this.getProvinces = function () {
	      return provinces;
	    };
	
	    this.statesAsOptions = function () {
	      return regionsAsOptions(states);
	    };
	    this.provincesAsOptions = function () {
	      return regionsAsOptions(provinces);
	    };
	    this.byCode = function (code) {
	      return _.findWhere(regions, { code: code });
	    };
	
	    this.byTwoLetterCode = function (code) {
	      if (code.match(/^STTE_/)) {
	        return _.findWhere(regions, { code: code });
	      }
	      return _.findWhere(regions, { two_letter: code });
	    };
	
	    this.byText = function (text) {
	      return _.findWhere(regions, { text: text });
	    };
	
	    this.toCode = function (region, country) {
	      return ["STTE_", country, region].join('');
	    };
	  }
	
	  return new RegionsService();
	}

/***/ },
/* 71 */
/***/ function(module, exports) {

	'use strict';
	
	safeGa.$inject = ["ga", "$timeout"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = safeGa;
	/*@ngInject*/
	// TODO EVENTS: id=ooc6b fixtype=infra subsystem=analytics . safeGa functionality stays but is less exposed
	function safeGa(ga, $timeout) {
	  this.sendEvent = function (action, category, label, callback) {
	    if (typeof callback === 'undefined') {
	      callback = angular.noop;
	    }
	
	    // wrap the callback https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#hitCallback
	    var alreadyCalled = false;
	    function callMeOnce() {
	      if (alreadyCalled) return;
	      alreadyCalled = true;
	      callback();
	    }
	
	    // make sure the callback gets triggered even when ga is not loaded
	    if (typeof ga !== 'undefined' && ga.loaded) {
	      ga('send', 'event', action, category, label, {
	        hitCallback: callMeOnce
	      });
	    } else {
	      callMeOnce();
	    }
	
	    // make sure callback happens after 2 seconds even if something with ga went catastrophically wrong
	    $timeout(callMeOnce, 2000);
	  };
	}

/***/ },
/* 72 */
/***/ function(module, exports) {

	'use strict';
	
	searchExpression.$inject = ["i18n", "countriesService"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = searchExpression;
	/*@ngInject*/
	function searchExpression(i18n, countriesService) {
	  var countries = countriesService;
	  function addFilter(filterList, text, whenToAdd) {
	    if (whenToAdd) {
	      filterList.push(text);
	    }
	  }
	
	  function quotedList(filterList) {
	    var finalList = [];
	    filterList.forEach(function (item) {
	      if (item && !_.isEmpty(item)) {
	        finalList.push('"' + item + '"');
	      }
	    });
	    return finalList.join(", ");
	  }
	
	  function notBlank(field) {
	    return field && !_.isEmpty(field);
	  }
	
	  return function (searchParams) {
	    var filterList = [];
	    addFilter(filterList, searchParams.filter_category, !!searchParams.filter_category);
	    var location = [];
	    if (notBlank(searchParams.filter_city)) {
	      location.push(searchParams.filter_city);
	    }
	    if (notBlank(searchParams.filter_country)) {
	      var country = countries.findByCode(searchParams.filter_country).text;
	      if (country) {
	        location.push(country);
	      }
	    }
	    if (location.length > 0) {
	      filterList.push(location.join(", "));
	    }
	    addFilter(filterList, '50% - 75%', searchParams.filter_percent_funded === '50_to_75');
	    addFilter(filterList, '75% - 100+%', searchParams.filter_percent_funded === '75_to_100_plus');
	    addFilter(filterList, i18n.t('adv_search.funding_open'), searchParams.filter_status === 'open');
	    addFilter(filterList, i18n.t('adv_search.funding_ended'), searchParams.filter_status === 'ended');
	    addFilter(filterList, i18n.t('flexible'), searchParams.filter_funding === 'flexible');
	    addFilter(filterList, i18n.t('fixed'), searchParams.filter_funding === 'fixed');
	    addFilter(filterList, i18n.t('verified_nonprofit'), searchParams.filter_nonprofit === 'nonprofit');
	    addFilter(filterList, i18n.t('in_demand_label'), !!searchParams.filter_forever_funding_active);
	
	    if (notBlank(searchParams.search_text)) {
	      var quotedTitle = '"' + searchParams.search_text + '"';
	      if (filterList.length > 0) {
	        return i18n.t('x_in_category', { x: quotedTitle, category: quotedList(filterList) });
	      } else {
	        return quotedTitle;
	      }
	    } else {
	      if (notBlank(searchParams.filter_quick)) {
	        var quickKey = searchParams.filter_quick;
	        if (quickKey === 'popular_all') {
	          quickKey = 'trending';
	        }
	        filterList.push(i18n.t("quick_pick_filters." + quickKey));
	      }
	      return quotedList(filterList);
	    }
	  };
	}

/***/ },
/* 73 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shareBanner;
	/*@ngInject*/
	function shareBanner() {
	  return {
	    scope: {
	      labelText: '@',
	      labelHoverText: '@',
	      variant: '@',
	      hideLabel: '='
	    },
	    template: __webpack_require__(74),
	    restrict: 'A',
	    link: function link(scope, element, attrs) {
	      scope.xhref = '#' + attrs.icon;
	    }
	  };
	}

/***/ },
/* 74 */
/***/ function(module, exports) {

	module.exports = "<div class=\"shareBanner\" ng-class=\"variant ? 'shareBanner--' + variant : null\">\n  <div class=\"shareBanner-icon\">\n    <svg><use xlink:href=\"{{xhref}}\"></use></svg>\n  </div>\n  <div ng-if=\"!hideLabel\" class=\"shareBanner-label shareBanner-label--hoverable\">\n    <div class=\"shareBanner-labelDimple\">\n      <svg><use xlink:href=\"#dimple\"></use></svg>\n    </div>\n    <div class=\"shareBanner-labelText\">{{labelText}}</div>\n  </div>\n  <div ng-if=\"!hideLabel\" class=\"shareBanner-label shareBanner-label--hover\">\n    <div class=\"shareBanner-labelDimple\">\n      <svg><use xlink:href=\"#dimple\"></use></svg>\n    </div>\n    <div class=\"shareBanner-labelText\">{{labelHoverText || labelText}}</div>\n  </div>\n</div>\n";

/***/ },
/* 75 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function () {
	  return {
	    scope: { emailVisible: '=' },
	    restrict: 'A',
	    template: __webpack_require__(76),
	    link: function link(scope, element) {}
	  };
	};

/***/ },
/* 76 */
/***/ function(module, exports) {

	module.exports = "<div class=\"campaignShare\">\n  <div facebook-share show-label=\"true\" />\n  <div twitter-share show-label=\"true\" />\n  <div email-share ng-if=\"::emailVisible\" show-label=\"true\" />\n  <div embed-share show-label=\"true\" />\n  <div link-share show-label=\"true\" />\n  <div follow-share show-label=\"true\" />\n</div>\n";

/***/ },
/* 77 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	shippingInfo.$inject = ["countriesService", "regions"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = shippingInfo;
	/*@ngInject*/
	function shippingInfo(countriesService, regions) {
	  return {
	    restrict: 'E',
	    scope: {
	      shipping: '='
	    },
	    template: __webpack_require__(78),
	    link: function link(scope, element, attrs, nullController) {
	      scope.countries = countriesService;
	      scope.regions = regions;
	    }
	  };
	}

/***/ },
/* 78 */
/***/ function(module, exports) {

	module.exports = "<span>{{shipping.name}}</span><br />\n<span> {{shipping.address}}</span> <br />\n<span ng-if=\"shipping.address2\"> {{shipping.address2}}<br /></span>\n<span>{{shipping.city}}</span><span ng-if=\"shipping.state\">, {{regions.byTwoLetterCode(shipping.state).two_letter}}</span> <span>{{shipping.zipcode}}</span><br />\n<span>{{countries.findByTwoLetterCode(shipping.country).text}}</span>\n";

/***/ },
/* 79 */
/***/ function(module, exports) {

	'use strict';
	
	signup.$inject = ["i18n", "gon", "$sce", "$http"];
	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = signup;
	/*@ngInject*/
	function signup(i18n, gon, $sce, $http) {
	  function safeBasicSignupParams(account) {
	    var params = {
	      timestamp: gon.negative_captcha.timestamp,
	      spinner: gon.negative_captcha.spinner,
	      email: null,
	      password: null
	    };
	    params[gon.negative_captcha.fields.email] = account.email;
	    params[gon.negative_captcha.fields.password] = account.password;
	    return params;
	  }
	
	  return {
	    submitSignup: function submitSignup(account, domainCode) {
	      var params = safeBasicSignupParams(account);
	      params.domain_code = domainCode;
	      params.account = {
	        firstname: account.firstname,
	        lastname: account.lastname,
	        general_opt_in: account.general_opt_in
	      };
	      return $http.post(gon.session_modal.signup_url, params);
	    },
	    termsHtml: function termsHtml(sentenceKey) {
	      if (!gon.session_modal) {
	        return null;
	      }
	      var termsLinkDiv = $('<div><a target="_blank"></a></div>');
	      var termsLink = termsLinkDiv.find('a');
	      termsLink.attr('href', gon.session_modal.terms_url);
	      termsLink.text(i18n.t('content_for_title.terms_of_use'));
	      var privacyLinkDiv = $('<div><a target="_blank"></a></div>');
	      var privacyLink = privacyLinkDiv.find('a');
	      privacyLink.attr('href', gon.session_modal.privacy_policy_url);
	      privacyLink.text(i18n.t('content_for_title.privacy_policy'));
	      var rawText = i18n.t(sentenceKey, {
	        terms_of_service_url: termsLinkDiv.html(),
	        privacy_policy_link: privacyLinkDiv.html()
	      });
	      if ((typeof rawText === 'undefined' ? 'undefined' : _typeof(rawText)) === 'object') {
	        return rawText;
	      } else {
	        return $sce.trustAsHtml(rawText);
	      }
	    }
	  };
	}

/***/ },
/* 80 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	simpleImageUpload.$inject = ["cloudinary", "$http", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = simpleImageUpload;
	/*@ngInject*/
	function simpleImageUpload(cloudinary, $http, i18n) {
	  return {
	    restrict: 'A',
	    scope: {
	      imagePublicId: '@',
	      updateImagePath: '@',
	      placeholderPath: '@',
	      attr: '@',
	      width: '@',
	      height: '@',
	      crop: '@'
	    },
	    template: __webpack_require__(81),
	    link: function link(scope, element) {
	      scope.i18n = i18n;
	      var fileInput = element.find("input");
	      scope.status = { loading: false, publicId: scope.imagePublicId };
	
	      function setupFileUpload() {
	        var fileUploader = cloudinary.forFileInput(fileInput, element);
	
	        fileUploader.onUploadStart(function () {
	          scope.status.loading = true;
	        }).onUploadComplete(function (result) {
	          scope.status.loading = false;
	          scope.status.publicId = result.public_id;
	          scope.$apply();
	          var data = { image_params: result };
	          if (scope.attr) {
	            data.attr = scope.attr;
	          }
	          $http.post(scope.updateImagePath, data);
	          fileInput = element.find("input");
	        }).onUploadFail(function () {
	          scope.status.loading = false;
	          fileInput = element.find("input");
	        });
	      }
	      setupFileUpload();
	
	      scope.clickPhoto = function () {
	        fileInput.trigger('click');
	      };
	    }
	  };
	}

/***/ },
/* 81 */
/***/ function(module, exports) {

	module.exports = "<div class=\"i-cloudinaryUploader-image\" ng-click=\"clickPhoto()\">\n  <img ng-if=\"placeholderPath && !status.publicId\" ng-src=\"{{placeholderPath}}\" width=\"{{width}}\" height=\"{{height}}\" />\n  <img ng-if=\"status.publicId\" cl-image width=\"{{width}}\" height=\"{{height}}\" crop=\"{{crop}}\" public-id=\"status.publicId\" />\n  <div ng-if=\"!placeholderPath && !status.publicId\" class=\"i-cloudinaryUploader-placeholder\" ng-style=\"{width: width + 'px', height: height + 'px'}\"></div>\n  <i class=\"i-fa-centered i-fa-gogenta fa fa-spinner fa-4x fa-spin\" ng-show=\"status.loading\"></i>\n</div><input type=\"file\" name=\"file\" class=\"i-hide-offscreen\" data-cloudinary-field=\"image_id\" />\n<button type=\"button\" ng-click=\"clickPhoto()\" class=\"i-cta-1 i-cta-1--grey i-cloudinaryUploader-button\">\n  <span ng-if=\"status.publicId\">{{::i18n.t('change_image')}}</span>\n  <span ng-if=\"!status.publicId\">{{::i18n.t('add_image')}}</span>\n</button>\n";

/***/ },
/* 82 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (split) {
	  return {
	    /*@ngInject*/
	    scope: {
	      experiment: '@',
	      variant: '@',
	      variants: '='
	    },
	    transclude: true,
	    template: '<div ng-transclude ng-if="variantActive"></div>',
	    link: function link($scope) {
	      $scope.variantActive = false;
	      var variants;
	      if ($scope.variant) {
	        variants = [$scope.variant];
	      } else if ($scope.variants) {
	        variants = $scope.variants;
	      }
	      $scope.$watch(function () {
	        return split.checkVariantState($scope.experiment);
	      }, function (state) {
	        $scope.variantActive = _.includes(variants, state);
	      });
	    }
	  };
	};

/***/ },
/* 83 */
/***/ function(module, exports) {

	'use strict';
	
	split.$inject = ["$http"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = split;
	/*@ngInject*/
	function split($http) {
	  var service = {
	    experimentBuckets: {}
	  };
	
	  service.checkVariantState = function (name) {
	    if (!service.experimentBuckets[name]) {
	      service.experimentBuckets[name] = '$loading';
	      $http.put('/private_api/experiments/fetch_and_update', { name: name }).then(function (response) {
	        var buckets = response.data.response.buckets;
	        service.experimentBuckets = _.merge(service.experimentBuckets, buckets);
	      }).catch(function (error) {
	        service.experimentBuckets[name] = 'control';
	      });
	    }
	    return service.experimentBuckets[name];
	  };
	
	  service.fetchVariantState = function (name) {
	    return $http.put('/private_api/experiments/fetch_and_update', { name: name }).then(function (response) {
	      var buckets = response.data.response.buckets;
	      return buckets[name];
	    });
	  };
	
	  function projectVariant(name, projectId) {
	    return $http({
	      url: '/private_api/campaigns/' + projectId + '/split_bucket',
	      method: 'GET',
	      params: { name: name }
	    });
	  }
	  service.projectVariant = projectVariant;
	
	  return service;
	}

/***/ },
/* 84 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = startsWith;
	/*@ngInject*/
	function startsWith() {
	  return function (actual, expected) {
	    var lowerStr = (actual + "").toLowerCase();
	    return lowerStr.indexOf(expected.toLowerCase()) === 0;
	  };
	}

/***/ },
/* 85 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = stripTags;
	/*@ngInject*/
	function stripTags() {
	  return function (html) {
	    return $('<div>' + html + '</div>').text().replace(/\t+/g, " ").replace(/\n/g, "").replace(/^\s/g, "");
	  };
	}

/***/ },
/* 86 */
/***/ function(module, exports) {

	'use strict';
	
	svgIcon.$inject = ["$sce"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = svgIcon;
	/*@ngInject*/
	function svgIcon($sce) {
	  return {
	    template: '<svg><use xlink:href="{{iconName}}"></svg>',
	    scope: { icon: '@' },
	    link: function link(scope) {
	      scope.iconName = $sce.trustAsResourceUrl('#' + scope.icon);
	    }
	  };
	}

/***/ },
/* 87 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = truncateFilter;
	/*@ngInject*/
	function truncateFilter() {
	  return function (text, length, end) {
	    if (isNaN(length)) {
	      length = 10;
	    }
	
	    if (_.isNull(text) || _.isUndefined(text)) {
	      return text;
	    }
	
	    if (end === undefined) {
	      end = '…';
	    }
	
	    if (text.length <= length || text.length - end.length <= length) {
	      return text;
	    } else {
	      return String(text).substring(0, length - end.length) + end;
	    }
	  };
	}

/***/ },
/* 88 */
/***/ function(module, exports) {

	'use strict';
	
	twitter.$inject = ["$window", "$http"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = twitter;
	/*@ngInject*/
	function twitter($window, $http) {
	  return {
	    onTweet: function onTweet(callback) {
	      $window.twttr.ready(function (twttr) {
	        twttr.events.bind('tweet', callback);
	      });
	    },
	    refreshAllWidgets: function refreshAllWidgets() {
	      $window.twttr.ready(function (twttr) {
	        twttr.widgets.load();
	      });
	    },
	    countForUrl: function countForUrl(url) {
	      return $http.jsonp('https://urls.api.twitter.com/1/urls/count.json?url=' + $window.escape(url) + '&callback=JSON_CALLBACK').then(function (response) {
	        return response.data.count;
	      });
	    },
	    shareTwitter: function shareTwitter(url, text, from) {
	      var originalReferrer = _.isUndefined(from) ? $window.location.toString() : from;
	      var shareUrl = 'https://twitter.com/intent/tweet?' + 'original_referer=' + $window.escape(originalReferrer) + '&related=indiegogo%3AIndiegogo&' + '&text=' + text + '&url=' + $window.escape(url);
	      $window.open(shareUrl, 'twitter_share', 'height=450, width=550');
	    }
	  };
	}

/***/ },
/* 89 */
/***/ function(module, exports) {

	'use strict';
	
	typeaheadUtils.$inject = ["startsWith"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = typeaheadUtils;
	/*@ngInject*/
	function typeaheadUtils(startsWith) {
	  return {
	    firefoxWorkaround: function firefoxWorkaround(scope, modelProp, valueProp) {
	      // https://github.com/mgcrea/angular-strap/issues/1319
	      scope.$watch(modelProp + '.' + valueProp, function (newValue, oldValue) {
	        if (newValue !== oldValue) {
	          console.log('Changing from', oldValue, newValue);
	          // revert change if newValue is a string
	          if (angular.isString(newValue) && angular.isObject(oldValue)) {
	            console.log('Reverting change');
	            scope[modelProp][valueProp] = oldValue;
	          }
	        }
	      });
	    },
	    startsWith: {
	      country: function country(actual, expected) {
	        if (!_.isString(actual)) {
	          return false;
	        }
	        if (_.isString(actual) && actual.indexOf('CTRY_') === 0) {
	          return false;
	        }
	        if (actual === 'common') {
	          return false;
	        }
	        return startsWith(actual, expected);
	      },
	      region: function region(actual, expected) {
	        //if (_.isString(actual) && actual.indexOf('STTE_') === 0) { return false; }
	        if (actual === 'us' || actual === 'ca') {
	          return false;
	        }
	        return startsWith(actual, expected);
	      },
	      basic: startsWith
	    }
	  };
	}

/***/ },
/* 90 */
/***/ function(module, exports) {

	"use strict";
	
	userConfig.$inject = ["gon"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = userConfig;
	/*@ngInject*/
	function userConfig(gon) {
	  if (gon && gon.services && gon.services.user_service) {
	    return _.cloneDeep(gon.services.user_service);
	  } else {
	    return { urls: {} };
	  }
	}

/***/ },
/* 91 */
/***/ function(module, exports) {

	'use strict';
	
	userService.$inject = ["$http", "$q", "$log", "userServiceConfig", "backupBeforeUnloadService", "gon", "fb"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = userService;
	/*@ngInject*/
	function userService($http, $q, $log, userServiceConfig, backupBeforeUnloadService, gon, fb) {
	  var oauthServiceEndpoint = userServiceConfig.urls.oauth_service + '/oauth/token';
	  var token = '';
	  var user = {};
	
	  function load() {
	    backupBeforeUnloadService.restoreStateIfSaved('user', user);
	    if (_.isEmpty(user) && gon.contribution && gon.contribution.contributor) {
	      setUser(gon.contribution.contributor.account_privileged);
	    }
	  }
	
	  function oauthLogInPromise(email, password) {
	    var deferred = $q.defer();
	
	    $http.post(oauthServiceEndpoint, {
	      credential_type: 'email',
	      grant_type: 'password',
	      email: email,
	      password: password
	    }).success(function (data) {
	      token = data.access_token;
	      $http.get(userServiceConfig.urls.current_user + '?access_token=' + token).success(function (data) {
	        setUser(data.response);
	        deferred.resolve(user);
	      }).error(function (data) {
	        deferred.reject('Rejected in credentials: ', data);
	      });
	    }).error(function (data) {
	      deferred.reject(data.error);
	    });
	
	    return deferred.promise;
	  }
	
	  function logInPromise(email, password) {
	    var deferred = $q.defer();
	
	    $http.post(userServiceConfig.urls.signin, {
	      account: {
	        email: email,
	        password: password
	      }
	    }).success(function success(data) {
	      setUser(data.account);
	      deferred.resolve(user);
	    }).error(function error(data) {
	      deferred.reject(data.error);
	    });
	
	    return deferred.promise;
	  }
	
	  function logOut() {
	    var oauthDeferred = $q.defer();
	    if (token) {
	      $http.post(userServiceConfig.urls.oauth_service + '/oauth/revoke', {
	        token: token,
	        access_token: token
	      }).success(function (data) {
	        oauthDeferred.resolve(data);
	      }).error(function (error) {
	        $log.debug('revoke error');
	        oauthDeferred.reject(error);
	      });
	    } else {
	      oauthDeferred.resolve('No oauth credentials');
	    }
	
	    var sessionDeferred = $q.defer();
	    $http.delete(userServiceConfig.urls.signout).success(function (data) {
	      setUser(null);
	      token = null;
	      sessionDeferred.resolve(data);
	    }).error(function (error) {
	      $log.debug('logout rejected', error);
	      sessionDeferred.reject(error);
	    });
	
	    return $q.all([oauthDeferred.promise, sessionDeferred.promise]);
	  }
	
	  function signUp(firstname, lastname, email, password, newsletterOptIn) {
	    var deferred = $q.defer();
	
	    $http.post(userServiceConfig.urls.signup + '?api_token=' + userServiceConfig.api_token, {
	      account: {
	        fullname: [firstname, lastname].join(' '),
	        email: email,
	        password: password,
	        general_opt_in: newsletterOptIn
	      }
	    }).success(function () {
	      oauthLogInPromise(email, password).then(deferred.resolve(user));
	    }).error(function (data) {
	      deferred.reject(data.messages);
	    });
	
	    return deferred.promise;
	  }
	
	  function facebookLogin() {
	    var deferred = $q.defer();
	
	    fb.login({ scope: 'email', state: 'abc123' }).then(function (response) {
	      if (response.authResponse) {
	        var callbackUrl = userServiceConfig.urls.facebook_callback;
	        $log.debug('Connected! Hitting OmniAuth callback (GET ' + callbackUrl + ')...');
	        // since we have cookies enabled, this request will allow omniauth to parse
	        // out the auth code from the signed request in the fbsr_XXX cookie
	        $http.get(userServiceConfig.urls.facebook_callback, { headers: { Accept: 'application/json' } }).success(function (json) {
	          $log.debug('Connected! Callback complete.');
	          $log.debug(JSON.stringify(json));
	          setUser(json.account_privileged);
	          deferred.resolve(json.account_privileged);
	        }).error(function (error) {
	          $log.debug('error getting ' + callbackUrl);
	          $log.debug(error);
	          deferred.reject(error);
	        });
	      }
	    });
	
	    return deferred.promise;
	  }
	
	  function resetPassword(resetPasswordToken, password, passwordConfirmation) {
	    var deferred = $q.defer();
	
	    $http.put(userServiceConfig.urls.change_password, {
	      account: {
	        reset_password_token: resetPasswordToken,
	        password: password,
	        password_confirmation: passwordConfirmation
	      }
	    }).then(function (successResponse) {
	      deferred.resolve(successResponse);
	    }, function (failureResponse) {
	      deferred.reject(failureResponse);
	    });
	
	    return deferred.promise;
	  }
	
	  function setUser(data) {
	    if (data === null) {
	      _.each(_.keys(user), function (k) {
	        delete user[k];
	      });
	    } else {
	      var displayName = data.display_for_feed || data.firstname || data.email;
	      user.id = data.id;
	      user.firstname = data.firstname;
	      user.lastname = data.lastname;
	      user.email = data.email;
	      user.avatarUrl = data.avatar_url;
	      user.displayName = displayName;
	    }
	  }
	
	  function current() {
	    return user;
	  }
	
	  function authToken() {
	    return token;
	  }
	
	  _.merge(this, {
	    oauthLogIn: oauthLogInPromise,
	    logIn: logInPromise,
	    logOut: logOut,
	    signUp: signUp,
	    facebookLogin: facebookLogin,
	    resetPassword: resetPassword,
	    current: current,
	    authToken: authToken,
	    setUser: setUser,
	    load: load
	  });
	
	  load();
	
	  backupBeforeUnloadService.register({ user: this.current });
	}

/***/ },
/* 92 */
/***/ function(module, exports) {

	'use strict';
	
	youtube.$inject = ["$window"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = youtube;
	/*@ngInject*/
	function youtube($window) {
	
	  $window.iframeAPIIncluded = false;
	
	  $window.onYouTubeIframeAPIReady = function () {
	    for (var i = 0; i < $window.youtubeIframeApiCallbacks.length; ++i) {
	      $window.youtubeIframeApiCallbacks[i]();
	    }
	    $window.youtubeApiReady = true;
	  };
	
	  return {
	    onReady: function onReady(callback, include) {
	      if (typeof include === 'undefined') {
	        include = true;
	      }
	
	      if (include && !$window.iframeAPIIncluded) {
	        console.log('in iFrameAPIIncluded blog');
	        igg.externalService(function () {
	          // This code loads the IFrame Player API code asynchronously.
	          var tag = document.createElement('script');
	          tag.src = "https://www.youtube.com/iframe_api";
	          var firstScriptTag = document.getElementsByTagName('script')[0];
	          firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
	          $window.iframeAPIIncluded = true;
	        });
	      }
	
	      if ($window.youtubeApiReady) {
	        console.log('yo, youtube was already ready.. calling');
	        callback();
	      } else {
	        $window.youtubeIframeApiCallbacks = $window.youtubeIframeApiCallbacks || [];
	        $window.youtubeIframeApiCallbacks.push(function () {
	          $window.youtubeApiReady = true;
	        });
	        $window.youtubeIframeApiCallbacks.push(callback);
	      }
	    }
	  };
	}

/***/ },
/* 93 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = h;
	
	var _deleteLinkDirective = __webpack_require__(94);
	
	var _deleteLinkDirective2 = _interopRequireDefault(_deleteLinkDirective);
	
	var _headerMainDirective = __webpack_require__(95);
	
	var _headerMainDirective2 = _interopRequireDefault(_headerMainDirective);
	
	var _headerSearchFormDirective = __webpack_require__(96);
	
	var _headerSearchFormDirective2 = _interopRequireDefault(_headerSearchFormDirective);
	
	var _loginFormDirective = __webpack_require__(109);
	
	var _loginFormDirective2 = _interopRequireDefault(_loginFormDirective);
	
	var _sessionModalDirective = __webpack_require__(111);
	
	var _sessionModalDirective2 = _interopRequireDefault(_sessionModalDirective);
	
	var _sessionModalLinkDirective = __webpack_require__(112);
	
	var _sessionModalLinkDirective2 = _interopRequireDefault(_sessionModalLinkDirective);
	
	var _signupFormDirective = __webpack_require__(113);
	
	var _signupFormDirective2 = _interopRequireDefault(_signupFormDirective);
	
	var _headerFlashDirectives = __webpack_require__(114);
	
	var _headerFlashDirectives2 = _interopRequireDefault(_headerFlashDirectives);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
	
	function h(header) {
	  (0, _headerFlashDirectives2.default)(header);
	  header.directive('deleteLink', _deleteLinkDirective2.default).directive('headerMain', _headerMainDirective2.default).directive('headerSearchForm', _headerSearchFormDirective2.default).directive('loginForm', _loginFormDirective2.default).directive('sessionModal', _sessionModalDirective2.default).directive('sessionModalLink', _sessionModalLinkDirective2.default).directive('signupForm', _signupFormDirective2.default);
	}

/***/ },
/* 94 */
/***/ function(module, exports) {

	"use strict";
	
	deleteLink.$inject = ["$window", "$http"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = deleteLink;
	/*@ngInject*/
	function deleteLink($window, $http) {
	  return {
	    restrict: "A",
	    scope: {},
	    link: function link(scope, element, attrs) {
	      function performDeleteRequest() {
	        $http.delete(element.attr("href")).then(function () {
	          $window.location.href = attrs.deleteLinkHref || '/';
	        });
	      }
	
	      element.on("click", function (e) {
	        e.preventDefault();
	        e.stopImmediatePropagation();
	        if (attrs.deleteLinkConfirm) {
	          if ($window.confirm(attrs.deleteLinkConfirm)) {
	            performDeleteRequest();
	          }
	        } else {
	          performDeleteRequest();
	        }
	      });
	    }
	  };
	}

/***/ },
/* 95 */
/***/ function(module, exports) {

	"use strict";
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = headerMain;
	/*@ngInject*/
	function headerMain() {
	  return {
	    restrict: "A",
	    scope: false,
	    link: function link(scope) {
	      scope.inSearchMode = false;
	
	      scope.toggleSearchMode = function () {
	        scope.inSearchMode = !scope.inSearchMode;
	      };
	
	      scope.$on('dropdownOpen', function () {
	        scope.inSearchMode = false;
	        scope.$digest();
	      });
	    }
	  };
	}

/***/ },
/* 96 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	headerSearchForm.$inject = ["i18n", "browser", "$timeout"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = headerSearchForm;
	/*@ngInject*/
	function headerSearchForm(i18n, browser, $timeout) {
	  return {
	    restrict: 'A',
	    scope: true,
	    template: function template(elem, attrs) {
	      return __webpack_require__(97)("./" + attrs.template + '.html');
	    },
	    link: function link(scope, element, attrs) {
	      scope.$watch('inSearchMode', function (subsequent, last) {
	        if (!last && subsequent) {
	
	          // element is required to be visible before focusing.
	          $timeout(function () {
	            element.find('input').focus();
	          }, 100, false);
	        }
	      });
	
	      scope.i18n = i18n;
	      scope.searchTerm = attrs.term;
	      scope.inputName = attrs.inputName;
	      scope.reset = function () {
	        scope.searchTerm = '';
	        if (attrs.term && attrs.term.length > 0) {
	          browser.redirectTo(attrs.action);
	        }
	      };
	      scope.go = function () {
	        element.submit();
	      };
	    }
	  };
	}

/***/ },
/* 97 */
/***/ function(module, exports, __webpack_require__) {

	var map = {
		"./generosity-header-search-dropdown.html": 98,
		"./header-flash-container.html": 99,
		"./header-flash.html": 100,
		"./header-search-dropdown.html": 101,
		"./header-search-form.html": 102,
		"./login-form-generosity.html": 103,
		"./login-form-indiegogo.html": 104,
		"./session-modal-generosity.html": 105,
		"./session-modal-indiegogo.html": 106,
		"./signup-form-generosity.html": 107,
		"./signup-form-indiegogo.html": 108
	};
	function webpackContext(req) {
		return __webpack_require__(webpackContextResolve(req));
	};
	function webpackContextResolve(req) {
		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	};
	webpackContext.keys = function webpackContextKeys() {
		return Object.keys(map);
	};
	webpackContext.resolve = webpackContextResolve;
	module.exports = webpackContext;
	webpackContext.id = 97;


/***/ },
/* 98 */
/***/ function(module, exports) {

	module.exports = "<input class=\"siteSearch-text\" type=\"text\" name=\"filter_title\" placeholder='{{::i18n.t(\"search_by_title\")}}' ng-model=\"searchTerm\" maxlength=\"300\" />\n<a class=\"small-cta siteSearch-cta\" ng-click=\"go()\">{{::i18n.t('go')}}</a>\n";

/***/ },
/* 99 */
/***/ function(module, exports) {

	module.exports = "<div ng-transclude></div>\n<div header-flash\n  header-flash-level=\"{{flash.alertLevel}}\"\n  ng-repeat=\"flash in flash.flashes\">\n    <span ng-if=\"::flash.messageHtml\" ng-bind-html=\"::flash.messageHtml\"></span>\n    <span ng-if=\"::flash.messageText\" ng-bind=\"::flash.messageText\"></span>\n</div>\n";

/***/ },
/* 100 */
/***/ function(module, exports) {

	module.exports = "<div class=\"messageNotification\" ng-class=\"style\" ng-if=\"open\">\n  <div class=\"container messageNotification-container\">\n    <span ng-transclude />\n    <a class=\"messageNotification-close\" href=\"\" ng-click=\"closeFlash()\">\n      <svg><use xlink:href=\"#icon-icon-close\"></use></svg>\n    </a>\n  </div>\n</div>\n";

/***/ },
/* 101 */
/***/ function(module, exports) {

	module.exports = "<div class=\"i-search-box\">\n  <div class=\"i-search-cell\">\n    <div class=\"i-search-close\" ng-show=\"searchTerm.length > 0\" ng-click=\"reset()\">\n      <svg class=\"i-search-close-icon\"><use xlink:href=\"#icon-icon-close\"></use></svg>\n    </div>\n    <input type=\"text\" name=\"{{::inputName}}\" ng-model=\"searchTerm\" maxlength=\"300\" />\n  </div>\n  <div class=\"i-go-cell\">\n    <!-- TODO EVENTS: id=coaw4 fixtype=ga-event-dir action=Complete.Search category=Mobile.Web.Campaign.Page trigger=click dom=div subsystem=explore name-new=TBD . -->\n    <div class=\"i-search-go\"\n         ng-click=\"go()\"\n         ga-event-on=\"click\"\n         ga-event-category=\"Mobile Web Campaign Page\"\n         ga-event-action=\"Complete Search\">\n      <a href=\"\">{{::i18n.t('go')}}</a>\n    </div>\n  </div>\n</div>\n";

/***/ },
/* 102 */
/***/ function(module, exports) {

	module.exports = "<label class=\"visible-only-to-screenreader\" for=\"search_term\">{{i18n.t('search')}}</label>\n<input type=\"text\" name=\"{{::inputName}}\" id=\"search_term\" ng-model=\"searchTerm\" maxlength=\"300\" class=\"i-text-field i-text-field--searchBar\" />\n<svg class=\"siteHeader-search-icon\"><use xlink:href=\"#icon-icon-search\"></use></svg>\n<a class=\"siteHeader-search-close\" href=\"\" ng-click=\"reset()\" ng-show=\"searchTerm.length > 0\"><svg><use xlink:href=\"#icon-icon-close\"></use></svg></a>\n";

/***/ },
/* 103 */
/***/ function(module, exports) {

	module.exports = "<p class=\"sign-up-with-email divider\"><span class=\"divider-line\">{{::i18n.t('or_log_in_with_email') }}</span></p>\n<form name=\"loginForm\" novalidate ng-submit=\"submitLogin()\">\n  <p class=\"i-error\" ng-if=\"loginFailed\">{{::i18n.t('login_modal.invalid_email_or_password')}}</p>\n  <label class=\"hide i-error signup\"></label>\n\n  <input name=\"emailField\" id=\"account_email\" type=\"email\" class=\"i-text-field\" placeholder=\"{{::i18n.t('email_caps')}}\"\n         ng-model=\"loginAccount.email\" required />\n  <label for=\"account_email\" class=\"i-error\" ng-if=\"loginForm.emailField.$error.email\">{{::i18n.t('login_modal.please_enter_a_valid_email_address')}}</label>\n  <label for=\"account_email\" class=\"i-error\" ng-if=\"loginForm.emailField.$error.required && loginForm.emailField.$dirty\">{{::i18n.t('login_modal.this_field_is_required')}}</label>\n\n  <input name=\"passwordField\" id=\"account_password\" type=\"password\" ng-minlength=\"6\" class=\"i-text-field\" ng-model=\"loginAccount.password\" required placeholder=\"{{::i18n.t('password')}}\" autocomplete=\"off\" />\n  <label for=\"account_password\" class=\"i-error\" ng-if=\"loginForm.passwordField.$error.minlength\">{{::i18n.t('must_be_at_least_6_characters_long')}}</label>\n  <label for=\"account_password\" class=\"i-error\" ng-if=\"loginForm.passwordField.$error.required && loginForm.passwordField.$dirty\">{{::i18n.t('login_modal.this_field_is_required')}}</label>\n\n  <div class=\"i-field-row splitApart\">\n    <div class=\"i-checkbox-with-label\">\n      <input type=\"checkbox\" id=\"rememberme\" ng-model=\"loginAccount.rememberme\" />\n      <label for=\"rememberme\">{{::i18n.t('remember_me')}}</label>\n    </div>\n    <div class=\"i-forgot\">\n      <a ng-href=\"{{::forgotPasswordUrl}}\">{{::i18n.t('forgot_password')}}</a>\n    </div>\n  </div>\n\n  <input type=\"submit\" class=\"small-cta\" value=\"{{::i18n.t('log_in')}}\" />\n</form>\n";

/***/ },
/* 104 */
/***/ function(module, exports) {

	module.exports = "<p class=\"sign-up-with-email divider\"><span class=\"divider-line\">{{::i18n.t('or_log_in_with_email')}}</span></p>\n<form name=\"loginForm\" novalidate ng-submit=\"submitLogin()\">\n  <p class=\"i-error\" ng-if=\"loginFailed\">{{::i18n.t('login_modal.invalid_email_or_password')}}</p>\n  <label class=\"hide i-error signup\"></label>\n\n  <input name=\"emailField\" id=\"account_email\" type=\"email\" class=\"i-text-field\" placeholder=\"{{::i18n.t('email_caps')}}\"\n         ng-model=\"loginAccount.email\" required />\n  <label for=\"account_email\" class=\"i-input-error-subtext i-error\" ng-if=\"loginForm.emailField.$error.email\">{{::i18n.t('login_modal.please_enter_a_valid_email_address')}}</label>\n  <label for=\"account_email\" class=\"i-input-error-subtext i-error\" ng-if=\"loginForm.emailField.$error.required && loginForm.emailField.$dirty\">{{::i18n.t('login_modal.this_field_is_required')}}</label>\n\n  <input name=\"passwordField\" id=\"account_password\" type=\"password\" ng-minlength=\"6\" class=\"i-text-field\" ng-model=\"loginAccount.password\" required placeholder=\"{{::i18n.t('password')}}\" autocomplete=\"off\" />\n  <label for=\"account_password\" class=\"i-input-error-subtext i-error\" ng-if=\"loginForm.passwordField.$error.minlength\">{{::i18n.t('must_be_at_least_6_characters_long')}}</label>\n  <label for=\"account_password\" class=\"i-input-error-subtext i-error\" ng-if=\"loginForm.passwordField.$error.required && loginForm.passwordField.$dirty\">{{::i18n.t('login_modal.this_field_is_required')}}</label>\n\n  <div class=\"i-field-row\">\n    <div class=\"col-sm-6 i-checkbox-with-label\">\n      <input type=\"checkbox\" id=\"rememberme\" ng-model=\"loginAccount.rememberme\" />\n      <label for=\"rememberme\">{{::i18n.t('remember_me')}}</label>\n    </div>\n    <div class=\"col-sm-6 i-forgot\">\n      <a class=\"i-aqua-link\" ng-href=\"{{::forgotPasswordUrl}}\">{{::i18n.t('forgot_password')}}</a>\n    </div>\n  </div>\n\n  <input type=\"submit\" class=\"i-cta-1 login\" value=\"{{::i18n.t('log_in')}}\" />\n</form>\n";

/***/ },
/* 105 */
/***/ function(module, exports) {

	module.exports = "<div id=\"session_modal\" class=\"modal i-session-modal\">\n  <div class=\"modal-dialog\">\n    <div class=\"modal-content auth-modal\">\n      <a class=\"modal-close\" data-dismiss=\"modal\" aria-hidden=\"true\" ng-click=\"$hide()\"><svg-icon icon=\"icon-icon-close\"></svg-icon></a>\n\n      <div class=\"i-security-message center-text\" ng-show=\"securityMessage\">\n        <svg-icon icon=\"icon-icon-lock\"></svg-icon>\n        <h4>{{::i18n.t('session_modal.check_your_email')}}</h4>\n        <div ng-bind=\"securityMessage\"></div>\n        <a class=\"primary-cta\" ng-href=\"{{securityUrl}}\">{{::i18n.t('learn_more')}}</a>\n      </div>\n      <div ng-hide=\"securityMessage\">\n        <div class=\"center-text fb-auth\">\n          <a ng-href=\"{{::fbAuthUrl}}\" class=\"small-cta small-cta--fbConnect\">\n            <svg-icon icon=\"icon-icon-facebook\"></svg-icon>\n            <span>{{::i18n.t('continue_with_facebook')}}</span>\n          </a>\n          <p>{{::i18n.t(\"generosity.login_page.facebook_intro_2\")}}</p>\n        </div>\n\n        <div class=\"auth-fields\">\n          <div id=\"loginSession\" ng-if=\"currentForm === 'loginForm'\">\n            <login-form template-url=\"login-form-generosity.html\"\n                        modal=\"modal\"\n                        callbacks=\"status.callbacks\"\n            ></login-form>\n            <div class=\"topborder\">\n              {{::i18n.t('generosity.session_modal.new_to_generosity') }}\n              <a href=\"\" ng-click=\"switchForm('signupForm')\" class=\"toggler\">{{::i18n.t('sign_up')}}</a>\n            </div>\n          </div>\n          <div id=\"signUpSession\" ng-if=\"currentForm === 'signupForm'\">\n            <signup-form template-url=\"signup-form-generosity.html\"\n                         domain-code=\"generosity\"\n                         modal=\"modal\"\n                         callbacks=\"status.callbacks\"\n            ></signup-form>\n            <div class=\"topborder\">\n              {{::i18n.t('already_have_an_account')}}\n              <a href=\"\" ng-click=\"switchForm('loginForm')\" class=\"toggler\">{{::i18n.t('log_in')}}</a>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },
/* 106 */
/***/ function(module, exports) {

	module.exports = "<div id=\"session_modal\" class=\"modal i-modal i-session-modal\">\n  <div class=\"modal-dialog\">\n    <div class=\"modal-content auth-modal\">\n      <a class=\"modal-close\" data-dismiss=\"modal\" aria-hidden=\"true\" ng-click=\"$hide()\"><svg><use xlink:href=\"#icon-icon-close\"></use></svg></a>\n\n      <div class=\"securityMessage\" ng-show=\"securityMessage\">\n        <svg class=\"securityMessage-lock\"><use xlink:href=\"#icon-icon-lock\"></use></svg>\n        <div class=\"securityMessage-header\">{{::i18n.t('session_modal.check_your_email')}}</div>\n        <div ng-bind=\"securityMessage\"></div>\n        <a class=\"i-cta-1 securityMessage-cta\" target=\"_blank\" ng-href=\"{{securityUrl}}\">{{::i18n.t('learn_more')}}</a>\n      </div>\n      <div ng-hide=\"securityMessage\">\n        <div class=\"center-text fb-auth\">\n          <a ng-href=\"{{::fbAuthUrl}}\" class=\"i-cta-1 i-cta-1--iconed i-cta-1--facebook authModal-facebook\">\n            <svg class=\"i-cta-1-icon\"><use xlink:href=\"#icon-icon-facebook\"></use></svg>\n            <span>{{::i18n.t('continue_with_facebook')}}</span>\n          </a>\n          <p>{{::i18n.t(\"login_page.facebook_intro_2\") }}</p>\n        </div>\n\n        <div class=\"auth-fields\">\n          <div id=\"loginSession\" ng-if=\"currentForm === 'loginForm'\">\n            <login-form template-url=\"login-form-indiegogo.html\"\n                        modal=\"modal\"\n                        callbacks=\"status.callbacks\"\n              ></login-form>\n            <div class=\"topborder\">\n              {{::i18n.t('new_to_igg')}}\n              <a href=\"\" ng-click=\"switchForm('signupForm')\" class=\"toggler\">{{::i18n.t('sign_up')}}</a>\n            </div>\n          </div>\n\n          <div id=\"signUpSession\" ng-if=\"currentForm === 'signupForm'\">\n            <signup-form template-url=\"signup-form-indiegogo.html\"\n                         domain-code=\"www\"\n                         modal=\"modal\"\n                         callbacks=\"status.callbacks\"\n              ></signup-form>\n            <div class=\"topborder\">\n              {{::i18n.t('already_have_an_account')}}\n              <a href=\"\" ng-click=\"switchForm('loginForm')\" class=\"toggler\">{{::i18n.t('log_in')}}</a>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n";

/***/ },
/* 107 */
/***/ function(module, exports) {

	module.exports = "<p class=\"sign-up-with-email divider\"><span class=\"divider-line\">{{::i18n.t('or_sign_up_with_email') }}</span></p>\n<form name=\"signupForm\" novalidate ng-submit=\"submitSignup()\">\n\n  <p class=\"i-error\" ng-if=\"errorMessage\" ng-bind=\"errorMessage\"></p>\n  <input type=\"text\" name=\"firstnameField\" id=\"account_firstname\" class=\"i-text-field\" placeholder=\"{{::i18n.t('first_name')}}\" ng-model=\"signupAccount.firstname\" required />\n  <label for=\"account_firstname\" class=\"i-error\" ng-if=\"signupForm.firstnameField.$error.required && signupForm.firstnameField.$dirty\">{{::i18n.t('signup_modal.this_field_is_required')}}</label>\n\n  <input type=\"text\" name=\"lastnameField\" id=\"account_lastname\" class=\"i-text-field\" placeholder=\"{{::i18n.t('last_name')}}\" ng-model=\"signupAccount.lastname\" required />\n  <label for=\"account_lastname\" class=\"i-error\" ng-if=\"signupForm.lastnameField.$error.required && signupForm['account[lastname]'].$dirty\">{{::i18n.t('signup_modal.this_field_is_required')}}</label>\n\n  <input type=\"text\" name=\"emailField\" id=\"account_email\" class=\"i-text-field\" placeholder=\"{{::i18n.t('email_caps')}}\" ng-model=\"signupAccount.email\" required />\n  <label for=\"account_email\" class=\"i-error\" ng-if=\"signupFailed && !signupAccount.emailValid()\">{{::i18n.t('signup_modal.please_enter_a_valid_email_address')}}</label>\n  <label for=\"account_email\" class=\"i-error\" ng-if=\"signupFailed && !signupAccount.email\">{{::i18n.t('signup_modal.this_field_is_required')}}</label>\n\n  <input type=\"password\" name=\"passwordField\" id=\"take\" class=\"i-text-field\" minlength=\"6\" autocomplete=\"off\" placeholder=\"{{::i18n.t('password')}}\" ng-model=\"signupAccount.password\" required />\n  <label for=\"take\" class=\"i-error\" ng-if=\"signupFailed && !signupAccount.passwordValid()\">{{::i18n.t('must_be_between_6_and_40_characters')}}</label>\n  <label for=\"take\" class=\"i-error\" ng-if=\"signupFailed && !signupAccount.password\">{{::i18n.t('signup_modal.invalid_password')}}</label>\n\n  <div class=\"i-field-row checkboxWithLabel\">\n    <input type=\"checkbox\" ng-model=\"signupAccount.general_opt_in\" id=\"optIn\" />\n    <label for=\"optIn\">{{::i18n.t('generosity.login_page.sign_me_up_for_newsletter')}}</label>\n  </div>\n  <input type=\"submit\" value=\"{{::i18n.t('create_an_account')}}\" class=\"small-cta\" />\n\n  <div class=\"finePrint\">\n    {{::i18n.t('generosity.session_modal.fee_signup_info')}}\n    <span ng-bind-html=\"boilerplateHtml\"></span>\n  </div>\n</form>\n";

/***/ },
/* 108 */
/***/ function(module, exports) {

	module.exports = "<p class=\"sign-up-with-email divider\"><span class=\"divider-line\">{{::i18n.t('or_sign_up_with_email') }}</span></p>\n<form name=\"signupForm\" novalidate ng-submit=\"submitSignup()\">\n\n  <p class=\"i-error\" ng-if=\"errorMessage\" ng-bind=\"errorMessage\"></p>\n  <input type=\"text\" name=\"firstnameField\" id=\"account_firstname\" class=\"i-text-field\" placeholder=\"{{::i18n.t('first_name')}}\" ng-model=\"signupAccount.firstname\" required />\n  <label for=\"account_firstname\" class=\"i-input-error-subtext i-error\" ng-if=\"signupForm.firstnameField.$error.required && (signupFailed || signupForm.firstnameField.$dirty)\">{{::i18n.t('signup_modal.this_field_is_required')}}</label>\n\n  <input type=\"text\" name=\"lastnameField\" id=\"account_lastname\" class=\"i-text-field\" placeholder=\"{{::i18n.t('last_name')}}\" ng-model=\"signupAccount.lastname\" required />\n  <label for=\"account_lastname\" class=\"i-input-error-subtext i-error\" ng-if=\"signupForm.lastnameField.$error.required && (signupFailed || signupForm.lastnameField.$dirty)\">{{::i18n.t('signup_modal.this_field_is_required')}}</label>\n\n  <input type=\"text\" name=\"emailField\" id=\"account_email\" class=\"i-text-field\" placeholder=\"{{::i18n.t('email_caps')}}\" ng-model=\"signupAccount.email\" required />\n  <label for=\"account_email\" class=\"i-input-error-subtext i-error\" ng-if=\"signupFailed && !signupAccount.emailValid()\">{{::i18n.t('signup_modal.please_enter_a_valid_email_address')}}</label>\n  <label for=\"account_email\" class=\"i-input-error-subtext i-error\" ng-if=\"signupFailed && !signupAccount.email\">{{::i18n.t('signup_modal.this_field_is_required')}}</label>\n\n  <input type=\"password\" name=\"passwordField\" id=\"take\" class=\"i-text-field\" minlength=\"6\" autocomplete=\"off\" placeholder=\"{{::i18n.t('password')}}\" ng-model=\"signupAccount.password\" required />\n  <label for=\"take\" class=\"i-input-error-subtext i-error\" ng-if=\"signupFailed && !signupAccount.passwordValid()\">{{::i18n.t('must_be_between_6_and_40_characters')}}</label>\n  <label for=\"take\" class=\"i-input-error-subtext i-error\" ng-if=\"signupFailed && !signupAccount.password\">{{::i18n.t('signup_modal.invalid_password')}}</label>\n\n  <div class=\"i-field-row i-checkbox-with-label\">\n    <input type=\"checkbox\" ng-model=\"signupAccount.general_opt_in\" id=\"optIn\" />\n    <label for=\"optIn\">{{::i18n.t('sign_me_up_for_newsletter')}}</label>\n  </div>\n  <input ng-disabled=\"disableSignUp\" type=\"submit\" value=\"{{::i18n.t('create_an_account')}}\" class=\"i-cta-1\" />\n\n  <div class=\"i-fine-print\">\n    <span ng-bind-html=\"boilerplateHtml\"></span>\n  </div>\n</form>\n";

/***/ },
/* 109 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	loginForm.$inject = ["i18n", "csrfToken", "$http", "gon", "safeGa", "browser", "gogoEvents"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = loginForm;
	/*@ngInject*/
	function loginForm(i18n, csrfToken, $http, gon, safeGa, browser, gogoEvents) {
	  return {
	    scope: {
	      modal: '=',
	      callbacks: '='
	    },
	    template: function template(element, attrs) {
	      return __webpack_require__(110)('./' + attrs.templateUrl);
	    },
	    link: function link(scope) {
	      scope.loginAccount = {
	        password: null,
	        rememberme: true
	      };
	
	      function sendGaForLoginSuccess(headerRedirect) {
	        var cb = function cb() {
	          browser.refreshPage();
	        };
	
	        if (scope.callbacks && scope.callbacks.successCallback) {
	          cb = scope.callbacks.successCallback;
	        } else if (headerRedirect) {
	          cb = function cb() {
	            browser.redirectTo(headerRedirect);
	          };
	        }
	
	        // TODO EVENTS: id=lie7a category=Account.Login action=login_complete subsystem=accounts label=dynamic fixtype=safega+captureEvent name=login.complete .
	        safeGa.sendEvent('Account Login', 'login complete', browser.currentHref(), cb);
	        gogoEvents.captureEvent('login complete', {
	          category: 'Account Login',
	          label: browser.currentHref()
	        });
	      }
	
	      function loginSuccess(response) {
	        scope.modal.hide();
	        csrfToken.setToken(response.headers()['x-csrf-token']);
	        sendGaForLoginSuccess(response.headers().location);
	      }
	
	      function loginError(response) {
	        scope.loginFailed = true;
	        // TODO EVENTS: id=ohw0a category=Account.Login action=error label=dynamic fixtype=safega-only subsystem=accounts name-new=TBD .
	        safeGa.sendEvent('Account Login', 'error', response.data.error);
	        if (response.data.error == "resource_owner_credentials_revoked") {
	          scope.securityMessage = response.data.error_description;
	        }
	      }
	
	      scope.i18n = i18n;
	      scope.forgotPasswordUrl = gon.session_modal.forgot_password_url;
	
	      scope.submitLogin = function () {
	        $http.post(gon.session_modal.login_url, {
	          from: gon.session_modal.from,
	          account: scope.loginAccount
	        }).then(loginSuccess, loginError);
	      };
	    }
	  };
	}

/***/ },
/* 110 */
/***/ function(module, exports, __webpack_require__) {

	var map = {
		"./generosity-header-search-dropdown.html": 98,
		"./header-flash-container.html": 99,
		"./header-flash.html": 100,
		"./header-search-dropdown.html": 101,
		"./header-search-form.html": 102,
		"./login-form-generosity.html": 103,
		"./login-form-indiegogo.html": 104,
		"./session-modal-generosity.html": 105,
		"./session-modal-indiegogo.html": 106,
		"./signup-form-generosity.html": 107,
		"./signup-form-indiegogo.html": 108
	};
	function webpackContext(req) {
		return __webpack_require__(webpackContextResolve(req));
	};
	function webpackContextResolve(req) {
		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
	};
	webpackContext.keys = function webpackContextKeys() {
		return Object.keys(map);
	};
	webpackContext.resolve = webpackContextResolve;
	module.exports = webpackContext;
	webpackContext.id = 110;


/***/ },
/* 111 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	sessionModal.$inject = ["$modal", "gon", "gogoEvents", "safeGa", "$http", "browser", "i18n"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = sessionModal;
	/*@ngInject*/
	function sessionModal($modal, gon, gogoEvents, safeGa, $http, browser, i18n) {
	  var modalTemplateUrl;
	  if (gon.domain === 'generosity') {
	    modalTemplateUrl = 'session-modal-generosity.html';
	  } else {
	    modalTemplateUrl = 'session-modal-indiegogo.html';
	  }
	
	  function sendGaForForm(currentForm) {
	    if (currentForm == 'loginForm') {
	      // TODO EVENTS: id=ieni2 fixtype=safega-only subsystem=accounts category=Account.Login action=view label=dynamic subsystem=accounts name-new=TBD .
	      safeGa.sendEvent('Account Login', 'view', browser.currentHref());
	    } else {
	      // TODO EVENTS: id=quou5 fixtype=safega-only subsystem=accounts category=Account.Sign-up action=view label=dynamic name-new=TBD subsystem=accounts name-new=TBD .
	      safeGa.sendEvent('Account Sign-up', 'view', browser.currentHref());
	    }
	  }
	
	  return {
	    restrict: 'E',
	    scope: {
	      status: '='
	    },
	    link: function link(scope) {
	      scope.i18n = i18n;
	      scope.fbAuthUrl = gon && gon.session_modal && gon.session_modal.fb_auth_url;
	      scope.securityUrl = gon && gon.session_modal && gon.session_modal.security_url;
	
	      scope.switchForm = function (newForm) {
	        scope.currentForm = newForm;
	        sendGaForForm(scope.currentForm);
	      };
	
	      function openModal() {
	        scope.currentForm = scope.status.startingForm || 'loginForm';
	        sendGaForForm(scope.currentForm);
	        scope.modal = $modal({
	          template: __webpack_require__(110)('./' + modalTemplateUrl),
	          scope: scope
	        });
	      }
	
	      scope.$watch('status.open', function (newVal) {
	        if (newVal) {
	          openModal();
	          scope.status.open = false; // Since we're watching for status.open to change, we need to reset this to false every time we open the modal so that subsequent setting of status.open to true triggers the change. Without this line, the modal only ever opens once on the page.
	        }
	      });
	    }
	  };
	}

/***/ },
/* 112 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = sessionModalLink;
	/*@ngInject*/
	function sessionModalLink() {
	  return {
	    scope: {
	      startingForm: '@'
	    },
	    restrict: 'A',
	    template: '<a href="" ng-click="openModal()" ng-transclude></a><session-modal status="status"></session-modal>',
	    transclude: true,
	    link: function link(scope) {
	      scope.status = {
	        startingForm: scope.startingForm,
	        open: false
	      };
	
	      scope.openModal = function () {
	        scope.status.open = true;
	      };
	    }
	  };
	}

/***/ },
/* 113 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	signupForm.$inject = ["i18n", "csrfToken", "$http", "gon", "safeGa", "browser", "gogoEvents", "signup"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = signupForm;
	/*@ngInject*/
	function signupForm(i18n, csrfToken, $http, gon, safeGa, browser, gogoEvents, signup) {
	  var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
	
	  return {
	    scope: {
	      domainCode: '@',
	      modal: '=',
	      callbacks: '='
	    },
	    template: function template(element, attrs) {
	      return __webpack_require__(110)('./' + attrs.templateUrl);
	    },
	    link: function link(scope) {
	      scope.disableSignUp = false;
	
	      function sendGaForSignupSuccess(headerRedirect) {
	        var cb = function cb() {
	          browser.refreshPage();
	        };
	
	        if (scope.callbacks && scope.callbacks.successCallback) {
	          cb = scope.callbacks.successCallback;
	        } else if (headerRedirect) {
	          cb = function cb() {
	            browser.redirectTo(headerRedirect);
	          };
	        }
	
	        // TODO EVENTS: id=cei2b fixtype=safega+captureEvent subsystem=accounts category=Account_Sign-up action=sign-up_complete label=dynamic name=sign-up!complete .
	        safeGa.sendEvent('Account Sign-up', 'sign-up complete', browser.currentHref(), cb);
	        gogoEvents.captureEvent('sign-up complete', {
	          category: 'Account Sign-up',
	          label: browser.currentHref()
	        });
	      }
	
	      function signupSuccess(response) {
	        scope.modal.hide();
	        csrfToken.setToken(response.headers()['x-csrf-token']);
	        sendGaForSignupSuccess(response.headers().location);
	      }
	
	      function signupError(response) {
	        scope.signupFailed = false;
	        scope.errorMessage = response.data.error;
	        // TODO EVENTS: id=roo0r fixtype=safega-only subsystem=accounts category=Account_Sign-up action=error label=dynamic subsystem=accounts name-new=TBD .
	        safeGa.sendEvent('Account Sign-up', 'error', response.data.error);
	      }
	
	      scope.i18n = i18n;
	      scope.signupFailed = false;
	      scope.signupAccount = {
	        general_opt_in: true,
	        emailValid: function emailValid() {
	          if (_.isUndefined(this.email)) {
	            return true;
	          } else {
	            return EMAIL_REGEXP.test(this.email);
	          }
	        },
	
	        passwordValid: function passwordValid() {
	          if (_.isUndefined(this.password)) {
	            return true;
	          } else {
	            var length = this.password.length;
	            return length >= 6 && length <= 40;
	          }
	        },
	
	        allFieldsPresent: function allFieldsPresent() {
	          return !!(this.firstname && this.lastname && this.email && this.password);
	        }
	      };
	
	      scope.boilerplateHtml = signup.termsHtml('by_signing_up_html');
	      scope.submitSignup = function () {
	        var account = scope.signupAccount;
	        if (account.passwordValid() && account.emailValid() && account.allFieldsPresent()) {
	          scope.disableSignUp = true;
	          signup.submitSignup(account, scope.domainCode).then(signupSuccess, signupError).finally(function () {
	            scope.disableSignUp = false;
	          });
	        } else {
	          scope.signupFailed = true;
	        }
	      };
	    }
	  };
	}

/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = headerFlashDirectives;
	function headerFlashDirectives(headerModule) {
	  headerModule.directive("headerFlashContainer", ['flash', function (flash) {
	    return {
	      restrict: 'A',
	      scope: {},
	      template: __webpack_require__(99),
	      transclude: true,
	      link: function link(scope, element) {
	        element.removeClass("hidden");
	        scope.flash = flash;
	      }
	    };
	  }]);
	
	  headerModule.directive("headerFlash", function () {
	    return {
	      restrict: 'A',
	      scope: {
	        level: "@headerFlashLevel"
	      },
	      template: __webpack_require__(100),
	      transclude: true,
	      link: function link(scope) {
	        if (scope.level === "alert" || scope.level === "error") {
	          scope.style = "messageNotification--error";
	        } else {
	          scope.style = "messageNotification--success";
	        }
	
	        scope.open = true;
	        scope.closeFlash = function () {
	          scope.open = false;
	        };
	      }
	    };
	  });
	}

/***/ },
/* 115 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (footer) {
	  footer.directive('footerLocaleDropdown', _footerLocaleDropdownDirective2.default).directive('footerNewsletterForm', _footerNewsletterFormDirective2.default).directive('footerTrustBbb', _footerTrustBbbDirective2.default);
	};
	
	var _footerLocaleDropdownDirective = __webpack_require__(116);
	
	var _footerLocaleDropdownDirective2 = _interopRequireDefault(_footerLocaleDropdownDirective);
	
	var _footerNewsletterFormDirective = __webpack_require__(118);
	
	var _footerNewsletterFormDirective2 = _interopRequireDefault(_footerNewsletterFormDirective);
	
	var _footerTrustBbbDirective = __webpack_require__(119);
	
	var _footerTrustBbbDirective2 = _interopRequireDefault(_footerTrustBbbDirective);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/***/ },
/* 116 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	footerLocaleDropdown.$inject = ["$window", "i18n", "browser"];
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	exports.default = footerLocaleDropdown;
	/*@ngInject*/
	function footerLocaleDropdown($window, i18n, browser) {
	  return {
	    restrict: 'A',
	    template: __webpack_require__(117),
	    scope: {},
	    link: function link(scope, element, attrs) {
	      var localeHash = JSON.parse(attrs.localeOptions);
	      var localeOptions = [];
	      for (var localeKey in localeHash) {
	        localeOptions.push({ key: localeKey, value: localeHash[localeKey] });
	      }
	      scope.localeOptions = _.sortBy(localeOptions, 'key');
	      scope.currentLocale = localeHash[i18n.locale];
	
	      var localeUrl = function localeUrl(locale) {
	        var location = $window.location;
	        var queryParams = location.search === "" ? [] : location.search.substring(1).split("&");
	        queryParams = _.reject(queryParams, function (param) {
	          return param.indexOf("locale") != -1;
	        });
	        queryParams.push("locale=" + locale);
	        return location.protocol + "//" + location.host + location.pathname + "?" + queryParams.join("&");
	      };
	
	      scope.selectLocale = function (locale) {
	        browser.redirectTo(localeUrl(locale));
	      };
	    }
	  };
	}

/***/ },
/* 117 */
/***/ function(module, exports) {

	module.exports = "<a href=\"\" bs-dropdown>\n  <span>{{::currentLocale}}</span>\n  <svg-icon icon=\"down-caret\"></svg-icon>\n</a>\n<ul class=\"dropdown-menu\">\n  <li ng-repeat=\"localeOption in localeOptions\">\n    <a href=\"\" ng-click=\"selectLocale(localeOption.key)\">{{::localeOption.value}}</a>\n  </li>\n</ul>\n";

/***/ },
/* 118 */
/***/ function(module, exports) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function () {
	  return {
	    restrict: 'A',
	    link: function link(scope, element) {
	      scope.submitForm = function () {
	        element.submit();
	      };
	    }
	  };
	};

/***/ },
/* 119 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, "__esModule", {
	  value: true
	});
	
	exports.default = function (i18n) {
	  return {
	    restrict: 'A',
	    template: __webpack_require__(120),
	    scope: {
	      bbbImageUrl: "@footerTrustBbbImageUrl"
	    },
	    link: function link(scope) {
	      igg.externalService(function () {
	        // TRUSTe logo in footer
	        var tl = document.createElement('script');
	        tl.type = 'text/javascript';
	        tl.src = '//privacy-policy.truste.com/privacy-seal/Indiegogo,-Inc-/asc?rid=f11cda4f-ffd6-4d45-b3c3-dea39f0b8194';
	        tl.async = true;
	        var s = document.getElementsByTagName('script')[0];
	        s.parentNode.insertBefore(tl, s);
	      });
	      scope.inEnglish = i18n.locale === 'en';
	    }
	  };
	};

/***/ },
/* 120 */
/***/ function(module, exports) {

	module.exports = "<a id=\"bbblink\" class=\"bbb sehzbus\" href=\"http://www.bbb.org/greater-san-francisco/business-reviews/internet-services/indiegogo-in-san-francisco-ca-372843#bbblogo\" target=\"_blank\"><img id=\"bbblinkimg\" ng-src=\"{{bbbImageUrl}}\" width=\"100\" height=\"38\" alt=\"{{::i18n.t('footer.bbb')}}\"/></a>\n<div ng-if=\"::inEnglish\" id=\"f11cda4f-ffd6-4d45-b3c3-dea39f0b8194\" class=\"truste\"><a href=\"//privacy.truste.com/privacy-seal/Indiegogo,-Inc-/validation?rid=6d279abc-bf79-4648-bbc3-ac58bb077a34\" title=\"TRUSTe European Safe Harbor certification\" target=\"_blank\"><img style=\"border: none\" src=\"//privacy-policy.truste.com/privacy-seal/Indiegogo,-Inc-/seal?rid=6d279abc-bf79-4648-bbc3-ac58bb077a34\" height=\"38\" alt=\"TRUSTe European Safe Harbor certification\"/></a></div>\n";

/***/ },
/* 121 */
/***/ function(module, exports) {

	/**
	 * @license Angulartics v0.19.2
	 * (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics
	 * License: MIT
	 */
	(function(angular, analytics) {
	'use strict';
	
	var angulartics = window.angulartics || (window.angulartics = {});
	angulartics.waitForVendorCount = 0;
	angulartics.waitForVendorApi = function (objectName, delay, containsField, registerFn, onTimeout) {
	  if (!onTimeout) { angulartics.waitForVendorCount++; }
	  if (!registerFn) { registerFn = containsField; containsField = undefined; }
	  if (!Object.prototype.hasOwnProperty.call(window, objectName) || (containsField !== undefined && window[objectName][containsField] === undefined)) {
	    setTimeout(function () { angulartics.waitForVendorApi(objectName, delay, containsField, registerFn, true); }, delay);
	  }
	  else {
	    angulartics.waitForVendorCount--;
	    registerFn(window[objectName]);
	  }
	};
	
	/**
	 * @ngdoc overview
	 * @name angulartics
	 */
	angular.module('angulartics', [])
	.provider('$analytics', function () {
	  var settings = {
	    pageTracking: {
	      autoTrackFirstPage: true,
	      autoTrackVirtualPages: true,
	      trackRelativePath: false,
	      autoBasePath: false,
	      basePath: ''
	    },
	    eventTracking: {},
	    bufferFlushDelay: 1000, // Support only one configuration for buffer flush delay to simplify buffering
	    developerMode: false // Prevent sending data in local/development environment
	  };
	
	  // List of known handlers that plugins can register themselves for
	  var knownHandlers = [
	    'pageTrack',
	    'eventTrack',
	    'setAlias',
	    'setUsername',
	    'setUserProperties',
	    'setUserPropertiesOnce',
	    'setSuperProperties',
	    'setSuperPropertiesOnce'
	  ];
	  // Cache and handler properties will match values in 'knownHandlers' as the buffering functons are installed.
	  var cache = {};
	  var handlers = {};
	
	  // General buffering handler
	  var bufferedHandler = function(handlerName){
	    return function(){
	      if(angulartics.waitForVendorCount){
	        if(!cache[handlerName]){ cache[handlerName] = []; }
	        cache[handlerName].push(arguments);
	      }
	    };
	  };
	
	  // As handlers are installed by plugins, they get pushed into a list and invoked in order.
	  var updateHandlers = function(handlerName, fn){
	    if(!handlers[handlerName]){
	      handlers[handlerName] = [];
	    }
	    handlers[handlerName].push(fn);
	    return function(){
	      var handlerArgs = arguments;
	      angular.forEach(handlers[handlerName], function(handler){
	        handler.apply(this, handlerArgs);
	      }, this);
	    };
	  };
	
	  // The api (returned by this provider) gets populated with handlers below.
	  var api = {
	    settings: settings
	  };
	
	  // Will run setTimeout if delay is > 0
	  // Runs immediately if no delay to make sure cache/buffer is flushed before anything else.
	  // Plugins should take care to register handlers by order of precedence.
	  var onTimeout = function(fn, delay){
	    if(delay){
	      setTimeout(fn, delay);
	    } else {
	      fn();
	    }
	  };
	
	  var provider = {
	    $get: function($injector) {
	      return apiWithInjector($injector);
	    },
	    api: api,
	    settings: settings,
	    virtualPageviews: function (value) { this.settings.pageTracking.autoTrackVirtualPages = value; },
	    firstPageview: function (value) { this.settings.pageTracking.autoTrackFirstPage = value; },
	    withBase: function (value) {
	      this.settings.pageTracking.basePath = (value) ? angular.element(document).find('base').attr('href') : '';
	    },
	    withAutoBase: function (value) { this.settings.pageTracking.autoBasePath = value; },
	    developerMode: function(value) { this.settings.developerMode = value; }
	  };
	
	  // General function to register plugin handlers. Flushes buffers immediately upon registration according to the specified delay.
	  var register = function(handlerName, fn){
	    api[handlerName] = updateHandlers(handlerName, fn);
	    var handlerSettings = settings[handlerName];
	    var handlerDelay = (handlerSettings) ? handlerSettings.bufferFlushDelay : null;
	    var delay = (handlerDelay !== null) ? handlerDelay : settings.bufferFlushDelay;
	    angular.forEach(cache[handlerName], function (args, index) {
	      onTimeout(function () { fn.apply(this, args); }, index * delay);
	    });
	  };
	
	  var capitalize = function (input) {
	      return input.replace(/^./, function (match) {
	          return match.toUpperCase();
	      });
	  };
	
	  //provide a method to inject services into handlers
	  var apiWithInjector = function(injector) {
	    return angular.extend(api, {
	      '$inject': injector.invoke
	    });
	  };
	
	  // Adds to the provider a 'register#{handlerName}' function that manages multiple plugins and buffer flushing.
	  var installHandlerRegisterFunction = function(handlerName){
	    var registerName = 'register'+capitalize(handlerName);
	    provider[registerName] = function(fn){
	      register(handlerName, fn);
	    };
	    api[handlerName] = updateHandlers(handlerName, bufferedHandler(handlerName));
	  };
	
	  // Set up register functions for each known handler
	  angular.forEach(knownHandlers, installHandlerRegisterFunction);
	  return provider;
	})
	
	.run(['$rootScope', '$window', '$analytics', '$injector', function ($rootScope, $window, $analytics, $injector) {
	  if ($analytics.settings.pageTracking.autoTrackFirstPage) {
	    $injector.invoke(['$location', function ($location) {
	      /* Only track the 'first page' if there are no routes or states on the page */
	      var noRoutesOrStates = true;
	      if ($injector.has('$route')) {
	         var $route = $injector.get('$route');
	         for (var route in $route.routes) {
	           noRoutesOrStates = false;
	           break;
	         }
	      } else if ($injector.has('$state')) {
	        var $state = $injector.get('$state');
	        for (var state in $state.get()) {
	          noRoutesOrStates = false;
	          break;
	        }
	      }
	      if (noRoutesOrStates) {
	        if ($analytics.settings.pageTracking.autoBasePath) {
	          $analytics.settings.pageTracking.basePath = $window.location.pathname;
	        }
	        if ($analytics.settings.pageTracking.trackRelativePath) {
	          var url = $analytics.settings.pageTracking.basePath + $location.url();
	          $analytics.pageTrack(url, $location);
	        } else {
	          $analytics.pageTrack($location.absUrl(), $location);
	        }
	      }
	    }]);
	  }
	
	  if ($analytics.settings.pageTracking.autoTrackVirtualPages) {
	    $injector.invoke(['$location', function ($location) {
	      if ($analytics.settings.pageTracking.autoBasePath) {
	        /* Add the full route to the base. */
	        $analytics.settings.pageTracking.basePath = $window.location.pathname + "#";
	      }
	      var noRoutesOrStates = true;
	      if ($injector.has('$route')) {
	        var $route = $injector.get('$route');
	        for (var route in $route.routes) {
	          noRoutesOrStates = false;
	          break;
	        }
	        $rootScope.$on('$routeChangeSuccess', function (event, current) {
	          if (current && (current.$$route||current).redirectTo) return;
	          var url = $analytics.settings.pageTracking.basePath + $location.url();
	          $analytics.pageTrack(url, $location);
	        });
	      }
	      if ($injector.has('$state')) {
	        noRoutesOrStates = false;
	        $rootScope.$on('$stateChangeSuccess', function (event, current) {
	          var url = $analytics.settings.pageTracking.basePath + $location.url();
	          $analytics.pageTrack(url, $location);
	        });
	      }
	      if (noRoutesOrStates) {
	        $rootScope.$on('$locationChangeSuccess', function (event, current) {
	          if (current && (current.$$route || current).redirectTo) return;
	          if ($analytics.settings.pageTracking.trackRelativePath) {
	            var url = $analytics.settings.pageTracking.basePath + $location.url();
	            $analytics.pageTrack(url, $location);
	          } else {
	            $analytics.pageTrack($location.absUrl(), $location);
	          }
	        });
	      }
	    }]);
	  }
	  if ($analytics.settings.developerMode) {
	    angular.forEach($analytics, function(attr, name) {
	      if (typeof attr === 'function') {
	        $analytics[name] = function(){};
	      }
	    });
	  }
	}])
	
	.directive('analyticsOn', ['$analytics', function ($analytics) {
	  function isCommand(element) {
	    return ['a:','button:','button:button','button:submit','input:button','input:submit'].indexOf(
	      element.tagName.toLowerCase()+':'+(element.type||'')) >= 0;
	  }
	
	  function inferEventType(element) {
	    if (isCommand(element)) return 'click';
	    return 'click';
	  }
	
	  function inferEventName(element) {
	    if (isCommand(element)) return element.innerText || element.value;
	    return element.id || element.name || element.tagName;
	  }
	
	  function isProperty(name) {
	    return name.substr(0, 9) === 'analytics' && ['On', 'Event', 'If', 'Properties', 'EventType'].indexOf(name.substr(9)) === -1;
	  }
	
	  function propertyName(name) {
	    var s = name.slice(9); // slice off the 'analytics' prefix
	    if (typeof s !== 'undefined' && s!==null && s.length > 0) {
	      return s.substring(0, 1).toLowerCase() + s.substring(1);
	    }
	    else {
	      return s;
	    }
	  }
	
	  return {
	    restrict: 'A',
	    link: function ($scope, $element, $attrs) {
	      var eventType = $attrs.analyticsOn || inferEventType($element[0]);
	      var trackingData = {};
	
	      angular.forEach($attrs.$attr, function(attr, name) {
	        if (isProperty(name)) {
	          trackingData[propertyName(name)] = $attrs[name];
	          $attrs.$observe(name, function(value){
	            trackingData[propertyName(name)] = value;
	          });
	        }
	      });
	
	      angular.element($element[0]).bind(eventType, function ($event) {
	        var eventName = $attrs.analyticsEvent || inferEventName($element[0]);
	        trackingData.eventType = $event.type;
	
	        if($attrs.analyticsIf){
	          if(! $scope.$eval($attrs.analyticsIf)){
	            return; // Cancel this event if we don't pass the analytics-if condition
	          }
	        }
	        // Allow components to pass through an expression that gets merged on to the event properties
	        // eg. analytics-properites='myComponentScope.someConfigExpression.$analyticsProperties'
	        if($attrs.analyticsProperties){
	          angular.extend(trackingData, $scope.$eval($attrs.analyticsProperties));
	        }
	        $analytics.eventTrack(eventName, trackingData);
	      });
	    }
	  };
	}]);
	})(angular);


/***/ },
/* 122 */
/***/ function(module, exports) {

	/**
	 * @license AngularJS v1.4.6
	 * (c) 2010-2015 Google, Inc. http://angularjs.org
	 * License: MIT
	 */
	(function(window, angular, undefined) {'use strict';
	
	var $resourceMinErr = angular.$$minErr('$resource');
	
	// Helper functions and regex to lookup a dotted path on an object
	// stopping at undefined/null.  The path must be composed of ASCII
	// identifiers (just like $parse)
	var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
	
	function isValidDottedPath(path) {
	  return (path != null && path !== '' && path !== 'hasOwnProperty' &&
	      MEMBER_NAME_REGEX.test('.' + path));
	}
	
	function lookupDottedPath(obj, path) {
	  if (!isValidDottedPath(path)) {
	    throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
	  }
	  var keys = path.split('.');
	  for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
	    var key = keys[i];
	    obj = (obj !== null) ? obj[key] : undefined;
	  }
	  return obj;
	}
	
	/**
	 * Create a shallow copy of an object and clear other fields from the destination
	 */
	function shallowClearAndCopy(src, dst) {
	  dst = dst || {};
	
	  angular.forEach(dst, function(value, key) {
	    delete dst[key];
	  });
	
	  for (var key in src) {
	    if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
	      dst[key] = src[key];
	    }
	  }
	
	  return dst;
	}
	
	/**
	 * @ngdoc module
	 * @name ngResource
	 * @description
	 *
	 * # ngResource
	 *
	 * The `ngResource` module provides interaction support with RESTful services
	 * via the $resource service.
	 *
	 *
	 * <div doc-module-components="ngResource"></div>
	 *
	 * See {@link ngResource.$resource `$resource`} for usage.
	 */
	
	/**
	 * @ngdoc service
	 * @name $resource
	 * @requires $http
	 *
	 * @description
	 * A factory which creates a resource object that lets you interact with
	 * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
	 *
	 * The returned resource object has action methods which provide high-level behaviors without
	 * the need to interact with the low level {@link ng.$http $http} service.
	 *
	 * Requires the {@link ngResource `ngResource`} module to be installed.
	 *
	 * By default, trailing slashes will be stripped from the calculated URLs,
	 * which can pose problems with server backends that do not expect that
	 * behavior.  This can be disabled by configuring the `$resourceProvider` like
	 * this:
	 *
	 * ```js
	     app.config(['$resourceProvider', function($resourceProvider) {
	       // Don't strip trailing slashes from calculated URLs
	       $resourceProvider.defaults.stripTrailingSlashes = false;
	     }]);
	 * ```
	 *
	 * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
	 *   `/user/:username`. If you are using a URL with a port number (e.g.
	 *   `http://example.com:8080/api`), it will be respected.
	 *
	 *   If you are using a url with a suffix, just add the suffix, like this:
	 *   `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
	 *   or even `$resource('http://example.com/resource/:resource_id.:format')`
	 *   If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
	 *   collapsed down to a single `.`.  If you need this sequence to appear and not collapse then you
	 *   can escape it with `/\.`.
	 *
	 * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
	 *   `actions` methods. If any of the parameter value is a function, it will be executed every time
	 *   when a param value needs to be obtained for a request (unless the param was overridden).
	 *
	 *   Each key value in the parameter object is first bound to url template if present and then any
	 *   excess keys are appended to the url search query after the `?`.
	 *
	 *   Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
	 *   URL `/path/greet?salutation=Hello`.
	 *
	 *   If the parameter value is prefixed with `@` then the value for that parameter will be extracted
	 *   from the corresponding property on the `data` object (provided when calling an action method).  For
	 *   example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of `someParam`
	 *   will be `data.someProp`.
	 *
	 * @param {Object.<Object>=} actions Hash with declaration of custom actions that should extend
	 *   the default set of resource actions. The declaration should be created in the format of {@link
	 *   ng.$http#usage $http.config}:
	 *
	 *       {action1: {method:?, params:?, isArray:?, headers:?, ...},
	 *        action2: {method:?, params:?, isArray:?, headers:?, ...},
	 *        ...}
	 *
	 *   Where:
	 *
	 *   - **`action`** – {string} – The name of action. This name becomes the name of the method on
	 *     your resource object.
	 *   - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,
	 *     `DELETE`, `JSONP`, etc).
	 *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
	 *     the parameter value is a function, it will be executed every time when a param value needs to
	 *     be obtained for a request (unless the param was overridden).
	 *   - **`url`** – {string} – action specific `url` override. The url templating is supported just
	 *     like for the resource-level urls.
	 *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
	 *     see `returns` section.
	 *   - **`transformRequest`** –
	 *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
	 *     transform function or an array of such functions. The transform function takes the http
	 *     request body and headers and returns its transformed (typically serialized) version.
	 *     By default, transformRequest will contain one function that checks if the request data is
	 *     an object and serializes to using `angular.toJson`. To prevent this behavior, set
	 *     `transformRequest` to an empty array: `transformRequest: []`
	 *   - **`transformResponse`** –
	 *     `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
	 *     transform function or an array of such functions. The transform function takes the http
	 *     response body and headers and returns its transformed (typically deserialized) version.
	 *     By default, transformResponse will contain one function that checks if the response looks like
	 *     a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, set
	 *     `transformResponse` to an empty array: `transformResponse: []`
	 *   - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
	 *     GET request, otherwise if a cache instance built with
	 *     {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
	 *     caching.
	 *   - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that
	 *     should abort the request when resolved.
	 *   - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
	 *     XHR object. See
	 *     [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
	 *     for more information.
	 *   - **`responseType`** - `{string}` - see
	 *     [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
	 *   - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
	 *     `response` and `responseError`. Both `response` and `responseError` interceptors get called
	 *     with `http response` object. See {@link ng.$http $http interceptors}.
	 *
	 * @param {Object} options Hash with custom settings that should extend the
	 *   default `$resourceProvider` behavior.  The only supported option is
	 *
	 *   Where:
	 *
	 *   - **`stripTrailingSlashes`** – {boolean} – If true then the trailing
	 *   slashes from any calculated URL will be stripped. (Defaults to true.)
	 *
	 * @returns {Object} A resource "class" object with methods for the default set of resource actions
	 *   optionally extended with custom `actions`. The default set contains these actions:
	 *   ```js
	 *   { 'get':    {method:'GET'},
	 *     'save':   {method:'POST'},
	 *     'query':  {method:'GET', isArray:true},
	 *     'remove': {method:'DELETE'},
	 *     'delete': {method:'DELETE'} };
	 *   ```
	 *
	 *   Calling these methods invoke an {@link ng.$http} with the specified http method,
	 *   destination and parameters. When the data is returned from the server then the object is an
	 *   instance of the resource class. The actions `save`, `remove` and `delete` are available on it
	 *   as  methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
	 *   read, update, delete) on server-side data like this:
	 *   ```js
	 *   var User = $resource('/user/:userId', {userId:'@id'});
	 *   var user = User.get({userId:123}, function() {
	 *     user.abc = true;
	 *     user.$save();
	 *   });
	 *   ```
	 *
	 *   It is important to realize that invoking a $resource object method immediately returns an
	 *   empty reference (object or array depending on `isArray`). Once the data is returned from the
	 *   server the existing reference is populated with the actual data. This is a useful trick since
	 *   usually the resource is assigned to a model which is then rendered by the view. Having an empty
	 *   object results in no rendering, once the data arrives from the server then the object is
	 *   populated with the data and the view automatically re-renders itself showing the new data. This
	 *   means that in most cases one never has to write a callback function for the action methods.
	 *
	 *   The action methods on the class object or instance object can be invoked with the following
	 *   parameters:
	 *
	 *   - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
	 *   - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
	 *   - non-GET instance actions:  `instance.$action([parameters], [success], [error])`
	 *
	 *
	 *   Success callback is called with (value, responseHeaders) arguments, where the value is
	 *   the populated resource instance or collection object. The error callback is called
	 *   with (httpResponse) argument.
	 *
	 *   Class actions return empty instance (with additional properties below).
	 *   Instance actions return promise of the action.
	 *
	 *   The Resource instances and collection have these additional properties:
	 *
	 *   - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
	 *     instance or collection.
	 *
	 *     On success, the promise is resolved with the same resource instance or collection object,
	 *     updated with data from server. This makes it easy to use in
	 *     {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
	 *     rendering until the resource(s) are loaded.
	 *
	 *     On failure, the promise is resolved with the {@link ng.$http http response} object, without
	 *     the `resource` property.
	 *
	 *     If an interceptor object was provided, the promise will instead be resolved with the value
	 *     returned by the interceptor.
	 *
	 *   - `$resolved`: `true` after first server interaction is completed (either with success or
	 *      rejection), `false` before that. Knowing if the Resource has been resolved is useful in
	 *      data-binding.
	 *
	 * @example
	 *
	 * # Credit card resource
	 *
	 * ```js
	     // Define CreditCard class
	     var CreditCard = $resource('/user/:userId/card/:cardId',
	      {userId:123, cardId:'@id'}, {
	       charge: {method:'POST', params:{charge:true}}
	      });
	
	     // We can retrieve a collection from the server
	     var cards = CreditCard.query(function() {
	       // GET: /user/123/card
	       // server returns: [ {id:456, number:'1234', name:'Smith'} ];
	
	       var card = cards[0];
	       // each item is an instance of CreditCard
	       expect(card instanceof CreditCard).toEqual(true);
	       card.name = "J. Smith";
	       // non GET methods are mapped onto the instances
	       card.$save();
	       // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
	       // server returns: {id:456, number:'1234', name: 'J. Smith'};
	
	       // our custom method is mapped as well.
	       card.$charge({amount:9.99});
	       // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
	     });
	
	     // we can create an instance as well
	     var newCard = new CreditCard({number:'0123'});
	     newCard.name = "Mike Smith";
	     newCard.$save();
	     // POST: /user/123/card {number:'0123', name:'Mike Smith'}
	     // server returns: {id:789, number:'0123', name: 'Mike Smith'};
	     expect(newCard.id).toEqual(789);
	 * ```
	 *
	 * The object returned from this function execution is a resource "class" which has "static" method
	 * for each action in the definition.
	 *
	 * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
	 * `headers`.
	 * When the data is returned from the server then the object is an instance of the resource type and
	 * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
	 * operations (create, read, update, delete) on server-side data.
	
	   ```js
	     var User = $resource('/user/:userId', {userId:'@id'});
	     User.get({userId:123}, function(user) {
	       user.abc = true;
	       user.$save();
	     });
	   ```
	 *
	 * It's worth noting that the success callback for `get`, `query` and other methods gets passed
	 * in the response that came from the server as well as $http header getter function, so one
	 * could rewrite the above example and get access to http headers as:
	 *
	   ```js
	     var User = $resource('/user/:userId', {userId:'@id'});
	     User.get({userId:123}, function(u, getResponseHeaders){
	       u.abc = true;
	       u.$save(function(u, putResponseHeaders) {
	         //u => saved user object
	         //putResponseHeaders => $http header getter
	       });
	     });
	   ```
	 *
	 * You can also access the raw `$http` promise via the `$promise` property on the object returned
	 *
	   ```
	     var User = $resource('/user/:userId', {userId:'@id'});
	     User.get({userId:123})
	         .$promise.then(function(user) {
	           $scope.user = user;
	         });
	   ```
	
	 * # Creating a custom 'PUT' request
	 * In this example we create a custom method on our resource to make a PUT request
	 * ```js
	 *    var app = angular.module('app', ['ngResource', 'ngRoute']);
	 *
	 *    // Some APIs expect a PUT request in the format URL/object/ID
	 *    // Here we are creating an 'update' method
	 *    app.factory('Notes', ['$resource', function($resource) {
	 *    return $resource('/notes/:id', null,
	 *        {
	 *            'update': { method:'PUT' }
	 *        });
	 *    }]);
	 *
	 *    // In our controller we get the ID from the URL using ngRoute and $routeParams
	 *    // We pass in $routeParams and our Notes factory along with $scope
	 *    app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
	                                      function($scope, $routeParams, Notes) {
	 *    // First get a note object from the factory
	 *    var note = Notes.get({ id:$routeParams.id });
	 *    $id = note.id;
	 *
	 *    // Now call update passing in the ID first then the object you are updating
	 *    Notes.update({ id:$id }, note);
	 *
	 *    // This will PUT /notes/ID with the note object in the request payload
	 *    }]);
	 * ```
	 */
	angular.module('ngResource', ['ng']).
	  provider('$resource', function() {
	    var PROTOCOL_AND_DOMAIN_REGEX = /^https?:\/\/[^\/]*/;
	    var provider = this;
	
	    this.defaults = {
	      // Strip slashes by default
	      stripTrailingSlashes: true,
	
	      // Default actions configuration
	      actions: {
	        'get': {method: 'GET'},
	        'save': {method: 'POST'},
	        'query': {method: 'GET', isArray: true},
	        'remove': {method: 'DELETE'},
	        'delete': {method: 'DELETE'}
	      }
	    };
	
	    this.$get = ['$http', '$q', function($http, $q) {
	
	      var noop = angular.noop,
	        forEach = angular.forEach,
	        extend = angular.extend,
	        copy = angular.copy,
	        isFunction = angular.isFunction;
	
	      /**
	       * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
	       * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set
	       * (pchar) allowed in path segments:
	       *    segment       = *pchar
	       *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
	       *    pct-encoded   = "%" HEXDIG HEXDIG
	       *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
	       *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
	       *                     / "*" / "+" / "," / ";" / "="
	       */
	      function encodeUriSegment(val) {
	        return encodeUriQuery(val, true).
	          replace(/%26/gi, '&').
	          replace(/%3D/gi, '=').
	          replace(/%2B/gi, '+');
	      }
	
	
	      /**
	       * This method is intended for encoding *key* or *value* parts of query component. We need a
	       * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
	       * have to be encoded per http://tools.ietf.org/html/rfc3986:
	       *    query       = *( pchar / "/" / "?" )
	       *    pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
	       *    unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
	       *    pct-encoded   = "%" HEXDIG HEXDIG
	       *    sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
	       *                     / "*" / "+" / "," / ";" / "="
	       */
	      function encodeUriQuery(val, pctEncodeSpaces) {
	        return encodeURIComponent(val).
	          replace(/%40/gi, '@').
	          replace(/%3A/gi, ':').
	          replace(/%24/g, '$').
	          replace(/%2C/gi, ',').
	          replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
	      }
	
	      function Route(template, defaults) {
	        this.template = template;
	        this.defaults = extend({}, provider.defaults, defaults);
	        this.urlParams = {};
	      }
	
	      Route.prototype = {
	        setUrlParams: function(config, params, actionUrl) {
	          var self = this,
	            url = actionUrl || self.template,
	            val,
	            encodedVal,
	            protocolAndDomain = '';
	
	          var urlParams = self.urlParams = {};
	          forEach(url.split(/\W/), function(param) {
	            if (param === 'hasOwnProperty') {
	              throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
	            }
	            if (!(new RegExp("^\\d+$").test(param)) && param &&
	              (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
	              urlParams[param] = true;
	            }
	          });
	          url = url.replace(/\\:/g, ':');
	          url = url.replace(PROTOCOL_AND_DOMAIN_REGEX, function(match) {
	            protocolAndDomain = match;
	            return '';
	          });
	
	          params = params || {};
	          forEach(self.urlParams, function(_, urlParam) {
	            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
	            if (angular.isDefined(val) && val !== null) {
	              encodedVal = encodeUriSegment(val);
	              url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
	                return encodedVal + p1;
	              });
	            } else {
	              url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
	                  leadingSlashes, tail) {
	                if (tail.charAt(0) == '/') {
	                  return tail;
	                } else {
	                  return leadingSlashes + tail;
	                }
	              });
	            }
	          });
	
	          // strip trailing slashes and set the url (unless this behavior is specifically disabled)
	          if (self.defaults.stripTrailingSlashes) {
	            url = url.replace(/\/+$/, '') || '/';
	          }
	
	          // then replace collapse `/.` if found in the last URL path segment before the query
	          // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
	          url = url.replace(/\/\.(?=\w+($|\?))/, '.');
	          // replace escaped `/\.` with `/.`
	          config.url = protocolAndDomain + url.replace(/\/\\\./, '/.');
	
	
	          // set params - delegate param encoding to $http
	          forEach(params, function(value, key) {
	            if (!self.urlParams[key]) {
	              config.params = config.params || {};
	              config.params[key] = value;
	            }
	          });
	        }
	      };
	
	
	      function resourceFactory(url, paramDefaults, actions, options) {
	        var route = new Route(url, options);
	
	        actions = extend({}, provider.defaults.actions, actions);
	
	        function extractParams(data, actionParams) {
	          var ids = {};
	          actionParams = extend({}, paramDefaults, actionParams);
	          forEach(actionParams, function(value, key) {
	            if (isFunction(value)) { value = value(); }
	            ids[key] = value && value.charAt && value.charAt(0) == '@' ?
	              lookupDottedPath(data, value.substr(1)) : value;
	          });
	          return ids;
	        }
	
	        function defaultResponseInterceptor(response) {
	          return response.resource;
	        }
	
	        function Resource(value) {
	          shallowClearAndCopy(value || {}, this);
	        }
	
	        Resource.prototype.toJSON = function() {
	          var data = extend({}, this);
	          delete data.$promise;
	          delete data.$resolved;
	          return data;
	        };
	
	        forEach(actions, function(action, name) {
	          var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
	
	          Resource[name] = function(a1, a2, a3, a4) {
	            var params = {}, data, success, error;
	
	            /* jshint -W086 */ /* (purposefully fall through case statements) */
	            switch (arguments.length) {
	              case 4:
	                error = a4;
	                success = a3;
	              //fallthrough
	              case 3:
	              case 2:
	                if (isFunction(a2)) {
	                  if (isFunction(a1)) {
	                    success = a1;
	                    error = a2;
	                    break;
	                  }
	
	                  success = a2;
	                  error = a3;
	                  //fallthrough
	                } else {
	                  params = a1;
	                  data = a2;
	                  success = a3;
	                  break;
	                }
	              case 1:
	                if (isFunction(a1)) success = a1;
	                else if (hasBody) data = a1;
	                else params = a1;
	                break;
	              case 0: break;
	              default:
	                throw $resourceMinErr('badargs',
	                  "Expected up to 4 arguments [params, data, success, error], got {0} arguments",
	                  arguments.length);
	            }
	            /* jshint +W086 */ /* (purposefully fall through case statements) */
	
	            var isInstanceCall = this instanceof Resource;
	            var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
	            var httpConfig = {};
	            var responseInterceptor = action.interceptor && action.interceptor.response ||
	              defaultResponseInterceptor;
	            var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
	              undefined;
	
	            forEach(action, function(value, key) {
	              if (key != 'params' && key != 'isArray' && key != 'interceptor') {
	                httpConfig[key] = copy(value);
	              }
	            });
	
	            if (hasBody) httpConfig.data = data;
	            route.setUrlParams(httpConfig,
	              extend({}, extractParams(data, action.params || {}), params),
	              action.url);
	
	            var promise = $http(httpConfig).then(function(response) {
	              var data = response.data,
	                promise = value.$promise;
	
	              if (data) {
	                // Need to convert action.isArray to boolean in case it is undefined
	                // jshint -W018
	                if (angular.isArray(data) !== (!!action.isArray)) {
	                  throw $resourceMinErr('badcfg',
	                      'Error in resource configuration for action `{0}`. Expected response to ' +
	                      'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
	                    angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
	                }
	                // jshint +W018
	                if (action.isArray) {
	                  value.length = 0;
	                  forEach(data, function(item) {
	                    if (typeof item === "object") {
	                      value.push(new Resource(item));
	                    } else {
	                      // Valid JSON values may be string literals, and these should not be converted
	                      // into objects. These items will not have access to the Resource prototype
	                      // methods, but unfortunately there
	                      value.push(item);
	                    }
	                  });
	                } else {
	                  shallowClearAndCopy(data, value);
	                  value.$promise = promise;
	                }
	              }
	
	              value.$resolved = true;
	
	              response.resource = value;
	
	              return response;
	            }, function(response) {
	              value.$resolved = true;
	
	              (error || noop)(response);
	
	              return $q.reject(response);
	            });
	
	            promise = promise.then(
	              function(response) {
	                var value = responseInterceptor(response);
	                (success || noop)(value, response.headers);
	                return value;
	              },
	              responseErrorInterceptor);
	
	            if (!isInstanceCall) {
	              // we are creating instance / collection
	              // - set the initial promise
	              // - return the instance / collection
	              value.$promise = promise;
	              value.$resolved = false;
	
	              return value;
	            }
	
	            // instance call
	            return promise;
	          };
	
	
	          Resource.prototype['$' + name] = function(params, success, error) {
	            if (isFunction(params)) {
	              error = success; success = params; params = {};
	            }
	            var result = Resource[name].call(this, params, this, success, error);
	            return result.$promise || result;
	          };
	        });
	
	        Resource.bind = function(additionalParamDefaults) {
	          return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
	        };
	
	        return Resource;
	      }
	
	      return resourceFactory;
	    }];
	  });
	
	
	})(window, window.angular);


/***/ },
/* 123 */
/***/ function(module, exports) {

	/**
	 * A resource factory inspired by $resource from AngularJS
	 * @version v2.0.0 - 2015-02-11
	 * @link https://github.com/FineLinePrototyping/angularjs-rails-resource.git
	 * @author 
	 */
	
	(function (undefined) {
	    angular.module('rails', ['ng']);
	}());
	
	
	
	(function (undefined) {
	    angular.module('rails').factory('RailsInflector', function() {
	        function camelize(key) {
	            if (!angular.isString(key)) {
	                return key;
	            }
	
	            // should this match more than word and digit characters?
	            return key.replace(/_[\w\d]/g, function (match, index, string) {
	                return index === 0 ? match : string.charAt(index + 1).toUpperCase();
	            });
	        }
	
	        function underscore(key) {
	            if (!angular.isString(key)) {
	                return key;
	            }
	
	            // TODO match the latest logic from Active Support
	            return key.replace(/[A-Z]/g, function (match, index) {
	                return index === 0 ? match : '_' + match.toLowerCase();
	            });
	        }
	
	        function pluralize(value) {
	            // TODO match Active Support
	            return value + 's';
	        }
	
	        return {
	            camelize: camelize,
	            underscore: underscore,
	            pluralize: pluralize
	        };
	    });
	}());
	(function (undefined) {
	    angular.module('rails').factory('RailsResourceInjector', ['$injector', function($injector) {
	        /**
	         * Allow dependencies to be referenced by name or instance.  If referenced by name AngularJS $injector
	         * is used to retrieve the dependency.
	         *
	         * @param dependency (string | function) The dependency to retrieve
	         * @returns {*} The dependency
	         */
	        function getDependency(dependency) {
	            if (dependency) {
	                return angular.isString(dependency) ? $injector.get(dependency) : dependency;
	            }
	
	            return undefined;
	        }
	
	        /**
	         * Looks up and instantiates an instance of the requested service.  If the service is not a string then it is
	         * assumed to be a constructor function.
	         *
	         * @param {String|function|Object} service  The service to instantiate
	         * @returns {*} A new instance of the requested service
	         */
	        function createService(service) {
	            if (service) {
	                return $injector.instantiate(getDependency(service));
	            }
	
	            return undefined;
	        }
	
	        /**
	         * Looks up and instantiates an instance of the requested service if .
	         * @param {String|function|Object} service The service to instantiate
	         * @returns {*}
	         */
	        function getService(service) {
	            // strings and functions are not considered objects by angular.isObject()
	            if (angular.isObject(service)) {
	                return service;
	            } else if (service) {
	                return createService(service);
	            }
	
	            return undefined;
	        }
	
	        return {
	            createService: createService,
	            getService: getService,
	            getDependency: getDependency
	        };
	    }]);
	}());
	/**
	 * @ngdoc function
	 * @name rails.railsUrlBuilder
	 * @function
	 * @requires $interpolate
	 *
	 * @description
	 *
	 * Compiles a URL template string into an interpolation function using $interpolate.  If no interpolation bindings
	 * found then {{id}} is appended to the url string.
	 *
	   <pre>
	       expect(railsUrlBuilder('/books')()).toEqual('/books')
	       expect(railsUrlBuilder('/books')({id: 1})).toEqual('/books/1')
	       expect(railsUrlBuilder('/authors/{{authorId}}/books/{{id}}')({id: 1, authorId: 2})).toEqual('/authors/2/books/1')
	   </pre>
	 *
	 * If the $interpolate startSymbol and endSymbol have been customized those values should be used instead of {{ and }}
	 *
	 * @param {string|function} url If the url is a function then that function is returned.  Otherwise the url string
	 *    is passed to $interpolate as an expression.
	 *
	 * @returns {function(context)} As stated by $interpolate documentation:
	 *    An interpolation function which is used to compute the interpolated
	 *    string. The function has these parameters:
	 *
	 *    * `context`: an object against which any expressions embedded in the strings are evaluated
	 *      against.
	 *
	 */
	(function (undefined) {
	    angular.module('rails').factory('railsUrlBuilder', ['$interpolate', function($interpolate) {
	        return function (config) {
	            var url = config.url,
	              idAttribute = config.idAttribute,
	              expression;
	
	            if (angular.isFunction(url) || angular.isUndefined(url)) {
	                return url;
	            }
	
	            if (url.indexOf($interpolate.startSymbol()) === -1) {
	                url = url + '/' + $interpolate.startSymbol() + idAttribute + $interpolate.endSymbol();
	            }
	
	            expression = $interpolate(url);
	
	            return function (params) {
	                url = expression(params);
	
	                if (url.charAt(url.length - 1) === '/') {
	                    url = url.substr(0, url.length - 1);
	                }
	
	                return url;
	            };
	        };
	    }]);
	}());
	
	(function (undefined) {
	    angular.module('rails').provider('railsSerializer', function() {
	        var defaultOptions = {
	            underscore: undefined,
	            camelize: undefined,
	            pluralize: undefined,
	            exclusionMatchers: []
	        };
	
	        /**
	         * Configures the underscore method used by the serializer.  If not defined then <code>RailsInflector.underscore</code>
	         * will be used.
	         *
	         * @param {function(string):string} fn The function to use for underscore conversion
	         * @returns {railsSerializerProvider} The provider for chaining
	         */
	        this.underscore = function(fn) {
	            defaultOptions.underscore = fn;
	            return this;
	        };
	
	        /**
	         * Configures the camelize method used by the serializer.  If not defined then <code>RailsInflector.camelize</code>
	         * will be used.
	         *
	         * @param {function(string):string} fn The function to use for camelize conversion
	         * @returns {railsSerializerProvider} The provider for chaining
	         */
	        this.camelize = function(fn) {
	            defaultOptions.camelize = fn;
	            return this;
	        };
	
	        /**
	         * Configures the pluralize method used by the serializer.  If not defined then <code>RailsInflector.pluralize</code>
	         * will be used.
	         *
	         * @param {function(string):string} fn The function to use for pluralizing strings.
	         * @returns {railsSerializerProvider} The provider for chaining
	         */
	        this.pluralize = function(fn) {
	            defaultOptions.pluralize = fn;
	            return this;
	        };
	
	        /**
	         * Configures the array exclusion matchers by the serializer.  Exclusion matchers can be one of the following:
	         * * string - Defines a prefix that is used to test for exclusion
	         * * RegExp - A custom regular expression that is tested against the attribute name
	         * * function - A custom function that accepts a string argument and returns a boolean with true indicating exclusion.
	         *
	         * @param {Array.<string|function(string):boolean|RegExp} exclusions An array of exclusion matchers
	         * @returns {railsSerializerProvider} The provider for chaining
	         */
	        this.exclusionMatchers = function(exclusions) {
	            defaultOptions.exclusionMatchers = exclusions;
	            return this;
	        };
	
	        this.$get = ['$injector', 'RailsInflector', 'RailsResourceInjector', function ($injector, RailsInflector, RailsResourceInjector) {
	            defaultOptions.underscore = defaultOptions.underscore || RailsInflector.underscore;
	            defaultOptions.camelize = defaultOptions.camelize || RailsInflector.camelize;
	            defaultOptions.pluralize = defaultOptions.pluralize || RailsInflector.pluralize;
	
	            function railsSerializer(options, customizer) {
	
	                function Serializer() {
	                    if (angular.isFunction(options)) {
	                        customizer = options;
	                        options = {};
	                    }
	
	                    this.exclusions = {};
	                    this.inclusions = {};
	                    this.serializeMappings = {};
	                    this.deserializeMappings = {};
	                    this.customSerializedAttributes = {};
	                    this.preservedAttributes = {};
	                    this.customSerializers = {};
	                    this.nestedResources = {};
	                    this.options = angular.extend({excludeByDefault: false}, defaultOptions, options || {});
	
	                    if (customizer) {
	                        customizer.call(this, this);
	                    }
	                }
	
	                /**
	                 * Accepts a variable list of attribute names to exclude from JSON serialization.
	                 *
	                 * @param attributeNames... {string} Variable number of attribute name parameters
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.exclude = function () {
	                    var exclusions = this.exclusions;
	
	                    angular.forEach(arguments, function (attributeName) {
	                        exclusions[attributeName] = false;
	                    });
	
	                    return this;
	                };
	
	                /**
	                 * Accepts a variable list of attribute names that should be included in JSON serialization.
	                 * Using this method will by default exclude all other attributes and only the ones explicitly included using <code>only</code> will be serialized.
	                 * @param attributeNames... {string} Variable number of attribute name parameters
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.only = function () {
	                    var inclusions = this.inclusions;
	                    this.options.excludeByDefault = true;
	
	                    angular.forEach(arguments, function (attributeName) {
	                        inclusions[attributeName] = true;
	                    });
	
	                    return this;
	                };
	
	                /**
	                 * This is a shortcut for rename that allows you to specify a variable number of attributes that should all be renamed to
	                 * <code>{attributeName}_attributes</code> to work with the Rails nested_attributes feature.
	                 * @param attributeNames... {string} Variable number of attribute name parameters
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.nestedAttribute = function () {
	                    var self = this;
	
	                    angular.forEach(arguments, function (attributeName) {
	                        self.rename(attributeName, attributeName + '_attributes');
	                    });
	
	                    return this;
	                };
	
	                /**
	                 * Specifies an attribute that is a nested resource within the parent object.
	                 * Nested resources do not imply nested attributes, if you want both you still have to specify call <code>nestedAttribute</code> as well.
	                 *
	                 * A nested resource serves two purposes.  First, it defines the resource that should be used when constructing resources from the server.
	                 * Second, it specifies how the nested object should be serialized.
	                 *
	                 * An optional third parameter <code>serializer</code> is available to override the serialization logic
	                 * of the resource in case you need to serialize it differently in multiple contexts.
	                 *
	                 * @param attributeName {string} The name of the attribute that is a nested resource
	                 * @param resource {string | Resource} A reference to the resource that the attribute is a type of.
	                 * @param serializer {string | Serializer} (optional) An optional serializer reference to override the nested resource's default serializer
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.resource = function (attributeName, resource, serializer) {
	                    this.nestedResources[attributeName] = resource;
	
	                    if (serializer) {
	                        this.serializeWith(attributeName, serializer);
	                    }
	
	                    return this;
	                };
	
	                /**
	                 * Specifies a custom name mapping for an attribute.
	                 * On serializing to JSON the jsonName will be used.
	                 * On deserialization, if jsonName is seen then it will be renamed as javascriptName in the resulting resource.
	                 *
	                 * @param javascriptName {string} The attribute name as it appears in the JavaScript object
	                 * @param jsonName {string} The attribute name as it should appear in JSON
	                 * @param bidirectional {boolean} (optional) Allows turning off the bidirectional renaming, defaults to true.
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.rename = function (javascriptName, jsonName, bidirectional) {
	                    this.serializeMappings[javascriptName] = jsonName;
	
	                    if (bidirectional || bidirectional === undefined) {
	                        this.deserializeMappings[jsonName] = javascriptName;
	                    }
	                    return this;
	                };
	
	                /**
	                 * Allows custom attribute creation as part of the serialization to JSON.
	                 *
	                 * @param attributeName {string} The name of the attribute to add
	                 * @param value {*} The value to add, if specified as a function then the function will be called during serialization
	                 *     and should return the value to add.
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.add = function (attributeName, value) {
	                    this.customSerializedAttributes[attributeName] = value;
	                    return this;
	                };
	
	
	                /**
	                 * Allows the attribute to be preserved unmodified in the resulting object.
	                 *
	                 * @param attributeName {string} The name of the attribute to add
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.preserve = function(attributeName) {
	                    this.preservedAttributes[attributeName] =  true;
	                    return this;
	                };
	
	                /**
	                 * Specify a custom serializer to use for an attribute.
	                 *
	                 * @param attributeName {string} The name of the attribute
	                 * @param serializer {string | function} A reference to the custom serializer to use for the attribute.
	                 * @returns {Serializer} this for chaining support
	                 */
	                Serializer.prototype.serializeWith = function (attributeName, serializer) {
	                    this.customSerializers[attributeName] = serializer;
	                    return this;
	                };
	
	                /**
	                 * Determines whether or not an attribute should be excluded.
	                 *
	                 * If the option excludeByDefault has been set then attributes will default to excluded and will only
	                 * be included if they have been included using the "only" customization function.
	                 *
	                 * If the option excludeByDefault has not been set then attributes must be explicitly excluded using the "exclude"
	                 * customization function or must be matched by one of the exclusionMatchers.
	                 *
	                 * @param attributeName The name of the attribute to check for exclusion
	                 * @returns {boolean} true if excluded, false otherwise
	                 */
	                Serializer.prototype.isExcludedFromSerialization = function (attributeName) {
	                    if ((this.options.excludeByDefault && !this.inclusions.hasOwnProperty(attributeName)) || this.exclusions.hasOwnProperty(attributeName)) {
	                        return true;
	                    }
	
	                    if (this.options.exclusionMatchers) {
	                        var excluded = false;
	
	                        angular.forEach(this.options.exclusionMatchers, function (matcher) {
	                            if (angular.isString(matcher)) {
	                                excluded = excluded || attributeName.indexOf(matcher) === 0;
	                            } else if (angular.isFunction(matcher)) {
	                                excluded = excluded || matcher.call(undefined, attributeName);
	                            } else if (matcher instanceof RegExp) {
	                                excluded = excluded || matcher.test(attributeName);
	                            }
	                        });
	
	                        return excluded;
	                    }
	
	                    return false;
	                };
	
	                /**
	                 * Remaps the attribute name to the serialized form which includes:
	                 *   - checking for exclusion
	                 *   - remapping to a custom value specified by the rename customization function
	                 *   - underscoring the name
	                 *
	                 * @param attributeName The current attribute name
	                 * @returns {*} undefined if the attribute should be excluded or the mapped attribute name
	                 */
	                Serializer.prototype.getSerializedAttributeName = function (attributeName) {
	                    var mappedName = this.serializeMappings[attributeName] || attributeName;
	
	                    var mappedNameExcluded = this.isExcludedFromSerialization(mappedName),
	                        attributeNameExcluded = this.isExcludedFromSerialization(attributeName);
	
	                    if(this.options.excludeByDefault) {
	                        if(mappedNameExcluded && attributeNameExcluded) {
	                            return undefined;
	                        }
	                    } else {
	                        if (mappedNameExcluded || attributeNameExcluded) {
	                            return undefined;
	                        }
	                    }
	
	                    return this.underscore(mappedName);
	                };
	
	                /**
	                 * Determines whether or not an attribute should be excluded from deserialization.
	                 *
	                 * By default, we do not exclude any attributes from deserialization.
	                 *
	                 * @param attributeName The name of the attribute to check for exclusion
	                 * @returns {boolean} true if excluded, false otherwise
	                 */
	                Serializer.prototype.isExcludedFromDeserialization = function (attributeName) {
	                    return false;
	                };
	
	                /**
	                 * Remaps the attribute name to the deserialized form which includes:
	                 *   - camelizing the name
	                 *   - checking for exclusion
	                 *   - remapping to a custom value specified by the rename customization function
	                 *
	                 * @param attributeName The current attribute name
	                 * @returns {*} undefined if the attribute should be excluded or the mapped attribute name
	                 */
	                Serializer.prototype.getDeserializedAttributeName = function (attributeName) {
	                    var camelizedName = this.camelize(attributeName);
	
	                    camelizedName = this.deserializeMappings[attributeName] ||
	                        this.deserializeMappings[camelizedName] ||
	                        camelizedName;
	
	                    if (this.isExcludedFromDeserialization(attributeName) || this.isExcludedFromDeserialization(camelizedName)) {
	                        return undefined;
	                    }
	
	                    return camelizedName;
	                };
	
	                /**
	                 * Returns a reference to the nested resource that has been specified for the attribute.
	                 * @param attributeName The attribute name
	                 * @returns {*} undefined if no nested resource has been specified or a reference to the nested resource class
	                 */
	                Serializer.prototype.getNestedResource = function (attributeName) {
	                    return RailsResourceInjector.getDependency(this.nestedResources[attributeName]);
	                };
	
	                /**
	                 * Returns a custom serializer for the attribute if one has been specified.  Custom serializers can be specified
	                 * in one of two ways.  The serializeWith customization method allows specifying a custom serializer for any attribute.
	                 * Or an attribute could have been specified as a nested resource in which case the nested resource's serializer
	                 * is used.  Custom serializers specified using serializeWith take precedence over the nested resource serializer.
	                 *
	                 * @param attributeName The attribute name
	                 * @returns {*} undefined if no custom serializer has been specified or an instance of the Serializer
	                 */
	                Serializer.prototype.getAttributeSerializer = function (attributeName) {
	                    var resource = this.getNestedResource(attributeName),
	                        serializer = this.customSerializers[attributeName];
	
	                    // custom serializer takes precedence over resource serializer
	                    if (serializer) {
	                        return RailsResourceInjector.createService(serializer);
	                    } else if (resource) {
	                        return resource.config.serializer;
	                    }
	
	                    return undefined;
	                };
	
	
	                /**
	                 * Prepares the data for serialization to JSON.
	                 *
	                 * @param data The data to prepare
	                 * @returns {*} A new object or array that is ready for JSON serialization
	                 */
	                Serializer.prototype.serializeData = function (data) {
	                    var result = data,
	                        self = this;
	
	                    if (angular.isArray(data)) {
	                        result = [];
	
	                        angular.forEach(data, function (value) {
	                            result.push(self.serializeData(value));
	                        });
	                    } else if (angular.isObject(data)) {
	                        if (angular.isDate(data)) {
	                            return data;
	                        }
	                        result = {};
	
	                        this.serializeObject(result, data);
	
	                    }
	
	                    return result;
	                };
	
	                Serializer.prototype.serializeObject = function(result, data){
	
	
	                    var tthis = this;
	                    angular.forEach(data, function (value, key) {
	                        // if the value is a function then it can't be serialized to JSON so we'll just skip it
	                        if (!angular.isFunction(value)) {
	                            tthis.serializeAttribute(result, key, value);
	                        }
	                    });
	                    return data;
	                };
	
	                /**
	                 * Transforms an attribute and its value and stores it on the parent data object.  The attribute will be
	                 * renamed as needed and the value itself will be serialized as well.
	                 *
	                 * @param data The object that the attribute will be added to
	                 * @param attribute The attribute to transform
	                 * @param value The current value of the attribute
	                 */
	                Serializer.prototype.serializeAttribute = function (data, attribute, value) {
	                    var serializer = this.getAttributeSerializer(attribute),
	                        serializedAttributeName = this.getSerializedAttributeName(attribute);
	
	                    // undefined means the attribute should be excluded from serialization
	                    if (serializedAttributeName === undefined) {
	                        return;
	                    }
	
	                    data[serializedAttributeName] = serializer ? serializer.serialize(value) : this.serializeData(value);
	                };
	
	                /**
	                 * Serializes the data by applying various transformations such as:
	                 *   - Underscoring attribute names
	                 *   - attribute renaming
	                 *   - attribute exclusion
	                 *   - custom attribute addition
	                 *
	                 * @param data The data to prepare
	                 * @returns {*} A new object or array that is ready for JSON serialization
	                 */
	                Serializer.prototype.serialize = function (data) {
	                    var result = angular.copy(data),
	                        self = this;
	
	                    if (angular.isObject(result)) {
	                        angular.forEach(this.customSerializedAttributes, function (value, key) {
	                            if (angular.isArray(result)) {
	                                angular.forEach(result, function (item, index) {
	                                    var itemValue = value;
	                                    if (angular.isFunction(value)) {
	                                        itemValue = itemValue.call(item, item);
	                                    }
	
	                                    self.serializeAttribute(item, key, itemValue);
	                                });
	                            } else {
	                                if (angular.isFunction(value)) {
	                                    value = value.call(data, data);
	                                }
	
	                                self.serializeAttribute(result, key, value);
	                            }
	                        });
	                    }
	
	                    result = this.serializeData(result);
	
	                    return result;
	                };
	
	                /**
	                 * Iterates over the data deserializing each entry on arrays and each key/value on objects.
	                 *
	                 * @param data The object to deserialize
	                 * @param Resource (optional) The resource type to deserialize the result into
	                 * @returns {*} A new object or an instance of Resource populated with deserialized data.
	                 */
	                Serializer.prototype.deserializeData = function (data, Resource) {
	                    var result = data,
	                        self = this;
	
	                    if (angular.isArray(data)) {
	                        result = [];
	
	                        angular.forEach(data, function (value) {
	                            result.push(self.deserializeData(value, Resource));
	                        });
	                    } else if (angular.isObject(data)) {
	                        if (angular.isDate(data)) {
	                            return data;
	                        }
	                        result = {};
	
	                        if (Resource) {
	                            result = new Resource.config.resourceConstructor();
	                        }
	
	                        this.deserializeObject(result, data);
	
	                    }
	
	                    return result;
	                };
	
	                Serializer.prototype.deserializeObject = function (result, data) {
	
	                    var tthis = this;
	                    angular.forEach(data, function (value, key) {
	                        tthis.deserializeAttribute(result, key, value);
	                    });
	                    return data;
	                };
	
	
	                /**
	                 * Transforms an attribute and its value and stores it on the parent data object.  The attribute will be
	                 * renamed as needed and the value itself will be deserialized as well.
	                 *
	                 * @param data The object that the attribute will be added to
	                 * @param attribute The attribute to transform
	                 * @param value The current value of the attribute
	                 */
	                Serializer.prototype.deserializeAttribute = function (data, attribute, value) {
	                    var serializer,
	                        NestedResource,
	                        attributeName = this.getDeserializedAttributeName(attribute);
	
	                    // undefined means the attribute should be excluded from serialization
	                    if (attributeName === undefined) {
	                        return;
	                    }
	
	                    serializer = this.getAttributeSerializer(attributeName);
	                    NestedResource = this.getNestedResource(attributeName);
	
	                    // preserved attributes are assigned unmodified
	                    if (this.preservedAttributes[attributeName]) {
	                        data[attributeName] = value;
	                    } else {
	                        data[attributeName] = serializer ? serializer.deserialize(value, NestedResource) : this.deserializeData(value, NestedResource);
	                    }
	                };
	
	                /**
	                 * Deserializes the data by applying various transformations such as:
	                 *   - Camelizing attribute names
	                 *   - attribute renaming
	                 *   - attribute exclusion
	                 *   - nested resource creation
	                 *
	                 * @param data The object to deserialize
	                 * @param Resource (optional) The resource type to deserialize the result into
	                 * @returns {*} A new object or an instance of Resource populated with deserialized data
	                 */
	                Serializer.prototype.deserialize = function (data, Resource) {
	                    // just calls deserializeValue for now so we can more easily add on custom attribute logic for deserialize too
	                    return this.deserializeData(data, Resource);
	                };
	
	                Serializer.prototype.pluralize = function (value) {
	                    if (this.options.pluralize) {
	                        return this.options.pluralize(value);
	                    }
	                    return value;
	                };
	
	                Serializer.prototype.underscore = function (value) {
	                    if (this.options.underscore) {
	                        return this.options.underscore(value);
	                    }
	                    return value;
	                };
	
	                Serializer.prototype.camelize = function (value) {
	                    if (this.options.camelize) {
	                        return this.options.camelize(value);
	                    }
	                    return value;
	                };
	
	                return Serializer;
	            }
	
	            railsSerializer.defaultOptions = defaultOptions;
	            return railsSerializer;
	        }];
	    });
	}());
	(function (undefined) {
	    angular.module('rails').factory('railsRootWrapper', function () {
	        return {
	            wrap: function (data, resource) {
	                var result = {};
	                result[angular.isArray(data) ? resource.config.pluralName : resource.config.name] = data;
	                return result;
	            },
	            unwrap: function (response, resource, isObject) {
	                if (response.data && response.data.hasOwnProperty(resource.config.name)) {
	                    response.data = response.data[resource.config.name];
	                } else if (response.data && response.data.hasOwnProperty(resource.config.pluralName) && !isObject) {
	                    response.data = response.data[resource.config.pluralName];
	                }
	
	                return response;
	            }
	        };
	    });
	
	    angular.module('rails').provider('RailsResource', function () {
	        var defaultOptions = {
	            rootWrapping: true,
	            updateMethod: 'put',
	            httpConfig: {},
	            defaultParams: undefined,
	            underscoreParams: true,
	            fullResponse: false,
	            extensions: []
	        };
	
	        /**
	         * Enables or disables root wrapping by default for RailsResources
	         * Defaults to true.
	         * @param {boolean} value true to enable root wrapping, false to disable
	         * @returns {RailsResourceProvider} The provider instance
	         */
	        this.rootWrapping = function (value) {
	            defaultOptions.rootWrapping = value;
	            return this;
	        };
	
	        /**
	         * Configures what HTTP operation should be used for update by default for RailsResources.
	         * Defaults to 'put'
	         * @param value
	         * @returns {RailsResourceProvider} The provider instance
	         */
	        this.updateMethod = function (value) {
	            defaultOptions.updateMethod = value;
	            return this;
	        };
	
	        /**
	         * Configures default HTTP configuration operations for all RailsResources.
	         *
	         * @param {Object} value See $http for available configuration options.
	         * @returns {RailsResourceProvider} The provider instance
	         */
	        this.httpConfig = function (value) {
	            defaultOptions.httpConfig = value;
	            return this;
	        };
	
	        /**
	         * Configures default HTTP query parameters for all RailsResources.
	         *
	         * @param {Object} value Object of key/value pairs representing the HTTP query parameters for all HTTP operations.
	         * @returns {RailsResourceProvider} The provider instance
	         */
	        this.defaultParams = function (value) {
	            defaultOptions.defaultParams = value;
	            return this;
	        };
	
	        /**
	         * Configures whether or not underscore query parameters
	         * @param {boolean} value true to underscore.  Defaults to true.
	         * @returns {RailsResourceProvider} The provider instance
	         */
	        this.underscoreParams = function (value) {
	            defaultOptions.underscoreParams = value;
	            return this;
	        };
	
	        /**
	         * Configures whether the full response from $http is returned or just the result data.
	         * @param {boolean} value true to return full $http response.  Defaults to false.
	         * @returns {RailsResourceProvider} The provider instance
	         */
	        this.fullResponse = function (value) {
	            defaultOptions.fullResponse = value;
	            return this;
	        };
	
	        /**
	         * List of RailsResource extensions to include by default.
	         *
	         * @param {...string} extensions One or more extension names to include
	         * @returns {*}
	         */
	        this.extensions = function () {
	            defaultOptions.extensions = [];
	            angular.forEach(arguments, function (value) {
	                defaultOptions.extensions = defaultOptions.extensions.concat(value);
	            });
	            return this;
	        };
	
	        this.$get = ['$http', '$q', 'railsUrlBuilder', 'railsSerializer', 'railsRootWrapper', 'RailsResourceInjector',
	            function ($http, $q, railsUrlBuilder, railsSerializer, railsRootWrapper, RailsResourceInjector) {
	
	                function RailsResource(value) {
	                    if (value) {
	                        var response = this.constructor.deserialize({data: value});
	                        if (this.constructor.config.rootWrapping) {
	                            response = railsRootWrapper.unwrap(response, this.constructor, true);
	                        }
	                        angular.extend(this, response.data);
	                    }
	                }
	
	                /**
	                 * Extends the RailsResource to the child constructor function making the child constructor a subclass of
	                 * RailsResource.  This is modeled off of CoffeeScript's class extend function.  All RailsResource
	                 * class properties defined are copied to the child class and the child's prototype chain is configured
	                 * to allow instances of the child class to have all of the instance methods of RailsResource.
	                 *
	                 * Like CoffeeScript, a __super__ property is set on the child class to the parent resource's prototype chain.
	                 * This is done to allow subclasses to extend the functionality of instance methods and still
	                 * call back to the original method using:
	                 *
	                 *     Class.__super__.method.apply(this, arguments);
	                 *
	                 * @param {function} child Child constructor function
	                 * @returns {function} Child constructor function
	                 */
	                RailsResource.extendTo = function (child) {
	                    angular.forEach(this, function (value, key) {
	                        child[key] = value;
	                    });
	
	                    if (angular.isArray(this.$modules)) {
	                        child.$modules = this.$modules.slice(0);
	                    }
	
	                    function ctor() {
	                        this.constructor = child;
	                    }
	
	                    ctor.prototype = this.prototype;
	                    child.prototype = new ctor();
	                    child.__super__ = this.prototype;
	                    return child;
	                };
	
	                /**
	                 * Copies a mixin's properties to the resource.
	                 *
	                 * If module is a String then we it will be loaded using Angular's dependency injection.  If the name is
	                 * not valid then Angular will throw an error.
	                 *
	                 * @param {...String|function|Object} mixins The mixin or name of the mixin to add.
	                 * @returns {RailsResource} this
	                 */
	                RailsResource.extend = function () {
	                    angular.forEach(arguments, function (mixin) {
	                        addMixin(this, this, mixin, function (Resource, mixin) {
	                            if (angular.isFunction(mixin.extended)) {
	                                mixin.extended(Resource);
	                            }
	                        });
	                    }, this);
	
	                    return this;
	                };
	
	                /**
	                 * Copies a mixin's properties to the resource's prototype chain.
	                 *
	                 * If module is a String then we it will be loaded using Angular's dependency injection.  If the name is
	                 * not valid then Angular will throw an error.
	                 *
	                 * @param {...String|function|Object} mixins The mixin or name of the mixin to add
	                 * @returns {RailsResource} this
	                 */
	                RailsResource.include = function () {
	                    angular.forEach(arguments, function (mixin) {
	                        addMixin(this, this.prototype, mixin, function (Resource, mixin) {
	                            if (angular.isFunction(mixin.included)) {
	                                mixin.included(Resource);
	                            }
	                        });
	                    }, this);
	
	                    return this;
	                };
	
	                /**
	                 * Sets configuration options.  This method may be called multiple times to set additional options or to
	                 * override previous values (such as the case with inherited resources).
	                 * @param cfg
	                 */
	                RailsResource.configure = function (cfg) {
	                    cfg = cfg || {};
	
	                    if (this.config) {
	                        cfg = angular.extend({}, this.config, cfg);
	                    }
	
	                    this.config = {};
	                    this.config.idAttribute = cfg.idAttribute || 'id';
	                    this.config.url = cfg.url;
	                    this.config.rootWrapping = booleanParam(cfg.rootWrapping, defaultOptions.rootWrapping); // using undefined check because config.rootWrapping || true would be true when config.rootWrapping === false
	                    this.config.httpConfig = cfg.httpConfig || defaultOptions.httpConfig;
	                    this.config.httpConfig.headers = angular.extend({'Accept': 'application/json', 'Content-Type': 'application/json'}, this.config.httpConfig.headers || {});
	                    this.config.defaultParams = cfg.defaultParams || defaultOptions.defaultParams;
	                    this.config.underscoreParams = booleanParam(cfg.underscoreParams, defaultOptions.underscoreParams);
	                    this.config.updateMethod = (cfg.updateMethod || defaultOptions.updateMethod).toLowerCase();
	                    this.config.fullResponse = booleanParam(cfg.fullResponse, defaultOptions.fullResponse);
	
	                    this.config.requestTransformers = cfg.requestTransformers ? cfg.requestTransformers.slice(0) : [];
	                    this.config.responseInterceptors = cfg.responseInterceptors ? cfg.responseInterceptors.slice(0) : [];
	                    this.config.afterResponseInterceptors = cfg.afterResponseInterceptors ? cfg.afterResponseInterceptors.slice(0) : [];
	                    this.config.interceptors = cfg.interceptors ? cfg.interceptors.slice(0) : [];
	
	                    this.config.serializer = RailsResourceInjector.getService(cfg.serializer || railsSerializer());
	
	                    this.config.name = this.config.serializer.underscore(cfg.name);
	
	                    // we don't want to turn undefined name into "undefineds" then the plural name won't update when the name is set
	                    if (this.config.name) {
	                        this.config.pluralName = this.config.serializer.underscore(cfg.pluralName || this.config.serializer.pluralize(this.config.name));
	                    }
	
	                    this.config.urlBuilder = railsUrlBuilder(this.config);
	                    this.config.resourceConstructor = this;
	
	                    this.extend.apply(this, loadExtensions((cfg.extensions || []).concat(defaultOptions.extensions)));
	
	                    angular.forEach(this.$mixins, function (mixin) {
	                        if (angular.isFunction(mixin.configure)) {
	                            mixin.configure(this.config, cfg);
	                        }
	                    }, this);
	                };
	
	                /**
	                 * Configures the URL for the resource.
	                 * @param {String|function} url The url string or function.
	                 */
	                RailsResource.setUrl = function (url) {
	                    this.configure({url: url});
	                };
	
	                RailsResource.buildUrl = function (context) {
	                    return this.config.urlBuilder(context);
	                };
	
	                /**
	                 * Interceptors utilize $q promises to allow for both synchronous and asynchronous processing during
	                 * a request / response cycle.
	                 *
	                 * Interceptors can be added as a service factory name or as an object with properties matching one
	                 * or more of the phases.  Each property should have a value of a function to be called during that phase.
	                 *
	                 * There are multiple phases for both request and response.  In addition, each phase has a corresponding
	                 * error phase to handle promise rejections.
	                 *
	                 * Each request phase interceptor is called with the $http config object, the resource constructor, and if
	                 * applicable the resource instance.  The interceptor is free to modify the config or create a new one.
	                 * The interceptor function must return a valid $http config or a promise that will eventually resolve
	                 * to a config object.
	                 *
	                 * The valid request phases are:
	                 *
	                 * * beforeRequest: Interceptors are called prior to any data serialization or root wrapping.
	                 * * beforeRequestError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 * * beforeRequestWrapping: Interceptors are called after data serialization but before root wrapping.
	                 * * beforeRequestWrappingError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 * * request:  Interceptors are called after any data serialization and root wrapping have been performed.
	                 * * requestError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 *
	                 * The beforeResponse and response interceptors are called with the $http response object,
	                 * the resource constructor, and if applicable the resource instance.  The afterResponse interceptors
	                 * are typically called with the response data instead of the full response object unless the config option
	                 * fullResponse has been set to true.  Like the request interceptor callbacks the response callbacks can
	                 * manipulate the data or return new data.  The interceptor function must return
	                 *
	                 * The valid response phases are:
	                 *
	                 * * beforeResponse: Interceptors are called prior to any data processing.
	                 * * beforeResponseError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 * * beforeResponseDeserialize: Interceptors are called after root unwrapping but prior to data deserializing.
	                 * * beforeResponseDeserializeError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 * * response:  Interceptors are called after the data has been deserialized and root unwrapped but
	                 *      prior to the data being copied to the resource instance if applicable.
	                 * * responseError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 * * afterResponse:  Interceptors are called at the very end of the response chain after all processing
	                 *      has been completed.  The value of the first parameter is one of the following:
	                 *       - resource instance: When fullResponse is false and the operation was called on a resource instance.
	                 *       - response data: When fullResponse is false and the operation was called on the resource class.
	                 *       - $http response: When fullResponse is true
	                 * * afterResponseError: Interceptors get called when a previous interceptor threw an error or
	                 *      resolved with a rejection.
	                 *
	                 * @param {String | Object} interceptor
	                 */
	                RailsResource.addInterceptor = function (interceptor) {
	                    this.config.interceptors.push(interceptor);
	                };
	
	                /**
	                 * Adds an interceptor callback function for the specified phase.
	                 * @param {String} phase The interceptor phase, one of:
	                 *      beforeRequest, request, beforeResponse, response, afterResponse
	                 * @param fn The function to call.
	                 */
	                RailsResource.intercept = function (phase, fn) {
	                    var interceptor = {};
	                    fn = RailsResourceInjector.getDependency(fn);
	
	                    interceptor[phase] = function (value, resourceConstructor, context) {
	                        return fn(value, resourceConstructor, context) || value;
	                    };
	
	                    this.addInterceptor(interceptor);
	                };
	
	                /**
	                 * Adds interceptor on 'beforeRequest' phase.
	                 * @param fn(httpConfig, constructor, context) - httpConfig is the config object to pass to $http,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptBeforeRequest = function (fn) {
	                    this.intercept('beforeRequest', fn);
	                };
	
	                /**
	                 * Adds interceptor on 'beforeRequestWrapping' phase.
	                 * @param fn(httpConfig, constructor, context) - httpConfig is the config object to pass to $http,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptBeforeRequestWrapping = function (fn) {
	                    this.intercept('beforeRequestWrapping', fn);
	                };
	
	                /**
	                 * Adds interceptor on 'request' phase.
	                 * @param fn(httpConfig, constructor, context) - httpConfig is the config object to pass to $http,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptRequest = function (fn) {
	                    this.intercept('request', fn);
	                };
	
	                /**
	                 * Adds interceptor on 'beforeResponse' phase.
	                 * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptBeforeResponse = function (fn) {
	                    this.intercept('beforeResponse', fn);
	                };
	
	                /**
	                 * Adds interceptor on 'beforeResponseDeserialize' phase.
	                 * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptBeforeResponseDeserialize = function (fn) {
	                    this.intercept('beforeResponseDeserialize', fn);
	                };
	
	                /**
	                 * Adds interceptor on 'response' phase.
	                 * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptResponse = function (fn) {
	                    this.intercept('response', fn);
	                };
	
	                /**
	                 * Adds interceptor on 'afterResponse' phase.
	                 * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.interceptAfterResponse = function (fn) {
	                    this.intercept('afterResponse', fn);
	                };
	
	                /**
	                 * Deprecated, see interceptors
	                 * Add a callback to run on response.
	                 * @deprecated since version 1.0.0, use interceptResponse instead
	                 * @param fn(response data, constructor, context) - response data is either the resource instance returned or an array of resource instances,
	                 *      constructor is the resource class calling the function,
	                 *      context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
	                 */
	                RailsResource.beforeResponse = function (fn) {
	                    fn = RailsResourceInjector.getDependency(fn);
	                    this.interceptResponse(function (response, resource, context) {
	                        fn(response.data, resource.config.resourceConstructor, context);
	                        return response;
	                    });
	                };
	
	                /**
	                 * Deprecated, see interceptors
	                 * Add a callback to run after response has been processed.  These callbacks are not called on object construction.
	                 * @deprecated since version 1.0.0, use interceptAfterResponse instead
	                 * @param fn(response data, constructor) - response data is either the resource instance returned or an array of resource instances and constructor is the resource class calling the function
	                 */
	                RailsResource.afterResponse = function (fn) {
	                    fn = RailsResourceInjector.getDependency(fn);
	                    this.interceptAfterResponse(function (response, resource, context) {
	                        fn(response, resource.config.resourceConstructor, context);
	                        return response;
	                    });
	                };
	
	                /**
	                 * Deprecated, see interceptors
	                 * Adds a function to run after serializing the data to send to the server, but before root-wrapping it.
	                 * @deprecated since version 1.0.0, use interceptBeforeRequestWrapping instead
	                 * @param fn (data, constructor) - data object is the serialized resource instance, and constructor the resource class calling the function
	                 */
	                RailsResource.beforeRequest = function (fn) {
	                    fn = RailsResourceInjector.getDependency(fn);
	                    this.interceptBeforeRequestWrapping(function (httpConfig, resource) {
	                        httpConfig.data = fn(httpConfig.data, resource.config.resourceConstructor) || httpConfig.data;
	                        return httpConfig;
	                    });
	                };
	
	                RailsResource.serialize = function (httpConfig) {
	                    if (httpConfig.data) {
	                        httpConfig.data = this.config.serializer.serialize(httpConfig.data);
	                    }
	
	                    return httpConfig;
	                };
	
	                /**
	                 * Deserializes the response data on the $http response.  Stores the original version of the data
	                 * on the response as "originalData" and sets the deserialized data in the "data" property.
	                 * @param response The $http response object
	                 * @returns {*} The $http response
	                 */
	                RailsResource.deserialize = function (response) {
	                    response.data = this.config.serializer.deserialize(response.data, this.config.resourceConstructor);
	                    return response;
	                };
	
	                /**
	                 * Deprecated, see interceptors
	                 * Transform data after response has been converted to a resource instance
	                 * @deprecated
	                 * @param promise
	                 * @param context
	                 */
	                RailsResource.callResponseInterceptors = function (promise, context) {
	                    var config = this.config;
	                    forEachDependency(config.responseInterceptors, function (interceptor) {
	                        promise.resource = config.resourceConstructor;
	                        promise.context = context;
	                        promise = interceptor(promise);
	                    });
	                    return promise;
	                };
	
	                /**
	                 * Deprecated, see interceptors
	                 * Transform data after response has been converted to a resource instance
	                 * @deprecated
	                 * @param promise
	                 * @param context
	                 */
	                RailsResource.callAfterResponseInterceptors = function (promise) {
	                    var config = this.config;
	                    // data is now deserialized. call response interceptors including afterResponse
	                    forEachDependency(config.afterResponseInterceptors, function (interceptor) {
	                        promise.resource = config.resourceConstructor;
	                        promise = interceptor(promise);
	                    });
	
	                    return promise;
	                };
	
	                RailsResource.runInterceptorPhase = function (phase, context, promise) {
	                    var config = this.config, chain = [];
	
	                    forEachDependency(config.interceptors, function (interceptor) {
	                        if (interceptor[phase] || interceptor[phase + 'Error']) {
	                            chain.push(interceptor[phase], interceptor[phase + 'Error']);
	                        }
	                    });
	
	                    while (chain.length) {
	                        var thenFn = chain.shift();
	                        var rejectFn = chain.shift();
	
	                        promise = promise.then(createInterceptorSuccessCallback(thenFn, config.resourceConstructor, context),
	                            createInterceptorRejectionCallback(rejectFn, config.resourceConstructor, context));
	                    }
	
	                    return promise;
	                };
	
	                /**
	                 * Executes an HTTP request using $http.
	                 *
	                 * This method is used by all RailsResource operations that execute HTTP requests.  Handles serializing
	                 * the request data using the resource serializer, root wrapping (if enabled), deserializing the response
	                 * data using the resource serializer, root unwrapping (if enabled), and copying the result back into the
	                 * resource context if applicable.  Executes interceptors at each phase of the request / response to allow
	                 * users to build synchronous & asynchronous customizations to manipulate the data as necessary.
	                 *
	                 * @param httpConfig The config to pass to $http, see $http docs for details
	                 * @param context An optional reference to the resource instance that is the context for the operation.
	                 *      If specified, the result data will be copied into the context during the response handling.
	                 * @param resourceConfigOverrides An optional set of RailsResource configuration options overrides.
	                 *      These overrides allow users to build custom operations more easily with different resource settings.
	                 * @returns {Promise} The promise that will eventually be resolved after all request / response handling
	                 *      has completed.
	                 */
	                RailsResource.$http = function (httpConfig, context, resourceConfigOverrides) {
	                    var config = angular.extend(angular.copy(this.config), resourceConfigOverrides || {}),
	                        resourceConstructor = config.resourceConstructor,
	                        promise = $q.when(httpConfig);
	
	                    if (!config.skipRequestProcessing) {
	
	                        promise = this.runInterceptorPhase('beforeRequest', context, promise).then(function (httpConfig) {
	                            httpConfig = resourceConstructor.serialize(httpConfig);
	
	                            forEachDependency(config.requestTransformers, function (transformer) {
	                                httpConfig.data = transformer(httpConfig.data, config.resourceConstructor);
	                            });
	
	                            return httpConfig;
	                        });
	
	                        promise = this.runInterceptorPhase('beforeRequestWrapping', context, promise);
	
	                        if (config.rootWrapping) {
	                            promise = promise.then(function (httpConfig) {
	                                httpConfig.data = railsRootWrapper.wrap(httpConfig.data, config.resourceConstructor);
	                                return httpConfig;
	                            });
	                        }
	
	                        promise = this.runInterceptorPhase('request', context, promise).then(function (httpConfig) {
	                            return $http(httpConfig);
	                        });
	
	                    } else {
	
	                        promise = $http(httpConfig);
	
	                    }
	
	                    promise = this.runInterceptorPhase('beforeResponse', context, promise).then(function (response) {
	                      // store off the data so we don't lose access to it after deserializing and unwrapping
	                      response.originalData = response.data;
	                      return response;
	                    });
	
	                    if (config.rootWrapping) {
	                        promise = promise.then(function (response) {
	                            return railsRootWrapper.unwrap(response, config.resourceConstructor, false);
	                        });
	                    }
	
	                    promise = this.runInterceptorPhase('beforeResponseDeserialize', context, promise).then(function (response) {
	                        return resourceConstructor.deserialize(response);
	                    });
	
	                    promise = this.callResponseInterceptors(promise, context);
	                    promise = this.runInterceptorPhase('response', context, promise).then(function (response) {
	                        if (context) {
	                            // we may not have response data
	                            if (response.hasOwnProperty('data') && angular.isObject(response.data)) {
	                                angular.extend(context, response.data);
	                            }
	                        }
	
	                        return config.fullResponse ? response : (context || response.data);
	                    });
	
	                    promise = this.callAfterResponseInterceptors(promise, context);
	                    promise = this.runInterceptorPhase('afterResponse', context, promise);
	                    promise.resource = config.resourceConstructor;
	                    promise.context = context;
	                    return promise;
	                };
	
	                /**
	                 * Processes query parameters before request.  You can override to modify
	                 * the query params or return a new object.
	                 *
	                 * @param {Object} queryParams - The query parameters for the request
	                 * @returns {Object} The query parameters for the request
	                 */
	                RailsResource.processParameters = function (queryParams) {
	                    var newParams = {};
	
	                    if (angular.isObject(queryParams) && this.config.underscoreParams) {
	                        angular.forEach(queryParams, function (v, k) {
	                            newParams[this.config.serializer.underscore(k)] = v;
	                        }, this);
	
	                        return newParams;
	                    }
	
	                    return queryParams;
	                };
	
	                RailsResource.getParameters = function (queryParams) {
	                    var params;
	
	                    if (this.config.defaultParams) {
	                        // we need to clone it so we don't modify it when we add the additional
	                        // query params below
	                        params = angular.copy(this.config.defaultParams);
	                    }
	
	                    if (angular.isObject(queryParams)) {
	                        params = angular.extend(params || {}, queryParams);
	                    }
	
	                    return this.processParameters(params);
	                };
	
	                RailsResource.getHttpConfig = function (queryParams) {
	                    var params = this.getParameters(queryParams);
	
	                    if (params) {
	                        return angular.extend({params: params}, this.config.httpConfig);
	                    }
	
	                    return angular.copy(this.config.httpConfig);
	                };
	
	                /**
	                 * Returns a URL from the given parameters.  You can override this method on your resource definitions to provide
	                 * custom logic for building your URLs or you can utilize the parameterized url strings to substitute values in the
	                 * URL string.
	                 *
	                 * The parameters in the URL string follow the normal Angular binding expression using {{ and }} for the start/end symbols.
	                 *
	                 * If the context is a number and the URL string does not contain an id parameter then the number is appended
	                 * to the URL string.
	                 *
	                 * If the context is a number and the URL string does
	                 * @param context
	                 * @param path {string} (optional) An additional path to append to the URL
	                 * @return {string}
	                 */
	                RailsResource.$url = RailsResource.resourceUrl = function (context, path) {
	                    if (!angular.isObject(context)) {
	                        context = {id: context};
	                    }
	
	                    return appendPath(this.buildUrl(context || {}), path);
	                };
	
	                RailsResource.$get = function (url, queryParams) {
	                    return this.$http(angular.extend({method: 'get', url: url}, this.getHttpConfig(queryParams)));
	                };
	
	                RailsResource.query = function (queryParams, context) {
	                    return this.$get(this.resourceUrl(context), queryParams);
	                };
	
	                RailsResource.get = function (context, queryParams) {
	                    return this.$get(this.resourceUrl(context), queryParams);
	                };
	
	                /**
	                 * Returns the URL for this resource.
	                 *
	                 * @param path {string} (optional) An additional path to append to the URL
	                 * @returns {string} The URL for the resource
	                 */
	                RailsResource.prototype.$url = function (path) {
	                    return appendPath(this.constructor.resourceUrl(this), path);
	                };
	
	                /**
	                 * Executes $http with the resource instance as the context.
	                 *
	                 * @param httpConfig The config to pass to $http, see $http docs for details
	                 * @param context An optional reference to the resource instance that is the context for the operation.
	                 *      If specified, the result data will be copied into the context during the response handling.
	                 * @param resourceConfigOverrides An optional set of RailsResource configuration options overrides.
	                 *      These overrides allow users to build custom operations more easily with different resource settings.
	                 * @returns {Promise} The promise that will eventually be resolved after all request / response handling
	                 *      has completed.
	                 */
	                RailsResource.prototype.$http = function (httpConfig, resourceConfigOverrides) {
	                    return this.constructor.$http(httpConfig, this, resourceConfigOverrides);
	                };
	
	                angular.forEach(['post', 'put', 'patch'], function (method) {
	                    RailsResource['$' + method] = function (url, data, resourceConfigOverrides) {
	                        // clone so we can manipulate w/o modifying the actual instance
	                        data = angular.copy(data);
	                        return this.$http(angular.extend({method: method, url: url, data: data}, this.getHttpConfig()), null, resourceConfigOverrides);
	                    };
	
	                    RailsResource.prototype['$' + method] = function (url) {
	                        // clone so we can manipulate w/o modifying the actual instance
	                        var data = angular.copy(this, {});
	                        return this.constructor.$http(angular.extend({method: method, url: url, data: data}, this.constructor.getHttpConfig()), this);
	
	                    };
	                });
	
	                RailsResource.prototype.create = function () {
	                    return this.$post(this.$url(), this);
	                };
	
	                RailsResource.prototype.update = function () {
	                    return this['$' + this.constructor.config.updateMethod](this.$url(), this);
	                };
	
	                RailsResource.prototype.get = function () {
	                    return this.constructor.$http(angular.extend({method: 'GET', url: this.$url()}, this.constructor.getHttpConfig()), this);
	                };
	
	                RailsResource.prototype.isNew = function () {
	                    var idAttribute = this.constructor.config.idAttribute;
	                    return angular.isUndefined(this[idAttribute]) ||
	                        this[idAttribute] === null;
	                };
	
	                RailsResource.prototype.save = function () {
	                    if (this.isNew()) {
	                        return this.create();
	                    } else {
	                        return this.update();
	                    }
	                };
	
	                RailsResource.$delete = function (url, queryParams) {
	                    return this.$http(angular.extend({method: 'delete', url: url}, this.getHttpConfig(queryParams)));
	                };
	
	                RailsResource.prototype.$delete = function (url, queryParams) {
	                    return this.constructor.$http(angular.extend({method: 'delete', url: url}, this.constructor.getHttpConfig(queryParams)), this);
	                };
	
	                //using ['delete'] instead of .delete for IE7/8 compatibility
	                RailsResource.prototype.remove = RailsResource.prototype['delete'] = function () {
	                    return this.$delete(this.$url());
	                };
	
	                return RailsResource;
	
	                function appendPath(url, path) {
	                    if (path) {
	                        if (path[0] !== '/') {
	                            url += '/';
	                        }
	
	                        url += path;
	                    }
	
	                    return url;
	                }
	
	                function forEachDependency(list, callback) {
	                    var dependency;
	
	                    for (var i = 0, len = list.length; i < len; i++) {
	                        dependency = list[i];
	
	                        if (angular.isString(dependency)) {
	                            dependency = list[i] = RailsResourceInjector.getDependency(dependency);
	                        }
	
	                        callback(dependency);
	                    }
	                }
	
	                function addMixin(Resource, destination, mixin, callback) {
	                    var excludedKeys = ['included', 'extended,', 'configure'];
	
	                    if (!Resource.$mixins) {
	                        Resource.$mixins = [];
	                    }
	
	                    if (angular.isString(mixin)) {
	                        mixin = RailsResourceInjector.getDependency(mixin);
	                    }
	
	                    if (mixin && Resource.$mixins.indexOf(mixin) === -1) {
	                        angular.forEach(mixin, function (value, key) {
	                            if (excludedKeys.indexOf(key) === -1) {
	                                destination[key] = value;
	                            }
	                        });
	
	                        Resource.$mixins.push(mixin);
	
	                        if (angular.isFunction(callback)) {
	                            callback(Resource, mixin);
	                        }
	                    }
	                }
	
	                function loadExtensions(extensions) {
	                    var modules = [];
	
	                    angular.forEach(extensions, function (extensionName) {
	                        extensionName = 'RailsResource' + extensionName.charAt(0).toUpperCase() + extensionName.slice(1) + 'Mixin';
	
	                        modules.push(RailsResourceInjector.getDependency(extensionName));
	                    });
	
	                    return modules;
	                }
	
	                function booleanParam(value, defaultValue) {
	                    return angular.isUndefined(value) ? defaultValue : value;
	                }
	
	                function createInterceptorSuccessCallback(thenFn, resourceConstructor, context) {
	                    return function (data) {
	                        return (thenFn || angular.identity)(data, resourceConstructor, context);
	                    };
	                }
	
	                function createInterceptorRejectionCallback(rejectFn, resourceConstructor, context) {
	                    return function (rejection) {
	                        // can't use identity because we need to return a rejected promise to keep the error chain going
	                        return rejectFn ? rejectFn(rejection, resourceConstructor, context) : $q.reject(rejection);
	                    };
	                }
	            }];
	    });
	
	    angular.module('rails').factory('railsResourceFactory', ['RailsResource', function (RailsResource) {
	        return function (config) {
	            function Resource() {
	                Resource.__super__.constructor.apply(this, arguments);
	            }
	
	            RailsResource.extendTo(Resource);
	            Resource.configure(config);
	
	            return Resource;
	        };
	    }]);
	
	}());


/***/ },
/* 124 */
/***/ function(module, exports) {

	!function(window,angular,undefined){"use strict";angular.module("angulartics.google.analytics",["angulartics"]).config(["$analyticsProvider",function($analyticsProvider){$analyticsProvider.settings.pageTracking.trackRelativePath=!0,$analyticsProvider.settings.ga={additionalAccountNames:undefined,userId:null},$analyticsProvider.registerPageTrack(function(path){window._gaq&&(_gaq.push(["_trackPageview",path]),angular.forEach($analyticsProvider.settings.ga.additionalAccountNames,function(accountName){_gaq.push([accountName+"._trackPageview",path])})),window.ga&&($analyticsProvider.settings.ga.userId&&ga("set","&uid",$analyticsProvider.settings.ga.userId),ga("send","pageview",path),angular.forEach($analyticsProvider.settings.ga.additionalAccountNames,function(accountName){ga(accountName+".send","pageview",path)}))}),$analyticsProvider.registerEventTrack(function(action,properties){if(properties&&properties.category||(properties=properties||{},properties.category="Event"),properties.value){var parsed=parseInt(properties.value,10);properties.value=isNaN(parsed)?0:parsed}if(window.ga){for(var eventOptions={eventCategory:properties.category,eventAction:action,eventLabel:properties.label,eventValue:properties.value,nonInteraction:properties.noninteraction,page:properties.page||window.location.hash.substring(1)||window.location.pathname,userId:$analyticsProvider.settings.ga.userId},idx=1;20>=idx;idx++)properties["dimension"+idx.toString()]&&(eventOptions["dimension"+idx.toString()]=properties["dimension"+idx.toString()]),properties["metric"+idx.toString()]&&(eventOptions["metric"+idx.toString()]=properties["metric"+idx.toString()]);ga("send","event",eventOptions),angular.forEach($analyticsProvider.settings.ga.additionalAccountNames,function(accountName){ga(accountName+".send","event",eventOptions)})}else window._gaq&&_gaq.push(["_trackEvent",properties.category,action,properties.label,properties.value,properties.noninteraction])}),$analyticsProvider.registerSetUsername(function(userId){$analyticsProvider.settings.ga.userId=userId})}])}(window,window.angular);
	//# sourceMappingURL=../dist/angulartics-google-analytics.min.js.map

/***/ },
/* 125 */
/***/ function(module, exports) {

	angular.module('angular-clipboard', [])
	    .directive('clipboard', ['$document', function ($document) {
	        return {
	            restrict: 'A',
	            scope: {
	                onCopied: '&',
	                onError: '&',
	                text: '='
	            },
	            link: function (scope, element) {
	                function createNode(text) {
	                    var node = $document[0].createElement('textarea');
	                    node.style.position = 'absolute';
	                    node.style.left = '-10000px';
	                    node.textContent = text;
	                    return node;
	                }
	
	                function copyNode(node) {
	                    // Set inline style to override css styles
	                    $document[0].body.style.webkitUserSelect = 'initial';
	
	                    var selection = $document[0].getSelection();
	                    selection.removeAllRanges();
	                    node.select();
	
	                    if(!$document[0].execCommand('copy')) {
	                      throw('failure copy');
	                    }
	                    selection.removeAllRanges();
	
	                    // Reset inline style
	                    $document[0].body.style.webkitUserSelect = '';
	                }
	
	                function copyText(text) {
	                    var node = createNode(text);
	                    $document[0].body.appendChild(node);
	                    copyNode(node);
	                    $document[0].body.removeChild(node);
	                }
	
	                element.on('click', function (event) {
	                    try {
	                        copyText(scope.text);
	                        if (angular.isFunction(scope.onCopied)) {
	                            scope.$evalAsync(scope.onCopied());
	                        }
	                    } catch (err) {
	                        if (angular.isFunction(scope.onError)) {
	                            scope.$evalAsync(scope.onError({err: err}));
	                        }
	                    }
	                });
	            }
	        };
	    }]);


/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {"use strict";
	
	__webpack_require__(127);
	
	__webpack_require__(314);
	
	if (global._babelPolyfill) {
	  throw new Error("only one instance of babel-polyfill is allowed");
	}
	global._babelPolyfill = true;
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {

	__webpack_require__(128);
	__webpack_require__(161);
	__webpack_require__(167);
	__webpack_require__(169);
	__webpack_require__(171);
	__webpack_require__(173);
	__webpack_require__(175);
	__webpack_require__(177);
	__webpack_require__(178);
	__webpack_require__(179);
	__webpack_require__(180);
	__webpack_require__(181);
	__webpack_require__(182);
	__webpack_require__(183);
	__webpack_require__(184);
	__webpack_require__(185);
	__webpack_require__(186);
	__webpack_require__(187);
	__webpack_require__(188);
	__webpack_require__(191);
	__webpack_require__(192);
	__webpack_require__(193);
	__webpack_require__(195);
	__webpack_require__(196);
	__webpack_require__(197);
	__webpack_require__(198);
	__webpack_require__(199);
	__webpack_require__(200);
	__webpack_require__(201);
	__webpack_require__(203);
	__webpack_require__(204);
	__webpack_require__(205);
	__webpack_require__(207);
	__webpack_require__(208);
	__webpack_require__(209);
	__webpack_require__(211);
	__webpack_require__(212);
	__webpack_require__(213);
	__webpack_require__(214);
	__webpack_require__(215);
	__webpack_require__(216);
	__webpack_require__(217);
	__webpack_require__(218);
	__webpack_require__(219);
	__webpack_require__(220);
	__webpack_require__(221);
	__webpack_require__(222);
	__webpack_require__(223);
	__webpack_require__(224);
	__webpack_require__(229);
	__webpack_require__(230);
	__webpack_require__(234);
	__webpack_require__(235);
	__webpack_require__(237);
	__webpack_require__(238);
	__webpack_require__(243);
	__webpack_require__(244);
	__webpack_require__(247);
	__webpack_require__(249);
	__webpack_require__(251);
	__webpack_require__(253);
	__webpack_require__(254);
	__webpack_require__(255);
	__webpack_require__(257);
	__webpack_require__(258);
	__webpack_require__(260);
	__webpack_require__(261);
	__webpack_require__(262);
	__webpack_require__(263);
	__webpack_require__(270);
	__webpack_require__(273);
	__webpack_require__(274);
	__webpack_require__(276);
	__webpack_require__(277);
	__webpack_require__(278);
	__webpack_require__(279);
	__webpack_require__(280);
	__webpack_require__(281);
	__webpack_require__(282);
	__webpack_require__(283);
	__webpack_require__(284);
	__webpack_require__(285);
	__webpack_require__(286);
	__webpack_require__(287);
	__webpack_require__(289);
	__webpack_require__(290);
	__webpack_require__(291);
	__webpack_require__(292);
	__webpack_require__(293);
	__webpack_require__(294);
	__webpack_require__(296);
	__webpack_require__(297);
	__webpack_require__(298);
	__webpack_require__(299);
	__webpack_require__(301);
	__webpack_require__(302);
	__webpack_require__(304);
	__webpack_require__(305);
	__webpack_require__(307);
	__webpack_require__(308);
	__webpack_require__(309);
	__webpack_require__(312);
	__webpack_require__(313);
	module.exports = __webpack_require__(132);

/***/ },
/* 128 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $                 = __webpack_require__(129)
	  , $export           = __webpack_require__(130)
	  , DESCRIPTORS       = __webpack_require__(135)
	  , createDesc        = __webpack_require__(134)
	  , html              = __webpack_require__(141)
	  , cel               = __webpack_require__(142)
	  , has               = __webpack_require__(144)
	  , cof               = __webpack_require__(145)
	  , invoke            = __webpack_require__(146)
	  , fails             = __webpack_require__(136)
	  , anObject          = __webpack_require__(147)
	  , aFunction         = __webpack_require__(140)
	  , isObject          = __webpack_require__(143)
	  , toObject          = __webpack_require__(148)
	  , toIObject         = __webpack_require__(150)
	  , toInteger         = __webpack_require__(152)
	  , toIndex           = __webpack_require__(153)
	  , toLength          = __webpack_require__(154)
	  , IObject           = __webpack_require__(151)
	  , IE_PROTO          = __webpack_require__(138)('__proto__')
	  , createArrayMethod = __webpack_require__(155)
	  , arrayIndexOf      = __webpack_require__(160)(false)
	  , ObjectProto       = Object.prototype
	  , ArrayProto        = Array.prototype
	  , arraySlice        = ArrayProto.slice
	  , arrayJoin         = ArrayProto.join
	  , defineProperty    = $.setDesc
	  , getOwnDescriptor  = $.getDesc
	  , defineProperties  = $.setDescs
	  , factories         = {}
	  , IE8_DOM_DEFINE;
	
	if(!DESCRIPTORS){
	  IE8_DOM_DEFINE = !fails(function(){
	    return defineProperty(cel('div'), 'a', {get: function(){ return 7; }}).a != 7;
	  });
	  $.setDesc = function(O, P, Attributes){
	    if(IE8_DOM_DEFINE)try {
	      return defineProperty(O, P, Attributes);
	    } catch(e){ /* empty */ }
	    if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
	    if('value' in Attributes)anObject(O)[P] = Attributes.value;
	    return O;
	  };
	  $.getDesc = function(O, P){
	    if(IE8_DOM_DEFINE)try {
	      return getOwnDescriptor(O, P);
	    } catch(e){ /* empty */ }
	    if(has(O, P))return createDesc(!ObjectProto.propertyIsEnumerable.call(O, P), O[P]);
	  };
	  $.setDescs = defineProperties = function(O, Properties){
	    anObject(O);
	    var keys   = $.getKeys(Properties)
	      , length = keys.length
	      , i = 0
	      , P;
	    while(length > i)$.setDesc(O, P = keys[i++], Properties[P]);
	    return O;
	  };
	}
	$export($export.S + $export.F * !DESCRIPTORS, 'Object', {
	  // 19.1.2.6 / 15.2.3.3 Object.getOwnPropertyDescriptor(O, P)
	  getOwnPropertyDescriptor: $.getDesc,
	  // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
	  defineProperty: $.setDesc,
	  // 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)
	  defineProperties: defineProperties
	});
	
	  // IE 8- don't enum bug keys
	var keys1 = ('constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,' +
	            'toLocaleString,toString,valueOf').split(',')
	  // Additional keys for getOwnPropertyNames
	  , keys2 = keys1.concat('length', 'prototype')
	  , keysLen1 = keys1.length;
	
	// Create object with `null` prototype: use iframe Object with cleared prototype
	var createDict = function(){
	  // Thrash, waste and sodomy: IE GC bug
	  var iframe = cel('iframe')
	    , i      = keysLen1
	    , gt     = '>'
	    , iframeDocument;
	  iframe.style.display = 'none';
	  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('<script>document.F=Object</script' + gt);
	  iframeDocument.close();
	  createDict = iframeDocument.F;
	  while(i--)delete createDict.prototype[keys1[i]];
	  return createDict();
	};
	var createGetKeys = function(names, length){
	  return function(object){
	    var O      = toIObject(object)
	      , i      = 0
	      , result = []
	      , key;
	    for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);
	    // Don't enum bug & hidden keys
	    while(length > i)if(has(O, key = names[i++])){
	      ~arrayIndexOf(result, key) || result.push(key);
	    }
	    return result;
	  };
	};
	var Empty = function(){};
	$export($export.S, 'Object', {
	  // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
	  getPrototypeOf: $.getProto = $.getProto || 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;
	  },
	  // 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
	  getOwnPropertyNames: $.getNames = $.getNames || createGetKeys(keys2, keys2.length, true),
	  // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
	  create: $.create = $.create || function(O, /*?*/Properties){
	    var result;
	    if(O !== null){
	      Empty.prototype = anObject(O);
	      result = new Empty();
	      Empty.prototype = null;
	      // add "__proto__" for Object.getPrototypeOf shim
	      result[IE_PROTO] = O;
	    } else result = createDict();
	    return Properties === undefined ? result : defineProperties(result, Properties);
	  },
	  // 19.1.2.14 / 15.2.3.14 Object.keys(O)
	  keys: $.getKeys = $.getKeys || createGetKeys(keys1, keysLen1, false)
	});
	
	var construct = function(F, len, args){
	  if(!(len in factories)){
	    for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']';
	    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');
	  }
	  return factories[len](F, args);
	};
	
	// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)
	$export($export.P, 'Function', {
	  bind: function bind(that /*, args... */){
	    var fn       = aFunction(this)
	      , partArgs = arraySlice.call(arguments, 1);
	    var bound = function(/* args... */){
	      var args = partArgs.concat(arraySlice.call(arguments));
	      return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);
	    };
	    if(isObject(fn.prototype))bound.prototype = fn.prototype;
	    return bound;
	  }
	});
	
	// fallback for not array-like ES3 strings and DOM objects
	$export($export.P + $export.F * fails(function(){
	  if(html)arraySlice.call(html);
	}), 'Array', {
	  slice: function(begin, end){
	    var len   = toLength(this.length)
	      , klass = cof(this);
	    end = end === undefined ? len : end;
	    if(klass == 'Array')return arraySlice.call(this, begin, end);
	    var start  = toIndex(begin, len)
	      , upTo   = toIndex(end, len)
	      , size   = toLength(upTo - start)
	      , cloned = Array(size)
	      , i      = 0;
	    for(; i < size; i++)cloned[i] = klass == 'String'
	      ? this.charAt(start + i)
	      : this[start + i];
	    return cloned;
	  }
	});
	$export($export.P + $export.F * (IObject != Object), 'Array', {
	  join: function join(separator){
	    return arrayJoin.call(IObject(this), separator === undefined ? ',' : separator);
	  }
	});
	
	// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)
	$export($export.S, 'Array', {isArray: __webpack_require__(157)});
	
	var createArrayReduce = function(isRight){
	  return function(callbackfn, memo){
	    aFunction(callbackfn);
	    var O      = IObject(this)
	      , length = toLength(O.length)
	      , index  = isRight ? length - 1 : 0
	      , i      = isRight ? -1 : 1;
	    if(arguments.length < 2)for(;;){
	      if(index in O){
	        memo = O[index];
	        index += i;
	        break;
	      }
	      index += i;
	      if(isRight ? index < 0 : length <= index){
	        throw TypeError('Reduce of empty array with no initial value');
	      }
	    }
	    for(;isRight ? index >= 0 : length > index; index += i)if(index in O){
	      memo = callbackfn(memo, O[index], index, this);
	    }
	    return memo;
	  };
	};
	
	var methodize = function($fn){
	  return function(arg1/*, arg2 = undefined */){
	    return $fn(this, arg1, arguments[1]);
	  };
	};
	
	$export($export.P, 'Array', {
	  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
	  forEach: $.each = $.each || methodize(createArrayMethod(0)),
	  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])
	  map: methodize(createArrayMethod(1)),
	  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])
	  filter: methodize(createArrayMethod(2)),
	  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])
	  some: methodize(createArrayMethod(3)),
	  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])
	  every: methodize(createArrayMethod(4)),
	  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])
	  reduce: createArrayReduce(false),
	  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])
	  reduceRight: createArrayReduce(true),
	  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])
	  indexOf: methodize(arrayIndexOf),
	  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])
	  lastIndexOf: function(el, fromIndex /* = @[*-1] */){
	    var O      = toIObject(this)
	      , length = toLength(O.length)
	      , index  = length - 1;
	    if(arguments.length > 1)index = Math.min(index, toInteger(fromIndex));
	    if(index < 0)index = toLength(length + index);
	    for(;index >= 0; index--)if(index in O)if(O[index] === el)return index;
	    return -1;
	  }
	});
	
	// 20.3.3.1 / 15.9.4.4 Date.now()
	$export($export.S, 'Date', {now: function(){ return +new Date; }});
	
	var lz = function(num){
	  return num > 9 ? num : '0' + num;
	};
	
	// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
	// PhantomJS / old WebKit has a broken implementations
	$export($export.P + $export.F * (fails(function(){
	  return new Date(-5e13 - 1).toISOString() != '0385-07-25T07:06:39.999Z';
	}) || !fails(function(){
	  new Date(NaN).toISOString();
	})), 'Date', {
	  toISOString: function toISOString(){
	    if(!isFinite(this))throw RangeError('Invalid time value');
	    var d = this
	      , y = d.getUTCFullYear()
	      , m = d.getUTCMilliseconds()
	      , s = y < 0 ? '-' : y > 9999 ? '+' : '';
	    return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +
	      '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +
	      'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +
	      ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';
	  }
	});

/***/ },
/* 129 */
/***/ function(module, exports) {

	var $Object = Object;
	module.exports = {
	  create:     $Object.create,
	  getProto:   $Object.getPrototypeOf,
	  isEnum:     {}.propertyIsEnumerable,
	  getDesc:    $Object.getOwnPropertyDescriptor,
	  setDesc:    $Object.defineProperty,
	  setDescs:   $Object.defineProperties,
	  getKeys:    $Object.keys,
	  getNames:   $Object.getOwnPropertyNames,
	  getSymbols: $Object.getOwnPropertySymbols,
	  each:       [].forEach
	};

/***/ },
/* 130 */
/***/ function(module, exports, __webpack_require__) {

	var global    = __webpack_require__(131)
	  , core      = __webpack_require__(132)
	  , hide      = __webpack_require__(133)
	  , redefine  = __webpack_require__(137)
	  , ctx       = __webpack_require__(139)
	  , PROTOTYPE = 'prototype';
	
	var $export = function(type, name, source){
	  var IS_FORCED = type & $export.F
	    , IS_GLOBAL = type & $export.G
	    , IS_STATIC = type & $export.S
	    , IS_PROTO  = type & $export.P
	    , IS_BIND   = type & $export.B
	    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]
	    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
	    , expProto  = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})
	    , key, own, out, exp;
	  if(IS_GLOBAL)source = name;
	  for(key in source){
	    // contains in native
	    own = !IS_FORCED && target && key in target;
	    // 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 && !own)redefine(target, key, out);
	    // 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
	module.exports = $export;

/***/ },
/* 131 */
/***/ function(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 : Function('return this')();
	if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef

/***/ },
/* 132 */
/***/ function(module, exports) {

	var core = module.exports = {version: '1.2.6'};
	if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef

/***/ },
/* 133 */
/***/ function(module, exports, __webpack_require__) {

	var $          = __webpack_require__(129)
	  , createDesc = __webpack_require__(134);
	module.exports = __webpack_require__(135) ? function(object, key, value){
	  return $.setDesc(object, key, createDesc(1, value));
	} : function(object, key, value){
	  object[key] = value;
	  return object;
	};

/***/ },
/* 134 */
/***/ function(module, exports) {

	module.exports = function(bitmap, value){
	  return {
	    enumerable  : !(bitmap & 1),
	    configurable: !(bitmap & 2),
	    writable    : !(bitmap & 4),
	    value       : value
	  };
	};

/***/ },
/* 135 */
/***/ function(module, exports, __webpack_require__) {

	// Thank's IE8 for his funny defineProperty
	module.exports = !__webpack_require__(136)(function(){
	  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
	});

/***/ },
/* 136 */
/***/ function(module, exports) {

	module.exports = function(exec){
	  try {
	    return !!exec();
	  } catch(e){
	    return true;
	  }
	};

/***/ },
/* 137 */
/***/ function(module, exports, __webpack_require__) {

	// add fake Function#toString
	// for correct work wrapped methods / constructors with methods like LoDash isNative
	var global    = __webpack_require__(131)
	  , hide      = __webpack_require__(133)
	  , SRC       = __webpack_require__(138)('src')
	  , TO_STRING = 'toString'
	  , $toString = Function[TO_STRING]
	  , TPL       = ('' + $toString).split(TO_STRING);
	
	__webpack_require__(132).inspectSource = function(it){
	  return $toString.call(it);
	};
	
	(module.exports = function(O, key, val, safe){
	  if(typeof val == 'function'){
	    val.hasOwnProperty(SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
	    val.hasOwnProperty('name') || hide(val, 'name', key);
	  }
	  if(O === global){
	    O[key] = val;
	  } else {
	    if(!safe)delete O[key];
	    hide(O, key, val);
	  }
	})(Function.prototype, TO_STRING, function toString(){
	  return typeof this == 'function' && this[SRC] || $toString.call(this);
	});

/***/ },
/* 138 */
/***/ function(module, exports) {

	var id = 0
	  , px = Math.random();
	module.exports = function(key){
	  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
	};

/***/ },
/* 139 */
/***/ function(module, exports, __webpack_require__) {

	// optional / simple context binding
	var aFunction = __webpack_require__(140);
	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);
	  };
	};

/***/ },
/* 140 */
/***/ function(module, exports) {

	module.exports = function(it){
	  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
	  return it;
	};

/***/ },
/* 141 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(131).document && document.documentElement;

/***/ },
/* 142 */
/***/ function(module, exports, __webpack_require__) {

	var isObject = __webpack_require__(143)
	  , document = __webpack_require__(131).document
	  // in old IE typeof document.createElement is 'object'
	  , is = isObject(document) && isObject(document.createElement);
	module.exports = function(it){
	  return is ? document.createElement(it) : {};
	};

/***/ },
/* 143 */
/***/ function(module, exports) {

	module.exports = function(it){
	  return typeof it === 'object' ? it !== null : typeof it === 'function';
	};

/***/ },
/* 144 */
/***/ function(module, exports) {

	var hasOwnProperty = {}.hasOwnProperty;
	module.exports = function(it, key){
	  return hasOwnProperty.call(it, key);
	};

/***/ },
/* 145 */
/***/ function(module, exports) {

	var toString = {}.toString;
	
	module.exports = function(it){
	  return toString.call(it).slice(8, -1);
	};

/***/ },
/* 146 */
/***/ function(module, exports) {

	// fast apply, http://jsperf.lnkit.com/fast-apply/5
	module.exports = function(fn, args, that){
	  var un = that === undefined;
	  switch(args.length){
	    case 0: return un ? fn()
	                      : fn.call(that);
	    case 1: return un ? fn(args[0])
	                      : fn.call(that, args[0]);
	    case 2: return un ? fn(args[0], args[1])
	                      : fn.call(that, args[0], args[1]);
	    case 3: return un ? fn(args[0], args[1], args[2])
	                      : fn.call(that, args[0], args[1], args[2]);
	    case 4: return un ? fn(args[0], args[1], args[2], args[3])
	                      : fn.call(that, args[0], args[1], args[2], args[3]);
	  } return              fn.apply(that, args);
	};

/***/ },
/* 147 */
/***/ function(module, exports, __webpack_require__) {

	var isObject = __webpack_require__(143);
	module.exports = function(it){
	  if(!isObject(it))throw TypeError(it + ' is not an object!');
	  return it;
	};

/***/ },
/* 148 */
/***/ function(module, exports, __webpack_require__) {

	// 7.1.13 ToObject(argument)
	var defined = __webpack_require__(149);
	module.exports = function(it){
	  return Object(defined(it));
	};

/***/ },
/* 149 */
/***/ function(module, exports) {

	// 7.2.1 RequireObjectCoercible(argument)
	module.exports = function(it){
	  if(it == undefined)throw TypeError("Can't call method on  " + it);
	  return it;
	};

/***/ },
/* 150 */
/***/ function(module, exports, __webpack_require__) {

	// to indexed object, toObject with fallback for non-array-like ES3 strings
	var IObject = __webpack_require__(151)
	  , defined = __webpack_require__(149);
	module.exports = function(it){
	  return IObject(defined(it));
	};

/***/ },
/* 151 */
/***/ function(module, exports, __webpack_require__) {

	// fallback for non-array-like ES3 and non-enumerable old V8 strings
	var cof = __webpack_require__(145);
	module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
	  return cof(it) == 'String' ? it.split('') : Object(it);
	};

/***/ },
/* 152 */
/***/ function(module, exports) {

	// 7.1.4 ToInteger
	var ceil  = Math.ceil
	  , floor = Math.floor;
	module.exports = function(it){
	  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
	};

/***/ },
/* 153 */
/***/ function(module, exports, __webpack_require__) {

	var toInteger = __webpack_require__(152)
	  , max       = Math.max
	  , min       = Math.min;
	module.exports = function(index, length){
	  index = toInteger(index);
	  return index < 0 ? max(index + length, 0) : min(index, length);
	};

/***/ },
/* 154 */
/***/ function(module, exports, __webpack_require__) {

	// 7.1.15 ToLength
	var toInteger = __webpack_require__(152)
	  , min       = Math.min;
	module.exports = function(it){
	  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
	};

/***/ },
/* 155 */
/***/ function(module, exports, __webpack_require__) {

	// 0 -> Array#forEach
	// 1 -> Array#map
	// 2 -> Array#filter
	// 3 -> Array#some
	// 4 -> Array#every
	// 5 -> Array#find
	// 6 -> Array#findIndex
	var ctx      = __webpack_require__(139)
	  , IObject  = __webpack_require__(151)
	  , toObject = __webpack_require__(148)
	  , toLength = __webpack_require__(154)
	  , asc      = __webpack_require__(156);
	module.exports = function(TYPE){
	  var IS_MAP        = TYPE == 1
	    , IS_FILTER     = TYPE == 2
	    , IS_SOME       = TYPE == 3
	    , IS_EVERY      = TYPE == 4
	    , IS_FIND_INDEX = TYPE == 6
	    , NO_HOLES      = TYPE == 5 || IS_FIND_INDEX;
	  return function($this, callbackfn, that){
	    var O      = toObject($this)
	      , self   = IObject(O)
	      , f      = ctx(callbackfn, that, 3)
	      , length = toLength(self.length)
	      , index  = 0
	      , result = IS_MAP ? asc($this, length) : IS_FILTER ? asc($this, 0) : undefined
	      , 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;
	  };
	};

/***/ },
/* 156 */
/***/ function(module, exports, __webpack_require__) {

	// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
	var isObject = __webpack_require__(143)
	  , isArray  = __webpack_require__(157)
	  , SPECIES  = __webpack_require__(158)('species');
	module.exports = function(original, length){
	  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 new (C === undefined ? Array : C)(length);
	};

/***/ },
/* 157 */
/***/ function(module, exports, __webpack_require__) {

	// 7.2.2 IsArray(argument)
	var cof = __webpack_require__(145);
	module.exports = Array.isArray || function(arg){
	  return cof(arg) == 'Array';
	};

/***/ },
/* 158 */
/***/ function(module, exports, __webpack_require__) {

	var store  = __webpack_require__(159)('wks')
	  , uid    = __webpack_require__(138)
	  , Symbol = __webpack_require__(131).Symbol;
	module.exports = function(name){
	  return store[name] || (store[name] =
	    Symbol && Symbol[name] || (Symbol || uid)('Symbol.' + name));
	};

/***/ },
/* 159 */
/***/ function(module, exports, __webpack_require__) {

	var global = __webpack_require__(131)
	  , SHARED = '__core-js_shared__'
	  , store  = global[SHARED] || (global[SHARED] = {});
	module.exports = function(key){
	  return store[key] || (store[key] = {});
	};

/***/ },
/* 160 */
/***/ function(module, exports, __webpack_require__) {

	// false -> Array#indexOf
	// true  -> Array#includes
	var toIObject = __webpack_require__(150)
	  , toLength  = __webpack_require__(154)
	  , toIndex   = __webpack_require__(153);
	module.exports = function(IS_INCLUDES){
	  return function($this, el, fromIndex){
	    var O      = toIObject($this)
	      , length = toLength(O.length)
	      , index  = toIndex(fromIndex, length)
	      , value;
	    // Array#includes uses SameValueZero equality algorithm
	    if(IS_INCLUDES && el != el)while(length > index){
	      value = O[index++];
	      if(value != value)return true;
	    // Array#toIndex ignores holes, Array#includes - not
	    } else for(;length > index; index++)if(IS_INCLUDES || index in O){
	      if(O[index] === el)return IS_INCLUDES || index;
	    } return !IS_INCLUDES && -1;
	  };
	};

/***/ },
/* 161 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// ECMAScript 6 symbols shim
	var $              = __webpack_require__(129)
	  , global         = __webpack_require__(131)
	  , has            = __webpack_require__(144)
	  , DESCRIPTORS    = __webpack_require__(135)
	  , $export        = __webpack_require__(130)
	  , redefine       = __webpack_require__(137)
	  , $fails         = __webpack_require__(136)
	  , shared         = __webpack_require__(159)
	  , setToStringTag = __webpack_require__(162)
	  , uid            = __webpack_require__(138)
	  , wks            = __webpack_require__(158)
	  , keyOf          = __webpack_require__(163)
	  , $names         = __webpack_require__(164)
	  , enumKeys       = __webpack_require__(165)
	  , isArray        = __webpack_require__(157)
	  , anObject       = __webpack_require__(147)
	  , toIObject      = __webpack_require__(150)
	  , createDesc     = __webpack_require__(134)
	  , getDesc        = $.getDesc
	  , setDesc        = $.setDesc
	  , _create        = $.create
	  , getNames       = $names.get
	  , $Symbol        = global.Symbol
	  , $JSON          = global.JSON
	  , _stringify     = $JSON && $JSON.stringify
	  , setter         = false
	  , HIDDEN         = wks('_hidden')
	  , isEnum         = $.isEnum
	  , SymbolRegistry = shared('symbol-registry')
	  , AllSymbols     = shared('symbols')
	  , useNative      = typeof $Symbol == 'function'
	  , ObjectProto    = Object.prototype;
	
	// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
	var setSymbolDesc = DESCRIPTORS && $fails(function(){
	  return _create(setDesc({}, 'a', {
	    get: function(){ return setDesc(this, 'a', {value: 7}).a; }
	  })).a != 7;
	}) ? function(it, key, D){
	  var protoDesc = getDesc(ObjectProto, key);
	  if(protoDesc)delete ObjectProto[key];
	  setDesc(it, key, D);
	  if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc);
	} : setDesc;
	
	var wrap = function(tag){
	  var sym = AllSymbols[tag] = _create($Symbol.prototype);
	  sym._k = tag;
	  DESCRIPTORS && setter && setSymbolDesc(ObjectProto, tag, {
	    configurable: true,
	    set: function(value){
	      if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
	      setSymbolDesc(this, tag, createDesc(1, value));
	    }
	  });
	  return sym;
	};
	
	var isSymbol = function(it){
	  return typeof it == 'symbol';
	};
	
	var $defineProperty = function defineProperty(it, key, D){
	  if(D && has(AllSymbols, key)){
	    if(!D.enumerable){
	      if(!has(it, HIDDEN))setDesc(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 setDesc(it, key, D);
	};
	var $defineProperties = function defineProperties(it, P){
	  anObject(it);
	  var keys = enumKeys(P = toIObject(P))
	    , i    = 0
	    , l = keys.length
	    , 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);
	  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key]
	    ? E : true;
	};
	var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
	  var D = getDesc(it = toIObject(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  = getNames(toIObject(it))
	    , result = []
	    , i      = 0
	    , key;
	  while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key);
	  return result;
	};
	var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
	  var names  = getNames(toIObject(it))
	    , result = []
	    , i      = 0
	    , key;
	  while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]);
	  return result;
	};
	var $stringify = function stringify(it){
	  if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
	  var args = [it]
	    , i    = 1
	    , $$   = arguments
	    , replacer, $replacer;
	  while($$.length > i)args.push($$[i++]);
	  replacer = args[1];
	  if(typeof replacer == 'function')$replacer = replacer;
	  if($replacer || !isArray(replacer))replacer = function(key, value){
	    if($replacer)value = $replacer.call(this, key, value);
	    if(!isSymbol(value))return value;
	  };
	  args[1] = replacer;
	  return _stringify.apply($JSON, args);
	};
	var buggyJSON = $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)) != '{}';
	});
	
	// 19.4.1.1 Symbol([description])
	if(!useNative){
	  $Symbol = function Symbol(){
	    if(isSymbol(this))throw TypeError('Symbol is not a constructor');
	    return wrap(uid(arguments.length > 0 ? arguments[0] : undefined));
	  };
	  redefine($Symbol.prototype, 'toString', function toString(){
	    return this._k;
	  });
	
	  isSymbol = function(it){
	    return it instanceof $Symbol;
	  };
	
	  $.create     = $create;
	  $.isEnum     = $propertyIsEnumerable;
	  $.getDesc    = $getOwnPropertyDescriptor;
	  $.setDesc    = $defineProperty;
	  $.setDescs   = $defineProperties;
	  $.getNames   = $names.get = $getOwnPropertyNames;
	  $.getSymbols = $getOwnPropertySymbols;
	
	  if(DESCRIPTORS && !__webpack_require__(166)){
	    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
	  }
	}
	
	var symbolStatics = {
	  // 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(key){
	    return keyOf(SymbolRegistry, key);
	  },
	  useSetter: function(){ setter = true; },
	  useSimple: function(){ setter = false; }
	};
	// 19.4.2.2 Symbol.hasInstance
	// 19.4.2.3 Symbol.isConcatSpreadable
	// 19.4.2.4 Symbol.iterator
	// 19.4.2.6 Symbol.match
	// 19.4.2.8 Symbol.replace
	// 19.4.2.9 Symbol.search
	// 19.4.2.10 Symbol.species
	// 19.4.2.11 Symbol.split
	// 19.4.2.12 Symbol.toPrimitive
	// 19.4.2.13 Symbol.toStringTag
	// 19.4.2.14 Symbol.unscopables
	$.each.call((
	  'hasInstance,isConcatSpreadable,iterator,match,replace,search,' +
	  'species,split,toPrimitive,toStringTag,unscopables'
	).split(','), function(it){
	  var sym = wks(it);
	  symbolStatics[it] = useNative ? sym : wrap(sym);
	});
	
	setter = true;
	
	$export($export.G + $export.W, {Symbol: $Symbol});
	
	$export($export.S, 'Symbol', symbolStatics);
	
	$export($export.S + $export.F * !useNative, '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 * (!useNative || buggyJSON), 'JSON', {stringify: $stringify});
	
	// 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);

/***/ },
/* 162 */
/***/ function(module, exports, __webpack_require__) {

	var def = __webpack_require__(129).setDesc
	  , has = __webpack_require__(144)
	  , TAG = __webpack_require__(158)('toStringTag');
	
	module.exports = function(it, tag, stat){
	  if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
	};

/***/ },
/* 163 */
/***/ function(module, exports, __webpack_require__) {

	var $         = __webpack_require__(129)
	  , toIObject = __webpack_require__(150);
	module.exports = function(object, el){
	  var O      = toIObject(object)
	    , keys   = $.getKeys(O)
	    , length = keys.length
	    , index  = 0
	    , key;
	  while(length > index)if(O[key = keys[index++]] === el)return key;
	};

/***/ },
/* 164 */
/***/ function(module, exports, __webpack_require__) {

	// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
	var toIObject = __webpack_require__(150)
	  , getNames  = __webpack_require__(129).getNames
	  , toString  = {}.toString;
	
	var windowNames = typeof window == 'object' && Object.getOwnPropertyNames
	  ? Object.getOwnPropertyNames(window) : [];
	
	var getWindowNames = function(it){
	  try {
	    return getNames(it);
	  } catch(e){
	    return windowNames.slice();
	  }
	};
	
	module.exports.get = function getOwnPropertyNames(it){
	  if(windowNames && toString.call(it) == '[object Window]')return getWindowNames(it);
	  return getNames(toIObject(it));
	};

/***/ },
/* 165 */
/***/ function(module, exports, __webpack_require__) {

	// all enumerable object keys, includes symbols
	var $ = __webpack_require__(129);
	module.exports = function(it){
	  var keys       = $.getKeys(it)
	    , getSymbols = $.getSymbols;
	  if(getSymbols){
	    var symbols = getSymbols(it)
	      , isEnum  = $.isEnum
	      , i       = 0
	      , key;
	    while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))keys.push(key);
	  }
	  return keys;
	};

/***/ },
/* 166 */
/***/ function(module, exports) {

	module.exports = false;

/***/ },
/* 167 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.3.1 Object.assign(target, source)
	var $export = __webpack_require__(130);
	
	$export($export.S + $export.F, 'Object', {assign: __webpack_require__(168)});

/***/ },
/* 168 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.1 Object.assign(target, source, ...)
	var $        = __webpack_require__(129)
	  , toObject = __webpack_require__(148)
	  , IObject  = __webpack_require__(151);
	
	// should work with symbols and should have deterministic property order (V8 bug)
	module.exports = __webpack_require__(136)(function(){
	  var a = Object.assign
	    , A = {}
	    , B = {}
	    , S = Symbol()
	    , K = 'abcdefghijklmnopqrst';
	  A[S] = 7;
	  K.split('').forEach(function(k){ B[k] = k; });
	  return a({}, A)[S] != 7 || Object.keys(a({}, B)).join('') != K;
	}) ? function assign(target, source){ // eslint-disable-line no-unused-vars
	  var T     = toObject(target)
	    , $$    = arguments
	    , $$len = $$.length
	    , index = 1
	    , getKeys    = $.getKeys
	    , getSymbols = $.getSymbols
	    , isEnum     = $.isEnum;
	  while($$len > index){
	    var S      = IObject($$[index++])
	      , keys   = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)
	      , length = keys.length
	      , j      = 0
	      , key;
	    while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];
	  }
	  return T;
	} : Object.assign;

/***/ },
/* 169 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.3.10 Object.is(value1, value2)
	var $export = __webpack_require__(130);
	$export($export.S, 'Object', {is: __webpack_require__(170)});

/***/ },
/* 170 */
/***/ function(module, exports) {

	// 7.2.9 SameValue(x, y)
	module.exports = Object.is || function is(x, y){
	  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
	};

/***/ },
/* 171 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.3.19 Object.setPrototypeOf(O, proto)
	var $export = __webpack_require__(130);
	$export($export.S, 'Object', {setPrototypeOf: __webpack_require__(172).set});

/***/ },
/* 172 */
/***/ function(module, exports, __webpack_require__) {

	// Works with __proto__ only. Old v8 can't work with null proto objects.
	/* eslint-disable no-proto */
	var getDesc  = __webpack_require__(129).getDesc
	  , isObject = __webpack_require__(143)
	  , anObject = __webpack_require__(147);
	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 = __webpack_require__(139)(Function.call, getDesc(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
	};

/***/ },
/* 173 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// 19.1.3.6 Object.prototype.toString()
	var classof = __webpack_require__(174)
	  , test    = {};
	test[__webpack_require__(158)('toStringTag')] = 'z';
	if(test + '' != '[object z]'){
	  __webpack_require__(137)(Object.prototype, 'toString', function toString(){
	    return '[object ' + classof(this) + ']';
	  }, true);
	}

/***/ },
/* 174 */
/***/ function(module, exports, __webpack_require__) {

	// getting tag from 19.1.3.6 Object.prototype.toString()
	var cof = __webpack_require__(145)
	  , TAG = __webpack_require__(158)('toStringTag')
	  // ES3 wrong here
	  , ARG = cof(function(){ return arguments; }()) == 'Arguments';
	
	module.exports = function(it){
	  var O, T, B;
	  return it === undefined ? 'Undefined' : it === null ? 'Null'
	    // @@toStringTag case
	    : typeof (T = (O = Object(it))[TAG]) == 'string' ? T
	    // builtinTag case
	    : ARG ? cof(O)
	    // ES3 arguments fallback
	    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
	};

/***/ },
/* 175 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.5 Object.freeze(O)
	var isObject = __webpack_require__(143);
	
	__webpack_require__(176)('freeze', function($freeze){
	  return function freeze(it){
	    return $freeze && isObject(it) ? $freeze(it) : it;
	  };
	});

/***/ },
/* 176 */
/***/ function(module, exports, __webpack_require__) {

	// most Object methods by ES6 should accept primitives
	var $export = __webpack_require__(130)
	  , core    = __webpack_require__(132)
	  , fails   = __webpack_require__(136);
	module.exports = function(KEY, exec){
	  var fn  = (core.Object || {})[KEY] || Object[KEY]
	    , exp = {};
	  exp[KEY] = exec(fn);
	  $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);
	};

/***/ },
/* 177 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.17 Object.seal(O)
	var isObject = __webpack_require__(143);
	
	__webpack_require__(176)('seal', function($seal){
	  return function seal(it){
	    return $seal && isObject(it) ? $seal(it) : it;
	  };
	});

/***/ },
/* 178 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.15 Object.preventExtensions(O)
	var isObject = __webpack_require__(143);
	
	__webpack_require__(176)('preventExtensions', function($preventExtensions){
	  return function preventExtensions(it){
	    return $preventExtensions && isObject(it) ? $preventExtensions(it) : it;
	  };
	});

/***/ },
/* 179 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.12 Object.isFrozen(O)
	var isObject = __webpack_require__(143);
	
	__webpack_require__(176)('isFrozen', function($isFrozen){
	  return function isFrozen(it){
	    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;
	  };
	});

/***/ },
/* 180 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.13 Object.isSealed(O)
	var isObject = __webpack_require__(143);
	
	__webpack_require__(176)('isSealed', function($isSealed){
	  return function isSealed(it){
	    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;
	  };
	});

/***/ },
/* 181 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.11 Object.isExtensible(O)
	var isObject = __webpack_require__(143);
	
	__webpack_require__(176)('isExtensible', function($isExtensible){
	  return function isExtensible(it){
	    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;
	  };
	});

/***/ },
/* 182 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
	var toIObject = __webpack_require__(150);
	
	__webpack_require__(176)('getOwnPropertyDescriptor', function($getOwnPropertyDescriptor){
	  return function getOwnPropertyDescriptor(it, key){
	    return $getOwnPropertyDescriptor(toIObject(it), key);
	  };
	});

/***/ },
/* 183 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.9 Object.getPrototypeOf(O)
	var toObject = __webpack_require__(148);
	
	__webpack_require__(176)('getPrototypeOf', function($getPrototypeOf){
	  return function getPrototypeOf(it){
	    return $getPrototypeOf(toObject(it));
	  };
	});

/***/ },
/* 184 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.14 Object.keys(O)
	var toObject = __webpack_require__(148);
	
	__webpack_require__(176)('keys', function($keys){
	  return function keys(it){
	    return $keys(toObject(it));
	  };
	});

/***/ },
/* 185 */
/***/ function(module, exports, __webpack_require__) {

	// 19.1.2.7 Object.getOwnPropertyNames(O)
	__webpack_require__(176)('getOwnPropertyNames', function(){
	  return __webpack_require__(164).get;
	});

/***/ },
/* 186 */
/***/ function(module, exports, __webpack_require__) {

	var setDesc    = __webpack_require__(129).setDesc
	  , createDesc = __webpack_require__(134)
	  , has        = __webpack_require__(144)
	  , FProto     = Function.prototype
	  , nameRE     = /^\s*function ([^ (]*)/
	  , NAME       = 'name';
	// 19.2.4.2 name
	NAME in FProto || __webpack_require__(135) && setDesc(FProto, NAME, {
	  configurable: true,
	  get: function(){
	    var match = ('' + this).match(nameRE)
	      , name  = match ? match[1] : '';
	    has(this, NAME) || setDesc(this, NAME, createDesc(5, name));
	    return name;
	  }
	});

/***/ },
/* 187 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $             = __webpack_require__(129)
	  , isObject      = __webpack_require__(143)
	  , HAS_INSTANCE  = __webpack_require__(158)('hasInstance')
	  , FunctionProto = Function.prototype;
	// 19.2.3.6 Function.prototype[@@hasInstance](V)
	if(!(HAS_INSTANCE in FunctionProto))$.setDesc(FunctionProto, HAS_INSTANCE, {value: function(O){
	  if(typeof this != 'function' || !isObject(O))return false;
	  if(!isObject(this.prototype))return O instanceof this;
	  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:
	  while(O = $.getProto(O))if(this.prototype === O)return true;
	  return false;
	}});

/***/ },
/* 188 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $           = __webpack_require__(129)
	  , global      = __webpack_require__(131)
	  , has         = __webpack_require__(144)
	  , cof         = __webpack_require__(145)
	  , toPrimitive = __webpack_require__(189)
	  , fails       = __webpack_require__(136)
	  , $trim       = __webpack_require__(190).trim
	  , NUMBER      = 'Number'
	  , $Number     = global[NUMBER]
	  , Base        = $Number
	  , proto       = $Number.prototype
	  // Opera ~12 has broken Object#toString
	  , BROKEN_COF  = cof($.create(proto)) == NUMBER
	  , TRIM        = 'trim' in String.prototype;
	
	// 7.1.3 ToNumber(argument)
	var toNumber = function(argument){
	  var it = toPrimitive(argument, false);
	  if(typeof it == 'string' && it.length > 2){
	    it = TRIM ? it.trim() : $trim(it, 3);
	    var first = it.charCodeAt(0)
	      , third, radix, maxCode;
	    if(first === 43 || first === 45){
	      third = it.charCodeAt(2);
	      if(third === 88 || third === 120)return NaN; // Number('+0x1') should be NaN, old V8 fix
	    } else if(first === 48){
	      switch(it.charCodeAt(1)){
	        case 66 : case 98  : radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i
	        case 79 : case 111 : radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i
	        default : return +it;
	      }
	      for(var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++){
	        code = digits.charCodeAt(i);
	        // parseInt parses a string to a first unavailable symbol
	        // but ToNumber should return NaN if a string contains unavailable symbols
	        if(code < 48 || code > maxCode)return NaN;
	      } return parseInt(digits, radix);
	    }
	  } return +it;
	};
	
	if(!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')){
	  $Number = function Number(value){
	    var it = arguments.length < 1 ? 0 : value
	      , that = this;
	    return that instanceof $Number
	      // check on 1..constructor(foo) case
	      && (BROKEN_COF ? fails(function(){ proto.valueOf.call(that); }) : cof(that) != NUMBER)
	        ? new Base(toNumber(it)) : toNumber(it);
	  };
	  $.each.call(__webpack_require__(135) ? $.getNames(Base) : (
	    // ES3:
	    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
	    // ES6 (in case, if modules with ES6 Number statics required before):
	    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
	    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
	  ).split(','), function(key){
	    if(has(Base, key) && !has($Number, key)){
	      $.setDesc($Number, key, $.getDesc(Base, key));
	    }
	  });
	  $Number.prototype = proto;
	  proto.constructor = $Number;
	  __webpack_require__(137)(global, NUMBER, $Number);
	}

/***/ },
/* 189 */
/***/ function(module, exports, __webpack_require__) {

	// 7.1.1 ToPrimitive(input [, PreferredType])
	var isObject = __webpack_require__(143);
	// 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");
	};

/***/ },
/* 190 */
/***/ function(module, exports, __webpack_require__) {

	var $export = __webpack_require__(130)
	  , defined = __webpack_require__(149)
	  , fails   = __webpack_require__(136)
	  , spaces  = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
	      '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'
	  , space   = '[' + spaces + ']'
	  , non     = '\u200b\u0085'
	  , ltrim   = RegExp('^' + space + space + '*')
	  , rtrim   = RegExp(space + space + '*$');
	
	var exporter = function(KEY, exec){
	  var exp  = {};
	  exp[KEY] = exec(trim);
	  $export($export.P + $export.F * fails(function(){
	    return !!spaces[KEY]() || non[KEY]() != non;
	  }), 'String', exp);
	};
	
	// 1 -> String#trimLeft
	// 2 -> String#trimRight
	// 3 -> String#trim
	var trim = exporter.trim = function(string, TYPE){
	  string = String(defined(string));
	  if(TYPE & 1)string = string.replace(ltrim, '');
	  if(TYPE & 2)string = string.replace(rtrim, '');
	  return string;
	};
	
	module.exports = exporter;

/***/ },
/* 191 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.1 Number.EPSILON
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)});

/***/ },
/* 192 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.2 Number.isFinite(number)
	var $export   = __webpack_require__(130)
	  , _isFinite = __webpack_require__(131).isFinite;
	
	$export($export.S, 'Number', {
	  isFinite: function isFinite(it){
	    return typeof it == 'number' && _isFinite(it);
	  }
	});

/***/ },
/* 193 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.3 Number.isInteger(number)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {isInteger: __webpack_require__(194)});

/***/ },
/* 194 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.3 Number.isInteger(number)
	var isObject = __webpack_require__(143)
	  , floor    = Math.floor;
	module.exports = function isInteger(it){
	  return !isObject(it) && isFinite(it) && floor(it) === it;
	};

/***/ },
/* 195 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.4 Number.isNaN(number)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {
	  isNaN: function isNaN(number){
	    return number != number;
	  }
	});

/***/ },
/* 196 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.5 Number.isSafeInteger(number)
	var $export   = __webpack_require__(130)
	  , isInteger = __webpack_require__(194)
	  , abs       = Math.abs;
	
	$export($export.S, 'Number', {
	  isSafeInteger: function isSafeInteger(number){
	    return isInteger(number) && abs(number) <= 0x1fffffffffffff;
	  }
	});

/***/ },
/* 197 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.6 Number.MAX_SAFE_INTEGER
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff});

/***/ },
/* 198 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.10 Number.MIN_SAFE_INTEGER
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff});

/***/ },
/* 199 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.12 Number.parseFloat(string)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {parseFloat: parseFloat});

/***/ },
/* 200 */
/***/ function(module, exports, __webpack_require__) {

	// 20.1.2.13 Number.parseInt(string, radix)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Number', {parseInt: parseInt});

/***/ },
/* 201 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.3 Math.acosh(x)
	var $export = __webpack_require__(130)
	  , log1p   = __webpack_require__(202)
	  , sqrt    = Math.sqrt
	  , $acosh  = Math.acosh;
	
	// V8 bug https://code.google.com/p/v8/issues/detail?id=3509
	$export($export.S + $export.F * !($acosh && Math.floor($acosh(Number.MAX_VALUE)) == 710), 'Math', {
	  acosh: function acosh(x){
	    return (x = +x) < 1 ? NaN : x > 94906265.62425156
	      ? Math.log(x) + Math.LN2
	      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));
	  }
	});

/***/ },
/* 202 */
/***/ function(module, exports) {

	// 20.2.2.20 Math.log1p(x)
	module.exports = Math.log1p || function log1p(x){
	  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);
	};

/***/ },
/* 203 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.5 Math.asinh(x)
	var $export = __webpack_require__(130);
	
	function asinh(x){
	  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));
	}
	
	$export($export.S, 'Math', {asinh: asinh});

/***/ },
/* 204 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.7 Math.atanh(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {
	  atanh: function atanh(x){
	    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;
	  }
	});

/***/ },
/* 205 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.9 Math.cbrt(x)
	var $export = __webpack_require__(130)
	  , sign    = __webpack_require__(206);
	
	$export($export.S, 'Math', {
	  cbrt: function cbrt(x){
	    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);
	  }
	});

/***/ },
/* 206 */
/***/ function(module, exports) {

	// 20.2.2.28 Math.sign(x)
	module.exports = Math.sign || function sign(x){
	  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;
	};

/***/ },
/* 207 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.11 Math.clz32(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {
	  clz32: function clz32(x){
	    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;
	  }
	});

/***/ },
/* 208 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.12 Math.cosh(x)
	var $export = __webpack_require__(130)
	  , exp     = Math.exp;
	
	$export($export.S, 'Math', {
	  cosh: function cosh(x){
	    return (exp(x = +x) + exp(-x)) / 2;
	  }
	});

/***/ },
/* 209 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.14 Math.expm1(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {expm1: __webpack_require__(210)});

/***/ },
/* 210 */
/***/ function(module, exports) {

	// 20.2.2.14 Math.expm1(x)
	module.exports = Math.expm1 || function expm1(x){
	  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;
	};

/***/ },
/* 211 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.16 Math.fround(x)
	var $export   = __webpack_require__(130)
	  , sign      = __webpack_require__(206)
	  , pow       = Math.pow
	  , EPSILON   = pow(2, -52)
	  , EPSILON32 = pow(2, -23)
	  , MAX32     = pow(2, 127) * (2 - EPSILON32)
	  , MIN32     = pow(2, -126);
	
	var roundTiesToEven = function(n){
	  return n + 1 / EPSILON - 1 / EPSILON;
	};
	
	
	$export($export.S, 'Math', {
	  fround: function fround(x){
	    var $abs  = Math.abs(x)
	      , $sign = sign(x)
	      , a, result;
	    if($abs < MIN32)return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;
	    a = (1 + EPSILON32 / EPSILON) * $abs;
	    result = a - (a - $abs);
	    if(result > MAX32 || result != result)return $sign * Infinity;
	    return $sign * result;
	  }
	});

/***/ },
/* 212 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])
	var $export = __webpack_require__(130)
	  , abs     = Math.abs;
	
	$export($export.S, 'Math', {
	  hypot: function hypot(value1, value2){ // eslint-disable-line no-unused-vars
	    var sum   = 0
	      , i     = 0
	      , $$    = arguments
	      , $$len = $$.length
	      , larg  = 0
	      , arg, div;
	    while(i < $$len){
	      arg = abs($$[i++]);
	      if(larg < arg){
	        div  = larg / arg;
	        sum  = sum * div * div + 1;
	        larg = arg;
	      } else if(arg > 0){
	        div  = arg / larg;
	        sum += div * div;
	      } else sum += arg;
	    }
	    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);
	  }
	});

/***/ },
/* 213 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.18 Math.imul(x, y)
	var $export = __webpack_require__(130)
	  , $imul   = Math.imul;
	
	// some WebKit versions fails with big numbers, some has wrong arity
	$export($export.S + $export.F * __webpack_require__(136)(function(){
	  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;
	}), 'Math', {
	  imul: function imul(x, y){
	    var UINT16 = 0xffff
	      , xn = +x
	      , yn = +y
	      , xl = UINT16 & xn
	      , yl = UINT16 & yn;
	    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);
	  }
	});

/***/ },
/* 214 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.21 Math.log10(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {
	  log10: function log10(x){
	    return Math.log(x) / Math.LN10;
	  }
	});

/***/ },
/* 215 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.20 Math.log1p(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {log1p: __webpack_require__(202)});

/***/ },
/* 216 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.22 Math.log2(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {
	  log2: function log2(x){
	    return Math.log(x) / Math.LN2;
	  }
	});

/***/ },
/* 217 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.28 Math.sign(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {sign: __webpack_require__(206)});

/***/ },
/* 218 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.30 Math.sinh(x)
	var $export = __webpack_require__(130)
	  , expm1   = __webpack_require__(210)
	  , exp     = Math.exp;
	
	// V8 near Chromium 38 has a problem with very small numbers
	$export($export.S + $export.F * __webpack_require__(136)(function(){
	  return !Math.sinh(-2e-17) != -2e-17;
	}), 'Math', {
	  sinh: function sinh(x){
	    return Math.abs(x = +x) < 1
	      ? (expm1(x) - expm1(-x)) / 2
	      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);
	  }
	});

/***/ },
/* 219 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.33 Math.tanh(x)
	var $export = __webpack_require__(130)
	  , expm1   = __webpack_require__(210)
	  , exp     = Math.exp;
	
	$export($export.S, 'Math', {
	  tanh: function tanh(x){
	    var a = expm1(x = +x)
	      , b = expm1(-x);
	    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));
	  }
	});

/***/ },
/* 220 */
/***/ function(module, exports, __webpack_require__) {

	// 20.2.2.34 Math.trunc(x)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Math', {
	  trunc: function trunc(it){
	    return (it > 0 ? Math.floor : Math.ceil)(it);
	  }
	});

/***/ },
/* 221 */
/***/ function(module, exports, __webpack_require__) {

	var $export        = __webpack_require__(130)
	  , toIndex        = __webpack_require__(153)
	  , fromCharCode   = String.fromCharCode
	  , $fromCodePoint = String.fromCodePoint;
	
	// length should be 1, old FF problem
	$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
	  // 21.1.2.2 String.fromCodePoint(...codePoints)
	  fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars
	    var res   = []
	      , $$    = arguments
	      , $$len = $$.length
	      , i     = 0
	      , code;
	    while($$len > i){
	      code = +$$[i++];
	      if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point');
	      res.push(code < 0x10000
	        ? fromCharCode(code)
	        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
	      );
	    } return res.join('');
	  }
	});

/***/ },
/* 222 */
/***/ function(module, exports, __webpack_require__) {

	var $export   = __webpack_require__(130)
	  , toIObject = __webpack_require__(150)
	  , toLength  = __webpack_require__(154);
	
	$export($export.S, 'String', {
	  // 21.1.2.4 String.raw(callSite, ...substitutions)
	  raw: function raw(callSite){
	    var tpl   = toIObject(callSite.raw)
	      , len   = toLength(tpl.length)
	      , $$    = arguments
	      , $$len = $$.length
	      , res   = []
	      , i     = 0;
	    while(len > i){
	      res.push(String(tpl[i++]));
	      if(i < $$len)res.push(String($$[i]));
	    } return res.join('');
	  }
	});

/***/ },
/* 223 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// 21.1.3.25 String.prototype.trim()
	__webpack_require__(190)('trim', function($trim){
	  return function trim(){
	    return $trim(this, 3);
	  };
	});

/***/ },
/* 224 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $at  = __webpack_require__(225)(true);
	
	// 21.1.3.27 String.prototype[@@iterator]()
	__webpack_require__(226)(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
	    , index = this._i
	    , point;
	  if(index >= O.length)return {value: undefined, done: true};
	  point = $at(O, index);
	  this._i += point.length;
	  return {value: point, done: false};
	});

/***/ },
/* 225 */
/***/ function(module, exports, __webpack_require__) {

	var toInteger = __webpack_require__(152)
	  , defined   = __webpack_require__(149);
	// true  -> String#at
	// false -> String#codePointAt
	module.exports = function(TO_STRING){
	  return function(that, pos){
	    var s = String(defined(that))
	      , i = toInteger(pos)
	      , l = s.length
	      , 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;
	  };
	};

/***/ },
/* 226 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var LIBRARY        = __webpack_require__(166)
	  , $export        = __webpack_require__(130)
	  , redefine       = __webpack_require__(137)
	  , hide           = __webpack_require__(133)
	  , has            = __webpack_require__(144)
	  , Iterators      = __webpack_require__(227)
	  , $iterCreate    = __webpack_require__(228)
	  , setToStringTag = __webpack_require__(162)
	  , getProto       = __webpack_require__(129).getProto
	  , ITERATOR       = __webpack_require__(158)('iterator')
	  , BUGGY          = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
	  , FF_ITERATOR    = '@@iterator'
	  , KEYS           = 'keys'
	  , 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'
	    , DEF_VALUES = DEFAULT == VALUES
	    , VALUES_BUG = false
	    , proto      = Base.prototype
	    , $native    = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
	    , $default   = $native || getMethod(DEFAULT)
	    , methods, key;
	  // Fix native
	  if($native){
	    var IteratorPrototype = getProto($default.call(new Base));
	    // Set @@toStringTag to native iterators
	    setToStringTag(IteratorPrototype, TAG, true);
	    // FF fix
	    if(!LIBRARY && has(proto, FF_ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);
	    // fix Array#{values, @@iterator}.name in V8 / FF
	    if(DEF_VALUES && $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: !DEF_VALUES ? $default : getMethod('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;
	};

/***/ },
/* 227 */
/***/ function(module, exports) {

	module.exports = {};

/***/ },
/* 228 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $              = __webpack_require__(129)
	  , descriptor     = __webpack_require__(134)
	  , setToStringTag = __webpack_require__(162)
	  , IteratorPrototype = {};
	
	// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
	__webpack_require__(133)(IteratorPrototype, __webpack_require__(158)('iterator'), function(){ return this; });
	
	module.exports = function(Constructor, NAME, next){
	  Constructor.prototype = $.create(IteratorPrototype, {next: descriptor(1, next)});
	  setToStringTag(Constructor, NAME + ' Iterator');
	};

/***/ },
/* 229 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $export = __webpack_require__(130)
	  , $at     = __webpack_require__(225)(false);
	$export($export.P, 'String', {
	  // 21.1.3.3 String.prototype.codePointAt(pos)
	  codePointAt: function codePointAt(pos){
	    return $at(this, pos);
	  }
	});

/***/ },
/* 230 */
/***/ function(module, exports, __webpack_require__) {

	// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
	'use strict';
	var $export   = __webpack_require__(130)
	  , toLength  = __webpack_require__(154)
	  , context   = __webpack_require__(231)
	  , ENDS_WITH = 'endsWith'
	  , $endsWith = ''[ENDS_WITH];
	
	$export($export.P + $export.F * __webpack_require__(233)(ENDS_WITH), 'String', {
	  endsWith: function endsWith(searchString /*, endPosition = @length */){
	    var that = context(this, searchString, ENDS_WITH)
	      , $$   = arguments
	      , endPosition = $$.length > 1 ? $$[1] : undefined
	      , len    = toLength(that.length)
	      , end    = endPosition === undefined ? len : Math.min(toLength(endPosition), len)
	      , search = String(searchString);
	    return $endsWith
	      ? $endsWith.call(that, search, end)
	      : that.slice(end - search.length, end) === search;
	  }
	});

/***/ },
/* 231 */
/***/ function(module, exports, __webpack_require__) {

	// helper for String#{startsWith, endsWith, includes}
	var isRegExp = __webpack_require__(232)
	  , defined  = __webpack_require__(149);
	
	module.exports = function(that, searchString, NAME){
	  if(isRegExp(searchString))throw TypeError('String#' + NAME + " doesn't accept regex!");
	  return String(defined(that));
	};

/***/ },
/* 232 */
/***/ function(module, exports, __webpack_require__) {

	// 7.2.8 IsRegExp(argument)
	var isObject = __webpack_require__(143)
	  , cof      = __webpack_require__(145)
	  , MATCH    = __webpack_require__(158)('match');
	module.exports = function(it){
	  var isRegExp;
	  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
	};

/***/ },
/* 233 */
/***/ function(module, exports, __webpack_require__) {

	var MATCH = __webpack_require__(158)('match');
	module.exports = function(KEY){
	  var re = /./;
	  try {
	    '/./'[KEY](re);
	  } catch(e){
	    try {
	      re[MATCH] = false;
	      return !'/./'[KEY](re);
	    } catch(f){ /* empty */ }
	  } return true;
	};

/***/ },
/* 234 */
/***/ function(module, exports, __webpack_require__) {

	// 21.1.3.7 String.prototype.includes(searchString, position = 0)
	'use strict';
	var $export  = __webpack_require__(130)
	  , context  = __webpack_require__(231)
	  , INCLUDES = 'includes';
	
	$export($export.P + $export.F * __webpack_require__(233)(INCLUDES), 'String', {
	  includes: function includes(searchString /*, position = 0 */){
	    return !!~context(this, searchString, INCLUDES)
	      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
	  }
	});

/***/ },
/* 235 */
/***/ function(module, exports, __webpack_require__) {

	var $export = __webpack_require__(130);
	
	$export($export.P, 'String', {
	  // 21.1.3.13 String.prototype.repeat(count)
	  repeat: __webpack_require__(236)
	});

/***/ },
/* 236 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var toInteger = __webpack_require__(152)
	  , defined   = __webpack_require__(149);
	
	module.exports = function repeat(count){
	  var str = String(defined(this))
	    , res = ''
	    , n   = toInteger(count);
	  if(n < 0 || n == Infinity)throw RangeError("Count can't be negative");
	  for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str;
	  return res;
	};

/***/ },
/* 237 */
/***/ function(module, exports, __webpack_require__) {

	// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
	'use strict';
	var $export     = __webpack_require__(130)
	  , toLength    = __webpack_require__(154)
	  , context     = __webpack_require__(231)
	  , STARTS_WITH = 'startsWith'
	  , $startsWith = ''[STARTS_WITH];
	
	$export($export.P + $export.F * __webpack_require__(233)(STARTS_WITH), 'String', {
	  startsWith: function startsWith(searchString /*, position = 0 */){
	    var that   = context(this, searchString, STARTS_WITH)
	      , $$     = arguments
	      , index  = toLength(Math.min($$.length > 1 ? $$[1] : undefined, that.length))
	      , search = String(searchString);
	    return $startsWith
	      ? $startsWith.call(that, search, index)
	      : that.slice(index, index + search.length) === search;
	  }
	});

/***/ },
/* 238 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var ctx         = __webpack_require__(139)
	  , $export     = __webpack_require__(130)
	  , toObject    = __webpack_require__(148)
	  , call        = __webpack_require__(239)
	  , isArrayIter = __webpack_require__(240)
	  , toLength    = __webpack_require__(154)
	  , getIterFn   = __webpack_require__(241);
	$export($export.S + $export.F * !__webpack_require__(242)(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)
	      , C       = typeof this == 'function' ? this : Array
	      , $$      = arguments
	      , $$len   = $$.length
	      , mapfn   = $$len > 1 ? $$[1] : undefined
	      , mapping = mapfn !== undefined
	      , index   = 0
	      , iterFn  = getIterFn(O)
	      , length, result, step, iterator;
	    if(mapping)mapfn = ctx(mapfn, $$len > 2 ? $$[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++){
	        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++){
	        result[index] = mapping ? mapfn(O[index], index) : O[index];
	      }
	    }
	    result.length = index;
	    return result;
	  }
	});


/***/ },
/* 239 */
/***/ function(module, exports, __webpack_require__) {

	// call something on iterator step with safe closing on error
	var anObject = __webpack_require__(147);
	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;
	  }
	};

/***/ },
/* 240 */
/***/ function(module, exports, __webpack_require__) {

	// check on default Array iterator
	var Iterators  = __webpack_require__(227)
	  , ITERATOR   = __webpack_require__(158)('iterator')
	  , ArrayProto = Array.prototype;
	
	module.exports = function(it){
	  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
	};

/***/ },
/* 241 */
/***/ function(module, exports, __webpack_require__) {

	var classof   = __webpack_require__(174)
	  , ITERATOR  = __webpack_require__(158)('iterator')
	  , Iterators = __webpack_require__(227);
	module.exports = __webpack_require__(132).getIteratorMethod = function(it){
	  if(it != undefined)return it[ITERATOR]
	    || it['@@iterator']
	    || Iterators[classof(it)];
	};

/***/ },
/* 242 */
/***/ function(module, exports, __webpack_require__) {

	var ITERATOR     = __webpack_require__(158)('iterator')
	  , SAFE_CLOSING = false;
	
	try {
	  var riter = [7][ITERATOR]();
	  riter['return'] = function(){ SAFE_CLOSING = true; };
	  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]
	      , iter = arr[ITERATOR]();
	    iter.next = function(){ safe = true; };
	    arr[ITERATOR] = function(){ return iter; };
	    exec(arr);
	  } catch(e){ /* empty */ }
	  return safe;
	};

/***/ },
/* 243 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $export = __webpack_require__(130);
	
	// WebKit Array.of isn't generic
	$export($export.S + $export.F * __webpack_require__(136)(function(){
	  function F(){}
	  return !(Array.of.call(F) instanceof F);
	}), 'Array', {
	  // 22.1.2.3 Array.of( ...items)
	  of: function of(/* ...args */){
	    var index  = 0
	      , $$     = arguments
	      , $$len  = $$.length
	      , result = new (typeof this == 'function' ? this : Array)($$len);
	    while($$len > index)result[index] = $$[index++];
	    result.length = $$len;
	    return result;
	  }
	});

/***/ },
/* 244 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var addToUnscopables = __webpack_require__(245)
	  , step             = __webpack_require__(246)
	  , Iterators        = __webpack_require__(227)
	  , toIObject        = __webpack_require__(150);
	
	// 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 = __webpack_require__(226)(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
	    , kind  = this._k
	    , 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');

/***/ },
/* 245 */
/***/ function(module, exports, __webpack_require__) {

	// 22.1.3.31 Array.prototype[@@unscopables]
	var UNSCOPABLES = __webpack_require__(158)('unscopables')
	  , ArrayProto  = Array.prototype;
	if(ArrayProto[UNSCOPABLES] == undefined)__webpack_require__(133)(ArrayProto, UNSCOPABLES, {});
	module.exports = function(key){
	  ArrayProto[UNSCOPABLES][key] = true;
	};

/***/ },
/* 246 */
/***/ function(module, exports) {

	module.exports = function(done, value){
	  return {value: value, done: !!done};
	};

/***/ },
/* 247 */
/***/ function(module, exports, __webpack_require__) {

	__webpack_require__(248)('Array');

/***/ },
/* 248 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var global      = __webpack_require__(131)
	  , $           = __webpack_require__(129)
	  , DESCRIPTORS = __webpack_require__(135)
	  , SPECIES     = __webpack_require__(158)('species');
	
	module.exports = function(KEY){
	  var C = global[KEY];
	  if(DESCRIPTORS && C && !C[SPECIES])$.setDesc(C, SPECIES, {
	    configurable: true,
	    get: function(){ return this; }
	  });
	};

/***/ },
/* 249 */
/***/ function(module, exports, __webpack_require__) {

	// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
	var $export = __webpack_require__(130);
	
	$export($export.P, 'Array', {copyWithin: __webpack_require__(250)});
	
	__webpack_require__(245)('copyWithin');

/***/ },
/* 250 */
/***/ function(module, exports, __webpack_require__) {

	// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
	'use strict';
	var toObject = __webpack_require__(148)
	  , toIndex  = __webpack_require__(153)
	  , toLength = __webpack_require__(154);
	
	module.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){
	  var O     = toObject(this)
	    , len   = toLength(O.length)
	    , to    = toIndex(target, len)
	    , from  = toIndex(start, len)
	    , $$    = arguments
	    , end   = $$.length > 2 ? $$[2] : undefined
	    , count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to)
	    , inc   = 1;
	  if(from < to && to < from + count){
	    inc  = -1;
	    from += count - 1;
	    to   += count - 1;
	  }
	  while(count-- > 0){
	    if(from in O)O[to] = O[from];
	    else delete O[to];
	    to   += inc;
	    from += inc;
	  } return O;
	};

/***/ },
/* 251 */
/***/ function(module, exports, __webpack_require__) {

	// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
	var $export = __webpack_require__(130);
	
	$export($export.P, 'Array', {fill: __webpack_require__(252)});
	
	__webpack_require__(245)('fill');

/***/ },
/* 252 */
/***/ function(module, exports, __webpack_require__) {

	// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
	'use strict';
	var toObject = __webpack_require__(148)
	  , toIndex  = __webpack_require__(153)
	  , toLength = __webpack_require__(154);
	module.exports = [].fill || function fill(value /*, start = 0, end = @length */){
	  var O      = toObject(this)
	    , length = toLength(O.length)
	    , $$     = arguments
	    , $$len  = $$.length
	    , index  = toIndex($$len > 1 ? $$[1] : undefined, length)
	    , end    = $$len > 2 ? $$[2] : undefined
	    , endPos = end === undefined ? length : toIndex(end, length);
	  while(endPos > index)O[index++] = value;
	  return O;
	};

/***/ },
/* 253 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
	var $export = __webpack_require__(130)
	  , $find   = __webpack_require__(155)(5)
	  , KEY     = 'find'
	  , 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);
	  }
	});
	__webpack_require__(245)(KEY);

/***/ },
/* 254 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
	var $export = __webpack_require__(130)
	  , $find   = __webpack_require__(155)(6)
	  , KEY     = 'findIndex'
	  , 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);
	  }
	});
	__webpack_require__(245)(KEY);

/***/ },
/* 255 */
/***/ function(module, exports, __webpack_require__) {

	var $        = __webpack_require__(129)
	  , global   = __webpack_require__(131)
	  , isRegExp = __webpack_require__(232)
	  , $flags   = __webpack_require__(256)
	  , $RegExp  = global.RegExp
	  , Base     = $RegExp
	  , proto    = $RegExp.prototype
	  , re1      = /a/g
	  , re2      = /a/g
	  // "new" creates a new object, old webkit buggy here
	  , CORRECT_NEW = new $RegExp(re1) !== re1;
	
	if(__webpack_require__(135) && (!CORRECT_NEW || __webpack_require__(136)(function(){
	  re2[__webpack_require__(158)('match')] = false;
	  // RegExp constructor can alter flags and IsRegExp works correct with @@match
	  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';
	}))){
	  $RegExp = function RegExp(p, f){
	    var piRE = isRegExp(p)
	      , fiU  = f === undefined;
	    return !(this instanceof $RegExp) && piRE && p.constructor === $RegExp && fiU ? p
	      : CORRECT_NEW
	        ? new Base(piRE && !fiU ? p.source : p, f)
	        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f);
	  };
	  $.each.call($.getNames(Base), function(key){
	    key in $RegExp || $.setDesc($RegExp, key, {
	      configurable: true,
	      get: function(){ return Base[key]; },
	      set: function(it){ Base[key] = it; }
	    });
	  });
	  proto.constructor = $RegExp;
	  $RegExp.prototype = proto;
	  __webpack_require__(137)(global, 'RegExp', $RegExp);
	}
	
	__webpack_require__(248)('RegExp');

/***/ },
/* 256 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// 21.2.5.3 get RegExp.prototype.flags
	var anObject = __webpack_require__(147);
	module.exports = function(){
	  var that   = anObject(this)
	    , result = '';
	  if(that.global)     result += 'g';
	  if(that.ignoreCase) result += 'i';
	  if(that.multiline)  result += 'm';
	  if(that.unicode)    result += 'u';
	  if(that.sticky)     result += 'y';
	  return result;
	};

/***/ },
/* 257 */
/***/ function(module, exports, __webpack_require__) {

	// 21.2.5.3 get RegExp.prototype.flags()
	var $ = __webpack_require__(129);
	if(__webpack_require__(135) && /./g.flags != 'g')$.setDesc(RegExp.prototype, 'flags', {
	  configurable: true,
	  get: __webpack_require__(256)
	});

/***/ },
/* 258 */
/***/ function(module, exports, __webpack_require__) {

	// @@match logic
	__webpack_require__(259)('match', 1, function(defined, MATCH){
	  // 21.1.3.11 String.prototype.match(regexp)
	  return function match(regexp){
	    'use strict';
	    var O  = defined(this)
	      , fn = regexp == undefined ? undefined : regexp[MATCH];
	    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
	  };
	});

/***/ },
/* 259 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var hide     = __webpack_require__(133)
	  , redefine = __webpack_require__(137)
	  , fails    = __webpack_require__(136)
	  , defined  = __webpack_require__(149)
	  , wks      = __webpack_require__(158);
	
	module.exports = function(KEY, length, exec){
	  var SYMBOL   = wks(KEY)
	    , original = ''[KEY];
	  if(fails(function(){
	    var O = {};
	    O[SYMBOL] = function(){ return 7; };
	    return ''[KEY](O) != 7;
	  })){
	    redefine(String.prototype, KEY, exec(defined, SYMBOL, original));
	    hide(RegExp.prototype, SYMBOL, length == 2
	      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
	      // 21.2.5.11 RegExp.prototype[@@split](string, limit)
	      ? function(string, arg){ return original.call(string, this, arg); }
	      // 21.2.5.6 RegExp.prototype[@@match](string)
	      // 21.2.5.9 RegExp.prototype[@@search](string)
	      : function(string){ return original.call(string, this); }
	    );
	  }
	};

/***/ },
/* 260 */
/***/ function(module, exports, __webpack_require__) {

	// @@replace logic
	__webpack_require__(259)('replace', 2, function(defined, REPLACE, $replace){
	  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
	  return function replace(searchValue, replaceValue){
	    'use strict';
	    var O  = defined(this)
	      , fn = searchValue == undefined ? undefined : searchValue[REPLACE];
	    return fn !== undefined
	      ? fn.call(searchValue, O, replaceValue)
	      : $replace.call(String(O), searchValue, replaceValue);
	  };
	});

/***/ },
/* 261 */
/***/ function(module, exports, __webpack_require__) {

	// @@search logic
	__webpack_require__(259)('search', 1, function(defined, SEARCH){
	  // 21.1.3.15 String.prototype.search(regexp)
	  return function search(regexp){
	    'use strict';
	    var O  = defined(this)
	      , fn = regexp == undefined ? undefined : regexp[SEARCH];
	    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
	  };
	});

/***/ },
/* 262 */
/***/ function(module, exports, __webpack_require__) {

	// @@split logic
	__webpack_require__(259)('split', 2, function(defined, SPLIT, $split){
	  // 21.1.3.17 String.prototype.split(separator, limit)
	  return function split(separator, limit){
	    'use strict';
	    var O  = defined(this)
	      , fn = separator == undefined ? undefined : separator[SPLIT];
	    return fn !== undefined
	      ? fn.call(separator, O, limit)
	      : $split.call(String(O), separator, limit);
	  };
	});

/***/ },
/* 263 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $          = __webpack_require__(129)
	  , LIBRARY    = __webpack_require__(166)
	  , global     = __webpack_require__(131)
	  , ctx        = __webpack_require__(139)
	  , classof    = __webpack_require__(174)
	  , $export    = __webpack_require__(130)
	  , isObject   = __webpack_require__(143)
	  , anObject   = __webpack_require__(147)
	  , aFunction  = __webpack_require__(140)
	  , strictNew  = __webpack_require__(264)
	  , forOf      = __webpack_require__(265)
	  , setProto   = __webpack_require__(172).set
	  , same       = __webpack_require__(170)
	  , SPECIES    = __webpack_require__(158)('species')
	  , speciesConstructor = __webpack_require__(266)
	  , asap       = __webpack_require__(267)
	  , PROMISE    = 'Promise'
	  , process    = global.process
	  , isNode     = classof(process) == 'process'
	  , P          = global[PROMISE]
	  , Wrapper;
	
	var testResolve = function(sub){
	  var test = new P(function(){});
	  if(sub)test.constructor = Object;
	  return P.resolve(test) === test;
	};
	
	var USE_NATIVE = function(){
	  var works = false;
	  function P2(x){
	    var self = new P(x);
	    setProto(self, P2.prototype);
	    return self;
	  }
	  try {
	    works = P && P.resolve && testResolve();
	    setProto(P2, P);
	    P2.prototype = $.create(P.prototype, {constructor: {value: P2}});
	    // actual Firefox has broken subclass support, test that
	    if(!(P2.resolve(5).then(function(){}) instanceof P2)){
	      works = false;
	    }
	    // actual V8 bug, https://code.google.com/p/v8/issues/detail?id=4162
	    if(works && __webpack_require__(135)){
	      var thenableThenGotten = false;
	      P.resolve($.setDesc({}, 'then', {
	        get: function(){ thenableThenGotten = true; }
	      }));
	      works = thenableThenGotten;
	    }
	  } catch(e){ works = false; }
	  return works;
	}();
	
	// helpers
	var sameConstructor = function(a, b){
	  // library wrapper special case
	  if(LIBRARY && a === P && b === Wrapper)return true;
	  return same(a, b);
	};
	var getConstructor = function(C){
	  var S = anObject(C)[SPECIES];
	  return S != undefined ? S : C;
	};
	var isThenable = function(it){
	  var then;
	  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
	};
	var PromiseCapability = function(C){
	  var resolve, reject;
	  this.promise = new C(function($$resolve, $$reject){
	    if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');
	    resolve = $$resolve;
	    reject  = $$reject;
	  });
	  this.resolve = aFunction(resolve),
	  this.reject  = aFunction(reject)
	};
	var perform = function(exec){
	  try {
	    exec();
	  } catch(e){
	    return {error: e};
	  }
	};
	var notify = function(record, isReject){
	  if(record.n)return;
	  record.n = true;
	  var chain = record.c;
	  asap(function(){
	    var value = record.v
	      , ok    = record.s == 1
	      , i     = 0;
	    var run = function(reaction){
	      var handler = ok ? reaction.ok : reaction.fail
	        , resolve = reaction.resolve
	        , reject  = reaction.reject
	        , result, then;
	      try {
	        if(handler){
	          if(!ok)record.h = true;
	          result = handler === true ? value : handler(value);
	          if(result === reaction.promise){
	            reject(TypeError('Promise-chain cycle'));
	          } else if(then = isThenable(result)){
	            then.call(result, resolve, reject);
	          } else resolve(result);
	        } else reject(value);
	      } catch(e){
	        reject(e);
	      }
	    };
	    while(chain.length > i)run(chain[i++]); // variable length - can't use forEach
	    chain.length = 0;
	    record.n = false;
	    if(isReject)setTimeout(function(){
	      var promise = record.p
	        , handler, console;
	      if(isUnhandled(promise)){
	        if(isNode){
	          process.emit('unhandledRejection', value, promise);
	        } else if(handler = global.onunhandledrejection){
	          handler({promise: promise, reason: value});
	        } else if((console = global.console) && console.error){
	          console.error('Unhandled promise rejection', value);
	        }
	      } record.a = undefined;
	    }, 1);
	  });
	};
	var isUnhandled = function(promise){
	  var record = promise._d
	    , chain  = record.a || record.c
	    , i      = 0
	    , reaction;
	  if(record.h)return false;
	  while(chain.length > i){
	    reaction = chain[i++];
	    if(reaction.fail || !isUnhandled(reaction.promise))return false;
	  } return true;
	};
	var $reject = function(value){
	  var record = this;
	  if(record.d)return;
	  record.d = true;
	  record = record.r || record; // unwrap
	  record.v = value;
	  record.s = 2;
	  record.a = record.c.slice();
	  notify(record, true);
	};
	var $resolve = function(value){
	  var record = this
	    , then;
	  if(record.d)return;
	  record.d = true;
	  record = record.r || record; // unwrap
	  try {
	    if(record.p === value)throw TypeError("Promise can't be resolved itself");
	    if(then = isThenable(value)){
	      asap(function(){
	        var wrapper = {r: record, d: false}; // wrap
	        try {
	          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
	        } catch(e){
	          $reject.call(wrapper, e);
	        }
	      });
	    } else {
	      record.v = value;
	      record.s = 1;
	      notify(record, false);
	    }
	  } catch(e){
	    $reject.call({r: record, d: false}, e); // wrap
	  }
	};
	
	// constructor polyfill
	if(!USE_NATIVE){
	  // 25.4.3.1 Promise(executor)
	  P = function Promise(executor){
	    aFunction(executor);
	    var record = this._d = {
	      p: strictNew(this, P, PROMISE),         // <- promise
	      c: [],                                  // <- awaiting reactions
	      a: undefined,                           // <- checked in isUnhandled reactions
	      s: 0,                                   // <- state
	      d: false,                               // <- done
	      v: undefined,                           // <- value
	      h: false,                               // <- handled rejection
	      n: false                                // <- notify
	    };
	    try {
	      executor(ctx($resolve, record, 1), ctx($reject, record, 1));
	    } catch(err){
	      $reject.call(record, err);
	    }
	  };
	  __webpack_require__(269)(P.prototype, {
	    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
	    then: function then(onFulfilled, onRejected){
	      var reaction = new PromiseCapability(speciesConstructor(this, P))
	        , promise  = reaction.promise
	        , record   = this._d;
	      reaction.ok   = typeof onFulfilled == 'function' ? onFulfilled : true;
	      reaction.fail = typeof onRejected == 'function' && onRejected;
	      record.c.push(reaction);
	      if(record.a)record.a.push(reaction);
	      if(record.s)notify(record, false);
	      return promise;
	    },
	    // 25.4.5.1 Promise.prototype.catch(onRejected)
	    'catch': function(onRejected){
	      return this.then(undefined, onRejected);
	    }
	  });
	}
	
	$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: P});
	__webpack_require__(162)(P, PROMISE);
	__webpack_require__(248)(PROMISE);
	Wrapper = __webpack_require__(132)[PROMISE];
	
	// statics
	$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
	  // 25.4.4.5 Promise.reject(r)
	  reject: function reject(r){
	    var capability = new PromiseCapability(this)
	      , $$reject   = capability.reject;
	    $$reject(r);
	    return capability.promise;
	  }
	});
	$export($export.S + $export.F * (!USE_NATIVE || testResolve(true)), PROMISE, {
	  // 25.4.4.6 Promise.resolve(x)
	  resolve: function resolve(x){
	    // instanceof instead of internal slot check because we should fix it without replacement native Promise core
	    if(x instanceof P && sameConstructor(x.constructor, this))return x;
	    var capability = new PromiseCapability(this)
	      , $$resolve  = capability.resolve;
	    $$resolve(x);
	    return capability.promise;
	  }
	});
	$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(242)(function(iter){
	  P.all(iter)['catch'](function(){});
	})), PROMISE, {
	  // 25.4.4.1 Promise.all(iterable)
	  all: function all(iterable){
	    var C          = getConstructor(this)
	      , capability = new PromiseCapability(C)
	      , resolve    = capability.resolve
	      , reject     = capability.reject
	      , values     = [];
	    var abrupt = perform(function(){
	      forOf(iterable, false, values.push, values);
	      var remaining = values.length
	        , results   = Array(remaining);
	      if(remaining)$.each.call(values, function(promise, index){
	        var alreadyCalled = false;
	        C.resolve(promise).then(function(value){
	          if(alreadyCalled)return;
	          alreadyCalled = true;
	          results[index] = value;
	          --remaining || resolve(results);
	        }, reject);
	      });
	      else resolve(results);
	    });
	    if(abrupt)reject(abrupt.error);
	    return capability.promise;
	  },
	  // 25.4.4.4 Promise.race(iterable)
	  race: function race(iterable){
	    var C          = getConstructor(this)
	      , capability = new PromiseCapability(C)
	      , reject     = capability.reject;
	    var abrupt = perform(function(){
	      forOf(iterable, false, function(promise){
	        C.resolve(promise).then(capability.resolve, reject);
	      });
	    });
	    if(abrupt)reject(abrupt.error);
	    return capability.promise;
	  }
	});

/***/ },
/* 264 */
/***/ function(module, exports) {

	module.exports = function(it, Constructor, name){
	  if(!(it instanceof Constructor))throw TypeError(name + ": use the 'new' operator!");
	  return it;
	};

/***/ },
/* 265 */
/***/ function(module, exports, __webpack_require__) {

	var ctx         = __webpack_require__(139)
	  , call        = __webpack_require__(239)
	  , isArrayIter = __webpack_require__(240)
	  , anObject    = __webpack_require__(147)
	  , toLength    = __webpack_require__(154)
	  , getIterFn   = __webpack_require__(241);
	module.exports = function(iterable, entries, fn, that){
	  var iterFn = getIterFn(iterable)
	    , f      = ctx(fn, that, entries ? 2 : 1)
	    , index  = 0
	    , length, step, iterator;
	  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++){
	    entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
	  } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
	    call(iterator, f, step.value, entries);
	  }
	};

/***/ },
/* 266 */
/***/ function(module, exports, __webpack_require__) {

	// 7.3.20 SpeciesConstructor(O, defaultConstructor)
	var anObject  = __webpack_require__(147)
	  , aFunction = __webpack_require__(140)
	  , SPECIES   = __webpack_require__(158)('species');
	module.exports = function(O, D){
	  var C = anObject(O).constructor, S;
	  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
	};

/***/ },
/* 267 */
/***/ function(module, exports, __webpack_require__) {

	var global    = __webpack_require__(131)
	  , macrotask = __webpack_require__(268).set
	  , Observer  = global.MutationObserver || global.WebKitMutationObserver
	  , process   = global.process
	  , Promise   = global.Promise
	  , isNode    = __webpack_require__(145)(process) == 'process'
	  , head, last, notify;
	
	var flush = function(){
	  var parent, domain, fn;
	  if(isNode && (parent = process.domain)){
	    process.domain = null;
	    parent.exit();
	  }
	  while(head){
	    domain = head.domain;
	    fn     = head.fn;
	    if(domain)domain.enter();
	    fn(); // <- currently we use it only for Promise - try / catch not required
	    if(domain)domain.exit();
	    head = head.next;
	  } last = undefined;
	  if(parent)parent.enter();
	};
	
	// Node.js
	if(isNode){
	  notify = function(){
	    process.nextTick(flush);
	  };
	// browsers with MutationObserver
	} else if(Observer){
	  var toggle = 1
	    , node   = document.createTextNode('');
	  new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
	  notify = function(){
	    node.data = toggle = -toggle;
	  };
	// environments with maybe non-completely correct, but existent Promise
	} else if(Promise && Promise.resolve){
	  notify = function(){
	    Promise.resolve().then(flush);
	  };
	// for other environments - macrotask based on:
	// - setImmediate
	// - MessageChannel
	// - window.postMessag
	// - onreadystatechange
	// - setTimeout
	} else {
	  notify = function(){
	    // strange IE + webpack dev server bug - use .call(global)
	    macrotask.call(global, flush);
	  };
	}
	
	module.exports = function asap(fn){
	  var task = {fn: fn, next: undefined, domain: isNode && process.domain};
	  if(last)last.next = task;
	  if(!head){
	    head = task;
	    notify();
	  } last = task;
	};

/***/ },
/* 268 */
/***/ function(module, exports, __webpack_require__) {

	var ctx                = __webpack_require__(139)
	  , invoke             = __webpack_require__(146)
	  , html               = __webpack_require__(141)
	  , cel                = __webpack_require__(142)
	  , global             = __webpack_require__(131)
	  , process            = global.process
	  , setTask            = global.setImmediate
	  , clearTask          = global.clearImmediate
	  , MessageChannel     = global.MessageChannel
	  , counter            = 0
	  , queue              = {}
	  , ONREADYSTATECHANGE = 'onreadystatechange'
	  , defer, channel, port;
	var run = function(){
	  var id = +this;
	  if(queue.hasOwnProperty(id)){
	    var fn = queue[id];
	    delete queue[id];
	    fn();
	  }
	};
	var listner = function(event){
	  run.call(event.data);
	};
	// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
	if(!setTask || !clearTask){
	  setTask = function setImmediate(fn){
	    var args = [], i = 1;
	    while(arguments.length > i)args.push(arguments[i++]);
	    queue[++counter] = function(){
	      invoke(typeof fn == 'function' ? fn : Function(fn), args);
	    };
	    defer(counter);
	    return counter;
	  };
	  clearTask = function clearImmediate(id){
	    delete queue[id];
	  };
	  // Node.js 0.8-
	  if(__webpack_require__(145)(process) == 'process'){
	    defer = function(id){
	      process.nextTick(ctx(run, id, 1));
	    };
	  // Browsers with MessageChannel, includes WebWorkers
	  } else if(MessageChannel){
	    channel = new MessageChannel;
	    port    = channel.port2;
	    channel.port1.onmessage = listner;
	    defer = ctx(port.postMessage, port, 1);
	  // Browsers with postMessage, skip WebWorkers
	  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
	  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
	    defer = function(id){
	      global.postMessage(id + '', '*');
	    };
	    global.addEventListener('message', listner, false);
	  // IE8-
	  } else if(ONREADYSTATECHANGE in cel('script')){
	    defer = function(id){
	      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
	        html.removeChild(this);
	        run.call(id);
	      };
	    };
	  // Rest old browsers
	  } else {
	    defer = function(id){
	      setTimeout(ctx(run, id, 1), 0);
	    };
	  }
	}
	module.exports = {
	  set:   setTask,
	  clear: clearTask
	};

/***/ },
/* 269 */
/***/ function(module, exports, __webpack_require__) {

	var redefine = __webpack_require__(137);
	module.exports = function(target, src){
	  for(var key in src)redefine(target, key, src[key]);
	  return target;
	};

/***/ },
/* 270 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var strong = __webpack_require__(271);
	
	// 23.1 Map Objects
	__webpack_require__(272)('Map', function(get){
	  return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
	}, {
	  // 23.1.3.6 Map.prototype.get(key)
	  get: function get(key){
	    var entry = strong.getEntry(this, key);
	    return entry && entry.v;
	  },
	  // 23.1.3.9 Map.prototype.set(key, value)
	  set: function set(key, value){
	    return strong.def(this, key === 0 ? 0 : key, value);
	  }
	}, strong, true);

/***/ },
/* 271 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $            = __webpack_require__(129)
	  , hide         = __webpack_require__(133)
	  , redefineAll  = __webpack_require__(269)
	  , ctx          = __webpack_require__(139)
	  , strictNew    = __webpack_require__(264)
	  , defined      = __webpack_require__(149)
	  , forOf        = __webpack_require__(265)
	  , $iterDefine  = __webpack_require__(226)
	  , step         = __webpack_require__(246)
	  , ID           = __webpack_require__(138)('id')
	  , $has         = __webpack_require__(144)
	  , isObject     = __webpack_require__(143)
	  , setSpecies   = __webpack_require__(248)
	  , DESCRIPTORS  = __webpack_require__(135)
	  , isExtensible = Object.isExtensible || isObject
	  , SIZE         = DESCRIPTORS ? '_s' : 'size'
	  , id           = 0;
	
	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, ID)){
	    // can't set id to frozen object
	    if(!isExtensible(it))return 'F';
	    // not necessary to add id
	    if(!create)return 'E';
	    // add missing object id
	    hide(it, ID, ++id);
	  // return object id with prefix
	  } return 'O' + it[ID];
	};
	
	var getEntry = function(that, key){
	  // fast case
	  var index = fastKey(key), 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){
	      strictNew(that, C, NAME);
	      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 = this, 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  = this
	          , entry = getEntry(that, key);
	        if(entry){
	          var next = entry.n
	            , 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 */){
	        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)
	          , 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(this, key);
	      }
	    });
	    if(DESCRIPTORS)$.setDesc(C.prototype, 'size', {
	      get: function(){
	        return defined(this[SIZE]);
	      }
	    });
	    return C;
	  },
	  def: function(that, key, value){
	    var entry = getEntry(that, key)
	      , 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 = iterated;  // target
	      this._k = kind;      // kind
	      this._l = undefined; // previous
	    }, function(){
	      var that  = this
	        , kind  = that._k
	        , 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);
	  }
	};

/***/ },
/* 272 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var global         = __webpack_require__(131)
	  , $export        = __webpack_require__(130)
	  , redefine       = __webpack_require__(137)
	  , redefineAll    = __webpack_require__(269)
	  , forOf          = __webpack_require__(265)
	  , strictNew      = __webpack_require__(264)
	  , isObject       = __webpack_require__(143)
	  , fails          = __webpack_require__(136)
	  , $iterDetect    = __webpack_require__(242)
	  , setToStringTag = __webpack_require__(162);
	
	module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){
	  var Base  = global[NAME]
	    , C     = Base
	    , ADDER = IS_MAP ? 'set' : 'add'
	    , proto = C && C.prototype
	    , 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);
	  } else {
	    var instance             = new C
	      // early implementations not supports chaining
	      , HASNT_CHAINING       = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance
	      // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
	      , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })
	      // most early implementations doesn't supports iterables, most modern - not close it correctly
	      , ACCEPT_ITERABLES     = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new
	      // for early implementations -0 and +0 not the same
	      , BUGGY_ZERO;
	    if(!ACCEPT_ITERABLES){ 
	      C = wrapper(function(target, iterable){
	        strictNew(target, C, NAME);
	        var that = new Base;
	        if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
	        return that;
	      });
	      C.prototype = proto;
	      proto.constructor = C;
	    }
	    IS_WEAK || instance.forEach(function(val, key){
	      BUGGY_ZERO = 1 / key === -Infinity;
	    });
	    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;
	};

/***/ },
/* 273 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var strong = __webpack_require__(271);
	
	// 23.2 Set Objects
	__webpack_require__(272)('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(this, value = value === 0 ? 0 : value, value);
	  }
	}, strong);

/***/ },
/* 274 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $            = __webpack_require__(129)
	  , redefine     = __webpack_require__(137)
	  , weak         = __webpack_require__(275)
	  , isObject     = __webpack_require__(143)
	  , has          = __webpack_require__(144)
	  , frozenStore  = weak.frozenStore
	  , WEAK         = weak.WEAK
	  , isExtensible = Object.isExtensible || isObject
	  , tmp          = {};
	
	// 23.3 WeakMap Objects
	var $WeakMap = __webpack_require__(272)('WeakMap', function(get){
	  return function WeakMap(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
	}, {
	  // 23.3.3.3 WeakMap.prototype.get(key)
	  get: function get(key){
	    if(isObject(key)){
	      if(!isExtensible(key))return frozenStore(this).get(key);
	      if(has(key, WEAK))return key[WEAK][this._i];
	    }
	  },
	  // 23.3.3.5 WeakMap.prototype.set(key, value)
	  set: function set(key, value){
	    return weak.def(this, key, value);
	  }
	}, weak, true, true);
	
	// IE11 WeakMap frozen keys fix
	if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
	  $.each.call(['delete', 'has', 'get', 'set'], function(key){
	    var proto  = $WeakMap.prototype
	      , method = proto[key];
	    redefine(proto, key, function(a, b){
	      // store frozen objects on leaky map
	      if(isObject(a) && !isExtensible(a)){
	        var result = frozenStore(this)[key](a, b);
	        return key == 'set' ? this : result;
	      // store all the rest on native weakmap
	      } return method.call(this, a, b);
	    });
	  });
	}

/***/ },
/* 275 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var hide              = __webpack_require__(133)
	  , redefineAll       = __webpack_require__(269)
	  , anObject          = __webpack_require__(147)
	  , isObject          = __webpack_require__(143)
	  , strictNew         = __webpack_require__(264)
	  , forOf             = __webpack_require__(265)
	  , createArrayMethod = __webpack_require__(155)
	  , $has              = __webpack_require__(144)
	  , WEAK              = __webpack_require__(138)('weak')
	  , isExtensible      = Object.isExtensible || isObject
	  , arrayFind         = createArrayMethod(5)
	  , arrayFindIndex    = createArrayMethod(6)
	  , id                = 0;
	
	// fallback for frozen keys
	var frozenStore = function(that){
	  return that._l || (that._l = new FrozenStore);
	};
	var FrozenStore = function(){
	  this.a = [];
	};
	var findFrozen = function(store, key){
	  return arrayFind(store.a, function(it){
	    return it[0] === key;
	  });
	};
	FrozenStore.prototype = {
	  get: function(key){
	    var entry = findFrozen(this, key);
	    if(entry)return entry[1];
	  },
	  has: function(key){
	    return !!findFrozen(this, key);
	  },
	  set: function(key, value){
	    var entry = findFrozen(this, key);
	    if(entry)entry[1] = value;
	    else this.a.push([key, value]);
	  },
	  'delete': function(key){
	    var index = arrayFindIndex(this.a, function(it){
	      return it[0] === key;
	    });
	    if(~index)this.a.splice(index, 1);
	    return !!~index;
	  }
	};
	
	module.exports = {
	  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
	    var C = wrapper(function(that, iterable){
	      strictNew(that, C, NAME);
	      that._i = id++;      // collection id
	      that._l = undefined; // leak store for frozen objects
	      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
	    });
	    redefineAll(C.prototype, {
	      // 23.3.3.2 WeakMap.prototype.delete(key)
	      // 23.4.3.3 WeakSet.prototype.delete(value)
	      'delete': function(key){
	        if(!isObject(key))return false;
	        if(!isExtensible(key))return frozenStore(this)['delete'](key);
	        return $has(key, WEAK) && $has(key[WEAK], this._i) && delete key[WEAK][this._i];
	      },
	      // 23.3.3.4 WeakMap.prototype.has(key)
	      // 23.4.3.4 WeakSet.prototype.has(value)
	      has: function has(key){
	        if(!isObject(key))return false;
	        if(!isExtensible(key))return frozenStore(this).has(key);
	        return $has(key, WEAK) && $has(key[WEAK], this._i);
	      }
	    });
	    return C;
	  },
	  def: function(that, key, value){
	    if(!isExtensible(anObject(key))){
	      frozenStore(that).set(key, value);
	    } else {
	      $has(key, WEAK) || hide(key, WEAK, {});
	      key[WEAK][that._i] = value;
	    } return that;
	  },
	  frozenStore: frozenStore,
	  WEAK: WEAK
	};

/***/ },
/* 276 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var weak = __webpack_require__(275);
	
	// 23.4 WeakSet Objects
	__webpack_require__(272)('WeakSet', function(get){
	  return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
	}, {
	  // 23.4.3.1 WeakSet.prototype.add(value)
	  add: function add(value){
	    return weak.def(this, value, true);
	  }
	}, weak, false, true);

/***/ },
/* 277 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)
	var $export = __webpack_require__(130)
	  , _apply  = Function.apply;
	
	$export($export.S, 'Reflect', {
	  apply: function apply(target, thisArgument, argumentsList){
	    return _apply.call(target, thisArgument, argumentsList);
	  }
	});

/***/ },
/* 278 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])
	var $         = __webpack_require__(129)
	  , $export   = __webpack_require__(130)
	  , aFunction = __webpack_require__(140)
	  , anObject  = __webpack_require__(147)
	  , isObject  = __webpack_require__(143)
	  , bind      = Function.bind || __webpack_require__(132).Function.prototype.bind;
	
	// MS Edge supports only 2 arguments
	// FF Nightly sets third argument as `new.target`, but does not create `this` from it
	$export($export.S + $export.F * __webpack_require__(136)(function(){
	  function F(){}
	  return !(Reflect.construct(function(){}, [], F) instanceof F);
	}), 'Reflect', {
	  construct: function construct(Target, args /*, newTarget*/){
	    aFunction(Target);
	    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);
	    if(Target == newTarget){
	      // w/o altered newTarget, optimization for 0-4 arguments
	      if(args != undefined)switch(anObject(args).length){
	        case 0: return new Target;
	        case 1: return new Target(args[0]);
	        case 2: return new Target(args[0], args[1]);
	        case 3: return new Target(args[0], args[1], args[2]);
	        case 4: return new Target(args[0], args[1], args[2], args[3]);
	      }
	      // w/o altered newTarget, lot of arguments case
	      var $args = [null];
	      $args.push.apply($args, args);
	      return new (bind.apply(Target, $args));
	    }
	    // with altered newTarget, not support built-in constructors
	    var proto    = newTarget.prototype
	      , instance = $.create(isObject(proto) ? proto : Object.prototype)
	      , result   = Function.apply.call(Target, instance, args);
	    return isObject(result) ? result : instance;
	  }
	});

/***/ },
/* 279 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)
	var $        = __webpack_require__(129)
	  , $export  = __webpack_require__(130)
	  , anObject = __webpack_require__(147);
	
	// MS Edge has broken Reflect.defineProperty - throwing instead of returning false
	$export($export.S + $export.F * __webpack_require__(136)(function(){
	  Reflect.defineProperty($.setDesc({}, 1, {value: 1}), 1, {value: 2});
	}), 'Reflect', {
	  defineProperty: function defineProperty(target, propertyKey, attributes){
	    anObject(target);
	    try {
	      $.setDesc(target, propertyKey, attributes);
	      return true;
	    } catch(e){
	      return false;
	    }
	  }
	});

/***/ },
/* 280 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.4 Reflect.deleteProperty(target, propertyKey)
	var $export  = __webpack_require__(130)
	  , getDesc  = __webpack_require__(129).getDesc
	  , anObject = __webpack_require__(147);
	
	$export($export.S, 'Reflect', {
	  deleteProperty: function deleteProperty(target, propertyKey){
	    var desc = getDesc(anObject(target), propertyKey);
	    return desc && !desc.configurable ? false : delete target[propertyKey];
	  }
	});

/***/ },
/* 281 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// 26.1.5 Reflect.enumerate(target)
	var $export  = __webpack_require__(130)
	  , anObject = __webpack_require__(147);
	var Enumerate = function(iterated){
	  this._t = anObject(iterated); // target
	  this._i = 0;                  // next index
	  var keys = this._k = []       // keys
	    , key;
	  for(key in iterated)keys.push(key);
	};
	__webpack_require__(228)(Enumerate, 'Object', function(){
	  var that = this
	    , keys = that._k
	    , key;
	  do {
	    if(that._i >= keys.length)return {value: undefined, done: true};
	  } while(!((key = keys[that._i++]) in that._t));
	  return {value: key, done: false};
	});
	
	$export($export.S, 'Reflect', {
	  enumerate: function enumerate(target){
	    return new Enumerate(target);
	  }
	});

/***/ },
/* 282 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.6 Reflect.get(target, propertyKey [, receiver])
	var $        = __webpack_require__(129)
	  , has      = __webpack_require__(144)
	  , $export  = __webpack_require__(130)
	  , isObject = __webpack_require__(143)
	  , anObject = __webpack_require__(147);
	
	function get(target, propertyKey/*, receiver*/){
	  var receiver = arguments.length < 3 ? target : arguments[2]
	    , desc, proto;
	  if(anObject(target) === receiver)return target[propertyKey];
	  if(desc = $.getDesc(target, propertyKey))return has(desc, 'value')
	    ? desc.value
	    : desc.get !== undefined
	      ? desc.get.call(receiver)
	      : undefined;
	  if(isObject(proto = $.getProto(target)))return get(proto, propertyKey, receiver);
	}
	
	$export($export.S, 'Reflect', {get: get});

/***/ },
/* 283 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)
	var $        = __webpack_require__(129)
	  , $export  = __webpack_require__(130)
	  , anObject = __webpack_require__(147);
	
	$export($export.S, 'Reflect', {
	  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey){
	    return $.getDesc(anObject(target), propertyKey);
	  }
	});

/***/ },
/* 284 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.8 Reflect.getPrototypeOf(target)
	var $export  = __webpack_require__(130)
	  , getProto = __webpack_require__(129).getProto
	  , anObject = __webpack_require__(147);
	
	$export($export.S, 'Reflect', {
	  getPrototypeOf: function getPrototypeOf(target){
	    return getProto(anObject(target));
	  }
	});

/***/ },
/* 285 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.9 Reflect.has(target, propertyKey)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Reflect', {
	  has: function has(target, propertyKey){
	    return propertyKey in target;
	  }
	});

/***/ },
/* 286 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.10 Reflect.isExtensible(target)
	var $export       = __webpack_require__(130)
	  , anObject      = __webpack_require__(147)
	  , $isExtensible = Object.isExtensible;
	
	$export($export.S, 'Reflect', {
	  isExtensible: function isExtensible(target){
	    anObject(target);
	    return $isExtensible ? $isExtensible(target) : true;
	  }
	});

/***/ },
/* 287 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.11 Reflect.ownKeys(target)
	var $export = __webpack_require__(130);
	
	$export($export.S, 'Reflect', {ownKeys: __webpack_require__(288)});

/***/ },
/* 288 */
/***/ function(module, exports, __webpack_require__) {

	// all object keys, includes non-enumerable and symbols
	var $        = __webpack_require__(129)
	  , anObject = __webpack_require__(147)
	  , Reflect  = __webpack_require__(131).Reflect;
	module.exports = Reflect && Reflect.ownKeys || function ownKeys(it){
	  var keys       = $.getNames(anObject(it))
	    , getSymbols = $.getSymbols;
	  return getSymbols ? keys.concat(getSymbols(it)) : keys;
	};

/***/ },
/* 289 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.12 Reflect.preventExtensions(target)
	var $export            = __webpack_require__(130)
	  , anObject           = __webpack_require__(147)
	  , $preventExtensions = Object.preventExtensions;
	
	$export($export.S, 'Reflect', {
	  preventExtensions: function preventExtensions(target){
	    anObject(target);
	    try {
	      if($preventExtensions)$preventExtensions(target);
	      return true;
	    } catch(e){
	      return false;
	    }
	  }
	});

/***/ },
/* 290 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])
	var $          = __webpack_require__(129)
	  , has        = __webpack_require__(144)
	  , $export    = __webpack_require__(130)
	  , createDesc = __webpack_require__(134)
	  , anObject   = __webpack_require__(147)
	  , isObject   = __webpack_require__(143);
	
	function set(target, propertyKey, V/*, receiver*/){
	  var receiver = arguments.length < 4 ? target : arguments[3]
	    , ownDesc  = $.getDesc(anObject(target), propertyKey)
	    , existingDescriptor, proto;
	  if(!ownDesc){
	    if(isObject(proto = $.getProto(target))){
	      return set(proto, propertyKey, V, receiver);
	    }
	    ownDesc = createDesc(0);
	  }
	  if(has(ownDesc, 'value')){
	    if(ownDesc.writable === false || !isObject(receiver))return false;
	    existingDescriptor = $.getDesc(receiver, propertyKey) || createDesc(0);
	    existingDescriptor.value = V;
	    $.setDesc(receiver, propertyKey, existingDescriptor);
	    return true;
	  }
	  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);
	}
	
	$export($export.S, 'Reflect', {set: set});

/***/ },
/* 291 */
/***/ function(module, exports, __webpack_require__) {

	// 26.1.14 Reflect.setPrototypeOf(target, proto)
	var $export  = __webpack_require__(130)
	  , setProto = __webpack_require__(172);
	
	if(setProto)$export($export.S, 'Reflect', {
	  setPrototypeOf: function setPrototypeOf(target, proto){
	    setProto.check(target, proto);
	    try {
	      setProto.set(target, proto);
	      return true;
	    } catch(e){
	      return false;
	    }
	  }
	});

/***/ },
/* 292 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $export   = __webpack_require__(130)
	  , $includes = __webpack_require__(160)(true);
	
	$export($export.P, 'Array', {
	  // https://github.com/domenic/Array.prototype.includes
	  includes: function includes(el /*, fromIndex = 0 */){
	    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
	  }
	});
	
	__webpack_require__(245)('includes');

/***/ },
/* 293 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// https://github.com/mathiasbynens/String.prototype.at
	var $export = __webpack_require__(130)
	  , $at     = __webpack_require__(225)(true);
	
	$export($export.P, 'String', {
	  at: function at(pos){
	    return $at(this, pos);
	  }
	});

/***/ },
/* 294 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $export = __webpack_require__(130)
	  , $pad    = __webpack_require__(295);
	
	$export($export.P, 'String', {
	  padLeft: function padLeft(maxLength /*, fillString = ' ' */){
	    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
	  }
	});

/***/ },
/* 295 */
/***/ function(module, exports, __webpack_require__) {

	// https://github.com/ljharb/proposal-string-pad-left-right
	var toLength = __webpack_require__(154)
	  , repeat   = __webpack_require__(236)
	  , defined  = __webpack_require__(149);
	
	module.exports = function(that, maxLength, fillString, left){
	  var S            = String(defined(that))
	    , stringLength = S.length
	    , fillStr      = fillString === undefined ? ' ' : String(fillString)
	    , intMaxLength = toLength(maxLength);
	  if(intMaxLength <= stringLength)return S;
	  if(fillStr == '')fillStr = ' ';
	  var fillLen = intMaxLength - stringLength
	    , stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
	  if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen);
	  return left ? stringFiller + S : S + stringFiller;
	};

/***/ },
/* 296 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var $export = __webpack_require__(130)
	  , $pad    = __webpack_require__(295);
	
	$export($export.P, 'String', {
	  padRight: function padRight(maxLength /*, fillString = ' ' */){
	    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
	  }
	});

/***/ },
/* 297 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
	__webpack_require__(190)('trimLeft', function($trim){
	  return function trimLeft(){
	    return $trim(this, 1);
	  };
	});

/***/ },
/* 298 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
	__webpack_require__(190)('trimRight', function($trim){
	  return function trimRight(){
	    return $trim(this, 2);
	  };
	});

/***/ },
/* 299 */
/***/ function(module, exports, __webpack_require__) {

	// https://github.com/benjamingr/RexExp.escape
	var $export = __webpack_require__(130)
	  , $re     = __webpack_require__(300)(/[\\^$*+?.()|[\]{}]/g, '\\$&');
	
	$export($export.S, 'RegExp', {escape: function escape(it){ return $re(it); }});


/***/ },
/* 300 */
/***/ function(module, exports) {

	module.exports = function(regExp, replace){
	  var replacer = replace === Object(replace) ? function(part){
	    return replace[part];
	  } : replace;
	  return function(it){
	    return String(it).replace(regExp, replacer);
	  };
	};

/***/ },
/* 301 */
/***/ function(module, exports, __webpack_require__) {

	// https://gist.github.com/WebReflection/9353781
	var $          = __webpack_require__(129)
	  , $export    = __webpack_require__(130)
	  , ownKeys    = __webpack_require__(288)
	  , toIObject  = __webpack_require__(150)
	  , createDesc = __webpack_require__(134);
	
	$export($export.S, 'Object', {
	  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){
	    var O       = toIObject(object)
	      , setDesc = $.setDesc
	      , getDesc = $.getDesc
	      , keys    = ownKeys(O)
	      , result  = {}
	      , i       = 0
	      , key, D;
	    while(keys.length > i){
	      D = getDesc(O, key = keys[i++]);
	      if(key in result)setDesc(result, key, createDesc(0, D));
	      else result[key] = D;
	    } return result;
	  }
	});

/***/ },
/* 302 */
/***/ function(module, exports, __webpack_require__) {

	// http://goo.gl/XkBrjD
	var $export = __webpack_require__(130)
	  , $values = __webpack_require__(303)(false);
	
	$export($export.S, 'Object', {
	  values: function values(it){
	    return $values(it);
	  }
	});

/***/ },
/* 303 */
/***/ function(module, exports, __webpack_require__) {

	var $         = __webpack_require__(129)
	  , toIObject = __webpack_require__(150)
	  , isEnum    = $.isEnum;
	module.exports = function(isEntries){
	  return function(it){
	    var O      = toIObject(it)
	      , keys   = $.getKeys(O)
	      , length = keys.length
	      , i      = 0
	      , result = []
	      , key;
	    while(length > i)if(isEnum.call(O, key = keys[i++])){
	      result.push(isEntries ? [key, O[key]] : O[key]);
	    } return result;
	  };
	};

/***/ },
/* 304 */
/***/ function(module, exports, __webpack_require__) {

	// http://goo.gl/XkBrjD
	var $export  = __webpack_require__(130)
	  , $entries = __webpack_require__(303)(true);
	
	$export($export.S, 'Object', {
	  entries: function entries(it){
	    return $entries(it);
	  }
	});

/***/ },
/* 305 */
/***/ function(module, exports, __webpack_require__) {

	// https://github.com/DavidBruant/Map-Set.prototype.toJSON
	var $export  = __webpack_require__(130);
	
	$export($export.P, 'Map', {toJSON: __webpack_require__(306)('Map')});

/***/ },
/* 306 */
/***/ function(module, exports, __webpack_require__) {

	// https://github.com/DavidBruant/Map-Set.prototype.toJSON
	var forOf   = __webpack_require__(265)
	  , classof = __webpack_require__(174);
	module.exports = function(NAME){
	  return function toJSON(){
	    if(classof(this) != NAME)throw TypeError(NAME + "#toJSON isn't generic");
	    var arr = [];
	    forOf(this, false, arr.push, arr);
	    return arr;
	  };
	};

/***/ },
/* 307 */
/***/ function(module, exports, __webpack_require__) {

	// https://github.com/DavidBruant/Map-Set.prototype.toJSON
	var $export  = __webpack_require__(130);
	
	$export($export.P, 'Set', {toJSON: __webpack_require__(306)('Set')});

/***/ },
/* 308 */
/***/ function(module, exports, __webpack_require__) {

	// JavaScript 1.6 / Strawman array statics shim
	var $       = __webpack_require__(129)
	  , $export = __webpack_require__(130)
	  , $ctx    = __webpack_require__(139)
	  , $Array  = __webpack_require__(132).Array || Array
	  , statics = {};
	var setStatics = function(keys, length){
	  $.each.call(keys.split(','), function(key){
	    if(length == undefined && key in $Array)statics[key] = $Array[key];
	    else if(key in [])statics[key] = $ctx(Function.call, [][key], length);
	  });
	};
	setStatics('pop,reverse,shift,keys,values,entries', 1);
	setStatics('indexOf,every,some,forEach,map,filter,find,findIndex,includes', 3);
	setStatics('join,slice,concat,push,splice,unshift,sort,lastIndexOf,' +
	           'reduce,reduceRight,copyWithin,fill');
	$export($export.S, 'Array', statics);

/***/ },
/* 309 */
/***/ function(module, exports, __webpack_require__) {

	// ie9- setTimeout & setInterval additional parameters fix
	var global     = __webpack_require__(131)
	  , $export    = __webpack_require__(130)
	  , invoke     = __webpack_require__(146)
	  , partial    = __webpack_require__(310)
	  , navigator  = global.navigator
	  , MSIE       = !!navigator && /MSIE .\./.test(navigator.userAgent); // <- dirty ie9- check
	var wrap = function(set){
	  return MSIE ? function(fn, time /*, ...args */){
	    return set(invoke(
	      partial,
	      [].slice.call(arguments, 2),
	      typeof fn == 'function' ? fn : Function(fn)
	    ), time);
	  } : set;
	};
	$export($export.G + $export.B + $export.F * MSIE, {
	  setTimeout:  wrap(global.setTimeout),
	  setInterval: wrap(global.setInterval)
	});

/***/ },
/* 310 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	var path      = __webpack_require__(311)
	  , invoke    = __webpack_require__(146)
	  , aFunction = __webpack_require__(140);
	module.exports = function(/* ...pargs */){
	  var fn     = aFunction(this)
	    , length = arguments.length
	    , pargs  = Array(length)
	    , i      = 0
	    , _      = path._
	    , holder = false;
	  while(length > i)if((pargs[i] = arguments[i++]) === _)holder = true;
	  return function(/* ...args */){
	    var that  = this
	      , $$    = arguments
	      , $$len = $$.length
	      , j = 0, k = 0, args;
	    if(!holder && !$$len)return invoke(fn, pargs, that);
	    args = pargs.slice();
	    if(holder)for(;length > j; j++)if(args[j] === _)args[j] = $$[k++];
	    while($$len > k)args.push($$[k++]);
	    return invoke(fn, args, that);
	  };
	};

/***/ },
/* 311 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(131);

/***/ },
/* 312 */
/***/ function(module, exports, __webpack_require__) {

	var $export = __webpack_require__(130)
	  , $task   = __webpack_require__(268);
	$export($export.G + $export.B, {
	  setImmediate:   $task.set,
	  clearImmediate: $task.clear
	});

/***/ },
/* 313 */
/***/ function(module, exports, __webpack_require__) {

	__webpack_require__(244);
	var global      = __webpack_require__(131)
	  , hide        = __webpack_require__(133)
	  , Iterators   = __webpack_require__(227)
	  , ITERATOR    = __webpack_require__(158)('iterator')
	  , NL          = global.NodeList
	  , HTC         = global.HTMLCollection
	  , NLProto     = NL && NL.prototype
	  , HTCProto    = HTC && HTC.prototype
	  , ArrayValues = Iterators.NodeList = Iterators.HTMLCollection = Iterators.Array;
	if(NLProto && !NLProto[ITERATOR])hide(NLProto, ITERATOR, ArrayValues);
	if(HTCProto && !HTCProto[ITERATOR])hide(HTCProto, ITERATOR, ArrayValues);

/***/ },
/* 314 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global, process) {/**
	 * 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
	);
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(315)))

/***/ },
/* 315 */
/***/ function(module, exports) {

	// shim for using process in browser
	
	var process = module.exports = {};
	var queue = [];
	var draining = false;
	var currentQueue;
	var queueIndex = -1;
	
	function cleanUpNextTick() {
	    draining = false;
	    if (currentQueue.length) {
	        queue = currentQueue.concat(queue);
	    } else {
	        queueIndex = -1;
	    }
	    if (queue.length) {
	        drainQueue();
	    }
	}
	
	function drainQueue() {
	    if (draining) {
	        return;
	    }
	    var timeout = setTimeout(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;
	    clearTimeout(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) {
	        setTimeout(drainQueue, 0);
	    }
	};
	
	// 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.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; };


/***/ }
/******/ ]);
//# sourceMappingURL=ancillary.js.map
