Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have the chrome debugger run javascript within a web worker, to remove the global document. #1632

Closed
wants to merge 1 commit into from

Conversation

oveddan
Copy link
Contributor

@oveddan oveddan commented Jun 15, 2015

To make the chrome debugger environment consisten with the JSC executer environment,
where there is no window.document, make the chrome debugger run the javascript inside a web worker.

This fixes #1473

JSC executer environment, where there is no global.document,
make the chrome debugger run the javascript inside a web worker.

This fixes facebook#1473

Some issues:
- Ideally the websocket could be open inside the worker and communicated
  directly with it, but one of the messages requires access to
  localStorage, which is not accessable from within a worker.  So the
  socket is still loaded from the webpage itself, and messages that the
  worker should handle are forwarded to it.
- The worker does not have access to the global window object.  In a
  worker, the global scope is a DedicatedWorkerGlobalScope and can be
  accessed via `self`
@facebook-github-bot facebook-github-bot added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels Jun 15, 2015
@oveddan
Copy link
Contributor Author

oveddan commented Jun 15, 2015

Couple more things:

@@ -171,6 +171,10 @@ function getDevToolsLauncher(options) {
var debuggerPath = path.join(__dirname, 'debugger.html');
res.writeHead(200, {'Content-Type': 'text/html'});
fs.createReadStream(debuggerPath).pipe(res);
} else if (req.url === '/debuggerWorker.js') {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this belong here? The goal is to just serve a static js file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that seems like a decent way to do it

@brentvatne
Copy link
Collaborator

@jaredly - any chance you could review this?

@jaredly
Copy link
Contributor

jaredly commented Sep 15, 2015

Yeah, I'll take a look

@jaredly
Copy link
Contributor

jaredly commented Sep 16, 2015

@oveddan have you looked into how this effects performance? e.g. try animating a bunch of things, and see if it's noticeably slower using this method

@oveddan
Copy link
Contributor Author

oveddan commented Sep 16, 2015

@jaredly No I have not. Is there a sample project that would be good to run this on?

var object = message.data;

var sendReply = function(result) {
postMessage({replyID: object.id, result: result});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indent

@vjeux
Copy link
Contributor

vjeux commented Sep 23, 2015

@facebook-github-bot import

@facebook-github-bot
Copy link
Contributor

Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/366110346930126/int_phab to review.

@aleclarson
Copy link
Contributor

Does this affect accessing variables exposed via window (for debugging purposes)? Because I can't seem to do so.

@vjeux
Copy link
Contributor

vjeux commented Oct 20, 2015

@aleclarson you can change the drop down from top level to the worker and access global variables there

@aleclarson
Copy link
Contributor

Since this breaks the React dev tools, is it really worth keeping it?

@ide
Copy link
Contributor

ide commented Oct 27, 2015

Reverting this would break some people's apps during development. Best to fix the dev tools.

@aleclarson
Copy link
Contributor

Do you mean people are referencing window.document for feature detection? Just don't use libraries that want to touch window.document and you're golden. Either way, I'll just revert the PR in my fork since I'm not affected. Cheers 👍

MattFoley pushed a commit to skillz/react-native that referenced this pull request Nov 9, 2015
…e the global document.

Summary: To make the chrome debugger environment consisten with the JSC executer environment,
where there is no `window.document`, make the chrome debugger run the javascript inside a web worker.

This fixes facebook#1473
Closes facebook#1632

Reviewed By: @martinbigio

Differential Revision: D2471710

Pulled By: @vjeux
rayrutjes added a commit to algolia/algoliasearch-wordpress that referenced this pull request Nov 22, 2016
Resolves: #428

diff --git a/assets/js/algoliasearch/algoliasearch.jquery.js b/assets/js/algoliasearch/algoliasearch.jquery.js
index f44f614..877e5de 100644
--- a/assets/js/algoliasearch/algoliasearch.jquery.js
+++ b/assets/js/algoliasearch/algoliasearch.jquery.js
@@ -1,4 +1,4 @@
-/*! algoliasearch 3.18.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
+/*! algoliasearch 3.19.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
 (function(f){var g;if(typeof window!=='undefined'){g=window}else if(typeof self!=='undefined'){g=self}g.ALGOLIA_MIGRATION_LAYER=f()})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

 module.exports = function load (src, opts, cb) {
@@ -200,137 +200,6 @@ function migrationLayer(buildName) {

 },{"2":2,"3":3,"4":4}]},{},[5])(5)
 });(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- *  - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} options
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options){
-  options = options || {};
-  if ('string' == typeof val) return parse(val);
-  // long, short were "future reserved words in js", YUI compressor fail on them
-  // https://github.com/algolia/algoliasearch-client-js/issues/113#issuecomment-111978606
-  // https://github.com/yui/yuicompressor/issues/47
-  // https://github.com/rauchg/ms.js/pull/40
-  return options['long']
-    ? _long(val)
-    : _short(val);
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
-  str = '' + str;
-  if (str.length > 10000) return;
-  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
-  if (!match) return;
-  var n = parseFloat(match[1]);
-  var type = (match[2] || 'ms').toLowerCase();
-  switch (type) {
-    case 'years':
-    case 'year':
-    case 'yrs':
-    case 'yr':
-    case 'y':
-      return n * y;
-    case 'days':
-    case 'day':
-    case 'd':
-      return n * d;
-    case 'hours':
-    case 'hour':
-    case 'hrs':
-    case 'hr':
-    case 'h':
-      return n * h;
-    case 'minutes':
-    case 'minute':
-    case 'mins':
-    case 'min':
-    case 'm':
-      return n * m;
-    case 'seconds':
-    case 'second':
-    case 'secs':
-    case 'sec':
-    case 's':
-      return n * s;
-    case 'milliseconds':
-    case 'millisecond':
-    case 'msecs':
-    case 'msec':
-    case 'ms':
-      return n;
-  }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function _short(ms) {
-  if (ms >= d) return Math.round(ms / d) + 'd';
-  if (ms >= h) return Math.round(ms / h) + 'h';
-  if (ms >= m) return Math.round(ms / m) + 'm';
-  if (ms >= s) return Math.round(ms / s) + 's';
-  return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function _long(ms) {
-  return plural(ms, d, 'day')
-    || plural(ms, h, 'hour')
-    || plural(ms, m, 'minute')
-    || plural(ms, s, 'second')
-    || ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
-  if (ms < n) return;
-  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
-  return Math.ceil(ms / n) + ' ' + name + 's';
-}
-
-},{}],2:[function(require,module,exports){
 // shim for using process in browser
 var process = module.exports = {};

@@ -512,7 +381,8 @@ process.chdir = function (dir) {
 };
 process.umask = function() { return 0; };

-},{}],3:[function(require,module,exports){
+},{}],2:[function(require,module,exports){
+(function (process){

 /**
  * This is the web browser implementation of `debug()`.
@@ -520,7 +390,7 @@ process.umask = function() { return 0; };
  * Expose `debug()` as the module.
  */

-exports = module.exports = require(4);
+exports = module.exports = require(3);
 exports.log = log;
 exports.formatArgs = formatArgs;
 exports.save = save;
@@ -554,7 +424,8 @@ exports.colors = [

 function useColors() {
   // is webkit? http://stackoverflow.com/a/16459606/376773
-  return ('WebkitAppearance' in document.documentElement.style) ||
+  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
+  return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) ||
     // is firebug? http://stackoverflow.com/a/398120/376773
     (window.console && (console.firebug || (console.exception && console.table))) ||
     // is firefox >= v31?
@@ -656,6 +527,12 @@ function load() {
   try {
     r = exports.storage.debug;
   } catch(e) {}
+
+  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
+  if ('env' in (typeof process === 'undefined' ? {} : process)) {
+    r = process.env.DEBUG;
+  }
+
   return r;
 }

@@ -682,7 +559,8 @@ function localstorage(){
   } catch (e) {}
 }

-},{"4":4}],4:[function(require,module,exports){
+}).call(this,require(1))
+},{"1":1,"3":3}],3:[function(require,module,exports){

 /**
  * This is the common logic for both the Node.js and web browser
@@ -691,12 +569,12 @@ function localstorage(){
  * Expose `debug()` as the module.
  */

-exports = module.exports = debug;
+exports = module.exports = debug.debug = debug;
 exports.coerce = coerce;
 exports.disable = disable;
 exports.enable = enable;
 exports.enabled = enabled;
-exports.humanize = require(1);
+exports.humanize = require(4);

 /**
  * The currently active debug mode names, and names to skip.
@@ -768,7 +646,10 @@ function debug(namespace) {
     if (null == self.useColors) self.useColors = exports.useColors();
     if (null == self.color && self.useColors) self.color = selectColor();

-    var args = Array.prototype.slice.call(arguments);
+    var args = new Array(arguments.length);
+    for (var i = 0; i < args.length; i++) {
+      args[i] = arguments[i];
+    }

     args[0] = exports.coerce(args[0]);

@@ -795,9 +676,9 @@ function debug(namespace) {
       return match;
     });

-    if ('function' === typeof exports.formatArgs) {
-      args = exports.formatArgs.apply(self, args);
-    }
+    // apply env-specific formatting
+    args = exports.formatArgs.apply(self, args);
+
     var logFn = enabled.log || exports.log || console.log.bind(console);
     logFn.apply(self, args);
   }
@@ -826,7 +707,7 @@ function enable(namespaces) {

   for (var i = 0; i < len; i++) {
     if (!split[i]) continue; // ignore empty strings
-    namespaces = split[i].replace(/\*/g, '.*?');
+    namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?');
     if (namespaces[0] === '-') {
       exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
     } else {
@@ -881,7 +762,158 @@ function coerce(val) {
   return val;
 }

-},{"1":1}],5:[function(require,module,exports){
+},{"4":4}],4:[function(require,module,exports){
+/**
+ * Helpers.
+ */
+
+var s = 1000
+var m = s * 60
+var h = m * 60
+var d = h * 24
+var y = d * 365.25
+
+/**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ *  - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} options
+ * @throws {Error} throw an error if val is not a non-empty string or a number
+ * @return {String|Number}
+ * @api public
+ */
+
+module.exports = function (val, options) {
+  options = options || {}
+  var type = typeof val
+  if (type === 'string' && val.length > 0) {
+    return parse(val)
+  } else if (type === 'number' && isNaN(val) === false) {
+    return options.long ?
+			fmtLong(val) :
+			fmtShort(val)
+  }
+  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
+}
+
+/**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+function parse(str) {
+  str = String(str)
+  if (str.length > 10000) {
+    return
+  }
+  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
+  if (!match) {
+    return
+  }
+  var n = parseFloat(match[1])
+  var type = (match[2] || 'ms').toLowerCase()
+  switch (type) {
+    case 'years':
+    case 'year':
+    case 'yrs':
+    case 'yr':
+    case 'y':
+      return n * y
+    case 'days':
+    case 'day':
+    case 'd':
+      return n * d
+    case 'hours':
+    case 'hour':
+    case 'hrs':
+    case 'hr':
+    case 'h':
+      return n * h
+    case 'minutes':
+    case 'minute':
+    case 'mins':
+    case 'min':
+    case 'm':
+      return n * m
+    case 'seconds':
+    case 'second':
+    case 'secs':
+    case 'sec':
+    case 's':
+      return n * s
+    case 'milliseconds':
+    case 'millisecond':
+    case 'msecs':
+    case 'msec':
+    case 'ms':
+      return n
+    default:
+      return undefined
+  }
+}
+
+/**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function fmtShort(ms) {
+  if (ms >= d) {
+    return Math.round(ms / d) + 'd'
+  }
+  if (ms >= h) {
+    return Math.round(ms / h) + 'h'
+  }
+  if (ms >= m) {
+    return Math.round(ms / m) + 'm'
+  }
+  if (ms >= s) {
+    return Math.round(ms / s) + 's'
+  }
+  return ms + 'ms'
+}
+
+/**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function fmtLong(ms) {
+  return plural(ms, d, 'day') ||
+    plural(ms, h, 'hour') ||
+    plural(ms, m, 'minute') ||
+    plural(ms, s, 'second') ||
+    ms + ' ms'
+}
+
+/**
+ * Pluralization helper.
+ */
+
+function plural(ms, n, name) {
+  if (ms < n) {
+    return
+  }
+  if (ms < n * 1.5) {
+    return Math.floor(ms / n) + ' ' + name
+  }
+  return Math.ceil(ms / n) + ' ' + name + 's'
+}
+
+},{}],5:[function(require,module,exports){
 (function (process,global){
 /*!
  * @overview es6-promise - a tiny implementation of Promises/A+.
@@ -1843,8 +1875,8 @@ function coerce(val) {
 }).call(this);

-}).call(this,require(2),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"2":2}],6:[function(require,module,exports){
+}).call(this,require(1),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"1":1}],6:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -2218,6 +2250,167 @@ module.exports = Array.isArray || function (arr) {
 };

 },{}],11:[function(require,module,exports){
+'use strict';
+
+// modified from https://github.com/es-shims/es5-shim
+var has = Object.prototype.hasOwnProperty;
+var toStr = Object.prototype.toString;
+var slice = Array.prototype.slice;
+var isArgs = require(12);
+var isEnumerable = Object.prototype.propertyIsEnumerable;
+var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
+var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
+var dontEnums = [
+	'toString',
+	'toLocaleString',
+	'valueOf',
+	'hasOwnProperty',
+	'isPrototypeOf',
+	'propertyIsEnumerable',
+	'constructor'
+];
+var equalsConstructorPrototype = function (o) {
+	var ctor = o.constructor;
+	return ctor && ctor.prototype === o;
+};
+var excludedKeys = {
+	$console: true,
+	$external: true,
+	$frame: true,
+	$frameElement: true,
+	$frames: true,
+	$innerHeight: true,
+	$innerWidth: true,
+	$outerHeight: true,
+	$outerWidth: true,
+	$pageXOffset: true,
+	$pageYOffset: true,
+	$parent: true,
+	$scrollLeft: true,
+	$scrollTop: true,
+	$scrollX: true,
+	$scrollY: true,
+	$self: true,
+	$webkitIndexedDB: true,
+	$webkitStorageInfo: true,
+	$window: true
+};
+var hasAutomationEqualityBug = (function () {
+	/* global window */
+	if (typeof window === 'undefined') { return false; }
+	for (var k in window) {
+		try {
+			if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
+				try {
+					equalsConstructorPrototype(window[k]);
+				} catch (e) {
+					return true;
+				}
+			}
+		} catch (e) {
+			return true;
+		}
+	}
+	return false;
+}());
+var equalsConstructorPrototypeIfNotBuggy = function (o) {
+	/* global window */
+	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
+		return equalsConstructorPrototype(o);
+	}
+	try {
+		return equalsConstructorPrototype(o);
+	} catch (e) {
+		return false;
+	}
+};
+
+var keysShim = function keys(object) {
+	var isObject = object !== null && typeof object === 'object';
+	var isFunction = toStr.call(object) === '[object Function]';
+	var isArguments = isArgs(object);
+	var isString = isObject && toStr.call(object) === '[object String]';
+	var theKeys = [];
+
+	if (!isObject && !isFunction && !isArguments) {
+		throw new TypeError('Object.keys called on a non-object');
+	}
+
+	var skipProto = hasProtoEnumBug && isFunction;
+	if (isString && object.length > 0 && !has.call(object, 0)) {
+		for (var i = 0; i < object.length; ++i) {
+			theKeys.push(String(i));
+		}
+	}
+
+	if (isArguments && object.length > 0) {
+		for (var j = 0; j < object.length; ++j) {
+			theKeys.push(String(j));
+		}
+	} else {
+		for (var name in object) {
+			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
+				theKeys.push(String(name));
+			}
+		}
+	}
+
+	if (hasDontEnumBug) {
+		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+
+		for (var k = 0; k < dontEnums.length; ++k) {
+			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
+				theKeys.push(dontEnums[k]);
+			}
+		}
+	}
+	return theKeys;
+};
+
+keysShim.shim = function shimObjectKeys() {
+	if (Object.keys) {
+		var keysWorksWithArguments = (function () {
+			// Safari 5.0 bug
+			return (Object.keys(arguments) || '').length === 2;
+		}(1, 2));
+		if (!keysWorksWithArguments) {
+			var originalKeys = Object.keys;
+			Object.keys = function keys(object) {
+				if (isArgs(object)) {
+					return originalKeys(slice.call(object));
+				} else {
+					return originalKeys(object);
+				}
+			};
+		}
+	} else {
+		Object.keys = keysShim;
+	}
+	return Object.keys || keysShim;
+};
+
+module.exports = keysShim;
+
+},{"12":12}],12:[function(require,module,exports){
+'use strict';
+
+var toStr = Object.prototype.toString;
+
+module.exports = function isArguments(value) {
+	var str = toStr.call(value);
+	var isArgs = str === '[object Arguments]';
+	if (!isArgs) {
+		isArgs = str !== '[object Array]' &&
+			value !== null &&
+			typeof value === 'object' &&
+			typeof value.length === 'number' &&
+			value.length >= 0 &&
+			toStr.call(value.callee) === '[object Function]';
+	}
+	return isArgs;
+};
+
+},{}],13:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -2304,15 +2497,15 @@ var objectKeys = Object.keys || function (obj) {
   return res;
 };

-},{}],12:[function(require,module,exports){
+},{}],14:[function(require,module,exports){
 module.exports = AlgoliaSearch;

-var Index = require(14);
-var deprecate = require(25);
-var deprecatedMessage = require(26);
-var AlgoliaSearchCore = require(13);
+var Index = require(16);
+var deprecate = require(27);
+var deprecatedMessage = require(28);
+var AlgoliaSearchCore = require(15);
 var inherits = require(9);
-var errors = require(27);
+var errors = require(29);

 function AlgoliaSearch() {
   AlgoliaSearchCore.apply(this, arguments);
@@ -2393,7 +2586,7 @@ AlgoliaSearch.prototype.copyIndex = function(srcIndexName, dstIndexName, callbac
  *  content: the server answer that contains the task ID
  */
 AlgoliaSearch.prototype.getLogs = function(offset, length, callback) {
-  var clone = require(24);
+  var clone = require(26);
   var params = {};
   if (typeof offset === 'object') {
     // getLogs(params)
@@ -2764,12 +2957,12 @@ function notImplemented() {
   throw new errors.AlgoliaSearchError(message);
 }

-},{"10":10,"13":13,"14":14,"24":24,"25":25,"26":26,"27":27,"9":9}],13:[function(require,module,exports){
+},{"10":10,"15":15,"16":16,"26":26,"27":27,"28":28,"29":29,"9":9}],15:[function(require,module,exports){
 module.exports = AlgoliaSearchCore;

-var errors = require(27);
-var exitPromise = require(28);
-var IndexCore = require(16);
+var errors = require(29);
+var exitPromise = require(30);
+var IndexCore = require(18);

 // We will always put the API KEY in the JSON body in case of too long API KEY
 var MAX_API_KEY_LENGTH = 500;
@@ -2800,11 +2993,11 @@ var MAX_API_KEY_LENGTH = 500;
  *           If you provide them, you will less benefit from our HA implementation
  */
 function AlgoliaSearchCore(applicationID, apiKey, opts) {
-  var debug = require(3)('algoliasearch');
+  var debug = require(2)('algoliasearch');

-  var clone = require(24);
+  var clone = require(26);
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: algoliasearch(applicationID, apiKey, opts)';

@@ -2916,7 +3109,7 @@ AlgoliaSearchCore.prototype.addAlgoliaAgent = function(algoliaAgent) {
  * Wrapper that try all hosts to maximize the quality of service
  */
 AlgoliaSearchCore.prototype._jsonRequest = function(initialOpts) {
-  var requestDebug = require(3)('algoliasearch:' + initialOpts.url);
+  var requestDebug = require(2)('algoliasearch:' + initialOpts.url);

   var body;
   var cache = initialOpts.cache;
@@ -3246,7 +3439,7 @@ AlgoliaSearchCore.prototype._computeRequestHeaders = function(withAPIKey) {
  */
 AlgoliaSearchCore.prototype.search = function(queries, opts, callback) {
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: client.search(arrayOfQueries[, callback])';

@@ -3431,13 +3624,13 @@ function removeCredentials(headers) {
   return newHeaders;
 }

-},{"10":10,"16":16,"24":24,"27":27,"28":28,"29":29,"3":3,"7":7}],14:[function(require,module,exports){
+},{"10":10,"18":18,"2":2,"26":26,"29":29,"30":30,"31":31,"7":7}],16:[function(require,module,exports){
 var inherits = require(9);
-var IndexCore = require(16);
-var deprecate = require(25);
-var deprecatedMessage = require(26);
-var exitPromise = require(28);
-var errors = require(27);
+var IndexCore = require(18);
+var deprecate = require(27);
+var deprecatedMessage = require(28);
+var exitPromise = require(30);
+var errors = require(29);

 module.exports = Index;

@@ -3675,7 +3868,7 @@ Index.prototype.deleteObject = function(objectID, callback) {
 */
 Index.prototype.deleteObjects = function(objectIDs, callback) {
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: index.deleteObjects(arrayOfObjectIDs[, callback])';

@@ -3714,8 +3907,8 @@ Index.prototype.deleteObjects = function(objectIDs, callback) {
 *  error: null or Error('message')
 */
 Index.prototype.deleteByQuery = function(query, params, callback) {
-  var clone = require(24);
-  var map = require(29);
+  var clone = require(26);
+  var map = require(31);

   var indexObj = this;
   var client = indexObj.as;
@@ -3825,9 +4018,9 @@ Index.prototype.browseAll = function(query, queryParameters) {
     query = undefined;
   }

-  var merge = require(30);
+  var merge = require(32);

-  var IndexBrowser = require(15);
+  var IndexBrowser = require(17);

   var browser = new IndexBrowser();
   var client = this.as;
@@ -4408,7 +4601,7 @@ Index.prototype.updateUserKey = function(key, acls, params, callback) {
   });
 };

-},{"10":10,"15":15,"16":16,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"9":9}],15:[function(require,module,exports){
+},{"10":10,"17":17,"18":18,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"9":9}],17:[function(require,module,exports){
 'use strict';

 // This is the object returned by the `index.browseAll()` method
@@ -4449,8 +4642,8 @@ IndexBrowser.prototype._clean = function() {
   this.removeAllListeners('result');
 };

-},{"6":6,"9":9}],16:[function(require,module,exports){
-var buildSearchMethod = require(23);
+},{"6":6,"9":9}],18:[function(require,module,exports){
+var buildSearchMethod = require(25);

 module.exports = IndexCore;

@@ -4602,7 +4795,7 @@ IndexCore.prototype.similarSearch = buildSearchMethod('similarQuery');
 * @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
 */
 IndexCore.prototype.browse = function(query, queryParameters, callback) {
-  var merge = require(30);
+  var merge = require(32);

   var indexObj = this;

@@ -4682,6 +4875,43 @@ IndexCore.prototype.browseFrom = function(cursor, callback) {
   });
 };

+/*
+* Search in facets
+* https://www.algolia.com/doc/rest-api/search#search-in-a-facet
+*
+* @param {string} params.facetName Facet name, name of the attribute to search for values in.
+* Must be declared as a facet
+* @param {string} params.facetQuery Query for the facet search
+* @param {string} [params.*] Any search parameter of Algolia,
+* see https://www.algolia.com/doc/api-client/javascript/search#search-parameters
+* Pagination is not supported. The page and hitsPerPage parameters will be ignored.
+* @param callback (optional)
+*/
+IndexCore.prototype.searchFacet = function(params, callback) {
+  var clone = require(26);
+  var omit = require(33);
+  var usage = 'Usage: index.searchFacet({facetName, facetQuery, ...params}[, callback])';
+
+  if (params.facetName === undefined || params.facetQuery === undefined) {
+    throw new Error(usage);
+  }
+
+  var facetName = params.facetName;
+  var filteredParams = omit(clone(params), function(keyName) {
+    return keyName === 'facetName';
+  });
+  var searchParameters = this.as._getSearchParams(filteredParams, '');
+
+  return this.as._jsonRequest({
+    method: 'POST',
+    url: '/1/indexes/' +
+      encodeURIComponent(this.indexName) + '/facets/' + encodeURIComponent(facetName) + '/query',
+    hostType: 'read',
+    body: {params: searchParameters},
+    callback: callback
+  });
+};
+
 IndexCore.prototype._search = function(params, url, callback) {
   return this.as._jsonRequest({
     cache: this.cache,
@@ -4741,7 +4971,7 @@ IndexCore.prototype.getObject = function(objectID, attrs, callback) {
 */
 IndexCore.prototype.getObjects = function(objectIDs, attributesToRetrieve, callback) {
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: index.getObjects(arrayOfObjectIDs[, callback])';

@@ -4785,7 +5015,7 @@ IndexCore.prototype.indexName = null;
 IndexCore.prototype.typeAheadArgs = null;
 IndexCore.prototype.typeAheadValueOption = null;

-},{"10":10,"23":23,"29":29,"30":30}],17:[function(require,module,exports){
+},{"10":10,"25":25,"26":26,"31":31,"32":32,"33":33}],19:[function(require,module,exports){
 (function (process){
 'use strict';

@@ -4795,23 +5025,23 @@ IndexCore.prototype.typeAheadValueOption = null;

 var inherits = require(9);

-var AlgoliaSearch = require(12);
-var errors = require(27);
-var inlineHeaders = require(21);
-var jsonpRequest = require(22);
-var places = require(31);
+var AlgoliaSearch = require(14);
+var errors = require(29);
+var inlineHeaders = require(23);
+var jsonpRequest = require(24);
+var places = require(34);

 // expose original algoliasearch fn in window
-window.algoliasearch = require(18);
+window.algoliasearch = require(20);

 if (process.env.NODE_ENV === 'debug') {
-  require(3).enable('algoliasearch*');
+  require(2).enable('algoliasearch*');
 }

 function algoliasearch(applicationID, apiKey, opts) {
-  var cloneDeep = require(24);
+  var cloneDeep = require(26);

-  var getDocumentProtocol = require(20);
+  var getDocumentProtocol = require(22);

   opts = cloneDeep(opts || {});

@@ -4824,14 +5054,14 @@ function algoliasearch(applicationID, apiKey, opts) {
   return new AlgoliaSearchJQuery(applicationID, apiKey, opts);
 }

-algoliasearch.version = require(32);
+algoliasearch.version = require(35);
 algoliasearch.ua = 'Algolia for jQuery ' + algoliasearch.version;
 algoliasearch.initPlaces = places(algoliasearch);

 // we expose into window no matter how we are used, this will allow
 // us to easily debug any website running algolia
 window.__algolia = {
-  debug: require(3),
+  debug: require(2),
   algoliasearch: algoliasearch
 };

@@ -4938,16 +5168,16 @@ AlgoliaSearchJQuery.prototype._promise = {
   }
 };

-}).call(this,require(2))
-},{"12":12,"18":18,"2":2,"20":20,"21":21,"22":22,"24":24,"27":27,"3":3,"31":31,"32":32,"9":9}],18:[function(require,module,exports){
+}).call(this,require(1))
+},{"1":1,"14":14,"2":2,"20":20,"22":22,"23":23,"24":24,"26":26,"29":29,"34":34,"35":35,"9":9}],20:[function(require,module,exports){
 'use strict';

-var AlgoliaSearch = require(12);
-var createAlgoliasearch = require(19);
+var AlgoliaSearch = require(14);
+var createAlgoliasearch = require(21);

 module.exports = createAlgoliasearch(AlgoliaSearch);

-},{"12":12,"19":19}],19:[function(require,module,exports){
+},{"14":14,"21":21}],21:[function(require,module,exports){
 (function (process){
 'use strict';

@@ -4959,20 +5189,20 @@ var Promise = global.Promise || require(5).Promise;
 // using XMLHttpRequest, XDomainRequest and JSONP as fallback
 module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
   var inherits = require(9);
-  var errors = require(27);
-  var inlineHeaders = require(21);
-  var jsonpRequest = require(22);
-  var places = require(31);
+  var errors = require(29);
+  var inlineHeaders = require(23);
+  var jsonpRequest = require(24);
+  var places = require(34);
   uaSuffix = uaSuffix || '';

   if (process.env.NODE_ENV === 'debug') {
-    require(3).enable('algoliasearch*');
+    require(2).enable('algoliasearch*');
   }

   function algoliasearch(applicationID, apiKey, opts) {
-    var cloneDeep = require(24);
+    var cloneDeep = require(26);

-    var getDocumentProtocol = require(20);
+    var getDocumentProtocol = require(22);

     opts = cloneDeep(opts || {});

@@ -4985,14 +5215,14 @@ module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
     return new AlgoliaSearchBrowser(applicationID, apiKey, opts);
   }

-  algoliasearch.version = require(32);
+  algoliasearch.version = require(35);
   algoliasearch.ua = 'Algolia for vanilla JavaScript ' + uaSuffix + algoliasearch.version;
   algoliasearch.initPlaces = places(algoliasearch);

   // we expose into window no matter how we are used, this will allow
   // us to easily debug any website running algolia
   global.__algolia = {
-    debug: require(3),
+    debug: require(2),
     algoliasearch: algoliasearch
   };

@@ -5169,8 +5399,8 @@ module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
   return algoliasearch;
 };

-}).call(this,require(2))
-},{"2":2,"20":20,"21":21,"22":22,"24":24,"27":27,"3":3,"31":31,"32":32,"5":5,"8":8,"9":9}],20:[function(require,module,exports){
+}).call(this,require(1))
+},{"1":1,"2":2,"22":22,"23":23,"24":24,"26":26,"29":29,"34":34,"35":35,"5":5,"8":8,"9":9}],22:[function(require,module,exports){
 'use strict';

 module.exports = getDocumentProtocol;
@@ -5186,12 +5416,12 @@ function getDocumentProtocol() {
   return protocol;
 }

-},{}],21:[function(require,module,exports){
+},{}],23:[function(require,module,exports){
 'use strict';

 module.exports = inlineHeaders;

-var encode = require(11);
+var encode = require(13);

 function inlineHeaders(url, headers) {
   if (/\?/.test(url)) {
@@ -5203,12 +5433,12 @@ function inlineHeaders(url, headers) {
   return url + encode(headers);
 }

-},{"11":11}],22:[function(require,module,exports){
+},{"13":13}],24:[function(require,module,exports){
 'use strict';

 module.exports = jsonpRequest;

-var errors = require(27);
+var errors = require(29);

 var JSONPCounter = 0;

@@ -5330,10 +5560,10 @@ function jsonpRequest(url, opts, cb) {
   }
 }

-},{"27":27}],23:[function(require,module,exports){
+},{"29":29}],25:[function(require,module,exports){
 module.exports = buildSearchMethod;

-var errors = require(27);
+var errors = require(29);

 function buildSearchMethod(queryParam, url) {
   return function search(query, args, callback) {
@@ -5378,12 +5608,12 @@ function buildSearchMethod(queryParam, url) {
   };
 }

-},{"27":27}],24:[function(require,module,exports){
+},{"29":29}],26:[function(require,module,exports){
 module.exports = function clone(obj) {
   return JSON.parse(JSON.stringify(obj));
 };

-},{}],25:[function(require,module,exports){
+},{}],27:[function(require,module,exports){
 module.exports = function deprecate(fn, message) {
   var warned = false;

@@ -5400,7 +5630,7 @@ module.exports = function deprecate(fn, message) {
   return deprecated;
 };

-},{}],26:[function(require,module,exports){
+},{}],28:[function(require,module,exports){
 module.exports = function deprecatedMessage(previousUsage, newUsage) {
   var githubAnchorLink = previousUsage.toLowerCase()
     .replace('.', '')
@@ -5410,7 +5640,7 @@ module.exports = function deprecatedMessage(previousUsage, newUsage) {
     '`. Please see https://github.com/algolia/algoliasearch-client-js/wiki/Deprecated#' + githubAnchorLink;
 };

-},{}],27:[function(require,module,exports){
+},{}],29:[function(require,module,exports){
 'use strict';

 // This file hosts our error definitions
@@ -5490,7 +5720,7 @@ module.exports = {
   )
 };

-},{"7":7,"9":9}],28:[function(require,module,exports){
+},{"7":7,"9":9}],30:[function(require,module,exports){
 // Parse cloud does not supports setTimeout
 // We do not store a setTimeout reference in the client everytime
 // We only fallback to a fake setTimeout when not available
@@ -5499,7 +5729,7 @@ module.exports = function exitPromise(fn, _setTimeout) {
   _setTimeout(fn, 0);
 };

-},{}],29:[function(require,module,exports){
+},{}],31:[function(require,module,exports){
 var foreach = require(7);

 module.exports = function map(arr, fn) {
@@ -5510,7 +5740,7 @@ module.exports = function map(arr, fn) {
   return newArr;
 };

-},{"7":7}],30:[function(require,module,exports){
+},{"7":7}],32:[function(require,module,exports){
 var foreach = require(7);

 module.exports = function merge(destination/* , sources */) {
@@ -5531,14 +5761,30 @@ module.exports = function merge(destination/* , sources */) {
   return destination;
 };

-},{"7":7}],31:[function(require,module,exports){
+},{"7":7}],33:[function(require,module,exports){
+module.exports = function omit(obj, test) {
+  var keys = require(11);
+  var foreach = require(7);
+
+  var filtered = {};
+
+  foreach(keys(obj), function doFilter(keyName) {
+    if (test(keyName) !== true) {
+      filtered[keyName] = obj[keyName];
+    }
+  });
+
+  return filtered;
+};
+
+},{"11":11,"7":7}],34:[function(require,module,exports){
 module.exports = createPlacesClient;

-var buildSearchMethod = require(23);
+var buildSearchMethod = require(25);

 function createPlacesClient(algoliasearch) {
   return function places(appID, apiKey, opts) {
-    var cloneDeep = require(24);
+    var cloneDeep = require(26);

     opts = opts && cloneDeep(opts) || {};
     opts.hosts = opts.hosts || [
@@ -5562,9 +5808,9 @@ function createPlacesClient(algoliasearch) {
   };
 }

-},{"23":23,"24":24}],32:[function(require,module,exports){
+},{"25":25,"26":26}],35:[function(require,module,exports){
 'use strict';

-module.exports = '3.18.1';
+module.exports = '3.19.1';

-},{}]},{},[17]);
+},{}]},{},[19]);
diff --git a/assets/js/algoliasearch/algoliasearch.jquery.min.js b/assets/js/algoliasearch/algoliasearch.jquery.min.js
index e222164..d09f96a 100644
--- a/assets/js/algoliasearch/algoliasearch.jquery.min.js
+++ b/assets/js/algoliasearch/algoliasearch.jquery.min.js
@@ -1,3 +1,3 @@
-/*! algoliasearch 3.18.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
-!function(e){var t;"undefined"!=typeof window?t=window:"undefined"!=typeof self&&(t=self),t.ALGOLIA_MIGRATION_LAYER=e()}(function(){return function e(t,o,r){function n(i,a){if(!o[i]){if(!t[i]){var c="function"==typeof require&&require;if(!a&&c)return c(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=o[i]={exports:{}};t[i][0].call(l.exports,function(e){var o=t[i][1][e];return n(o?o:e)},l,l.exports,e,t,o,r)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i<r.length;i++)n(r[i]);return n}({1:[function(e,t,o){function r(e,t){for(var o in t)e.setAttribute(o,t[o])}function n(e,t){e.onload=function(){this.onerror=this.onload=null,t(null,e)},e.onerror=function(){this.onerror=this.onload=null,t(new Error("Failed to load "+this.src),e)}}function s(e,t){e.onreadystatechange=function(){"complete"!=this.readyState&&"loaded"!=this.readyState||(this.onreadystatechange=null,t(null,e))}}t.exports=function(e,t,o){var i=document.head||document.getElementsByTagName("head")[0],a=document.createElement("script");"function"==typeof t&&(o=t,t={}),t=t||{},o=o||function(){},a.type=t.type||"text/javascript",a.charset=t.charset||"utf8",a.async=!("async"in t)||!!t.async,a.src=e,t.attrs&&r(a,t.attrs),t.text&&(a.text=""+t.text);var c="onload"in a?n:s;c(a,o),a.onload||n(a,o),i.appendChild(a)}},{}],2:[function(e,t,o){"use strict";function r(e){for(var t=new RegExp("cdn\\.jsdelivr\\.net/algoliasearch/latest/"+e.replace(".","\\.")+"(?:\\.min)?\\.js$"),o=document.getElementsByTagName("script"),r=!1,n=0,s=o.length;n<s;n++)if(o[n].src&&t.test(o[n].src)){r=!0;break}return r}t.exports=r},{}],3:[function(e,t,o){"use strict";function r(t){var o=e(1),r="//cdn.jsdelivr.net/algoliasearch/2/"+t+".min.js",s="-- AlgoliaSearch `latest` warning --\nWarning, you are using the `latest` version string from jsDelivr to load the AlgoliaSearch library.\nUsing `latest` is no more recommended, you should load //cdn.jsdelivr.net/algoliasearch/2/algoliasearch.min.js\n\nAlso, we updated the AlgoliaSearch JavaScript client to V3. If you want to upgrade,\nplease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch  `latest` warning --";window.console&&(window.console.warn?window.console.warn(s):window.console.log&&window.console.log(s));try{document.write("<script>window.ALGOLIA_SUPPORTS_DOCWRITE = true</script>"),window.ALGOLIA_SUPPORTS_DOCWRITE===!0?(document.write('<script src="'+r+'"></script>'),n("document.write")()):o(r,n("DOMElement"))}catch(i){o(r,n("DOMElement"))}}function n(e){return function(){var t="AlgoliaSearch: loaded V2 script using "+e;window.console&&window.console.log&&window.console.log(t)}}t.exports=r},{1:1}],4:[function(e,t,o){"use strict";function r(){var e="-- AlgoliaSearch V2 => V3 error --\nYou are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\nPlease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch V2 => V3 error --";window.AlgoliaSearch=function(){throw new Error(e)},window.AlgoliaSearchHelper=function(){throw new Error(e)},window.AlgoliaExplainResults=function(){throw new Error(e)}}t.exports=r},{}],5:[function(e,t,o){"use strict";function r(t){var o=e(2),r=e(3),n=e(4);o(t)?r(t):n()}r("algoliasearch.jquery")},{2:2,3:3,4:4}]},{},[5])(5)}),function e(t,o,r){function n(i,a){if(!o[i]){if(!t[i]){var c="function"==typeof require&&require;if(!a&&c)return c(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=o[i]={exports:{}};t[i][0].call(l.exports,function(e){var o=t[i][1][e];return n(o?o:e)},l,l.exports,e,t,o,r)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i<r.length;i++)n(r[i]);return n}({1:[function(e,t,o){function r(e){if(e=""+e,!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var o=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return o*p;case"days":case"day":case"d":return o*l;case"hours":case"hour":case"hrs":case"hr":case"h":return o*u;case"minutes":case"minute":case"mins":case"min":case"m":return o*c;case"seconds":case"second":case"secs":case"sec":case"s":return o*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return o}}}}function n(e){return e>=l?Math.round(e/l)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function s(e){return i(e,l,"day")||i(e,u,"hour")||i(e,c,"minute")||i(e,a,"second")||e+" ms"}function i(e,t,o){if(!(e<t))return e<1.5*t?Math.floor(e/t)+" "+o:Math.ceil(e/t)+" "+o+"s"}var a=1e3,c=60*a,u=60*c,l=24*u,p=365.25*l;t.exports=function(e,t){return t=t||{},"string"==typeof e?r(e):t["long"]?s(e):n(e)}},{}],2:[function(e,t,o){function r(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function s(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function i(e){if(d===clearTimeout)return clearTimeout(e);if((d===n||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(e);try{return d(e)}catch(t){try{return d.call(null,e)}catch(t){return d.call(this,e)}}}function a(){m&&f&&(m=!1,f.length?y=f.concat(y):v=-1,y.length&&c())}function c(){if(!m){var e=s(a);m=!0;for(var t=y.length;t;){for(f=y,y=[];++v<t;)f&&f[v].run();v=-1,t=y.length}f=null,m=!1,i(e)}}function u(e,t){this.fun=e,this.array=t}function l(){}var p,d,h=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{d="function"==typeof clearTimeout?clearTimeout:n}catch(e){d=n}}();var f,y=[],m=!1,v=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var o=1;o<arguments.length;o++)t[o-1]=arguments[o];y.push(new u(e,t)),1!==y.length||m||s(c)},u.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=l,h.addListener=l,h.once=l,h.off=l,h.removeListener=l,h.removeAllListeners=l,h.emit=l,h.binding=function(e){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(e){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},{}],3:[function(e,t,o){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function n(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+o.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var n=0,s=0;return e[0].replace(/%[a-z%]/g,function(e){"%%"!==e&&(n++,"%c"===e&&(s=n))}),e.splice(s,0,r),e}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function i(e){try{null==e?o.storage.removeItem("debug"):o.storage.debug=e}catch(t){}}function a(){var e;try{e=o.storage.debug}catch(t){}return e}function c(){try{return window.localStorage}catch(e){}}o=t.exports=e(4),o.log=s,o.formatArgs=n,o.save=i,o.load=a,o.useColors=r,o.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:c(),o.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],o.formatters.j=function(e){return JSON.stringify(e)},o.enable(a())},{4:4}],4:[function(e,t,o){function r(){return o.colors[l++%o.colors.length]}function n(e){function t(){}function n(){var e=n,t=+new Date,s=t-(u||t);e.diff=s,e.prev=u,e.curr=t,u=t,null==e.useColors&&(e.useColors=o.useColors()),null==e.color&&e.useColors&&(e.color=r());var i=Array.prototype.slice.call(arguments);i[0]=o.coerce(i[0]),"string"!=typeof i[0]&&(i=["%o"].concat(i));var a=0;i[0]=i[0].replace(/%([a-z%])/g,function(t,r){if("%%"===t)return t;a++;var n=o.formatters[r];if("function"==typeof n){var s=i[a];t=n.call(e,s),i.splice(a,1),a--}return t}),"function"==typeof o.formatArgs&&(i=o.formatArgs.apply(e,i));var c=n.log||o.log||console.log.bind(console);c.apply(e,i)}t.enabled=!1,n.enabled=!0;var s=o.enabled(e)?n:t;return s.namespace=e,s}function s(e){o.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,n=0;n<r;n++)t[n]&&(e=t[n].replace(/\*/g,".*?"),"-"===e[0]?o.skips.push(new RegExp("^"+e.substr(1)+"$")):o.names.push(new RegExp("^"+e+"$")))}function i(){o.enable("")}function a(e){var t,r;for(t=0,r=o.skips.length;t<r;t++)if(o.skips[t].test(e))return!1;for(t=0,r=o.names.length;t<r;t++)if(o.names[t].test(e))return!0;return!1}function c(e){return e instanceof Error?e.stack||e.message:e}o=t.exports=n,o.coerce=c,o.disable=i,o.enable=s,o.enabled=a,o.humanize=e(1),o.names=[],o.skips=[],o.formatters={};var u,l=0},{1:1}],5:[function(e,t,o){(function(o,r){(function(){"use strict";function n(e){return"function"==typeof e||"object"==typeof e&&null!==e}function s(e){return"function"==typeof e}function i(e){X=e}function a(e){z=e}function c(){return function(){o.nextTick(h)}}function u(){return function(){V(h)}}function l(){var e=0,t=new te(h),o=document.createTextNode("");return t.observe(o,{characterData:!0}),function(){o.data=e=++e%2}}function p(){var e=new MessageChannel;return e.port1.onmessage=h,function(){e.port2.postMessage(0)}}function d(){return function(){setTimeout(h,1)}}function h(){for(var e=0;e<Y;e+=2){var t=ne[e],o=ne[e+1];t(o),ne[e]=void 0,ne[e+1]=void 0}Y=0}function f(){try{var t=e,o=t("vertx");return V=o.runOnLoop||o.runOnContext,u()}catch(r){return d()}}function y(e,t){var o=this,r=new this.constructor(v);void 0===r[ae]&&N(r);var n=o._state;if(n){var s=arguments[n-1];z(function(){U(n,r,s,o._result)})}else q(o,r,e,t);return r}function m(e){var t=this;if(e&&"object"==typeof e&&e.constructor===t)return e;var o=new t(v);return S(o,e),o}function v(){}function g(){return new TypeError("You cannot resolve a promise with itself")}function b(){return new TypeError("A promises callback cannot return that same promise.")}function w(e){try{return e.then}catch(t){return pe.error=t,pe}}function _(e,t,o,r){try{e.call(t,o,r)}catch(n){return n}}function x(e,t,o){z(function(e){var r=!1,n=_(o,t,function(o){r||(r=!0,t!==o?S(e,o):R(e,o))},function(t){r||(r=!0,O(e,t))},"Settle: "+(e._label||" unknown promise"));!r&&n&&(r=!0,O(e,n))},e)}function T(e,t){t._state===ue?R(e,t._result):t._state===le?O(e,t._result):q(t,void 0,function(t){S(e,t)},function(t){O(e,t)})}function j(e,t,o){t.constructor===e.constructor&&o===se&&constructor.resolve===ie?T(e,t):o===pe?O(e,pe.error):void 0===o?R(e,t):s(o)?x(e,t,o):R(e,t)}function S(e,t){e===t?O(e,g()):n(t)?j(e,t,w(t)):R(e,t)}function k(e){e._onerror&&e._onerror(e._result),P(e)}function R(e,t){e._state===ce&&(e._result=t,e._state=ue,0!==e._subscribers.length&&z(P,e))}function O(e,t){e._state===ce&&(e._state=le,e._result=t,z(k,e))}function q(e,t,o,r){var n=e._subscribers,s=n.length;e._onerror=null,n[s]=t,n[s+ue]=o,n[s+le]=r,0===s&&e._state&&z(P,e)}function P(e){var t=e._subscribers,o=e._state;if(0!==t.length){for(var r,n,s=e._result,i=0;i<t.length;i+=3)r=t[i],n=t[i+o],r?U(o,r,n,s):n(s);e._subscribers.length=0}}function E(){this.error=null}function I(e,t){try{return e(t)}catch(o){return de.error=o,de}}function U(e,t,o,r){var n,i,a,c,u=s(o);if(u){if(n=I(o,r),n===de?(c=!0,i=n.error,n=null):a=!0,t===n)return void O(t,b())}else n=r,a=!0;t._state!==ce||(u&&a?S(t,n):c?O(t,i):e===ue?R(t,n):e===le&&O(t,n))}function A(e,t){try{t(function(t){S(e,t)},function(t){O(e,t)})}catch(o){O(e,o)}}function C(){return he++}function N(e){e[ae]=he++,e._state=void 0,e._result=void 0,e._subscribers=[]}function L(e){return new ge(this,e).promise}function D(e){var t=this;return new t($(e)?function(o,r){for(var n=e.length,s=0;s<n;s++)t.resolve(e[s]).then(o,r)}:function(e,t){t(new TypeError("You must pass an array to race."))})}function H(e){var t=this,o=new t(v);return O(o,e),o}function M(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function J(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function K(e){this[ae]=C(),this._result=this._state=void 0,this._subscribers=[],v!==e&&("function"!=typeof e&&M(),this instanceof K?A(this,e):J())}function Q(e,t){this._instanceConstructor=e,this.promise=new e(v),this.promise[ae]||N(this.promise),$(t)?(this._input=t,this.length=t.length,this._remaining=t.length,this._result=new Array(this.length),0===this.length?R(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&R(this.promise,this._result))):O(this.promise,B())}function B(){return new Error("Array Methods must be provided an Array")}function F(){var e;if("undefined"!=typeof r)e=r;else if("undefined"!=typeof self)e=self;else try{e=Function("return this")()}catch(t){throw new Error("polyfill failed because global object is unavailable in this environment")}var o=e.Promise;o&&"[object Promise]"===Object.prototype.toString.call(o.resolve())&&!o.cast||(e.Promise=ve)}var G;G=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)};var V,X,W,$=G,Y=0,z=function(e,t){ne[Y]=e,ne[Y+1]=t,Y+=2,2===Y&&(X?X(h):W())},Z="undefined"!=typeof window?window:void 0,ee=Z||{},te=ee.MutationObserver||ee.WebKitMutationObserver,oe="undefined"==typeof self&&"undefined"!=typeof o&&"[object process]"==={}.toString.call(o),re="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,ne=new Array(1e3);W=oe?c():te?l():re?p():void 0===Z&&"function"==typeof e?f():d();var se=y,ie=m,ae=Math.random().toString(36).substring(16),ce=void 0,ue=1,le=2,pe=new E,de=new E,he=0,fe=L,ye=D,me=H,ve=K;K.all=fe,K.race=ye,K.resolve=ie,K.reject=me,K._setScheduler=i,K._setAsap=a,K._asap=z,K.prototype={constructor:K,then:se,"catch":function(e){return this.then(null,e)}};var ge=Q;Q.prototype._enumerate=function(){for(var e=this.length,t=this._input,o=0;this._state===ce&&o<e;o++)this._eachEntry(t[o],o)},Q.prototype._eachEntry=function(e,t){var o=this._instanceConstructor,r=o.resolve;if(r===ie){var n=w(e);if(n===se&&e._state!==ce)this._settledAt(e._state,t,e._result);else if("function"!=typeof n)this._remaining--,this._result[t]=e;else if(o===ve){var s=new o(v);j(s,e,n),this._willSettleAt(s,t)}else this._willSettleAt(new o(function(t){t(e)}),t)}else this._willSettleAt(r(e),t)},Q.prototype._settledAt=function(e,t,o){var r=this.promise;r._state===ce&&(this._remaining--,e===le?O(r,o):this._result[t]=o),0===this._remaining&&R(r,this._result)},Q.prototype._willSettleAt=function(e,t){var o=this;q(e,void 0,function(e){o._settledAt(ue,t,e)},function(e){o._settledAt(le,t,e)})};var be=F,we={Promise:ve,polyfill:be};"function"==typeof define&&define.amd?define(function(){return we}):"undefined"!=typeof t&&t.exports?t.exports=we:"undefined"!=typeof this&&(this.ES6Promise=we),be()}).call(this)}).call(this,e(2),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{2:2}],6:[function(e,t,o){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function n(e){return"function"==typeof e}function s(e){return"number"==typeof e}function i(e){return"object"==typeof e&&null!==e}function a(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,o,r,s,c,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var l=new Error('Uncaught, unspecified "error" event. ('+t+")");throw l.context=t,l}if(o=this._events[e],a(o))return!1;if(n(o))switch(arguments.length){case 1:o.call(this);break;case 2:o.call(this,arguments[1]);break;case 3:o.call(this,arguments[1],arguments[2]);break;default:s=Array.prototype.slice.call(arguments,1),o.apply(this,s)}else if(i(o))for(s=Array.prototype.slice.call(arguments,1),u=o.slice(),r=u.length,c=0;c<r;c++)u[c].apply(this,s);return!0},r.prototype.addListener=function(e,t){var o;if(!n(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,n(t.listener)?t.listener:t),this._events[e]?i(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,i(this._events[e])&&!this._events[e].warned&&(o=a(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,o&&o>0&&this._events[e].length>o&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function o(){this.removeListener(e,o),r||(r=!0,t.apply(this,arguments))}if(!n(t))throw TypeError("listener must be a function");var r=!1;return o.listener=t,this.on(e,o),this},r.prototype.removeListener=function(e,t){var o,r,s,a;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(o=this._events[e],s=o.length,r=-1,o===t||n(o.listener)&&o.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(i(o)){for(a=s;a-- >0;)if(o[a]===t||o[a].listener&&o[a].listener===t){r=a;break}if(r<0)return this;1===o.length?(o.length=0,delete this._events[e]):o.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,o;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(o=this._events[e],n(o))this.removeListener(e,o);else if(o)for(;o.length;)this.removeListener(e,o[o.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?n(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(n(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],7:[function(e,t,o){var r=Object.prototype.hasOwnProperty,n=Object.prototype.toString;t.exports=function(e,t,o){if("[object Function]"!==n.call(t))throw new TypeError("iterator must be a function");var s=e.length;if(s===+s)for(var i=0;i<s;i++)t.call(o,e[i],i,e);else for(var a in e)r.call(e,a)&&t.call(o,e[a],a,e)}},{}],8:[function(e,t,o){(function(e){"undefined"!=typeof window?t.exports=window:"undefined"!=typeof e?t.exports=e:"undefined"!=typeof self?t.exports=self:t.exports={}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],9:[function(e,t,o){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var o=function(){};o.prototype=t.prototype,e.prototype=new o,e.prototype.constructor=e}},{}],10:[function(e,t,o){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],11:[function(e,t,o){"use strict";function r(e,t){if(e.map)return e.map(t);for(var o=[],r=0;r<e.length;r++)o.push(t(e[r],r));return o}var n=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};t.exports=function(e,t,o,a){return t=t||"&",o=o||"=",null===e&&(e=void 0),"object"==typeof e?r(i(e),function(i){var a=encodeURIComponent(n(i))+o;return s(e[i])?r(e[i],function(e){return a+encodeURIComponent(n(e))}).join(t):a+encodeURIComponent(n(e[i]))}).join(t):a?encodeURIComponent(n(a))+o+encodeURIComponent(n(e)):""};var s=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},i=Object.keys||function(e){var t=[];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.push(o);return t}},{}],12:[function(e,t,o){function r(){c.apply(this,arguments)}function n(){var e="Not implemented in this environment.\nIf you feel this is a mistake, write to support@algolia.com";throw new l.AlgoliaSearchError(e)}t.exports=r;var s=e(14),i=e(25),a=e(26),c=e(13),u=e(9),l=e(27);u(r,c),r.prototype.deleteIndex=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(e),hostType:"write",callback:t})},r.prototype.moveIndex=function(e,t,o){var r={operation:"move",destination:t};return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:r,hostType:"write",callback:o})},r.prototype.copyIndex=function(e,t,o){var r={operation:"copy",destination:t};return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:r,hostType:"write",callback:o})},r.prototype.getLogs=function(t,o,r){var n=e(24),s={};return"object"==typeof t?(s=n(t),r=o):0===arguments.length||"function"==typeof t?r=t:1===arguments.length||"function"==typeof o?(r=o,s.offset=t):(s.offset=t,s.length=o),void 0===s.offset&&(s.offset=0),void 0===s.length&&(s.length=10),this._jsonRequest({method:"GET",url:"/1/logs?"+this._getSearchParams(s,""),hostType:"read",callback:r})},r.prototype.listIndexes=function(e,t){var o="";return void 0===e||"function"==typeof e?t=e:o="?page="+e,this._jsonRequest({method:"GET",url:"/1/indexes"+o,hostType:"read",callback:t})},r.prototype.initIndex=function(e){return new s(this,e)},r.prototype.listUserKeys=function(e){return this._jsonRequest({method:"GET",url:"/1/keys",hostType:"read",callback:e})},r.prototype.getUserKeyACL=function(e,t){return this._jsonRequest({method:"GET",url:"/1/keys/"+e,hostType:"read",callback:t})},r.prototype.deleteUserKey=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/keys/"+e,hostType:"write",callback:t})},r.prototype.addUserKey=function(t,o,r){var n=e(10),s="Usage: client.addUserKey(arrayOfAcls[, params, callback])";if(!n(t))throw new Error(s);1!==arguments.length&&"function"!=typeof o||(r=o,o=null);var i={acl:t};return o&&(i.validity=o.validity,i.maxQueriesPerIPPerHour=o.maxQueriesPerIPPerHour,i.maxHitsPerQuery=o.maxHitsPerQuery,i.indexes=o.indexes,i.description=o.description,o.queryParameters&&(i.queryParameters=this._getSearchParams(o.queryParameters,"")),i.referers=o.referers),this._jsonRequest({method:"POST",url:"/1/keys",body:i,hostType:"write",callback:r})},r.prototype.addUserKeyWithValidity=i(function(e,t,o){return this.addUserKey(e,t,o)},a("client.addUserKeyWithValidity()","client.addUserKey()")),r.prototype.updateUserKey=function(t,o,r,n){var s=e(10),i="Usage: client.updateUserKey(key, arrayOfAcls[, params, callback])";if(!s(o))throw new Error(i);2!==arguments.length&&"function"!=typeof r||(n=r,r=null);var a={acl:o};return r&&(a.validity=r.validity,a.maxQueriesPerIPPerHour=r.maxQueriesPerIPPerHour,a.maxHitsPerQuery=r.maxHitsPerQuery,a.indexes=r.indexes,a.description=r.description,r.queryParameters&&(a.queryParameters=this._getSearchParams(r.queryParameters,"")),a.referers=r.referers),this._jsonRequest({method:"PUT",url:"/1/keys/"+t,body:a,hostType:"write",callback:n})},r.prototype.startQueriesBatch=i(function(){this._batch=[]},a("client.startQueriesBatch()","client.search()")),r.prototype.addQueryInBatch=i(function(e,t,o){this._batch.push({indexName:e,query:t,params:o})},a("client.addQueryInBatch()","client.search()")),r.prototype.sendQueriesBatch=i(function(e){return this.search(this._batch,e)},a("client.sendQueriesBatch()","client.search()")),r.prototype.batch=function(t,o){var r=e(10),n="Usage: client.batch(operations[, callback])";if(!r(t))throw new Error(n);return this._jsonRequest({method:"POST",url:"/1/indexes/*/batch",body:{requests:t},hostType:"write",callback:o})},r.prototype.destroy=n,r.prototype.enableRateLimitForward=n,r.prototype.disableRateLimitForward=n,r.prototype.useSecuredAPIKey=n,r.prototype.disableSecuredAPIKey=n,r.prototype.generateSecuredApiKey=n},{10:10,13:13,14:14,24:24,25:25,26:26,27:27,9:9}],13:[function(e,t,o){function r(t,o,r){var s=e(3)("algoliasearch"),a=e(24),u=e(10),l=e(29),p="Usage: algoliasearch(applicationID, apiKey, opts)";if(r._allowEmptyCredentials!==!0&&!t)throw new c.AlgoliaSearchError("Please provide an application ID. "+p);if(r._allowEmptyCredentials!==!0&&!o)throw new c.AlgoliaSearchError("Please provide an API key. "+p);this.applicationID=t,this.apiKey=o;var d=i([this.applicationID+"-1.algolianet.com",this.applicationID+"-2.algolianet.com",this.applicationID+"-3.algolianet.com"]);this.hosts={read:[],write:[]},this.hostIndex={read:0,write:0},r=r||{};var h=r.protocol||"https:",f=void 0===r.timeout?2e3:r.timeout;if(/:$/.test(h)||(h+=":"),"http:"!==r.protocol&&"https:"!==r.protocol)throw new c.AlgoliaSearchError("protocol must be `http:` or `https:` (was `"+r.protocol+"`)");r.hosts?u(r.hosts)?(this.hosts.read=a(r.hosts),this.hosts.write=a(r.hosts)):(this.hosts.read=a(r.hosts.read),this.hosts.write=a(r.hosts.write)):(this.hosts.read=[this.applicationID+"-dsn.algolia.net"].concat(d),this.hosts.write=[this.applicationID+".algolia.net"].concat(d)),this.hosts.read=l(this.hosts.read,n(h)),this.hosts.write=l(this.hosts.write,n(h)),this.requestTimeout=f,this.extraHeaders=[],this.cache=r._cache||{},this._ua=r._ua,this._useCache=!(void 0!==r._useCache&&!r._cache)||r._useCache,this._useFallback=void 0===r.useFallback||r.useFallback,this._setTimeout=r._setTimeout,s("init done, %j",this)}function n(e){return function(t){return e+"//"+t.toLowerCase()}}function s(e){if(void 0===Array.prototype.toJSON)return JSON.stringify(e);var t=Array.prototype.toJSON;delete Array.prototype.toJSON;var o=JSON.stringify(e);return Array.prototype.toJSON=t,o}function i(e){for(var t,o,r=e.length;0!==r;)o=Math.floor(Math.random()*r),r-=1,t=e[r],e[r]=e[o],e[o]=t;return e}function a(e){var t={};for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var r;r="x-algolia-api-key"===o||"x-algolia-application-id"===o?"**hidden for security purposes**":e[o],t[o]=r}return t}t.exports=r;var c=e(27),u=e(28),l=e(16),p=500;r.prototype.initIndex=function(e){return new l(this,e)},r.prototype.setExtraHeader=function(e,t){this.extraHeaders.push({name:e.toLowerCase(),value:t})},r.prototype.addAlgoliaAgent=function(e){this._ua+=";"+e},r.prototype._jsonRequest=function(t){function o(e,u){function p(e){var t=e&&e.body&&e.body.message&&e.body.status||e.statusCode||e&&e.body&&200;i("received response: statusCode: %s, computed statusCode: %d, headers: %j",e.statusCode,t,e.headers);var o=2===Math.floor(t/100),s=new Date;if(m.push({currentHost:x,headers:a(n),content:r||null,contentLength:void 0!==r?r.length:null,method:u.method,timeout:u.timeout,url:u.url,startTime:_,endTime:s,duration:s-_,statusCode:t}),o)return d._useCache&&l&&(l[w]=e.responseText),e.body;var p=4!==Math.floor(t/100);if(p)return h+=1,g();i("unrecoverable error");var f=new c.AlgoliaSearchError(e.body&&e.body.message,{debugData:m,statusCode:t});return d._promise.reject(f)}function v(e){i("error: %s, stack: %s",e.message,e.stack);var o=new Date;return m.push({currentHost:x,headers:a(n),content:r||null,contentLength:void 0!==r?r.length:null,method:u.method,timeout:u.timeout,url:u.url,startTime:_,endTime:o,duration:o-_}),e instanceof c.AlgoliaSearchError||(e=new c.Unknown(e&&e.message,e)),h+=1,e instanceof c.Unknown||e instanceof c.UnparsableJSON||h>=d.hosts[t.hostType].length&&(f||!y)?(e.debugData=m,d._promise.reject(e)):e instanceof c.RequestTimeout?b():g()}function g(){return i("retrying request"),d.hostIndex[t.hostType]=(d.hostIndex[t.hostType]+1)%d.hosts[t.hostType].length,o(e,u)}function b(){return i("retrying request with higher timeout"),d.hostIndex[t.hostType]=(d.hostIndex[t.hostType]+1)%d.hosts[t.hostType].length,u.timeout=d.requestTimeout*(h+1),o(e,u)}var w,_=new Date;if(d._useCache&&(w=t.url),d._useCache&&r&&(w+="_body_"+u.body),d._useCache&&l&&void 0!==l[w])return i("serving response from cache"),d._promise.resolve(JSON.parse(l[w]));if(h>=d.hosts[t.hostType].length)return!y||f?(i("could not get any response"),d._promise.reject(new c.AlgoliaSearchError("Cannot connect to the AlgoliaSearch API. Send an email to support@algolia.com to report and resolve the issue. Application id was: "+d.applicationID,{debugData:m}))):(i("switching to fallback"),h=0,u.method=t.fallback.method,u.url=t.fallback.url,u.jsonBody=t.fallback.body,u.jsonBody&&(u.body=s(u.jsonBody)),n=d._computeRequestHeaders(),u.timeout=d.requestTimeout*(h+1),d.hostIndex[t.hostType]=0,f=!0,o(d._request.fallback,u));var x=d.hosts[t.hostType][d.hostIndex[t.hostType]],T=x+u.url,j={body:u.body,jsonBody:u.jsonBody,method:u.method,headers:n,timeout:u.timeout,debug:i};return i("method: %s, url: %s, headers: %j, timeout: %d",j.method,T,j.headers,j.timeout),e===d._request.fallback&&i("using fallback"),e.call(d,T,j).then(p,v)}var r,n,i=e(3)("algoliasearch:"+t.url),l=t.cache,d=this,h=0,f=!1,y=d._useFallback&&d._request.fallback&&t.fallback;this.apiKey.length>p&&void 0!==t.body&&(void 0!==t.body.params||void 0!==t.body.requests)?(t.body.apiKey=this.apiKey,n=this._computeRequestHeaders(!1)):n=this._computeRequestHeaders(),void 0!==t.body&&(r=s(t.body)),i("request start");var m=[],v=o(d._request,{url:t.url,method:t.method,body:r,jsonBody:t.body,timeout:d.requestTimeout*(h+1)});return t.callback?void v.then(function(e){u(function(){t.callback(null,e)},d._setTimeout||setTimeout)},function(e){u(function(){t.callback(e)},d._setTimeout||setTimeout)}):v},r.prototype._getSearchParams=function(e,t){if(void 0===e||null===e)return t;for(var o in e)null!==o&&void 0!==e[o]&&e.hasOwnProperty(o)&&(t+=""===t?"":"&",t+=o+"="+encodeURIComponent("[object Array]"===Object.prototype.toString.call(e[o])?s(e[o]):e[o]));return t},r.prototype._computeRequestHeaders=function(t){var o=e(7),r={"x-algolia-agent":this._ua,"x-algolia-application-id":this.applicationID};return t!==!1&&(r["x-algolia-api-key"]=this.apiKey),this.userToken&&(r["x-algolia-usertoken"]=this.userToken),this.securityTags&&(r["x-algolia-tagfilters"]=this.securityTags),this.extraHeaders&&o(this.extraHeaders,function(e){r[e.name]=e.value}),r},r.prototype.search=function(t,o,r){var n=e(10),s=e(29),i="Usage: client.search(arrayOfQueries[, callback])";if(!n(t))throw new Error(i);"function"==typeof o?(r=o,o={}):void 0===o&&(o={});var a=this,c={requests:s(t,function(e){var t="";return void 0!==e.query&&(t+="query="+encodeURIComponent(e.query)),{indexName:e.indexName,params:a._getSearchParams(e.params,t)}})},u=s(c.requests,function(e,t){return t+"="+encodeURIComponent("/1/indexes/"+encodeURIComponent(e.indexName)+"?"+e.params)}).join("&"),l="/1/indexes/*/queries";return void 0!==o.strategy&&(l+="?strategy="+o.strategy),this._jsonRequest({cache:this.cache,method:"POST",url:l,body:c,hostType:"read",fallback:{method:"GET",url:"/1/indexes/*",body:{params:u}},callback:r})},r.prototype.setSecurityTags=function(e){if("[object Array]"===Object.prototype.toString.call(e)){for(var t=[],o=0;o<e.length;++o)if("[object Array]"===Object.prototype.toString.call(e[o])){for(var r=[],n=0;n<e[o].length;++n)r.push(e[o][n]);
-t.push("("+r.join(",")+")")}else t.push(e[o]);e=t.join(",")}this.securityTags=e},r.prototype.setUserToken=function(e){this.userToken=e},r.prototype.clearCache=function(){this.cache={}},r.prototype.setRequestTimeout=function(e){e&&(this.requestTimeout=parseInt(e,10))}},{10:10,16:16,24:24,27:27,28:28,29:29,3:3,7:7}],14:[function(e,t,o){function r(){s.apply(this,arguments)}var n=e(9),s=e(16),i=e(25),a=e(26),c=e(28),u=e(27);t.exports=r,n(r,s),r.prototype.addObject=function(e,t,o){var…
rayrutjes added a commit to algolia/algoliasearch-wordpress that referenced this pull request Nov 22, 2016
Resolves: #428

diff --git a/assets/js/algoliasearch/algoliasearch.jquery.js b/assets/js/algoliasearch/algoliasearch.jquery.js
index f44f614..877e5de 100644
--- a/assets/js/algoliasearch/algoliasearch.jquery.js
+++ b/assets/js/algoliasearch/algoliasearch.jquery.js
@@ -1,4 +1,4 @@
-/*! algoliasearch 3.18.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
+/*! algoliasearch 3.19.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
 (function(f){var g;if(typeof window!=='undefined'){g=window}else if(typeof self!=='undefined'){g=self}g.ALGOLIA_MIGRATION_LAYER=f()})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

 module.exports = function load (src, opts, cb) {
@@ -200,137 +200,6 @@ function migrationLayer(buildName) {

 },{"2":2,"3":3,"4":4}]},{},[5])(5)
 });(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- *  - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} options
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options){
-  options = options || {};
-  if ('string' == typeof val) return parse(val);
-  // long, short were "future reserved words in js", YUI compressor fail on them
-  // https://github.com/algolia/algoliasearch-client-js/issues/113#issuecomment-111978606
-  // https://github.com/yui/yuicompressor/issues/47
-  // https://github.com/rauchg/ms.js/pull/40
-  return options['long']
-    ? _long(val)
-    : _short(val);
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
-  str = '' + str;
-  if (str.length > 10000) return;
-  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
-  if (!match) return;
-  var n = parseFloat(match[1]);
-  var type = (match[2] || 'ms').toLowerCase();
-  switch (type) {
-    case 'years':
-    case 'year':
-    case 'yrs':
-    case 'yr':
-    case 'y':
-      return n * y;
-    case 'days':
-    case 'day':
-    case 'd':
-      return n * d;
-    case 'hours':
-    case 'hour':
-    case 'hrs':
-    case 'hr':
-    case 'h':
-      return n * h;
-    case 'minutes':
-    case 'minute':
-    case 'mins':
-    case 'min':
-    case 'm':
-      return n * m;
-    case 'seconds':
-    case 'second':
-    case 'secs':
-    case 'sec':
-    case 's':
-      return n * s;
-    case 'milliseconds':
-    case 'millisecond':
-    case 'msecs':
-    case 'msec':
-    case 'ms':
-      return n;
-  }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function _short(ms) {
-  if (ms >= d) return Math.round(ms / d) + 'd';
-  if (ms >= h) return Math.round(ms / h) + 'h';
-  if (ms >= m) return Math.round(ms / m) + 'm';
-  if (ms >= s) return Math.round(ms / s) + 's';
-  return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function _long(ms) {
-  return plural(ms, d, 'day')
-    || plural(ms, h, 'hour')
-    || plural(ms, m, 'minute')
-    || plural(ms, s, 'second')
-    || ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
-  if (ms < n) return;
-  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
-  return Math.ceil(ms / n) + ' ' + name + 's';
-}
-
-},{}],2:[function(require,module,exports){
 // shim for using process in browser
 var process = module.exports = {};

@@ -512,7 +381,8 @@ process.chdir = function (dir) {
 };
 process.umask = function() { return 0; };

-},{}],3:[function(require,module,exports){
+},{}],2:[function(require,module,exports){
+(function (process){

 /**
  * This is the web browser implementation of `debug()`.
@@ -520,7 +390,7 @@ process.umask = function() { return 0; };
  * Expose `debug()` as the module.
  */

-exports = module.exports = require(4);
+exports = module.exports = require(3);
 exports.log = log;
 exports.formatArgs = formatArgs;
 exports.save = save;
@@ -554,7 +424,8 @@ exports.colors = [

 function useColors() {
   // is webkit? http://stackoverflow.com/a/16459606/376773
-  return ('WebkitAppearance' in document.documentElement.style) ||
+  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
+  return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) ||
     // is firebug? http://stackoverflow.com/a/398120/376773
     (window.console && (console.firebug || (console.exception && console.table))) ||
     // is firefox >= v31?
@@ -656,6 +527,12 @@ function load() {
   try {
     r = exports.storage.debug;
   } catch(e) {}
+
+  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
+  if ('env' in (typeof process === 'undefined' ? {} : process)) {
+    r = process.env.DEBUG;
+  }
+
   return r;
 }

@@ -682,7 +559,8 @@ function localstorage(){
   } catch (e) {}
 }

-},{"4":4}],4:[function(require,module,exports){
+}).call(this,require(1))
+},{"1":1,"3":3}],3:[function(require,module,exports){

 /**
  * This is the common logic for both the Node.js and web browser
@@ -691,12 +569,12 @@ function localstorage(){
  * Expose `debug()` as the module.
  */

-exports = module.exports = debug;
+exports = module.exports = debug.debug = debug;
 exports.coerce = coerce;
 exports.disable = disable;
 exports.enable = enable;
 exports.enabled = enabled;
-exports.humanize = require(1);
+exports.humanize = require(4);

 /**
  * The currently active debug mode names, and names to skip.
@@ -768,7 +646,10 @@ function debug(namespace) {
     if (null == self.useColors) self.useColors = exports.useColors();
     if (null == self.color && self.useColors) self.color = selectColor();

-    var args = Array.prototype.slice.call(arguments);
+    var args = new Array(arguments.length);
+    for (var i = 0; i < args.length; i++) {
+      args[i] = arguments[i];
+    }

     args[0] = exports.coerce(args[0]);

@@ -795,9 +676,9 @@ function debug(namespace) {
       return match;
     });

-    if ('function' === typeof exports.formatArgs) {
-      args = exports.formatArgs.apply(self, args);
-    }
+    // apply env-specific formatting
+    args = exports.formatArgs.apply(self, args);
+
     var logFn = enabled.log || exports.log || console.log.bind(console);
     logFn.apply(self, args);
   }
@@ -826,7 +707,7 @@ function enable(namespaces) {

   for (var i = 0; i < len; i++) {
     if (!split[i]) continue; // ignore empty strings
-    namespaces = split[i].replace(/\*/g, '.*?');
+    namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?');
     if (namespaces[0] === '-') {
       exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
     } else {
@@ -881,7 +762,158 @@ function coerce(val) {
   return val;
 }

-},{"1":1}],5:[function(require,module,exports){
+},{"4":4}],4:[function(require,module,exports){
+/**
+ * Helpers.
+ */
+
+var s = 1000
+var m = s * 60
+var h = m * 60
+var d = h * 24
+var y = d * 365.25
+
+/**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ *  - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} options
+ * @throws {Error} throw an error if val is not a non-empty string or a number
+ * @return {String|Number}
+ * @api public
+ */
+
+module.exports = function (val, options) {
+  options = options || {}
+  var type = typeof val
+  if (type === 'string' && val.length > 0) {
+    return parse(val)
+  } else if (type === 'number' && isNaN(val) === false) {
+    return options.long ?
+			fmtLong(val) :
+			fmtShort(val)
+  }
+  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
+}
+
+/**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+function parse(str) {
+  str = String(str)
+  if (str.length > 10000) {
+    return
+  }
+  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
+  if (!match) {
+    return
+  }
+  var n = parseFloat(match[1])
+  var type = (match[2] || 'ms').toLowerCase()
+  switch (type) {
+    case 'years':
+    case 'year':
+    case 'yrs':
+    case 'yr':
+    case 'y':
+      return n * y
+    case 'days':
+    case 'day':
+    case 'd':
+      return n * d
+    case 'hours':
+    case 'hour':
+    case 'hrs':
+    case 'hr':
+    case 'h':
+      return n * h
+    case 'minutes':
+    case 'minute':
+    case 'mins':
+    case 'min':
+    case 'm':
+      return n * m
+    case 'seconds':
+    case 'second':
+    case 'secs':
+    case 'sec':
+    case 's':
+      return n * s
+    case 'milliseconds':
+    case 'millisecond':
+    case 'msecs':
+    case 'msec':
+    case 'ms':
+      return n
+    default:
+      return undefined
+  }
+}
+
+/**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function fmtShort(ms) {
+  if (ms >= d) {
+    return Math.round(ms / d) + 'd'
+  }
+  if (ms >= h) {
+    return Math.round(ms / h) + 'h'
+  }
+  if (ms >= m) {
+    return Math.round(ms / m) + 'm'
+  }
+  if (ms >= s) {
+    return Math.round(ms / s) + 's'
+  }
+  return ms + 'ms'
+}
+
+/**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function fmtLong(ms) {
+  return plural(ms, d, 'day') ||
+    plural(ms, h, 'hour') ||
+    plural(ms, m, 'minute') ||
+    plural(ms, s, 'second') ||
+    ms + ' ms'
+}
+
+/**
+ * Pluralization helper.
+ */
+
+function plural(ms, n, name) {
+  if (ms < n) {
+    return
+  }
+  if (ms < n * 1.5) {
+    return Math.floor(ms / n) + ' ' + name
+  }
+  return Math.ceil(ms / n) + ' ' + name + 's'
+}
+
+},{}],5:[function(require,module,exports){
 (function (process,global){
 /*!
  * @overview es6-promise - a tiny implementation of Promises/A+.
@@ -1843,8 +1875,8 @@ function coerce(val) {
 }).call(this);

-}).call(this,require(2),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"2":2}],6:[function(require,module,exports){
+}).call(this,require(1),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"1":1}],6:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -2218,6 +2250,167 @@ module.exports = Array.isArray || function (arr) {
 };

 },{}],11:[function(require,module,exports){
+'use strict';
+
+// modified from https://github.com/es-shims/es5-shim
+var has = Object.prototype.hasOwnProperty;
+var toStr = Object.prototype.toString;
+var slice = Array.prototype.slice;
+var isArgs = require(12);
+var isEnumerable = Object.prototype.propertyIsEnumerable;
+var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
+var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
+var dontEnums = [
+	'toString',
+	'toLocaleString',
+	'valueOf',
+	'hasOwnProperty',
+	'isPrototypeOf',
+	'propertyIsEnumerable',
+	'constructor'
+];
+var equalsConstructorPrototype = function (o) {
+	var ctor = o.constructor;
+	return ctor && ctor.prototype === o;
+};
+var excludedKeys = {
+	$console: true,
+	$external: true,
+	$frame: true,
+	$frameElement: true,
+	$frames: true,
+	$innerHeight: true,
+	$innerWidth: true,
+	$outerHeight: true,
+	$outerWidth: true,
+	$pageXOffset: true,
+	$pageYOffset: true,
+	$parent: true,
+	$scrollLeft: true,
+	$scrollTop: true,
+	$scrollX: true,
+	$scrollY: true,
+	$self: true,
+	$webkitIndexedDB: true,
+	$webkitStorageInfo: true,
+	$window: true
+};
+var hasAutomationEqualityBug = (function () {
+	/* global window */
+	if (typeof window === 'undefined') { return false; }
+	for (var k in window) {
+		try {
+			if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
+				try {
+					equalsConstructorPrototype(window[k]);
+				} catch (e) {
+					return true;
+				}
+			}
+		} catch (e) {
+			return true;
+		}
+	}
+	return false;
+}());
+var equalsConstructorPrototypeIfNotBuggy = function (o) {
+	/* global window */
+	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
+		return equalsConstructorPrototype(o);
+	}
+	try {
+		return equalsConstructorPrototype(o);
+	} catch (e) {
+		return false;
+	}
+};
+
+var keysShim = function keys(object) {
+	var isObject = object !== null && typeof object === 'object';
+	var isFunction = toStr.call(object) === '[object Function]';
+	var isArguments = isArgs(object);
+	var isString = isObject && toStr.call(object) === '[object String]';
+	var theKeys = [];
+
+	if (!isObject && !isFunction && !isArguments) {
+		throw new TypeError('Object.keys called on a non-object');
+	}
+
+	var skipProto = hasProtoEnumBug && isFunction;
+	if (isString && object.length > 0 && !has.call(object, 0)) {
+		for (var i = 0; i < object.length; ++i) {
+			theKeys.push(String(i));
+		}
+	}
+
+	if (isArguments && object.length > 0) {
+		for (var j = 0; j < object.length; ++j) {
+			theKeys.push(String(j));
+		}
+	} else {
+		for (var name in object) {
+			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
+				theKeys.push(String(name));
+			}
+		}
+	}
+
+	if (hasDontEnumBug) {
+		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+
+		for (var k = 0; k < dontEnums.length; ++k) {
+			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
+				theKeys.push(dontEnums[k]);
+			}
+		}
+	}
+	return theKeys;
+};
+
+keysShim.shim = function shimObjectKeys() {
+	if (Object.keys) {
+		var keysWorksWithArguments = (function () {
+			// Safari 5.0 bug
+			return (Object.keys(arguments) || '').length === 2;
+		}(1, 2));
+		if (!keysWorksWithArguments) {
+			var originalKeys = Object.keys;
+			Object.keys = function keys(object) {
+				if (isArgs(object)) {
+					return originalKeys(slice.call(object));
+				} else {
+					return originalKeys(object);
+				}
+			};
+		}
+	} else {
+		Object.keys = keysShim;
+	}
+	return Object.keys || keysShim;
+};
+
+module.exports = keysShim;
+
+},{"12":12}],12:[function(require,module,exports){
+'use strict';
+
+var toStr = Object.prototype.toString;
+
+module.exports = function isArguments(value) {
+	var str = toStr.call(value);
+	var isArgs = str === '[object Arguments]';
+	if (!isArgs) {
+		isArgs = str !== '[object Array]' &&
+			value !== null &&
+			typeof value === 'object' &&
+			typeof value.length === 'number' &&
+			value.length >= 0 &&
+			toStr.call(value.callee) === '[object Function]';
+	}
+	return isArgs;
+};
+
+},{}],13:[function(require,module,exports){
 // Copyright Joyent, Inc. and other Node contributors.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
@@ -2304,15 +2497,15 @@ var objectKeys = Object.keys || function (obj) {
   return res;
 };

-},{}],12:[function(require,module,exports){
+},{}],14:[function(require,module,exports){
 module.exports = AlgoliaSearch;

-var Index = require(14);
-var deprecate = require(25);
-var deprecatedMessage = require(26);
-var AlgoliaSearchCore = require(13);
+var Index = require(16);
+var deprecate = require(27);
+var deprecatedMessage = require(28);
+var AlgoliaSearchCore = require(15);
 var inherits = require(9);
-var errors = require(27);
+var errors = require(29);

 function AlgoliaSearch() {
   AlgoliaSearchCore.apply(this, arguments);
@@ -2393,7 +2586,7 @@ AlgoliaSearch.prototype.copyIndex = function(srcIndexName, dstIndexName, callbac
  *  content: the server answer that contains the task ID
  */
 AlgoliaSearch.prototype.getLogs = function(offset, length, callback) {
-  var clone = require(24);
+  var clone = require(26);
   var params = {};
   if (typeof offset === 'object') {
     // getLogs(params)
@@ -2764,12 +2957,12 @@ function notImplemented() {
   throw new errors.AlgoliaSearchError(message);
 }

-},{"10":10,"13":13,"14":14,"24":24,"25":25,"26":26,"27":27,"9":9}],13:[function(require,module,exports){
+},{"10":10,"15":15,"16":16,"26":26,"27":27,"28":28,"29":29,"9":9}],15:[function(require,module,exports){
 module.exports = AlgoliaSearchCore;

-var errors = require(27);
-var exitPromise = require(28);
-var IndexCore = require(16);
+var errors = require(29);
+var exitPromise = require(30);
+var IndexCore = require(18);

 // We will always put the API KEY in the JSON body in case of too long API KEY
 var MAX_API_KEY_LENGTH = 500;
@@ -2800,11 +2993,11 @@ var MAX_API_KEY_LENGTH = 500;
  *           If you provide them, you will less benefit from our HA implementation
  */
 function AlgoliaSearchCore(applicationID, apiKey, opts) {
-  var debug = require(3)('algoliasearch');
+  var debug = require(2)('algoliasearch');

-  var clone = require(24);
+  var clone = require(26);
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: algoliasearch(applicationID, apiKey, opts)';

@@ -2916,7 +3109,7 @@ AlgoliaSearchCore.prototype.addAlgoliaAgent = function(algoliaAgent) {
  * Wrapper that try all hosts to maximize the quality of service
  */
 AlgoliaSearchCore.prototype._jsonRequest = function(initialOpts) {
-  var requestDebug = require(3)('algoliasearch:' + initialOpts.url);
+  var requestDebug = require(2)('algoliasearch:' + initialOpts.url);

   var body;
   var cache = initialOpts.cache;
@@ -3246,7 +3439,7 @@ AlgoliaSearchCore.prototype._computeRequestHeaders = function(withAPIKey) {
  */
 AlgoliaSearchCore.prototype.search = function(queries, opts, callback) {
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: client.search(arrayOfQueries[, callback])';

@@ -3431,13 +3624,13 @@ function removeCredentials(headers) {
   return newHeaders;
 }

-},{"10":10,"16":16,"24":24,"27":27,"28":28,"29":29,"3":3,"7":7}],14:[function(require,module,exports){
+},{"10":10,"18":18,"2":2,"26":26,"29":29,"30":30,"31":31,"7":7}],16:[function(require,module,exports){
 var inherits = require(9);
-var IndexCore = require(16);
-var deprecate = require(25);
-var deprecatedMessage = require(26);
-var exitPromise = require(28);
-var errors = require(27);
+var IndexCore = require(18);
+var deprecate = require(27);
+var deprecatedMessage = require(28);
+var exitPromise = require(30);
+var errors = require(29);

 module.exports = Index;

@@ -3675,7 +3868,7 @@ Index.prototype.deleteObject = function(objectID, callback) {
 */
 Index.prototype.deleteObjects = function(objectIDs, callback) {
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: index.deleteObjects(arrayOfObjectIDs[, callback])';

@@ -3714,8 +3907,8 @@ Index.prototype.deleteObjects = function(objectIDs, callback) {
 *  error: null or Error('message')
 */
 Index.prototype.deleteByQuery = function(query, params, callback) {
-  var clone = require(24);
-  var map = require(29);
+  var clone = require(26);
+  var map = require(31);

   var indexObj = this;
   var client = indexObj.as;
@@ -3825,9 +4018,9 @@ Index.prototype.browseAll = function(query, queryParameters) {
     query = undefined;
   }

-  var merge = require(30);
+  var merge = require(32);

-  var IndexBrowser = require(15);
+  var IndexBrowser = require(17);

   var browser = new IndexBrowser();
   var client = this.as;
@@ -4408,7 +4601,7 @@ Index.prototype.updateUserKey = function(key, acls, params, callback) {
   });
 };

-},{"10":10,"15":15,"16":16,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"9":9}],15:[function(require,module,exports){
+},{"10":10,"17":17,"18":18,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"9":9}],17:[function(require,module,exports){
 'use strict';

 // This is the object returned by the `index.browseAll()` method
@@ -4449,8 +4642,8 @@ IndexBrowser.prototype._clean = function() {
   this.removeAllListeners('result');
 };

-},{"6":6,"9":9}],16:[function(require,module,exports){
-var buildSearchMethod = require(23);
+},{"6":6,"9":9}],18:[function(require,module,exports){
+var buildSearchMethod = require(25);

 module.exports = IndexCore;

@@ -4602,7 +4795,7 @@ IndexCore.prototype.similarSearch = buildSearchMethod('similarQuery');
 * @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
 */
 IndexCore.prototype.browse = function(query, queryParameters, callback) {
-  var merge = require(30);
+  var merge = require(32);

   var indexObj = this;

@@ -4682,6 +4875,43 @@ IndexCore.prototype.browseFrom = function(cursor, callback) {
   });
 };

+/*
+* Search in facets
+* https://www.algolia.com/doc/rest-api/search#search-in-a-facet
+*
+* @param {string} params.facetName Facet name, name of the attribute to search for values in.
+* Must be declared as a facet
+* @param {string} params.facetQuery Query for the facet search
+* @param {string} [params.*] Any search parameter of Algolia,
+* see https://www.algolia.com/doc/api-client/javascript/search#search-parameters
+* Pagination is not supported. The page and hitsPerPage parameters will be ignored.
+* @param callback (optional)
+*/
+IndexCore.prototype.searchFacet = function(params, callback) {
+  var clone = require(26);
+  var omit = require(33);
+  var usage = 'Usage: index.searchFacet({facetName, facetQuery, ...params}[, callback])';
+
+  if (params.facetName === undefined || params.facetQuery === undefined) {
+    throw new Error(usage);
+  }
+
+  var facetName = params.facetName;
+  var filteredParams = omit(clone(params), function(keyName) {
+    return keyName === 'facetName';
+  });
+  var searchParameters = this.as._getSearchParams(filteredParams, '');
+
+  return this.as._jsonRequest({
+    method: 'POST',
+    url: '/1/indexes/' +
+      encodeURIComponent(this.indexName) + '/facets/' + encodeURIComponent(facetName) + '/query',
+    hostType: 'read',
+    body: {params: searchParameters},
+    callback: callback
+  });
+};
+
 IndexCore.prototype._search = function(params, url, callback) {
   return this.as._jsonRequest({
     cache: this.cache,
@@ -4741,7 +4971,7 @@ IndexCore.prototype.getObject = function(objectID, attrs, callback) {
 */
 IndexCore.prototype.getObjects = function(objectIDs, attributesToRetrieve, callback) {
   var isArray = require(10);
-  var map = require(29);
+  var map = require(31);

   var usage = 'Usage: index.getObjects(arrayOfObjectIDs[, callback])';

@@ -4785,7 +5015,7 @@ IndexCore.prototype.indexName = null;
 IndexCore.prototype.typeAheadArgs = null;
 IndexCore.prototype.typeAheadValueOption = null;

-},{"10":10,"23":23,"29":29,"30":30}],17:[function(require,module,exports){
+},{"10":10,"25":25,"26":26,"31":31,"32":32,"33":33}],19:[function(require,module,exports){
 (function (process){
 'use strict';

@@ -4795,23 +5025,23 @@ IndexCore.prototype.typeAheadValueOption = null;

 var inherits = require(9);

-var AlgoliaSearch = require(12);
-var errors = require(27);
-var inlineHeaders = require(21);
-var jsonpRequest = require(22);
-var places = require(31);
+var AlgoliaSearch = require(14);
+var errors = require(29);
+var inlineHeaders = require(23);
+var jsonpRequest = require(24);
+var places = require(34);

 // expose original algoliasearch fn in window
-window.algoliasearch = require(18);
+window.algoliasearch = require(20);

 if (process.env.NODE_ENV === 'debug') {
-  require(3).enable('algoliasearch*');
+  require(2).enable('algoliasearch*');
 }

 function algoliasearch(applicationID, apiKey, opts) {
-  var cloneDeep = require(24);
+  var cloneDeep = require(26);

-  var getDocumentProtocol = require(20);
+  var getDocumentProtocol = require(22);

   opts = cloneDeep(opts || {});

@@ -4824,14 +5054,14 @@ function algoliasearch(applicationID, apiKey, opts) {
   return new AlgoliaSearchJQuery(applicationID, apiKey, opts);
 }

-algoliasearch.version = require(32);
+algoliasearch.version = require(35);
 algoliasearch.ua = 'Algolia for jQuery ' + algoliasearch.version;
 algoliasearch.initPlaces = places(algoliasearch);

 // we expose into window no matter how we are used, this will allow
 // us to easily debug any website running algolia
 window.__algolia = {
-  debug: require(3),
+  debug: require(2),
   algoliasearch: algoliasearch
 };

@@ -4938,16 +5168,16 @@ AlgoliaSearchJQuery.prototype._promise = {
   }
 };

-}).call(this,require(2))
-},{"12":12,"18":18,"2":2,"20":20,"21":21,"22":22,"24":24,"27":27,"3":3,"31":31,"32":32,"9":9}],18:[function(require,module,exports){
+}).call(this,require(1))
+},{"1":1,"14":14,"2":2,"20":20,"22":22,"23":23,"24":24,"26":26,"29":29,"34":34,"35":35,"9":9}],20:[function(require,module,exports){
 'use strict';

-var AlgoliaSearch = require(12);
-var createAlgoliasearch = require(19);
+var AlgoliaSearch = require(14);
+var createAlgoliasearch = require(21);

 module.exports = createAlgoliasearch(AlgoliaSearch);

-},{"12":12,"19":19}],19:[function(require,module,exports){
+},{"14":14,"21":21}],21:[function(require,module,exports){
 (function (process){
 'use strict';

@@ -4959,20 +5189,20 @@ var Promise = global.Promise || require(5).Promise;
 // using XMLHttpRequest, XDomainRequest and JSONP as fallback
 module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
   var inherits = require(9);
-  var errors = require(27);
-  var inlineHeaders = require(21);
-  var jsonpRequest = require(22);
-  var places = require(31);
+  var errors = require(29);
+  var inlineHeaders = require(23);
+  var jsonpRequest = require(24);
+  var places = require(34);
   uaSuffix = uaSuffix || '';

   if (process.env.NODE_ENV === 'debug') {
-    require(3).enable('algoliasearch*');
+    require(2).enable('algoliasearch*');
   }

   function algoliasearch(applicationID, apiKey, opts) {
-    var cloneDeep = require(24);
+    var cloneDeep = require(26);

-    var getDocumentProtocol = require(20);
+    var getDocumentProtocol = require(22);

     opts = cloneDeep(opts || {});

@@ -4985,14 +5215,14 @@ module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
     return new AlgoliaSearchBrowser(applicationID, apiKey, opts);
   }

-  algoliasearch.version = require(32);
+  algoliasearch.version = require(35);
   algoliasearch.ua = 'Algolia for vanilla JavaScript ' + uaSuffix + algoliasearch.version;
   algoliasearch.initPlaces = places(algoliasearch);

   // we expose into window no matter how we are used, this will allow
   // us to easily debug any website running algolia
   global.__algolia = {
-    debug: require(3),
+    debug: require(2),
     algoliasearch: algoliasearch
   };

@@ -5169,8 +5399,8 @@ module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
   return algoliasearch;
 };

-}).call(this,require(2))
-},{"2":2,"20":20,"21":21,"22":22,"24":24,"27":27,"3":3,"31":31,"32":32,"5":5,"8":8,"9":9}],20:[function(require,module,exports){
+}).call(this,require(1))
+},{"1":1,"2":2,"22":22,"23":23,"24":24,"26":26,"29":29,"34":34,"35":35,"5":5,"8":8,"9":9}],22:[function(require,module,exports){
 'use strict';

 module.exports = getDocumentProtocol;
@@ -5186,12 +5416,12 @@ function getDocumentProtocol() {
   return protocol;
 }

-},{}],21:[function(require,module,exports){
+},{}],23:[function(require,module,exports){
 'use strict';

 module.exports = inlineHeaders;

-var encode = require(11);
+var encode = require(13);

 function inlineHeaders(url, headers) {
   if (/\?/.test(url)) {
@@ -5203,12 +5433,12 @@ function inlineHeaders(url, headers) {
   return url + encode(headers);
 }

-},{"11":11}],22:[function(require,module,exports){
+},{"13":13}],24:[function(require,module,exports){
 'use strict';

 module.exports = jsonpRequest;

-var errors = require(27);
+var errors = require(29);

 var JSONPCounter = 0;

@@ -5330,10 +5560,10 @@ function jsonpRequest(url, opts, cb) {
   }
 }

-},{"27":27}],23:[function(require,module,exports){
+},{"29":29}],25:[function(require,module,exports){
 module.exports = buildSearchMethod;

-var errors = require(27);
+var errors = require(29);

 function buildSearchMethod(queryParam, url) {
   return function search(query, args, callback) {
@@ -5378,12 +5608,12 @@ function buildSearchMethod(queryParam, url) {
   };
 }

-},{"27":27}],24:[function(require,module,exports){
+},{"29":29}],26:[function(require,module,exports){
 module.exports = function clone(obj) {
   return JSON.parse(JSON.stringify(obj));
 };

-},{}],25:[function(require,module,exports){
+},{}],27:[function(require,module,exports){
 module.exports = function deprecate(fn, message) {
   var warned = false;

@@ -5400,7 +5630,7 @@ module.exports = function deprecate(fn, message) {
   return deprecated;
 };

-},{}],26:[function(require,module,exports){
+},{}],28:[function(require,module,exports){
 module.exports = function deprecatedMessage(previousUsage, newUsage) {
   var githubAnchorLink = previousUsage.toLowerCase()
     .replace('.', '')
@@ -5410,7 +5640,7 @@ module.exports = function deprecatedMessage(previousUsage, newUsage) {
     '`. Please see https://github.com/algolia/algoliasearch-client-js/wiki/Deprecated#' + githubAnchorLink;
 };

-},{}],27:[function(require,module,exports){
+},{}],29:[function(require,module,exports){
 'use strict';

 // This file hosts our error definitions
@@ -5490,7 +5720,7 @@ module.exports = {
   )
 };

-},{"7":7,"9":9}],28:[function(require,module,exports){
+},{"7":7,"9":9}],30:[function(require,module,exports){
 // Parse cloud does not supports setTimeout
 // We do not store a setTimeout reference in the client everytime
 // We only fallback to a fake setTimeout when not available
@@ -5499,7 +5729,7 @@ module.exports = function exitPromise(fn, _setTimeout) {
   _setTimeout(fn, 0);
 };

-},{}],29:[function(require,module,exports){
+},{}],31:[function(require,module,exports){
 var foreach = require(7);

 module.exports = function map(arr, fn) {
@@ -5510,7 +5740,7 @@ module.exports = function map(arr, fn) {
   return newArr;
 };

-},{"7":7}],30:[function(require,module,exports){
+},{"7":7}],32:[function(require,module,exports){
 var foreach = require(7);

 module.exports = function merge(destination/* , sources */) {
@@ -5531,14 +5761,30 @@ module.exports = function merge(destination/* , sources */) {
   return destination;
 };

-},{"7":7}],31:[function(require,module,exports){
+},{"7":7}],33:[function(require,module,exports){
+module.exports = function omit(obj, test) {
+  var keys = require(11);
+  var foreach = require(7);
+
+  var filtered = {};
+
+  foreach(keys(obj), function doFilter(keyName) {
+    if (test(keyName) !== true) {
+      filtered[keyName] = obj[keyName];
+    }
+  });
+
+  return filtered;
+};
+
+},{"11":11,"7":7}],34:[function(require,module,exports){
 module.exports = createPlacesClient;

-var buildSearchMethod = require(23);
+var buildSearchMethod = require(25);

 function createPlacesClient(algoliasearch) {
   return function places(appID, apiKey, opts) {
-    var cloneDeep = require(24);
+    var cloneDeep = require(26);

     opts = opts && cloneDeep(opts) || {};
     opts.hosts = opts.hosts || [
@@ -5562,9 +5808,9 @@ function createPlacesClient(algoliasearch) {
   };
 }

-},{"23":23,"24":24}],32:[function(require,module,exports){
+},{"25":25,"26":26}],35:[function(require,module,exports){
 'use strict';

-module.exports = '3.18.1';
+module.exports = '3.19.1';

-},{}]},{},[17]);
+},{}]},{},[19]);
diff --git a/assets/js/algoliasearch/algoliasearch.jquery.min.js b/assets/js/algoliasearch/algoliasearch.jquery.min.js
index e222164..d09f96a 100644
--- a/assets/js/algoliasearch/algoliasearch.jquery.min.js
+++ b/assets/js/algoliasearch/algoliasearch.jquery.min.js
@@ -1,3 +1,3 @@
-/*! algoliasearch 3.18.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
-!function(e){var t;"undefined"!=typeof window?t=window:"undefined"!=typeof self&&(t=self),t.ALGOLIA_MIGRATION_LAYER=e()}(function(){return function e(t,o,r){function n(i,a){if(!o[i]){if(!t[i]){var c="function"==typeof require&&require;if(!a&&c)return c(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=o[i]={exports:{}};t[i][0].call(l.exports,function(e){var o=t[i][1][e];return n(o?o:e)},l,l.exports,e,t,o,r)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i<r.length;i++)n(r[i]);return n}({1:[function(e,t,o){function r(e,t){for(var o in t)e.setAttribute(o,t[o])}function n(e,t){e.onload=function(){this.onerror=this.onload=null,t(null,e)},e.onerror=function(){this.onerror=this.onload=null,t(new Error("Failed to load "+this.src),e)}}function s(e,t){e.onreadystatechange=function(){"complete"!=this.readyState&&"loaded"!=this.readyState||(this.onreadystatechange=null,t(null,e))}}t.exports=function(e,t,o){var i=document.head||document.getElementsByTagName("head")[0],a=document.createElement("script");"function"==typeof t&&(o=t,t={}),t=t||{},o=o||function(){},a.type=t.type||"text/javascript",a.charset=t.charset||"utf8",a.async=!("async"in t)||!!t.async,a.src=e,t.attrs&&r(a,t.attrs),t.text&&(a.text=""+t.text);var c="onload"in a?n:s;c(a,o),a.onload||n(a,o),i.appendChild(a)}},{}],2:[function(e,t,o){"use strict";function r(e){for(var t=new RegExp("cdn\\.jsdelivr\\.net/algoliasearch/latest/"+e.replace(".","\\.")+"(?:\\.min)?\\.js$"),o=document.getElementsByTagName("script"),r=!1,n=0,s=o.length;n<s;n++)if(o[n].src&&t.test(o[n].src)){r=!0;break}return r}t.exports=r},{}],3:[function(e,t,o){"use strict";function r(t){var o=e(1),r="//cdn.jsdelivr.net/algoliasearch/2/"+t+".min.js",s="-- AlgoliaSearch `latest` warning --\nWarning, you are using the `latest` version string from jsDelivr to load the AlgoliaSearch library.\nUsing `latest` is no more recommended, you should load //cdn.jsdelivr.net/algoliasearch/2/algoliasearch.min.js\n\nAlso, we updated the AlgoliaSearch JavaScript client to V3. If you want to upgrade,\nplease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch  `latest` warning --";window.console&&(window.console.warn?window.console.warn(s):window.console.log&&window.console.log(s));try{document.write("<script>window.ALGOLIA_SUPPORTS_DOCWRITE = true</script>"),window.ALGOLIA_SUPPORTS_DOCWRITE===!0?(document.write('<script src="'+r+'"></script>'),n("document.write")()):o(r,n("DOMElement"))}catch(i){o(r,n("DOMElement"))}}function n(e){return function(){var t="AlgoliaSearch: loaded V2 script using "+e;window.console&&window.console.log&&window.console.log(t)}}t.exports=r},{1:1}],4:[function(e,t,o){"use strict";function r(){var e="-- AlgoliaSearch V2 => V3 error --\nYou are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\nPlease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch V2 => V3 error --";window.AlgoliaSearch=function(){throw new Error(e)},window.AlgoliaSearchHelper=function(){throw new Error(e)},window.AlgoliaExplainResults=function(){throw new Error(e)}}t.exports=r},{}],5:[function(e,t,o){"use strict";function r(t){var o=e(2),r=e(3),n=e(4);o(t)?r(t):n()}r("algoliasearch.jquery")},{2:2,3:3,4:4}]},{},[5])(5)}),function e(t,o,r){function n(i,a){if(!o[i]){if(!t[i]){var c="function"==typeof require&&require;if(!a&&c)return c(i,!0);if(s)return s(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=o[i]={exports:{}};t[i][0].call(l.exports,function(e){var o=t[i][1][e];return n(o?o:e)},l,l.exports,e,t,o,r)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i<r.length;i++)n(r[i]);return n}({1:[function(e,t,o){function r(e){if(e=""+e,!(e.length>1e4)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var o=parseFloat(t[1]),r=(t[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return o*p;case"days":case"day":case"d":return o*l;case"hours":case"hour":case"hrs":case"hr":case"h":return o*u;case"minutes":case"minute":case"mins":case"min":case"m":return o*c;case"seconds":case"second":case"secs":case"sec":case"s":return o*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return o}}}}function n(e){return e>=l?Math.round(e/l)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function s(e){return i(e,l,"day")||i(e,u,"hour")||i(e,c,"minute")||i(e,a,"second")||e+" ms"}function i(e,t,o){if(!(e<t))return e<1.5*t?Math.floor(e/t)+" "+o:Math.ceil(e/t)+" "+o+"s"}var a=1e3,c=60*a,u=60*c,l=24*u,p=365.25*l;t.exports=function(e,t){return t=t||{},"string"==typeof e?r(e):t["long"]?s(e):n(e)}},{}],2:[function(e,t,o){function r(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function s(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function i(e){if(d===clearTimeout)return clearTimeout(e);if((d===n||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(e);try{return d(e)}catch(t){try{return d.call(null,e)}catch(t){return d.call(this,e)}}}function a(){m&&f&&(m=!1,f.length?y=f.concat(y):v=-1,y.length&&c())}function c(){if(!m){var e=s(a);m=!0;for(var t=y.length;t;){for(f=y,y=[];++v<t;)f&&f[v].run();v=-1,t=y.length}f=null,m=!1,i(e)}}function u(e,t){this.fun=e,this.array=t}function l(){}var p,d,h=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{d="function"==typeof clearTimeout?clearTimeout:n}catch(e){d=n}}();var f,y=[],m=!1,v=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var o=1;o<arguments.length;o++)t[o-1]=arguments[o];y.push(new u(e,t)),1!==y.length||m||s(c)},u.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=l,h.addListener=l,h.once=l,h.off=l,h.removeListener=l,h.removeAllListeners=l,h.emit=l,h.binding=function(e){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(e){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},{}],3:[function(e,t,o){function r(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}function n(){var e=arguments,t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+o.humanize(this.diff),!t)return e;var r="color: "+this.color;e=[e[0],r,"color: inherit"].concat(Array.prototype.slice.call(e,1));var n=0,s=0;return e[0].replace(/%[a-z%]/g,function(e){"%%"!==e&&(n++,"%c"===e&&(s=n))}),e.splice(s,0,r),e}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function i(e){try{null==e?o.storage.removeItem("debug"):o.storage.debug=e}catch(t){}}function a(){var e;try{e=o.storage.debug}catch(t){}return e}function c(){try{return window.localStorage}catch(e){}}o=t.exports=e(4),o.log=s,o.formatArgs=n,o.save=i,o.load=a,o.useColors=r,o.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:c(),o.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],o.formatters.j=function(e){return JSON.stringify(e)},o.enable(a())},{4:4}],4:[function(e,t,o){function r(){return o.colors[l++%o.colors.length]}function n(e){function t(){}function n(){var e=n,t=+new Date,s=t-(u||t);e.diff=s,e.prev=u,e.curr=t,u=t,null==e.useColors&&(e.useColors=o.useColors()),null==e.color&&e.useColors&&(e.color=r());var i=Array.prototype.slice.call(arguments);i[0]=o.coerce(i[0]),"string"!=typeof i[0]&&(i=["%o"].concat(i));var a=0;i[0]=i[0].replace(/%([a-z%])/g,function(t,r){if("%%"===t)return t;a++;var n=o.formatters[r];if("function"==typeof n){var s=i[a];t=n.call(e,s),i.splice(a,1),a--}return t}),"function"==typeof o.formatArgs&&(i=o.formatArgs.apply(e,i));var c=n.log||o.log||console.log.bind(console);c.apply(e,i)}t.enabled=!1,n.enabled=!0;var s=o.enabled(e)?n:t;return s.namespace=e,s}function s(e){o.save(e);for(var t=(e||"").split(/[\s,]+/),r=t.length,n=0;n<r;n++)t[n]&&(e=t[n].replace(/\*/g,".*?"),"-"===e[0]?o.skips.push(new RegExp("^"+e.substr(1)+"$")):o.names.push(new RegExp("^"+e+"$")))}function i(){o.enable("")}function a(e){var t,r;for(t=0,r=o.skips.length;t<r;t++)if(o.skips[t].test(e))return!1;for(t=0,r=o.names.length;t<r;t++)if(o.names[t].test(e))return!0;return!1}function c(e){return e instanceof Error?e.stack||e.message:e}o=t.exports=n,o.coerce=c,o.disable=i,o.enable=s,o.enabled=a,o.humanize=e(1),o.names=[],o.skips=[],o.formatters={};var u,l=0},{1:1}],5:[function(e,t,o){(function(o,r){(function(){"use strict";function n(e){return"function"==typeof e||"object"==typeof e&&null!==e}function s(e){return"function"==typeof e}function i(e){X=e}function a(e){z=e}function c(){return function(){o.nextTick(h)}}function u(){return function(){V(h)}}function l(){var e=0,t=new te(h),o=document.createTextNode("");return t.observe(o,{characterData:!0}),function(){o.data=e=++e%2}}function p(){var e=new MessageChannel;return e.port1.onmessage=h,function(){e.port2.postMessage(0)}}function d(){return function(){setTimeout(h,1)}}function h(){for(var e=0;e<Y;e+=2){var t=ne[e],o=ne[e+1];t(o),ne[e]=void 0,ne[e+1]=void 0}Y=0}function f(){try{var t=e,o=t("vertx");return V=o.runOnLoop||o.runOnContext,u()}catch(r){return d()}}function y(e,t){var o=this,r=new this.constructor(v);void 0===r[ae]&&N(r);var n=o._state;if(n){var s=arguments[n-1];z(function(){U(n,r,s,o._result)})}else q(o,r,e,t);return r}function m(e){var t=this;if(e&&"object"==typeof e&&e.constructor===t)return e;var o=new t(v);return S(o,e),o}function v(){}function g(){return new TypeError("You cannot resolve a promise with itself")}function b(){return new TypeError("A promises callback cannot return that same promise.")}function w(e){try{return e.then}catch(t){return pe.error=t,pe}}function _(e,t,o,r){try{e.call(t,o,r)}catch(n){return n}}function x(e,t,o){z(function(e){var r=!1,n=_(o,t,function(o){r||(r=!0,t!==o?S(e,o):R(e,o))},function(t){r||(r=!0,O(e,t))},"Settle: "+(e._label||" unknown promise"));!r&&n&&(r=!0,O(e,n))},e)}function T(e,t){t._state===ue?R(e,t._result):t._state===le?O(e,t._result):q(t,void 0,function(t){S(e,t)},function(t){O(e,t)})}function j(e,t,o){t.constructor===e.constructor&&o===se&&constructor.resolve===ie?T(e,t):o===pe?O(e,pe.error):void 0===o?R(e,t):s(o)?x(e,t,o):R(e,t)}function S(e,t){e===t?O(e,g()):n(t)?j(e,t,w(t)):R(e,t)}function k(e){e._onerror&&e._onerror(e._result),P(e)}function R(e,t){e._state===ce&&(e._result=t,e._state=ue,0!==e._subscribers.length&&z(P,e))}function O(e,t){e._state===ce&&(e._state=le,e._result=t,z(k,e))}function q(e,t,o,r){var n=e._subscribers,s=n.length;e._onerror=null,n[s]=t,n[s+ue]=o,n[s+le]=r,0===s&&e._state&&z(P,e)}function P(e){var t=e._subscribers,o=e._state;if(0!==t.length){for(var r,n,s=e._result,i=0;i<t.length;i+=3)r=t[i],n=t[i+o],r?U(o,r,n,s):n(s);e._subscribers.length=0}}function E(){this.error=null}function I(e,t){try{return e(t)}catch(o){return de.error=o,de}}function U(e,t,o,r){var n,i,a,c,u=s(o);if(u){if(n=I(o,r),n===de?(c=!0,i=n.error,n=null):a=!0,t===n)return void O(t,b())}else n=r,a=!0;t._state!==ce||(u&&a?S(t,n):c?O(t,i):e===ue?R(t,n):e===le&&O(t,n))}function A(e,t){try{t(function(t){S(e,t)},function(t){O(e,t)})}catch(o){O(e,o)}}function C(){return he++}function N(e){e[ae]=he++,e._state=void 0,e._result=void 0,e._subscribers=[]}function L(e){return new ge(this,e).promise}function D(e){var t=this;return new t($(e)?function(o,r){for(var n=e.length,s=0;s<n;s++)t.resolve(e[s]).then(o,r)}:function(e,t){t(new TypeError("You must pass an array to race."))})}function H(e){var t=this,o=new t(v);return O(o,e),o}function M(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function J(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function K(e){this[ae]=C(),this._result=this._state=void 0,this._subscribers=[],v!==e&&("function"!=typeof e&&M(),this instanceof K?A(this,e):J())}function Q(e,t){this._instanceConstructor=e,this.promise=new e(v),this.promise[ae]||N(this.promise),$(t)?(this._input=t,this.length=t.length,this._remaining=t.length,this._result=new Array(this.length),0===this.length?R(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&R(this.promise,this._result))):O(this.promise,B())}function B(){return new Error("Array Methods must be provided an Array")}function F(){var e;if("undefined"!=typeof r)e=r;else if("undefined"!=typeof self)e=self;else try{e=Function("return this")()}catch(t){throw new Error("polyfill failed because global object is unavailable in this environment")}var o=e.Promise;o&&"[object Promise]"===Object.prototype.toString.call(o.resolve())&&!o.cast||(e.Promise=ve)}var G;G=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)};var V,X,W,$=G,Y=0,z=function(e,t){ne[Y]=e,ne[Y+1]=t,Y+=2,2===Y&&(X?X(h):W())},Z="undefined"!=typeof window?window:void 0,ee=Z||{},te=ee.MutationObserver||ee.WebKitMutationObserver,oe="undefined"==typeof self&&"undefined"!=typeof o&&"[object process]"==={}.toString.call(o),re="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,ne=new Array(1e3);W=oe?c():te?l():re?p():void 0===Z&&"function"==typeof e?f():d();var se=y,ie=m,ae=Math.random().toString(36).substring(16),ce=void 0,ue=1,le=2,pe=new E,de=new E,he=0,fe=L,ye=D,me=H,ve=K;K.all=fe,K.race=ye,K.resolve=ie,K.reject=me,K._setScheduler=i,K._setAsap=a,K._asap=z,K.prototype={constructor:K,then:se,"catch":function(e){return this.then(null,e)}};var ge=Q;Q.prototype._enumerate=function(){for(var e=this.length,t=this._input,o=0;this._state===ce&&o<e;o++)this._eachEntry(t[o],o)},Q.prototype._eachEntry=function(e,t){var o=this._instanceConstructor,r=o.resolve;if(r===ie){var n=w(e);if(n===se&&e._state!==ce)this._settledAt(e._state,t,e._result);else if("function"!=typeof n)this._remaining--,this._result[t]=e;else if(o===ve){var s=new o(v);j(s,e,n),this._willSettleAt(s,t)}else this._willSettleAt(new o(function(t){t(e)}),t)}else this._willSettleAt(r(e),t)},Q.prototype._settledAt=function(e,t,o){var r=this.promise;r._state===ce&&(this._remaining--,e===le?O(r,o):this._result[t]=o),0===this._remaining&&R(r,this._result)},Q.prototype._willSettleAt=function(e,t){var o=this;q(e,void 0,function(e){o._settledAt(ue,t,e)},function(e){o._settledAt(le,t,e)})};var be=F,we={Promise:ve,polyfill:be};"function"==typeof define&&define.amd?define(function(){return we}):"undefined"!=typeof t&&t.exports?t.exports=we:"undefined"!=typeof this&&(this.ES6Promise=we),be()}).call(this)}).call(this,e(2),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{2:2}],6:[function(e,t,o){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function n(e){return"function"==typeof e}function s(e){return"number"==typeof e}function i(e){return"object"==typeof e&&null!==e}function a(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,o,r,s,c,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var l=new Error('Uncaught, unspecified "error" event. ('+t+")");throw l.context=t,l}if(o=this._events[e],a(o))return!1;if(n(o))switch(arguments.length){case 1:o.call(this);break;case 2:o.call(this,arguments[1]);break;case 3:o.call(this,arguments[1],arguments[2]);break;default:s=Array.prototype.slice.call(arguments,1),o.apply(this,s)}else if(i(o))for(s=Array.prototype.slice.call(arguments,1),u=o.slice(),r=u.length,c=0;c<r;c++)u[c].apply(this,s);return!0},r.prototype.addListener=function(e,t){var o;if(!n(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,n(t.listener)?t.listener:t),this._events[e]?i(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,i(this._events[e])&&!this._events[e].warned&&(o=a(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,o&&o>0&&this._events[e].length>o&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function o(){this.removeListener(e,o),r||(r=!0,t.apply(this,arguments))}if(!n(t))throw TypeError("listener must be a function");var r=!1;return o.listener=t,this.on(e,o),this},r.prototype.removeListener=function(e,t){var o,r,s,a;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(o=this._events[e],s=o.length,r=-1,o===t||n(o.listener)&&o.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(i(o)){for(a=s;a-- >0;)if(o[a]===t||o[a].listener&&o[a].listener===t){r=a;break}if(r<0)return this;1===o.length?(o.length=0,delete this._events[e]):o.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,o;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(o=this._events[e],n(o))this.removeListener(e,o);else if(o)for(;o.length;)this.removeListener(e,o[o.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?n(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(n(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],7:[function(e,t,o){var r=Object.prototype.hasOwnProperty,n=Object.prototype.toString;t.exports=function(e,t,o){if("[object Function]"!==n.call(t))throw new TypeError("iterator must be a function");var s=e.length;if(s===+s)for(var i=0;i<s;i++)t.call(o,e[i],i,e);else for(var a in e)r.call(e,a)&&t.call(o,e[a],a,e)}},{}],8:[function(e,t,o){(function(e){"undefined"!=typeof window?t.exports=window:"undefined"!=typeof e?t.exports=e:"undefined"!=typeof self?t.exports=self:t.exports={}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],9:[function(e,t,o){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var o=function(){};o.prototype=t.prototype,e.prototype=new o,e.prototype.constructor=e}},{}],10:[function(e,t,o){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],11:[function(e,t,o){"use strict";function r(e,t){if(e.map)return e.map(t);for(var o=[],r=0;r<e.length;r++)o.push(t(e[r],r));return o}var n=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};t.exports=function(e,t,o,a){return t=t||"&",o=o||"=",null===e&&(e=void 0),"object"==typeof e?r(i(e),function(i){var a=encodeURIComponent(n(i))+o;return s(e[i])?r(e[i],function(e){return a+encodeURIComponent(n(e))}).join(t):a+encodeURIComponent(n(e[i]))}).join(t):a?encodeURIComponent(n(a))+o+encodeURIComponent(n(e)):""};var s=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},i=Object.keys||function(e){var t=[];for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.push(o);return t}},{}],12:[function(e,t,o){function r(){c.apply(this,arguments)}function n(){var e="Not implemented in this environment.\nIf you feel this is a mistake, write to support@algolia.com";throw new l.AlgoliaSearchError(e)}t.exports=r;var s=e(14),i=e(25),a=e(26),c=e(13),u=e(9),l=e(27);u(r,c),r.prototype.deleteIndex=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(e),hostType:"write",callback:t})},r.prototype.moveIndex=function(e,t,o){var r={operation:"move",destination:t};return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:r,hostType:"write",callback:o})},r.prototype.copyIndex=function(e,t,o){var r={operation:"copy",destination:t};return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:r,hostType:"write",callback:o})},r.prototype.getLogs=function(t,o,r){var n=e(24),s={};return"object"==typeof t?(s=n(t),r=o):0===arguments.length||"function"==typeof t?r=t:1===arguments.length||"function"==typeof o?(r=o,s.offset=t):(s.offset=t,s.length=o),void 0===s.offset&&(s.offset=0),void 0===s.length&&(s.length=10),this._jsonRequest({method:"GET",url:"/1/logs?"+this._getSearchParams(s,""),hostType:"read",callback:r})},r.prototype.listIndexes=function(e,t){var o="";return void 0===e||"function"==typeof e?t=e:o="?page="+e,this._jsonRequest({method:"GET",url:"/1/indexes"+o,hostType:"read",callback:t})},r.prototype.initIndex=function(e){return new s(this,e)},r.prototype.listUserKeys=function(e){return this._jsonRequest({method:"GET",url:"/1/keys",hostType:"read",callback:e})},r.prototype.getUserKeyACL=function(e,t){return this._jsonRequest({method:"GET",url:"/1/keys/"+e,hostType:"read",callback:t})},r.prototype.deleteUserKey=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/keys/"+e,hostType:"write",callback:t})},r.prototype.addUserKey=function(t,o,r){var n=e(10),s="Usage: client.addUserKey(arrayOfAcls[, params, callback])";if(!n(t))throw new Error(s);1!==arguments.length&&"function"!=typeof o||(r=o,o=null);var i={acl:t};return o&&(i.validity=o.validity,i.maxQueriesPerIPPerHour=o.maxQueriesPerIPPerHour,i.maxHitsPerQuery=o.maxHitsPerQuery,i.indexes=o.indexes,i.description=o.description,o.queryParameters&&(i.queryParameters=this._getSearchParams(o.queryParameters,"")),i.referers=o.referers),this._jsonRequest({method:"POST",url:"/1/keys",body:i,hostType:"write",callback:r})},r.prototype.addUserKeyWithValidity=i(function(e,t,o){return this.addUserKey(e,t,o)},a("client.addUserKeyWithValidity()","client.addUserKey()")),r.prototype.updateUserKey=function(t,o,r,n){var s=e(10),i="Usage: client.updateUserKey(key, arrayOfAcls[, params, callback])";if(!s(o))throw new Error(i);2!==arguments.length&&"function"!=typeof r||(n=r,r=null);var a={acl:o};return r&&(a.validity=r.validity,a.maxQueriesPerIPPerHour=r.maxQueriesPerIPPerHour,a.maxHitsPerQuery=r.maxHitsPerQuery,a.indexes=r.indexes,a.description=r.description,r.queryParameters&&(a.queryParameters=this._getSearchParams(r.queryParameters,"")),a.referers=r.referers),this._jsonRequest({method:"PUT",url:"/1/keys/"+t,body:a,hostType:"write",callback:n})},r.prototype.startQueriesBatch=i(function(){this._batch=[]},a("client.startQueriesBatch()","client.search()")),r.prototype.addQueryInBatch=i(function(e,t,o){this._batch.push({indexName:e,query:t,params:o})},a("client.addQueryInBatch()","client.search()")),r.prototype.sendQueriesBatch=i(function(e){return this.search(this._batch,e)},a("client.sendQueriesBatch()","client.search()")),r.prototype.batch=function(t,o){var r=e(10),n="Usage: client.batch(operations[, callback])";if(!r(t))throw new Error(n);return this._jsonRequest({method:"POST",url:"/1/indexes/*/batch",body:{requests:t},hostType:"write",callback:o})},r.prototype.destroy=n,r.prototype.enableRateLimitForward=n,r.prototype.disableRateLimitForward=n,r.prototype.useSecuredAPIKey=n,r.prototype.disableSecuredAPIKey=n,r.prototype.generateSecuredApiKey=n},{10:10,13:13,14:14,24:24,25:25,26:26,27:27,9:9}],13:[function(e,t,o){function r(t,o,r){var s=e(3)("algoliasearch"),a=e(24),u=e(10),l=e(29),p="Usage: algoliasearch(applicationID, apiKey, opts)";if(r._allowEmptyCredentials!==!0&&!t)throw new c.AlgoliaSearchError("Please provide an application ID. "+p);if(r._allowEmptyCredentials!==!0&&!o)throw new c.AlgoliaSearchError("Please provide an API key. "+p);this.applicationID=t,this.apiKey=o;var d=i([this.applicationID+"-1.algolianet.com",this.applicationID+"-2.algolianet.com",this.applicationID+"-3.algolianet.com"]);this.hosts={read:[],write:[]},this.hostIndex={read:0,write:0},r=r||{};var h=r.protocol||"https:",f=void 0===r.timeout?2e3:r.timeout;if(/:$/.test(h)||(h+=":"),"http:"!==r.protocol&&"https:"!==r.protocol)throw new c.AlgoliaSearchError("protocol must be `http:` or `https:` (was `"+r.protocol+"`)");r.hosts?u(r.hosts)?(this.hosts.read=a(r.hosts),this.hosts.write=a(r.hosts)):(this.hosts.read=a(r.hosts.read),this.hosts.write=a(r.hosts.write)):(this.hosts.read=[this.applicationID+"-dsn.algolia.net"].concat(d),this.hosts.write=[this.applicationID+".algolia.net"].concat(d)),this.hosts.read=l(this.hosts.read,n(h)),this.hosts.write=l(this.hosts.write,n(h)),this.requestTimeout=f,this.extraHeaders=[],this.cache=r._cache||{},this._ua=r._ua,this._useCache=!(void 0!==r._useCache&&!r._cache)||r._useCache,this._useFallback=void 0===r.useFallback||r.useFallback,this._setTimeout=r._setTimeout,s("init done, %j",this)}function n(e){return function(t){return e+"//"+t.toLowerCase()}}function s(e){if(void 0===Array.prototype.toJSON)return JSON.stringify(e);var t=Array.prototype.toJSON;delete Array.prototype.toJSON;var o=JSON.stringify(e);return Array.prototype.toJSON=t,o}function i(e){for(var t,o,r=e.length;0!==r;)o=Math.floor(Math.random()*r),r-=1,t=e[r],e[r]=e[o],e[o]=t;return e}function a(e){var t={};for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var r;r="x-algolia-api-key"===o||"x-algolia-application-id"===o?"**hidden for security purposes**":e[o],t[o]=r}return t}t.exports=r;var c=e(27),u=e(28),l=e(16),p=500;r.prototype.initIndex=function(e){return new l(this,e)},r.prototype.setExtraHeader=function(e,t){this.extraHeaders.push({name:e.toLowerCase(),value:t})},r.prototype.addAlgoliaAgent=function(e){this._ua+=";"+e},r.prototype._jsonRequest=function(t){function o(e,u){function p(e){var t=e&&e.body&&e.body.message&&e.body.status||e.statusCode||e&&e.body&&200;i("received response: statusCode: %s, computed statusCode: %d, headers: %j",e.statusCode,t,e.headers);var o=2===Math.floor(t/100),s=new Date;if(m.push({currentHost:x,headers:a(n),content:r||null,contentLength:void 0!==r?r.length:null,method:u.method,timeout:u.timeout,url:u.url,startTime:_,endTime:s,duration:s-_,statusCode:t}),o)return d._useCache&&l&&(l[w]=e.responseText),e.body;var p=4!==Math.floor(t/100);if(p)return h+=1,g();i("unrecoverable error");var f=new c.AlgoliaSearchError(e.body&&e.body.message,{debugData:m,statusCode:t});return d._promise.reject(f)}function v(e){i("error: %s, stack: %s",e.message,e.stack);var o=new Date;return m.push({currentHost:x,headers:a(n),content:r||null,contentLength:void 0!==r?r.length:null,method:u.method,timeout:u.timeout,url:u.url,startTime:_,endTime:o,duration:o-_}),e instanceof c.AlgoliaSearchError||(e=new c.Unknown(e&&e.message,e)),h+=1,e instanceof c.Unknown||e instanceof c.UnparsableJSON||h>=d.hosts[t.hostType].length&&(f||!y)?(e.debugData=m,d._promise.reject(e)):e instanceof c.RequestTimeout?b():g()}function g(){return i("retrying request"),d.hostIndex[t.hostType]=(d.hostIndex[t.hostType]+1)%d.hosts[t.hostType].length,o(e,u)}function b(){return i("retrying request with higher timeout"),d.hostIndex[t.hostType]=(d.hostIndex[t.hostType]+1)%d.hosts[t.hostType].length,u.timeout=d.requestTimeout*(h+1),o(e,u)}var w,_=new Date;if(d._useCache&&(w=t.url),d._useCache&&r&&(w+="_body_"+u.body),d._useCache&&l&&void 0!==l[w])return i("serving response from cache"),d._promise.resolve(JSON.parse(l[w]));if(h>=d.hosts[t.hostType].length)return!y||f?(i("could not get any response"),d._promise.reject(new c.AlgoliaSearchError("Cannot connect to the AlgoliaSearch API. Send an email to support@algolia.com to report and resolve the issue. Application id was: "+d.applicationID,{debugData:m}))):(i("switching to fallback"),h=0,u.method=t.fallback.method,u.url=t.fallback.url,u.jsonBody=t.fallback.body,u.jsonBody&&(u.body=s(u.jsonBody)),n=d._computeRequestHeaders(),u.timeout=d.requestTimeout*(h+1),d.hostIndex[t.hostType]=0,f=!0,o(d._request.fallback,u));var x=d.hosts[t.hostType][d.hostIndex[t.hostType]],T=x+u.url,j={body:u.body,jsonBody:u.jsonBody,method:u.method,headers:n,timeout:u.timeout,debug:i};return i("method: %s, url: %s, headers: %j, timeout: %d",j.method,T,j.headers,j.timeout),e===d._request.fallback&&i("using fallback"),e.call(d,T,j).then(p,v)}var r,n,i=e(3)("algoliasearch:"+t.url),l=t.cache,d=this,h=0,f=!1,y=d._useFallback&&d._request.fallback&&t.fallback;this.apiKey.length>p&&void 0!==t.body&&(void 0!==t.body.params||void 0!==t.body.requests)?(t.body.apiKey=this.apiKey,n=this._computeRequestHeaders(!1)):n=this._computeRequestHeaders(),void 0!==t.body&&(r=s(t.body)),i("request start");var m=[],v=o(d._request,{url:t.url,method:t.method,body:r,jsonBody:t.body,timeout:d.requestTimeout*(h+1)});return t.callback?void v.then(function(e){u(function(){t.callback(null,e)},d._setTimeout||setTimeout)},function(e){u(function(){t.callback(e)},d._setTimeout||setTimeout)}):v},r.prototype._getSearchParams=function(e,t){if(void 0===e||null===e)return t;for(var o in e)null!==o&&void 0!==e[o]&&e.hasOwnProperty(o)&&(t+=""===t?"":"&",t+=o+"="+encodeURIComponent("[object Array]"===Object.prototype.toString.call(e[o])?s(e[o]):e[o]));return t},r.prototype._computeRequestHeaders=function(t){var o=e(7),r={"x-algolia-agent":this._ua,"x-algolia-application-id":this.applicationID};return t!==!1&&(r["x-algolia-api-key"]=this.apiKey),this.userToken&&(r["x-algolia-usertoken"]=this.userToken),this.securityTags&&(r["x-algolia-tagfilters"]=this.securityTags),this.extraHeaders&&o(this.extraHeaders,function(e){r[e.name]=e.value}),r},r.prototype.search=function(t,o,r){var n=e(10),s=e(29),i="Usage: client.search(arrayOfQueries[, callback])";if(!n(t))throw new Error(i);"function"==typeof o?(r=o,o={}):void 0===o&&(o={});var a=this,c={requests:s(t,function(e){var t="";return void 0!==e.query&&(t+="query="+encodeURIComponent(e.query)),{indexName:e.indexName,params:a._getSearchParams(e.params,t)}})},u=s(c.requests,function(e,t){return t+"="+encodeURIComponent("/1/indexes/"+encodeURIComponent(e.indexName)+"?"+e.params)}).join("&"),l="/1/indexes/*/queries";return void 0!==o.strategy&&(l+="?strategy="+o.strategy),this._jsonRequest({cache:this.cache,method:"POST",url:l,body:c,hostType:"read",fallback:{method:"GET",url:"/1/indexes/*",body:{params:u}},callback:r})},r.prototype.setSecurityTags=function(e){if("[object Array]"===Object.prototype.toString.call(e)){for(var t=[],o=0;o<e.length;++o)if("[object Array]"===Object.prototype.toString.call(e[o])){for(var r=[],n=0;n<e[o].length;++n)r.push(e[o][n]);
-t.push("("+r.join(",")+")")}else t.push(e[o]);e=t.join(",")}this.securityTags=e},r.prototype.setUserToken=function(e){this.userToken=e},r.prototype.clearCache=function(){this.cache={}},r.prototype.setRequestTimeout=function(e){e&&(this.requestTimeout=parseInt(e,10))}},{10:10,16:16,24:24,27:27,28:28,29:29,3:3,7:7}],14:[function(e,t,o){function r(){s.apply(this,arguments)}var n=e(9),s=e(16),i=e(25),a=e(26),c=e(28),u=e(27);t.exports=r,n(r,s),r.prototype.addObject=function(e,t,o){var r=this;…
cpojer pushed a commit to facebook/metro that referenced this pull request Jan 26, 2017
…e the global document.

Summary: To make the chrome debugger environment consisten with the JSC executer environment,
where there is no `window.document`, make the chrome debugger run the javascript inside a web worker.

This fixes #1473
Closes facebook/react-native#1632

Reviewed By: @martinbigio

Differential Revision: D2471710

Pulled By: @vjeux
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[JS] Remove the global document variable
7 participants