diff --git a/analytics/fs.js b/analytics/fs.js
index 7c8d3a5..07f031e 100644
--- a/analytics/fs.js
+++ b/analytics/fs.js
@@ -1,9 +1,9 @@
 /**
- * 
+ *
  * @twipped/utils
- * 
+ *
  * Copyright (c) 2020, Jocelyn Badgley
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
@@ -11,10 +11,10 @@
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be
  * included in all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -22,9 +22,8 @@
  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  */
-
 'use strict';
 
 Object.defineProperty(exports, '__esModule', { value: true });
@@ -36,16 +35,16 @@ var util = require('util');
 
 function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
 
-var stream__default = /*#__PURE__*/_interopDefaultLegacy(stream);
+var stream__default = /* #__PURE__*/_interopDefaultLegacy(stream);
 
-const pipeline = util.promisify(stream__default['default'].pipeline);
+const pipeline = util.promisify(stream__default.default.pipeline);
 const mkdir = (f, recursive = true) => fs.promises.mkdir(f, {
-  recursive
+  recursive,
 });
-const exists = f => fs.promises.access(f).then(() => true, () => false);
-const stat = f => fs.promises.stat(f).catch(() => null);
-const linkStat = f => fs.promises.lstat(f).catch(() => null);
-async function isWritable(file) {
+const exists = (f) => fs.promises.access(f).then(() => true, () => false);
+const stat = (f) => fs.promises.stat(f).catch(() => null);
+const linkStat = (f) => fs.promises.lstat(f).catch(() => null);
+async function isWritable (file) {
   try {
     await fs.promises.access(file, fs.constants.F_OK | fs.constants.W_OK);
     return true;
@@ -57,7 +56,7 @@ async function isWritable(file) {
     return false;
   }
 }
-async function touch(file) {
+async function touch (file) {
   const stats = await linkStat(file);
 
   if (stats) {
@@ -69,34 +68,36 @@ async function touch(file) {
   if (!(await exists(path.dirname(file)))) await mkdir(path.dirname(file));
   await fs.promises.writeFile(file, '');
 }
-async function remove(file) {
+async function remove (file) {
   const stats = await linkStat(file);
   if (!stats) return;
-  if (stats.isDirectory()) return fs.promises.rmdir(file, {
-    recursive: true
-  });
+  if (stats.isDirectory()) {
+    return fs.promises.rmdir(file, {
+      recursive: true,
+    });
+  }
   return fs.promises.unlink(file);
 }
-async function writeJson(file, object, options) {
+async function writeJson (file, object, options) {
   const {
     replacer,
     spaces,
     ...ops
   } = {
     encoding: 'utf8',
-    ...options
+    ...options,
   };
   await fs.promises.writeFile(file, `${JSON.stringify(object, replacer, spaces)}\n`, ops);
 }
 const writeJSON = writeJson;
-async function readJson(file, options) {
+async function readJson (file, options) {
   const {
     reviver,
     quiet,
     ...ops
   } = {
     encoding: 'utf8',
-    ...options
+    ...options,
   };
   const content = await fs.promises.readFile(file, ops);
 
@@ -109,7 +110,7 @@ async function readJson(file, options) {
 }
 const readJSON = readJson;
 
-function stripBom(content) {
+function stripBom (content) {
   if (Buffer.isBuffer(content)) {
     content = content.toString('utf8');
   }
diff --git a/build/cache.js b/build/cache.js
index c1af1a2..6382b15 100644
--- a/build/cache.js
+++ b/build/cache.js
@@ -48,7 +48,7 @@ module.exports = exports = class Manifest {
 
   hash ({ action, input, output, ...task }) {
     if (!isFunction(action)) {
-      console.error({ action, input, output });
+      console.error({ action, input, output }); // eslint-disable-line
       throw new Error('Task action is not a task action (function).');
     }
 
diff --git a/build/lib/util.js b/build/lib/util.js
index dd8a4d2..4a74930 100644
--- a/build/lib/util.js
+++ b/build/lib/util.js
@@ -1,9 +1,9 @@
 /**
- * 
+ *
  * handlebar-kit
- * 
+ *
  * Copyright (c) 2020, Jocelyn Badgley
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
@@ -11,10 +11,10 @@
  * distribute, sublicense, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be
  * included in all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -22,42 +22,41 @@
  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  * Portions of the MIT licensed date-fns library are bundled with this
  * software. https://github.com/date-fns/date-fns#readme
  */
-
 'use strict';
 
 Object.defineProperty(exports, '__esModule', { value: true });
 
 function equals (value) {
-	value = uc(value);
-	return (tok) => uc(tok) === value;
+  value = uc(value);
+  return (tok) => uc(tok) === value;
 }
 
 function re (pattern) {
-	if (isString(pattern)) pattern = new RegExp(pattern);
-	return (tok) => !!String(tok).match(pattern);
+  if (isString(pattern)) pattern = new RegExp(pattern);
+  return (tok) => !!String(tok).match(pattern);
 }
 
 function anyOf (...args) {
-	args = args.flat().map(uc);
-	if (!anyBy(args, isFunction)) {
-		// arguments do not contain a function, so we can optimize
-		if (args.length === 1) return (tok) => uc(tok) === args[0];
-		return (tok) => args.includes(uc(tok));
-	}
+  args = args.flat().map(uc);
+  if (!anyBy(args, isFunction)) {
+    // arguments do not contain a function, so we can optimize
+    if (args.length === 1) return (tok) => uc(tok) === args[0];
+    return (tok) => args.includes(uc(tok));
+  }
 
-	args = args.map((a) => isFunction(a) && a || equals(a));
-	if (args.length === 1) return (tok) => args[0](tok);
-	return (tok) => anyBy(args, (check) => check(tok));
+  args = args.map((a) => isFunction(a) && a || equals(a));
+  if (args.length === 1) return (tok) => args[0](tok);
+  return (tok) => anyBy(args, (check) => check(tok));
 }
 
 function allOf (...args) {
-	args = args.flat().map((a) => isFunction(a) && a || equals(a));
-	if (args.length === 1) return (tok) => args[0](tok);
-	return (tok) => allBy(args, (check) => check(tok));
+  args = args.flat().map((a) => isFunction(a) && a || equals(a));
+  if (args.length === 1) return (tok) => args[0](tok);
+  return (tok) => allBy(args, (check) => check(tok));
 }
 
 function isNumber    (input) { return typeof input === 'number' && !isNaN(input); }
@@ -75,65 +74,65 @@ function isNull      (input) { return input === null; }
 const isArray = Array.isArray;
 
 function isPrimitive (input) {
-	switch (typeof input) {
-	case 'string':
-	case 'number':
-	case 'boolean':
-		return true;
-	default:
-		return false;
-	}
+  switch (typeof input) {
+  case 'string':
+  case 'number':
+  case 'boolean':
+    return true;
+  default:
+    return false;
+  }
 }
 
 function isObject (input) {
-	if (!input) return false;
-	if (typeof input !== 'object') return false;
-	if (isArray(input)) return false;
-	if (!(input instanceof Object)) return false;
-	if (input.constructor !== Object.prototype.constructor) return false;
-	return true;
+  if (!input) return false;
+  if (typeof input !== 'object') return false;
+  if (isArray(input)) return false;
+  if (!(input instanceof Object)) return false;
+  if (input.constructor !== Object.prototype.constructor) return false;
+  return true;
 }
 
 
 const IS_LOOKUP = new Map([
-	[ Array,     isArray     ],
-	[ Number,    isNumber    ],
-	[ String,    isString    ],
-	[ Boolean,   isBoolean   ],
-	[ Map,       isMap       ],
-	[ Set,       isSet       ],
-	[ Function,  isFunction  ],
-	[ Date,      isDate      ],
-	[ undefined, isUndefined ],
-	[ true,      isTruthy    ],
-	[ false,     isFalsey    ],
+  [ Array,     isArray     ],
+  [ Number,    isNumber    ],
+  [ String,    isString    ],
+  [ Boolean,   isBoolean   ],
+  [ Map,       isMap       ],
+  [ Set,       isSet       ],
+  [ Function,  isFunction  ],
+  [ Date,      isDate      ],
+  [ undefined, isUndefined ],
+  [ true,      isTruthy    ],
+  [ false,     isFalsey    ],
 ]);
 
 function is (...args) {
-	args = args.flat().map((a) =>
-		IS_LOOKUP.get(a)
+  args = args.flat().map((a) =>
+    IS_LOOKUP.get(a)
 		|| (isFunction(a) && a)
 		|| (isRegExp(a) && re(a))
 		|| equals(a),
-	);
-	if (args.length === 1) return (tok) => args[0](tok);
-	return (tok) => anyBy(args, (check) => check(tok));
+  );
+  if (args.length === 1) return (tok) => args[0](tok);
+  return (tok) => anyBy(args, (check) => check(tok));
 }
 
 function isAll (...args) {
-	args = args.flat().map((a) =>
-		IS_LOOKUP.get(a)
+  args = args.flat().map((a) =>
+    IS_LOOKUP.get(a)
 		|| (isFunction(a) && a)
 		|| (isRegExp(a) && re(a))
 		|| equals(a),
-	);
-	if (args.length === 1) return (tok) => args[0](tok);
-	return (tok) => allBy(args, (check) => check(tok));
+  );
+  if (args.length === 1) return (tok) => args[0](tok);
+  return (tok) => allBy(args, (check) => check(tok));
 }
 
 function isArrayOf (...args) {
-	const predicate = is(...args);
-	return (tok) => (isArray(tok) ? allBy(tok, predicate) : predicate(tok));
+  const predicate = is(...args);
+  return (tok) => (isArray(tok) ? allBy(tok, predicate) : predicate(tok));
 }
 function isArrayOfStrings    (input) { return allBy(input, isString); }
 function isArrayOfNumbers    (input) { return allBy(input, isNumber); }
@@ -147,8 +146,8 @@ function isArrayOfTruthy     (input) { return allBy(input, isTruthy); }
 function isArrayOfFalsey     (input) { return allBy(input, isFalsey); }
 
 function contains (...args) {
-	const predicate = is(...args);
-	return (tok) => (isArray(tok) ? anyBy(tok, predicate) : predicate(tok));
+  const predicate = is(...args);
+  return (tok) => (isArray(tok) ? anyBy(tok, predicate) : predicate(tok));
 }
 function containsStrings    (input) { return anyBy(input, isString); }
 function containsNumbers    (input) { return anyBy(input, isNumber); }
@@ -162,644 +161,644 @@ function containsTruthy     (input) { return anyBy(input, isTruthy); }
 function containsFalsey     (input) { return anyBy(input, isFalsey); }
 
 function truthy (value) {
-	if (isMappable(value)) return !!sizeOf(value);
-	return !!value;
+  if (isMappable(value)) return !!sizeOf(value);
+  return !!value;
 }
 
 function hasOwn (obj, key) {
-	return Object.prototype.hasOwnProperty.call(obj, key);
+  return Object.prototype.hasOwnProperty.call(obj, key);
 }
 
 function lc (str) {
-	return isString(uc) ? str.toLowerCase() : str;
+  return isString(uc) ? str.toLowerCase() : str;
 }
 
 function uc (str) {
-	return isString(str) ? str.toUpperCase() : str;
+  return isString(str) ? str.toUpperCase() : str;
 }
 
 function ucfirst (input) {
-	input = String(input);
-	return input.charAt(0).toUpperCase() + input.slice(1);
+  input = String(input);
+  return input.charAt(0).toUpperCase() + input.slice(1);
 }
 
 function ucsentence (input) {
-	return input.replace(/((?:\S[^.?!]*)[.?!]*)/g, (txt) =>
-		txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(),
-	);
+  return input.replace(/((?:\S[^.?!]*)[.?!]*)/g, (txt) =>
+    txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(),
+  );
 }
 
 function ucwords (input) {
-	return input.replace(/\w\S*/g, (word) => word.charAt(0).toUpperCase() + word.substr(1));
+  return input.replace(/\w\S*/g, (word) => word.charAt(0).toUpperCase() + word.substr(1));
 }
 
 function merge (...sources) {
-	const result = {};
-	for (const source of sources) {
-		if (!source) continue;
-		for (const [ key, value ] of Object.entries(source)) {
-			if (isObject(value)) {
-				if (isObject(result[key])) {
-					result[key] = merge(result[key], value);
-				} else {
-					result[key] = merge(value);
-				}
-			} else {
-				result[key] = value;
-			}
-		}
-	}
-	return result;
+  const result = {};
+  for (const source of sources) {
+    if (!source) continue;
+    for (const [ key, value ] of Object.entries(source)) {
+      if (isObject(value)) {
+        if (isObject(result[key])) {
+          result[key] = merge(result[key], value);
+        } else {
+          result[key] = merge(value);
+        }
+      } else {
+        result[key] = value;
+      }
+    }
+  }
+  return result;
 }
 
 function set (obj, path, value) {
-	if (path === null && path === undefined && path === '') return false;
-	if (isNumber(path)) path = [ String(path) ];
-	else if (isString(path)) {
-		if (hasOwn(obj, path)) {
-			obj[path] = value;
-			return obj;
-		}
-		path = path.split(/[,[\].]+?/);
-	}
+  if (path === null && path === undefined && path === '') return false;
+  if (isNumber(path)) path = [ String(path) ];
+  else if (isString(path)) {
+    if (hasOwn(obj, path)) {
+      obj[path] = value;
+      return obj;
+    }
+    path = path.split(/[,[\].]+?/);
+  }
 
-	const c = path.length - 1;
-	path
-		.filter((s) => s || s === 0)
-		.reduce((res, key, i) => {
-			if (i === c) {
-				res[key] = value;
-				return true;
-			}
-			if (isObject(res[key]) || isFunction(res[key])) return res[key];
-			return (res[key] = {});
-		}, obj);
+  const c = path.length - 1;
+  path
+    .filter((s) => s || s === 0)
+    .reduce((res, key, i) => {
+      if (i === c) {
+        res[key] = value;
+        return true;
+      }
+      if (isObject(res[key]) || isFunction(res[key])) return res[key];
+      return (res[key] = {});
+    }, obj);
 
-	return obj;
+  return obj;
 }
 
 function get (obj, path, defaultValue) {
-	if (path === null && path === undefined && path === '') return defaultValue;
-	if (isNumber(path)) path = [ String(path) ];
-	else if (isString(path)) {
-		if (hasOwn(obj, path)) return obj[path];
-		path = path.split(/[,[\].]+?/);
-	}
+  if (path === null && path === undefined && path === '') return defaultValue;
+  if (isNumber(path)) path = [ String(path) ];
+  else if (isString(path)) {
+    if (hasOwn(obj, path)) return obj[path];
+    path = path.split(/[,[\].]+?/);
+  }
 
-	const result = path
-		.filter((s) => s !== null && s !== undefined && s !== '')
-		.reduce((res, key) =>
-			((res !== null && res !== undefined) ? res[key] : res)
-		, obj);
-	return (result === undefined || result === obj) ? defaultValue : result;
+  const result = path
+    .filter((s) => s !== null && s !== undefined && s !== '')
+    .reduce((res, key) =>
+      ((res !== null && res !== undefined) ? res[key] : res)
+    , obj);
+  return (result === undefined || result === obj) ? defaultValue : result;
 }
 
 function has (obj, path) {
-	if (isNumber(path)) path = [ String(path) ];
-	else if (isString(path)) path = String.prototype.split.call(path, /[,[\].]+?/);
-	let res = obj;
-	for (const key of path) {
-		if (res === null || res === undefined) return false;
-		if (typeof res !== 'object' && typeof res !== 'function') return false;
-		if (!hasOwn(res, key)) return false;
-		res = res[key];
-	}
-	return true;
+  if (isNumber(path)) path = [ String(path) ];
+  else if (isString(path)) path = String.prototype.split.call(path, /[,[\].]+?/);
+  let res = obj;
+  for (const key of path) {
+    if (res === null || res === undefined) return false;
+    if (typeof res !== 'object' && typeof res !== 'function') return false;
+    if (!hasOwn(res, key)) return false;
+    res = res[key];
+  }
+  return true;
 }
 
 function isMappable (collection, arrays = true) {
-	return (
-		(arrays && isArray(collection)) ||
+  return (
+    (arrays && isArray(collection)) ||
 		(arrays && isSet(collection)) ||
 		isMap(collection) ||
 		collection && (typeof collection === 'object' || typeof collection === 'function')
-	);
+  );
 }
 
 function sizeOf (collection) {
-	if (isArray(collection) || isString(collection)) return collection.length;
-	if (isSet(collection) || isMap(collection)) return collection.size;
-	if (isObject(collection)) return Object.keys(collection).length;
-	return !!collection;
+  if (isArray(collection) || isString(collection)) return collection.length;
+  if (isSet(collection) || isMap(collection)) return collection.size;
+  if (isObject(collection)) return Object.keys(collection).length;
+  return !!collection;
 }
 
 function keys (input) {
-	if (isArray(input)) return [ ...input.keys() ];
+  if (isArray(input)) return [ ...input.keys() ];
 
-	if (isSet(input)) return Array.from(input.entries(), ([ k ]) => k);
+  if (isSet(input)) return Array.from(input.entries(), ([ k ]) => k);
 
-	if (isMap(input)) return Array.from(input.keys());
+  if (isMap(input)) return Array.from(input.keys());
 
-	if (isObject(input)) return Object.keys(input);
+  if (isObject(input)) return Object.keys(input);
 
-	return [];
+  return [];
 }
 
 function values (input) {
-	if (isArray(input)) return [ ...input ];
+  if (isArray(input)) return [ ...input ];
 
-	if (isSet(input) || isMap(input)) return Array.from(input.values());
+  if (isSet(input) || isMap(input)) return Array.from(input.values());
 
-	if (isObject(input)) return Object.values(input);
+  if (isObject(input)) return Object.values(input);
 
-	return [];
+  return [];
 }
 
 function arrayify (input) {
-	if (isArray(input)) return input;
+  if (isArray(input)) return input;
 
-	if (isSet(input) || isMap(input)) return Array.from(input.values());
+  if (isSet(input) || isMap(input)) return Array.from(input.values());
 
-	if (isObject(input)) return Object.values(input);
+  if (isObject(input)) return Object.values(input);
 
-	return [ input ];
+  return [ input ];
 }
 
 function first (input, count = 1) {
-	if (count === 1) {
-		if (isArray(input) || isString(input)) return input[0];
-		if (isSet(input) || isObject(input)) for (const v of input) return v;
-		if (isMap(input)) for (const [ , v ] of input) return v;
-		return;
-	}
+  if (count === 1) {
+    if (isArray(input) || isString(input)) return input[0];
+    if (isSet(input) || isObject(input)) for (const v of input) return v;
+    if (isMap(input)) for (const [ , v ] of input) return v;
+    return;
+  }
 
-	if (isArray(input) || isString(input)) return input.slice(0, count);
-	if (isSet(input)) return Array.from(input).slice(0, count);
-	if (isObject(input)) return Object.values(input).slice(0, count);
-	if (isMap(input)) return Array.from(input.values()).slice(0, count);
+  if (isArray(input) || isString(input)) return input.slice(0, count);
+  if (isSet(input)) return Array.from(input).slice(0, count);
+  if (isObject(input)) return Object.values(input).slice(0, count);
+  if (isMap(input)) return Array.from(input.values()).slice(0, count);
 }
 
 function last (input, count = 1) {
-	if (count === 1) {
-		if (isArray(input) || isString(input)) return input[input.length - 1];
-	}
+  if (count === 1) {
+    if (isArray(input) || isString(input)) return input[input.length - 1];
+  }
 
-	if (isArray(input) || isString(input)) return input.slice(-count);
-	if (isSet(input)) return Array.from(input).slice(-count);
-	if (isObject(input)) return Object.values(input).slice(-count);
-	if (isMap(input)) return Array.from(input.values()).slice(-count);
+  if (isArray(input) || isString(input)) return input.slice(-count);
+  if (isSet(input)) return Array.from(input).slice(-count);
+  if (isObject(input)) return Object.values(input).slice(-count);
+  if (isMap(input)) return Array.from(input.values()).slice(-count);
 }
 
 function all (...args) {
-	let input;
-	if (args.length > 1) {
-		input = args;
-	} else {
-		input = arrayify(args[0]);
-	}
+  let input;
+  if (args.length > 1) {
+    input = args;
+  } else {
+    input = arrayify(args[0]);
+  }
 
-	let result = input.shift();
-	for (const value of input) {
-		if (!truthy(result)) {
-			return false;
-		}
-		result = value;
-	}
+  let result = input.shift();
+  for (const value of input) {
+    if (!truthy(result)) {
+      return false;
+    }
+    result = value;
+  }
 
-	return result;
+  return result;
 }
 
 function allBy (collection, predicate = null) {
-	if (!collection) return false;
-	if (predicate === null) {
-		predicate = (v) => v;
-	} else if (!isFunction(predicate)) {
-		predicate = iteratee(predicate);
-	}
+  if (!collection) return false;
+  if (predicate === null) {
+    predicate = (v) => v;
+  } else if (!isFunction(predicate)) {
+    predicate = iteratee(predicate);
+  }
 
-	if (isArray(collection)) {
-		let i = 0;
-		for (const value of collection) {
-			if (!predicate(value, i, i++)) return false;
-		}
-		return true;
-	}
+  if (isArray(collection)) {
+    let i = 0;
+    for (const value of collection) {
+      if (!predicate(value, i, i++)) return false;
+    }
+    return true;
+  }
 
-	if (isSet(collection)) {
-		let i = 0;
-		for (const item of collection) {
-			if (!predicate(item, i, i++)) return false;
-		}
-		return true;
-	}
+  if (isSet(collection)) {
+    let i = 0;
+    for (const item of collection) {
+      if (!predicate(item, i, i++)) return false;
+    }
+    return true;
+  }
 
-	// received a Map
-	if (isMap(collection)) {
-		let i = 0;
-		for (const [ key, value ] of collection.entries()) {
-			if (!predicate(value, key, i++)) return false;
-		}
-		return true;
-	}
+  // received a Map
+  if (isMap(collection)) {
+    let i = 0;
+    for (const [ key, value ] of collection.entries()) {
+      if (!predicate(value, key, i++)) return false;
+    }
+    return true;
+  }
 
-	// received an object hash
-	if (isObject(collection)) {
-		let i = 0;
-		for (const [ key, value ] of Object.entries(collection)) {
-			if (!predicate(value, key, i++)) return false;
-		}
-		return true;
-	}
+  // received an object hash
+  if (isObject(collection)) {
+    let i = 0;
+    for (const [ key, value ] of Object.entries(collection)) {
+      if (!predicate(value, key, i++)) return false;
+    }
+    return true;
+  }
 
-	return !!collection;
+  return !!collection;
 }
 
 function any (...args) {
-	let input;
-	if (args.length > 1) {
-		input = args;
-	} else {
-		input = arrayify(args[0]);
-	}
+  let input;
+  if (args.length > 1) {
+    input = args;
+  } else {
+    input = arrayify(args[0]);
+  }
 
-	for (const value of input) {
-		if (truthy(value)) {
-			return value;
-		}
-	}
+  for (const value of input) {
+    if (truthy(value)) {
+      return value;
+    }
+  }
 
-	return input[input.length - 1];
+  return input[input.length - 1];
 }
 
 function anyBy (collection, predicate = null) {
-	if (!collection) return false;
-	if (predicate === null) {
-		predicate = (v) => v;
-	} else if (!isFunction(iteratee)) {
-		predicate = iteratee(predicate);
-	}
+  if (!collection) return false;
+  if (predicate === null) {
+    predicate = (v) => v;
+  } else if (!isFunction(iteratee)) {
+    predicate = iteratee(predicate);
+  }
 
-	if (isArray(collection)) {
-		let i = 0;
-		for (const value of collection) {
-			if (predicate(value, i, i++)) return true;
-		}
-		return false;
-	}
+  if (isArray(collection)) {
+    let i = 0;
+    for (const value of collection) {
+      if (predicate(value, i, i++)) return true;
+    }
+    return false;
+  }
 
-	if (isSet(collection)) {
-		let i = 0;
-		for (const item of collection) {
-			if (predicate(item, i, i++)) return true;
-		}
-		return false;
-	}
+  if (isSet(collection)) {
+    let i = 0;
+    for (const item of collection) {
+      if (predicate(item, i, i++)) return true;
+    }
+    return false;
+  }
 
-	// received a Map
-	if (isMap(collection)) {
-		let i = 0;
-		for (const [ key, value ] of collection.entries()) {
-			if (predicate(value, key, i++)) return true;
-		}
-		return false;
-	}
+  // received a Map
+  if (isMap(collection)) {
+    let i = 0;
+    for (const [ key, value ] of collection.entries()) {
+      if (predicate(value, key, i++)) return true;
+    }
+    return false;
+  }
 
-	// received an object hash
-	if (isObject(collection)) {
-		let i = 0;
-		for (const [ key, value ] of Object.entries(collection)) {
-			if (predicate(value, key, i++)) return true;
-		}
-		return false;
-	}
+  // received an object hash
+  if (isObject(collection)) {
+    let i = 0;
+    for (const [ key, value ] of Object.entries(collection)) {
+      if (predicate(value, key, i++)) return true;
+    }
+    return false;
+  }
 
-	return !!collection;
+  return !!collection;
 }
 
 function iteratee (match) {
-	if (isUndefined(match) || match === null) return Boolean;
+  if (isUndefined(match) || match === null) return Boolean;
 
-	if (isFunction(match)) return match;
+  if (isFunction(match)) return match;
 
-	if (isString(match)) {
-		return (o) => {
-			if (isArray(o)) return o.includes(match);
-			if (isObject(o)) return o[match];
-			if (isMap(o)) return o.get(match);
-			if (isSet(o)) return o.has(match);
-			if (isPrimitive(o)) return o[match];
-			return o === match;
-		};
-	}
+  if (isString(match)) {
+    return (o) => {
+      if (isArray(o)) return o.includes(match);
+      if (isObject(o)) return o[match];
+      if (isMap(o)) return o.get(match);
+      if (isSet(o)) return o.has(match);
+      if (isPrimitive(o)) return o[match];
+      return o === match;
+    };
+  }
 
-	if (isNumber(match)) {
-		return (o) => {
-			if (isObject(o) || isArray(o)) return o[match];
-			if (isMap(o)) return o.get(match);
-			if (isSet(o)) return o.has(match);
-			if (isNumber(o)) return o === match;
-			if (isString(o)) return Number(o) === match;
-			return o === match;
-		};
-	}
+  if (isNumber(match)) {
+    return (o) => {
+      if (isObject(o) || isArray(o)) return o[match];
+      if (isMap(o)) return o.get(match);
+      if (isSet(o)) return o.has(match);
+      if (isNumber(o)) return o === match;
+      if (isString(o)) return Number(o) === match;
+      return o === match;
+    };
+  }
 
-	if (isArray(match)) {
-		const [ key, value ] = match;
-		return (o) => o[key] === value;
-	}
+  if (isArray(match)) {
+    const [ key, value ] = match;
+    return (o) => o[key] === value;
+  }
 
-	if (isObject(match)) {
-		// create an array of key/value iteratees
-		const tests = Object.entries(match).map(iteratee);
-		// evaluate the object against the array
-		return (o) => {
-			for (const t of tests) {
-				if (!t(o)) return false;
-			}
-			return true;
-		};
-	}
+  if (isObject(match)) {
+    // create an array of key/value iteratees
+    const tests = Object.entries(match).map(iteratee);
+    // evaluate the object against the array
+    return (o) => {
+      for (const t of tests) {
+        if (!t(o)) return false;
+      }
+      return true;
+    };
+  }
 }
 
 function sorter (match) {
 
-	if (isFunction(match)) return match;
+  if (isFunction(match)) return match;
 
-	function qs (a, b) {
-		if (a > b) return 1;
-		else if (b > a) return -1;
-		return 0;
-	}
+  function qs (a, b) {
+    if (a > b) return 1;
+    else if (b > a) return -1;
+    return 0;
+  }
 
-	if (isString(match)) {
-		return (a, b) => {
-			if (!isObject(a) && !isObject(b)) return qs(a, b);
-			if (!isObject(a)) return -1;
-			if (!isObject(b)) return 1;
-			return qs(a[match], b[match]);
-		};
-	}
+  if (isString(match)) {
+    return (a, b) => {
+      if (!isObject(a) && !isObject(b)) return qs(a, b);
+      if (!isObject(a)) return -1;
+      if (!isObject(b)) return 1;
+      return qs(a[match], b[match]);
+    };
+  }
 
-	if (isArray(match)) {
-		return (a, b) => {
-			if (!isObject(a) && !isObject(b)) return qs(a, b);
-			if (!isObject(a)) return -1;
-			if (!isObject(b)) return 1;
-			for (const k of match) {
-				const v = qs(a[k], b[k]);
-				if (v) return v;
-			}
-			return 0;
-		};
-	}
+  if (isArray(match)) {
+    return (a, b) => {
+      if (!isObject(a) && !isObject(b)) return qs(a, b);
+      if (!isObject(a)) return -1;
+      if (!isObject(b)) return 1;
+      for (const k of match) {
+        const v = qs(a[k], b[k]);
+        if (v) return v;
+      }
+      return 0;
+    };
+  }
 
-	if (isObject(match)) {
-		return (a, b) => {
-			if (!isObject(a) && !isObject(b)) return qs(a, b);
-			if (!isObject(a)) return -1;
-			if (!isObject(b)) return 1;
-			for (const [ k, d ] of Object.entries(match)) {
-				const v = qs(a[k], b[k]) * (d < 0 ? -1 : 1);
-				if (v) return v;
-			}
-			return 0;
-		};
-	}
+  if (isObject(match)) {
+    return (a, b) => {
+      if (!isObject(a) && !isObject(b)) return qs(a, b);
+      if (!isObject(a)) return -1;
+      if (!isObject(b)) return 1;
+      for (const [ k, d ] of Object.entries(match)) {
+        const v = qs(a[k], b[k]) * (d < 0 ? -1 : 1);
+        if (v) return v;
+      }
+      return 0;
+    };
+  }
 
-	return (a, b) => {
-		if (!isObject(a) && !isObject(b)) return qs(a, b);
-		if (!isObject(a)) return -1;
-		if (!isObject(b)) return 1;
-		return 0;
-	};
+  return (a, b) => {
+    if (!isObject(a) && !isObject(b)) return qs(a, b);
+    if (!isObject(a)) return -1;
+    if (!isObject(b)) return 1;
+    return 0;
+  };
 }
 
 function toPairs (object) {
-	return Object.entries(object);
+  return Object.entries(object);
 }
 
 function fromPairs (entries) {
-	return mapReduce(entries, ([ v, k ]) => [ v, k ]);
+  return mapReduce(entries, ([ v, k ]) => [ v, k ]);
 }
 
 function slice (collection, begin, end) {
-	if (isString(collection) || isArray(collection)) return collection.slice(begin, end);
+  if (isString(collection) || isArray(collection)) return collection.slice(begin, end);
 
-	if (isSet(collection)) {
-		return new Set(Array.from(collection.values()).slice(begin, end));
-	}
+  if (isSet(collection)) {
+    return new Set(Array.from(collection.values()).slice(begin, end));
+  }
 
-	if (isMap(collection)) {
-		return new Map(Array.from(collection.entries()).slice(begin, end));
-	}
+  if (isMap(collection)) {
+    return new Map(Array.from(collection.entries()).slice(begin, end));
+  }
 
-	if (isObject(collection)) {
-		return fromPairs(toPairs(collection).slice(begin, end));
-	}
+  if (isObject(collection)) {
+    return fromPairs(toPairs(collection).slice(begin, end));
+  }
 
-	return collection;
+  return collection;
 }
 
 function sort (collection, predicate) {
 
-	predicate = sorter(predicate);
+  predicate = sorter(predicate);
 
-	if (isArray(collection)) return [ ...collection ].sort(predicate);
+  if (isArray(collection)) return [ ...collection ].sort(predicate);
 
-	if (isSet(collection)) {
-		return new Set(Array.from(collection.values()).sort(predicate));
-	}
+  if (isSet(collection)) {
+    return new Set(Array.from(collection.values()).sort(predicate));
+  }
 
-	// sort by key for maps and objects
-	const hashpredicate = (a, b) => predicate(a[0], b[0]);
+  // sort by key for maps and objects
+  const hashpredicate = (a, b) => predicate(a[0], b[0]);
 
-	if (isMap(collection)) {
-		return new Map(Array.from(collection.entries()).sort(hashpredicate));
-	}
+  if (isMap(collection)) {
+    return new Map(Array.from(collection.entries()).sort(hashpredicate));
+  }
 
-	if (isObject(collection)) {
-		return fromPairs(toPairs(collection).sort(hashpredicate));
-	}
+  if (isObject(collection)) {
+    return fromPairs(toPairs(collection).sort(hashpredicate));
+  }
 
-	return collection;
+  return collection;
 }
 
 function map (collection, predicate) {
-	predicate = iteratee(predicate);
+  predicate = iteratee(predicate);
 
-	if (isArray(collection)) {
-		return collection.map((value, i) => predicate(value, i, i));
-	}
+  if (isArray(collection)) {
+    return collection.map((value, i) => predicate(value, i, i));
+  }
 
-	if (isSet(collection)) {
-		return Array.from(collection, (value, i) => predicate(value, i, i));
-	}
+  if (isSet(collection)) {
+    return Array.from(collection, (value, i) => predicate(value, i, i));
+  }
 
-	return mapReduce(collection, (value, key, index) => [ key, predicate(value, key, index) ]);
+  return mapReduce(collection, (value, key, index) => [ key, predicate(value, key, index) ]);
 }
 
 function uniq (collection, predicate = null) {
-	if (predicate === null) {
-		predicate = (v) => v;
-	} else {
-		predicate = iteratee(predicate);
-	}
+  if (predicate === null) {
+    predicate = (v) => v;
+  } else {
+    predicate = iteratee(predicate);
+  }
 
-	const exists = new Set();
+  const exists = new Set();
 
-	if (isArray(collection)) {
-		const result = [];
-		collection.forEach((v) => {
-			const match = predicate(v);
-			if (exists.has(match)) return;
-			exists.add(match);
-			result.push(v);
-		});
+  if (isArray(collection)) {
+    const result = [];
+    collection.forEach((v) => {
+      const match = predicate(v);
+      if (exists.has(match)) return;
+      exists.add(match);
+      result.push(v);
+    });
 
-		return result;
-	}
+    return result;
+  }
 
-	if (isSet(collection)) return new Set(collection); // really?
+  if (isSet(collection)) return new Set(collection); // really?
 
-	if (isMap(collection)) {
-		return new Map(Array.from(collection.entries(), ([ k, v ]) => {
-			const match = predicate(v);
-			if (exists.has(match)) return false;
-			exists.add(match);
-			return [ k, v ];
-		}).filter(Boolean));
-	}
+  if (isMap(collection)) {
+    return new Map(Array.from(collection.entries(), ([ k, v ]) => {
+      const match = predicate(v);
+      if (exists.has(match)) return false;
+      exists.add(match);
+      return [ k, v ];
+    }).filter(Boolean));
+  }
 
-	if (isObject(collection)) {
-		return mapReduce(collection, ([ v, k ]) => {
-			const match = predicate(v);
-			if (exists.has(match)) return null;
-			exists.add(match);
-			return [ k, v ];
-		});
-	}
+  if (isObject(collection)) {
+    return mapReduce(collection, ([ v, k ]) => {
+      const match = predicate(v);
+      if (exists.has(match)) return null;
+      exists.add(match);
+      return [ k, v ];
+    });
+  }
 
-	return collection;
+  return collection;
 }
 
 function keyBy (collection, predicate) {
-	predicate = iteratee(predicate);
-	return mapReduce(collection, (value, key, index) =>
-		[ predicate(value, key, index), value ],
-	);
+  predicate = iteratee(predicate);
+  return mapReduce(collection, (value, key, index) =>
+    [ predicate(value, key, index), value ],
+  );
 }
 
 function groupBy (collection, predicate) {
-	predicate = iteratee(predicate);
-	return reduce(collection, (result, value, key, index) => {
-		const k = predicate(value, key, index);
-		(result[k] || (result[k] = [])).push(value);
-		return result;
-	}, {});
+  predicate = iteratee(predicate);
+  return reduce(collection, (result, value, key, index) => {
+    const k = predicate(value, key, index);
+    (result[k] || (result[k] = [])).push(value);
+    return result;
+  }, {});
 }
 
 function filter (collection, predicate) {
-	predicate = iteratee(predicate);
+  predicate = iteratee(predicate);
 
-	if (isArray(collection)) {
-		return collection.filter((value, i) => predicate(value, i, i));
-	}
+  if (isArray(collection)) {
+    return collection.filter((value, i) => predicate(value, i, i));
+  }
 
-	if (isSet(collection)) {
-		return Array.from(collection).filter((value, i) => predicate(value, i, i));
-	}
+  if (isSet(collection)) {
+    return Array.from(collection).filter((value, i) => predicate(value, i, i));
+  }
 
-	throw new Error('filter can not be applied to objects or maps, perhaps you meant to use omit?');
+  throw new Error('filter can not be applied to objects or maps, perhaps you meant to use omit?');
 }
 
 function omit (collection, predicate) {
-	if (isFunction(predicate)) {
-		return mapReduce(collection, (value, key, index) =>
-			(predicate(value, key, index)
-				? [ undefined, undefined ]
-				: [ key, value ]),
-		);
-	}
+  if (isFunction(predicate)) {
+    return mapReduce(collection, (value, key, index) =>
+      (predicate(value, key, index)
+        ? [ undefined, undefined ]
+        : [ key, value ]),
+    );
+  }
 
-	if (isString(predicate)) {
-		predicate = [ predicate ];
-	}
+  if (isString(predicate)) {
+    predicate = [ predicate ];
+  }
 
-	if (!isArray(predicate)) throw new Error('omit requires a string or array of strings');
-	return mapReduce(collection, (value, key) =>
-		(predicate.includes(key)
-			? [ undefined, undefined ]
-			: [ key, value ]),
-	);
+  if (!isArray(predicate)) throw new Error('omit requires a string or array of strings');
+  return mapReduce(collection, (value, key) =>
+    (predicate.includes(key)
+      ? [ undefined, undefined ]
+      : [ key, value ]),
+  );
 }
 
 function pick (collection, predicate) {
-	if (!collection) return {};
+  if (!collection) return {};
 
-	if (isFunction(predicate)) {
-		return mapReduce(collection, (value, key, index) =>
-			(predicate(value, key, index)
-				? [ key, value ]
-				: [ undefined, undefined ]),
-		);
-	}
+  if (isFunction(predicate)) {
+    return mapReduce(collection, (value, key, index) =>
+      (predicate(value, key, index)
+        ? [ key, value ]
+        : [ undefined, undefined ]),
+    );
+  }
 
-	if (isString(predicate)) {
-		predicate = [ predicate ];
-	}
+  if (isString(predicate)) {
+    predicate = [ predicate ];
+  }
 
-	if (!isArray(predicate)) throw new Error('pick requires a string or array of strings');
-	return predicate.reduce((obj, key) => {
-		const value = get(collection, key);
-		if (isUndefined(value)) return obj;
-		return set(obj, key, value);
-	}, {});
+  if (!isArray(predicate)) throw new Error('pick requires a string or array of strings');
+  return predicate.reduce((obj, key) => {
+    const value = get(collection, key);
+    if (isUndefined(value)) return obj;
+    return set(obj, key, value);
+  }, {});
 }
 
 
 function deepPick (collection, schema) {
-	if (isPrimitive(schema) && isPrimitive(collection)) return collection;
+  if (isPrimitive(schema) && isPrimitive(collection)) return collection;
 
-	if (isArray(schema) && schema.length > 0) {
-		// collection does not match this schema tier, abort
-		if (!isArray(collection)) return;
+  if (isArray(schema) && schema.length > 0) {
+    // collection does not match this schema tier, abort
+    if (!isArray(collection)) return;
 
-		schema = schema[0];
-		return collection.map((branch) => deepPick(branch, schema));
-	}
+    schema = schema[0];
+    return collection.map((branch) => deepPick(branch, schema));
+  }
 
-	// if the schema at this tier is not an object,
-	// return the value at this tier only if schema is truthy
-	if (!isObject(schema)) return schema ? collection : undefined;
-	if (isPrimitive(collection)) return;
+  // if the schema at this tier is not an object,
+  // return the value at this tier only if schema is truthy
+  if (!isObject(schema)) return schema ? collection : undefined;
+  if (isPrimitive(collection)) return;
 
-	// if the collection isn't something we can pull data from, skip it
-	if (!isObject(collection) && !isFunction(collection)) return;
+  // if the collection isn't something we can pull data from, skip it
+  if (!isObject(collection) && !isFunction(collection)) return;
 
-	const result = {};
-	for (const [ key, subschema ] of Object.entries(schema)) {
+  const result = {};
+  for (const [ key, subschema ] of Object.entries(schema)) {
 
-		const target = collection[key];
-		if (isUndefined(target)) continue;
+    const target = collection[key];
+    if (isUndefined(target)) continue;
 
-		const child = deepPick(target, subschema);
-		if (isUndefined(child)) continue;
+    const child = deepPick(target, subschema);
+    if (isUndefined(child)) continue;
 
-		result[key] = child;
-	}
+    result[key] = child;
+  }
 
-	return result;
+  return result;
 }
 
 
 
 function pathinate (object, delimiter = '.') {
-	const paths = [];
+  const paths = [];
 
-	function descend (branch, ancest) {
-		if (!isObject(branch)) {
-			paths.push(ancest.join(delimiter));
-			return;
-		}
-		for (const [ k, v ] of Object.entries(branch)) {
-			descend(v, ancest.concat([ k ]));
-		}
-		return;
-	}
+  function descend (branch, ancest) {
+    if (!isObject(branch)) {
+      paths.push(ancest.join(delimiter));
+      return;
+    }
+    for (const [ k, v ] of Object.entries(branch)) {
+      descend(v, ancest.concat([ k ]));
+    }
+    return;
+  }
 
-	descend(object, []);
+  descend(object, []);
 
-	return uniq(paths);
+  return uniq(paths);
 }
 
 
@@ -811,761 +810,761 @@ function pathinate (object, delimiter = '.') {
  * @return {Object}
  */
 function mapReduce (collection, cb) {
-	if (!collection) return {};
+  if (!collection) return {};
 
-	const result = {};
-	function iterate (v, k, i) {
-		// return true to continue looping
-		const res = cb(v, k, i) || [];
-		if (res === false) return false;
-		if (!res || !isArray(res)) return true;
-		const [ key, value ] = res;
-		if (key === undefined || key === null || value === undefined) return true;
-		result[key] = value;
-		return true;
-	}
+  const result = {};
+  function iterate (v, k, i) {
+    // return true to continue looping
+    const res = cb(v, k, i) || [];
+    if (res === false) return false;
+    if (!res || !isArray(res)) return true;
+    const [ key, value ] = res;
+    if (key === undefined || key === null || value === undefined) return true;
+    result[key] = value;
+    return true;
+  }
 
-	if (isArray(collection)) {
-		let i = 0;
-		for (const value of collection) {
-			if (!iterate(value, i, i++)) break;
-		}
-		return result;
-	}
+  if (isArray(collection)) {
+    let i = 0;
+    for (const value of collection) {
+      if (!iterate(value, i, i++)) break;
+    }
+    return result;
+  }
 
-	if (isSet(collection)) {
-		let i = 0;
-		for (const item of collection) {
-			if (!iterate(item, i, i++)) break;
-		}
-		return result;
-	}
+  if (isSet(collection)) {
+    let i = 0;
+    for (const item of collection) {
+      if (!iterate(item, i, i++)) break;
+    }
+    return result;
+  }
 
-	// received a Map
-	if (isMap(collection)) {
-		let i = 0;
-		for (const [ key, value ] of collection.entries()) {
-			if (!iterate(value, key, i++)) break;
-		}
-		return result;
-	}
+  // received a Map
+  if (isMap(collection)) {
+    let i = 0;
+    for (const [ key, value ] of collection.entries()) {
+      if (!iterate(value, key, i++)) break;
+    }
+    return result;
+  }
 
-	// received an object hash
-	if (isObject(collection)) {
-		let i = 0;
-		for (const [ key, value ] of Object.entries(collection)) {
-			if (!iterate(value, key, i++)) break;
-		}
-		return result;
-	}
+  // received an object hash
+  if (isObject(collection)) {
+    let i = 0;
+    for (const [ key, value ] of Object.entries(collection)) {
+      if (!iterate(value, key, i++)) break;
+    }
+    return result;
+  }
 
-	return result;
+  return result;
 }
 
 function reduce (collection, predicate, init) {
-	if (!isFunction(predicate)) throw new TypeError('Predicate must be a function');
+  if (!isFunction(predicate)) throw new TypeError('Predicate must be a function');
 
-	if (isArray(collection)) return collection.reduce((r, v, i) => predicate(r, v, i, i), init);
+  if (isArray(collection)) return collection.reduce((r, v, i) => predicate(r, v, i, i), init);
 
-	if (isSet(collection)) {
-		return Array.from(collection).reduce((r, v, i) => predicate(r, v, i, i), init);
-	}
+  if (isSet(collection)) {
+    return Array.from(collection).reduce((r, v, i) => predicate(r, v, i, i), init);
+  }
 
-	if (isMap(collection)) {
-		return Array.from(collection.entries()).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init);
-	}
+  if (isMap(collection)) {
+    return Array.from(collection.entries()).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init);
+  }
 
-	if (isObject(collection)) {
-		return Object.entries(collection).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init);
-	}
+  if (isObject(collection)) {
+    return Object.entries(collection).reduce((prev, [ key, value ], i) => predicate(prev, value, key, i), init);
+  }
 }
 
 function flatten (collection, depth = Infinity) {
-	if (depth <= 0) return slice(collection);
-	return reduce(collection,
-		(acc, val) => acc.concat(...(
-			isMappable(val)
-				? flatten(val, depth - 1)
-				: [ val ]
-		)),
-		[],
-	);
+  if (depth <= 0) return slice(collection);
+  return reduce(collection,
+    (acc, val) => acc.concat(...(
+      isMappable(val)
+        ? flatten(val, depth - 1)
+        : [ val ]
+    )),
+    [],
+  );
 }
 
 function slugify (input, delimiter = '-', separators = false) {
-	var i = separators && separators.length;
-	var slug = input;
-	var regexEscape = new RegExp(/[[/\\^$*+?.()|{}\]]/g);
-	var regexDelimiter = delimiter.replace(regexEscape, '\\$&');
-	var prohibited = new RegExp('([^a-z0-9' + regexDelimiter + '])', 'g');
-	var consecutive = new RegExp('(' + regexDelimiter + '+)', 'g');
-	var trim = new RegExp('^' + regexDelimiter + '*(.*?)' + regexDelimiter + '*$');
-	var sanitizer = {
-		// common latin
-		'á': 'a',
-		'à': 'a',
-		'â': 'a',
-		'ä': 'a',
-		'ã': 'a',
-		'æ': 'ae',
-		'ç': 'c',
-		'é': 'e',
-		'è': 'e',
-		'ê': 'e',
-		'ë': 'e',
-		'ẽ': 'e',
-		'í': 'i',
-		'ì': 'i',
-		'î': 'i',
-		'ï': 'i',
-		'ĩ': 'i',
-		'ó': 'o',
-		'ò': 'o',
-		'ô': 'o',
-		'ö': 'o',
-		'õ': 'o',
-		'œ': 'oe',
-		'ß': 'ss',
-		'ú': 'u',
-		'ù': 'u',
-		'û': 'u',
-		'ü': 'u',
-		'ũ': 'u',
+  var i = separators && separators.length;
+  var slug = input;
+  var regexEscape = new RegExp(/[[/\\^$*+?.()|{}\]]/g);
+  var regexDelimiter = delimiter.replace(regexEscape, '\\$&');
+  var prohibited = new RegExp('([^a-z0-9' + regexDelimiter + '])', 'g');
+  var consecutive = new RegExp('(' + regexDelimiter + '+)', 'g');
+  var trim = new RegExp('^' + regexDelimiter + '*(.*?)' + regexDelimiter + '*$');
+  var sanitizer = {
+    // common latin
+    'á': 'a',
+    'à': 'a',
+    'â': 'a',
+    'ä': 'a',
+    'ã': 'a',
+    'æ': 'ae',
+    'ç': 'c',
+    'é': 'e',
+    'è': 'e',
+    'ê': 'e',
+    'ë': 'e',
+    'ẽ': 'e',
+    'í': 'i',
+    'ì': 'i',
+    'î': 'i',
+    'ï': 'i',
+    'ĩ': 'i',
+    'ó': 'o',
+    'ò': 'o',
+    'ô': 'o',
+    'ö': 'o',
+    'õ': 'o',
+    'œ': 'oe',
+    'ß': 'ss',
+    'ú': 'u',
+    'ù': 'u',
+    'û': 'u',
+    'ü': 'u',
+    'ũ': 'u',
 
-		// other diacritics
-		'ă': 'a',
-		'ắ': 'a',
-		'ằ': 'a',
-		'ẵ': 'a',
-		'ẳ': 'a',
-		'ấ': 'a',
-		'ầ': 'a',
-		'ẫ': 'a',
-		'ẩ': 'a',
-		'ǎ': 'a',
-		'å': 'a',
-		'ǻ': 'a',
-		'ǟ': 'a',
-		'ȧ': 'a',
-		'ǡ': 'a',
-		'ą': 'a',
-		'ā': 'a',
-		'ả': 'a',
-		'ȁ': 'a',
-		'ȃ': 'a',
-		'ạ': 'a',
-		'ặ': 'a',
-		'ậ': 'a',
-		'ḁ': 'a',
-		'ⱥ': 'a',
-		'ᶏ': 'a',
-		'ɐ': 'a',
-		'ɑ': 'a',
+    // other diacritics
+    'ă': 'a',
+    'ắ': 'a',
+    'ằ': 'a',
+    'ẵ': 'a',
+    'ẳ': 'a',
+    'ấ': 'a',
+    'ầ': 'a',
+    'ẫ': 'a',
+    'ẩ': 'a',
+    'ǎ': 'a',
+    'å': 'a',
+    'ǻ': 'a',
+    'ǟ': 'a',
+    'ȧ': 'a',
+    'ǡ': 'a',
+    'ą': 'a',
+    'ā': 'a',
+    'ả': 'a',
+    'ȁ': 'a',
+    'ȃ': 'a',
+    'ạ': 'a',
+    'ặ': 'a',
+    'ậ': 'a',
+    'ḁ': 'a',
+    'ⱥ': 'a',
+    'ᶏ': 'a',
+    'ɐ': 'a',
+    'ɑ': 'a',
 
-		'ḃ': 'b',
-		'ḅ': 'b',
-		'ḇ': 'b',
-		'ƀ': 'b',
-		'ɓ': 'b',
-		'ƃ': 'b',
-		'ᵬ': 'b',
-		'ᶀ': 'b',
-		'þ': 'b',
+    'ḃ': 'b',
+    'ḅ': 'b',
+    'ḇ': 'b',
+    'ƀ': 'b',
+    'ɓ': 'b',
+    'ƃ': 'b',
+    'ᵬ': 'b',
+    'ᶀ': 'b',
+    'þ': 'b',
 
-		'ć': 'c',
-		'ĉ': 'c',
-		'č': 'c',
-		'ċ': 'c',
-		'ḉ': 'c',
-		'ȼ': 'c',
-		'ƈ': 'c',
-		'ɕ': 'c',
+    'ć': 'c',
+    'ĉ': 'c',
+    'č': 'c',
+    'ċ': 'c',
+    'ḉ': 'c',
+    'ȼ': 'c',
+    'ƈ': 'c',
+    'ɕ': 'c',
 
-		'ď': 'd',
-		'ḋ': 'd',
-		'ḑ': 'd',
-		'ḍ': 'd',
-		'ḓ': 'd',
-		'ḏ': 'd',
-		'đ': 'd',
-		'ɖ': 'd',
-		'ɗ': 'd',
-		'ƌ': 'd',
-		'ᵭ': 'd',
-		'ᶁ': 'd',
-		'ᶑ': 'd',
-		'ȡ': 'd',
-		'∂': 'd',
+    'ď': 'd',
+    'ḋ': 'd',
+    'ḑ': 'd',
+    'ḍ': 'd',
+    'ḓ': 'd',
+    'ḏ': 'd',
+    'đ': 'd',
+    'ɖ': 'd',
+    'ɗ': 'd',
+    'ƌ': 'd',
+    'ᵭ': 'd',
+    'ᶁ': 'd',
+    'ᶑ': 'd',
+    'ȡ': 'd',
+    '∂': 'd',
 
-		'ĕ': 'e',
-		'ế': 'e',
-		'ề': 'e',
-		'ễ': 'e',
-		'ể': 'e',
-		'ě': 'e',
-		'ė': 'e',
-		'ȩ': 'e',
-		'ḝ': 'e',
-		'ę': 'e',
-		'ē': 'e',
-		'ḗ': 'e',
-		'ḕ': 'e',
-		'ẻ': 'e',
-		'ȅ': 'e',
-		'ȇ': 'e',
-		'ẹ': 'e',
-		'ệ': 'e',
-		'ḙ': 'e',
-		'ḛ': 'e',
-		'ɇ': 'e',
-		'ᶒ': 'e',
+    'ĕ': 'e',
+    'ế': 'e',
+    'ề': 'e',
+    'ễ': 'e',
+    'ể': 'e',
+    'ě': 'e',
+    'ė': 'e',
+    'ȩ': 'e',
+    'ḝ': 'e',
+    'ę': 'e',
+    'ē': 'e',
+    'ḗ': 'e',
+    'ḕ': 'e',
+    'ẻ': 'e',
+    'ȅ': 'e',
+    'ȇ': 'e',
+    'ẹ': 'e',
+    'ệ': 'e',
+    'ḙ': 'e',
+    'ḛ': 'e',
+    'ɇ': 'e',
+    'ᶒ': 'e',
 
-		'ḟ': 'f',
-		'ƒ': 'f',
-		'ᵮ': 'f',
-		'ᶂ': 'f',
+    'ḟ': 'f',
+    'ƒ': 'f',
+    'ᵮ': 'f',
+    'ᶂ': 'f',
 
-		'ǵ': 'g',
-		'ğ': 'g',
-		'ĝ': 'g',
-		'ǧ': 'g',
-		'ġ': 'g',
-		'ģ': 'g',
-		'ḡ': 'g',
-		'ǥ': 'g',
-		'ɠ': 'g',
-		'ᶃ': 'g',
+    'ǵ': 'g',
+    'ğ': 'g',
+    'ĝ': 'g',
+    'ǧ': 'g',
+    'ġ': 'g',
+    'ģ': 'g',
+    'ḡ': 'g',
+    'ǥ': 'g',
+    'ɠ': 'g',
+    'ᶃ': 'g',
 
-		'ĥ': 'h',
-		'ȟ': 'h',
-		'ḧ': 'h',
-		'ḣ': 'h',
-		'ḩ': 'h',
-		'ḥ': 'h',
-		'ḫ': 'h',
-		'ẖ': 'h',
-		'ħ': 'h',
-		'ⱨ': 'h',
+    'ĥ': 'h',
+    'ȟ': 'h',
+    'ḧ': 'h',
+    'ḣ': 'h',
+    'ḩ': 'h',
+    'ḥ': 'h',
+    'ḫ': 'h',
+    'ẖ': 'h',
+    'ħ': 'h',
+    'ⱨ': 'h',
 
-		'ĭ': 'i',
-		'ǐ': 'i',
-		'ḯ': 'i',
-		'į': 'i',
-		'ī': 'i',
-		'ỉ': 'i',
-		'ȉ': 'i',
-		'ȋ': 'i',
-		'ị': 'i',
-		'ḭ': 'i',
-		'ɨ': 'i',
-		'ᵻ': 'i',
-		'ᶖ': 'i',
-		'i': 'i',
-		'ı': 'i',
+    'ĭ': 'i',
+    'ǐ': 'i',
+    'ḯ': 'i',
+    'į': 'i',
+    'ī': 'i',
+    'ỉ': 'i',
+    'ȉ': 'i',
+    'ȋ': 'i',
+    'ị': 'i',
+    'ḭ': 'i',
+    'ɨ': 'i',
+    'ᵻ': 'i',
+    'ᶖ': 'i',
+    'i': 'i',
+    'ı': 'i',
 
-		'ĵ': 'j',
-		'ɉ': 'j',
-		'ǰ': 'j',
-		'ȷ': 'j',
-		'ʝ': 'j',
-		'ɟ': 'j',
-		'ʄ': 'j',
+    'ĵ': 'j',
+    'ɉ': 'j',
+    'ǰ': 'j',
+    'ȷ': 'j',
+    'ʝ': 'j',
+    'ɟ': 'j',
+    'ʄ': 'j',
 
-		'ḱ': 'k',
-		'ǩ': 'k',
-		'ķ': 'k',
-		'ḳ': 'k',
-		'ḵ': 'k',
-		'ƙ': 'k',
-		'ⱪ': 'k',
-		'ᶄ': 'k',
+    'ḱ': 'k',
+    'ǩ': 'k',
+    'ķ': 'k',
+    'ḳ': 'k',
+    'ḵ': 'k',
+    'ƙ': 'k',
+    'ⱪ': 'k',
+    'ᶄ': 'k',
 
-		'ĺ': 'l',
-		'ľ': 'l',
-		'ļ': 'l',
-		'ḷ': 'l',
-		'ḹ': 'l',
-		'ḽ': 'l',
-		'ḻ': 'l',
-		'ł': 'l',
-		'ŀ': 'l',
-		'ƚ': 'l',
-		'ⱡ': 'l',
-		'ɫ': 'l',
-		'ɬ': 'l',
-		'ᶅ': 'l',
-		'ɭ': 'l',
-		'ȴ': 'l',
+    'ĺ': 'l',
+    'ľ': 'l',
+    'ļ': 'l',
+    'ḷ': 'l',
+    'ḹ': 'l',
+    'ḽ': 'l',
+    'ḻ': 'l',
+    'ł': 'l',
+    'ŀ': 'l',
+    'ƚ': 'l',
+    'ⱡ': 'l',
+    'ɫ': 'l',
+    'ɬ': 'l',
+    'ᶅ': 'l',
+    'ɭ': 'l',
+    'ȴ': 'l',
 
-		'ḿ': 'm',
-		'ṁ': 'm',
-		'ṃ': 'm',
-		'ᵯ': 'm',
-		'ᶆ': 'm',
-		'ɱ': 'm',
+    'ḿ': 'm',
+    'ṁ': 'm',
+    'ṃ': 'm',
+    'ᵯ': 'm',
+    'ᶆ': 'm',
+    'ɱ': 'm',
 
-		'ń': 'n',
-		'ǹ': 'n',
-		'ň': 'n',
-		'ñ': 'n',
-		'ṅ': 'n',
-		'ņ': 'n',
-		'ṇ': 'n',
-		'ṋ': 'n',
-		'ṉ': 'n',
-		'n̈': 'n',
-		'ɲ': 'n',
-		'ƞ': 'n',
-		'ŋ': 'n',
-		'ᵰ': 'n',
-		'ᶇ': 'n',
-		'ɳ': 'n',
-		'ȵ': 'n',
+    'ń': 'n',
+    'ǹ': 'n',
+    'ň': 'n',
+    'ñ': 'n',
+    'ṅ': 'n',
+    'ņ': 'n',
+    'ṇ': 'n',
+    'ṋ': 'n',
+    'ṉ': 'n',
+    'n̈': 'n',
+    'ɲ': 'n',
+    'ƞ': 'n',
+    'ŋ': 'n',
+    'ᵰ': 'n',
+    'ᶇ': 'n',
+    'ɳ': 'n',
+    'ȵ': 'n',
 
-		'ŏ': 'o',
-		'ố': 'o',
-		'ồ': 'o',
-		'ỗ': 'o',
-		'ổ': 'o',
-		'ǒ': 'o',
-		'ȫ': 'o',
-		'ő': 'o',
-		'ṍ': 'o',
-		'ṏ': 'o',
-		'ȭ': 'o',
-		'ȯ': 'o',
-		'͘o͘': 'o',
-		'ȱ': 'o',
-		'ø': 'o',
-		'ǿ': 'o',
-		'ǫ': 'o',
-		'ǭ': 'o',
-		'ō': 'o',
-		'ṓ': 'o',
-		'ṑ': 'o',
-		'ỏ': 'o',
-		'ȍ': 'o',
-		'ȏ': 'o',
-		'ơ': 'o',
-		'ớ': 'o',
-		'ờ': 'o',
-		'ỡ': 'o',
-		'ở': 'o',
-		'ợ': 'o',
-		'ọ': 'o',
-		'ộ': 'o',
-		'ɵ': 'o',
-		'ɔ': 'o',
+    'ŏ': 'o',
+    'ố': 'o',
+    'ồ': 'o',
+    'ỗ': 'o',
+    'ổ': 'o',
+    'ǒ': 'o',
+    'ȫ': 'o',
+    'ő': 'o',
+    'ṍ': 'o',
+    'ṏ': 'o',
+    'ȭ': 'o',
+    'ȯ': 'o',
+    '͘o͘': 'o',
+    'ȱ': 'o',
+    'ø': 'o',
+    'ǿ': 'o',
+    'ǫ': 'o',
+    'ǭ': 'o',
+    'ō': 'o',
+    'ṓ': 'o',
+    'ṑ': 'o',
+    'ỏ': 'o',
+    'ȍ': 'o',
+    'ȏ': 'o',
+    'ơ': 'o',
+    'ớ': 'o',
+    'ờ': 'o',
+    'ỡ': 'o',
+    'ở': 'o',
+    'ợ': 'o',
+    'ọ': 'o',
+    'ộ': 'o',
+    'ɵ': 'o',
+    'ɔ': 'o',
 
-		'ṕ': 'p',
-		'ṗ': 'p',
-		'ᵽ': 'p',
-		'ƥ': 'p',
-		'p̃': 'p',
-		'ᵱ': 'p',
-		'ᶈ': 'p',
+    'ṕ': 'p',
+    'ṗ': 'p',
+    'ᵽ': 'p',
+    'ƥ': 'p',
+    'p̃': 'p',
+    'ᵱ': 'p',
+    'ᶈ': 'p',
 
-		'ɋ': 'q',
-		'ƣ': 'q',
-		'ʠ': 'q',
+    'ɋ': 'q',
+    'ƣ': 'q',
+    'ʠ': 'q',
 
-		'ŕ': 'r',
-		'ř': 'r',
-		'ṙ': 'r',
-		'ŗ': 'r',
-		'ȑ': 'r',
-		'ȓ': 'r',
-		'ṛ': 'r',
-		'ṝ': 'r',
-		'ṟ': 'r',
-		'ɍ': 'r',
-		'ɽ': 'r',
-		'ᵲ': 'r',
-		'ᶉ': 'r',
-		'ɼ': 'r',
-		'ɾ': 'r',
-		'ᵳ': 'r',
+    'ŕ': 'r',
+    'ř': 'r',
+    'ṙ': 'r',
+    'ŗ': 'r',
+    'ȑ': 'r',
+    'ȓ': 'r',
+    'ṛ': 'r',
+    'ṝ': 'r',
+    'ṟ': 'r',
+    'ɍ': 'r',
+    'ɽ': 'r',
+    'ᵲ': 'r',
+    'ᶉ': 'r',
+    'ɼ': 'r',
+    'ɾ': 'r',
+    'ᵳ': 'r',
 
-		'ś': 's',
-		'ṥ': 's',
-		'ŝ': 's',
-		'š': 's',
-		'ṧ': 's',
-		'ṡẛ': 's',
-		'ş': 's',
-		'ṣ': 's',
-		'ṩ': 's',
-		'ș': 's',
-		's̩': 's',
-		'ᵴ': 's',
-		'ᶊ': 's',
-		'ʂ': 's',
-		'ȿ': 's',
+    'ś': 's',
+    'ṥ': 's',
+    'ŝ': 's',
+    'š': 's',
+    'ṧ': 's',
+    'ṡẛ': 's',
+    'ş': 's',
+    'ṣ': 's',
+    'ṩ': 's',
+    'ș': 's',
+    's̩': 's',
+    'ᵴ': 's',
+    'ᶊ': 's',
+    'ʂ': 's',
+    'ȿ': 's',
 
-		'ť': 't',
-		'ṫ': 't',
-		'ţ': 't',
-		'ṭ': 't',
-		'ț': 't',
-		'ṱ': 't',
-		'ṯ': 't',
-		'ŧ': 't',
-		'ⱦ': 't',
-		'ƭ': 't',
-		'ʈ': 't',
-		'̈ẗ': 't',
-		'ᵵ': 't',
-		'ƫ': 't',
-		'ȶ': 't',
+    'ť': 't',
+    'ṫ': 't',
+    'ţ': 't',
+    'ṭ': 't',
+    'ț': 't',
+    'ṱ': 't',
+    'ṯ': 't',
+    'ŧ': 't',
+    'ⱦ': 't',
+    'ƭ': 't',
+    'ʈ': 't',
+    '̈ẗ': 't',
+    'ᵵ': 't',
+    'ƫ': 't',
+    'ȶ': 't',
 
-		'ŭ': 'u',
-		'ǔ': 'u',
-		'ů': 'u',
-		'ǘ': 'u',
-		'ǜ': 'u',
-		'ǚ': 'u',
-		'ǖ': 'u',
-		'ű': 'u',
-		'ṹ': 'u',
-		'ų': 'u',
-		'ū': 'u',
-		'ṻ': 'u',
-		'ủ': 'u',
-		'ȕ': 'u',
-		'ȗ': 'u',
-		'ư': 'u',
-		'ứ': 'u',
-		'ừ': 'u',
-		'ữ': 'u',
-		'ử': 'u',
-		'ự': 'u',
-		'ụ': 'u',
-		'ṳ': 'u',
-		'ṷ': 'u',
-		'ṵ': 'u',
-		'ʉ': 'u',
-		'ᵾ': 'u',
-		'ᶙ': 'u',
+    'ŭ': 'u',
+    'ǔ': 'u',
+    'ů': 'u',
+    'ǘ': 'u',
+    'ǜ': 'u',
+    'ǚ': 'u',
+    'ǖ': 'u',
+    'ű': 'u',
+    'ṹ': 'u',
+    'ų': 'u',
+    'ū': 'u',
+    'ṻ': 'u',
+    'ủ': 'u',
+    'ȕ': 'u',
+    'ȗ': 'u',
+    'ư': 'u',
+    'ứ': 'u',
+    'ừ': 'u',
+    'ữ': 'u',
+    'ử': 'u',
+    'ự': 'u',
+    'ụ': 'u',
+    'ṳ': 'u',
+    'ṷ': 'u',
+    'ṵ': 'u',
+    'ʉ': 'u',
+    'ᵾ': 'u',
+    'ᶙ': 'u',
 
-		'ṽ': 'v',
-		'ṿ': 'v',
-		'ʋ': 'v',
-		'ᶌ': 'v',
-		'ⱴ': 'v',
+    'ṽ': 'v',
+    'ṿ': 'v',
+    'ʋ': 'v',
+    'ᶌ': 'v',
+    'ⱴ': 'v',
 
-		'ẃ': 'w',
-		'ẁ': 'w',
-		'ŵ': 'w',
-		'ẅ': 'w',
-		'ẇ': 'w',
-		'ẉ': 'w',
-		'ẘ': 'w',
+    'ẃ': 'w',
+    'ẁ': 'w',
+    'ŵ': 'w',
+    'ẅ': 'w',
+    'ẇ': 'w',
+    'ẉ': 'w',
+    'ẘ': 'w',
 
-		'ẍ': 'x',
-		'ẋ': 'x',
-		'ᶍ': 'x',
+    'ẍ': 'x',
+    'ẋ': 'x',
+    'ᶍ': 'x',
 
-		'ý': 'y',
-		'ỳ': 'y',
-		'ŷ': 'y',
-		'ẙ': 'y',
-		'ÿ': 'y',
-		'ỹ': 'y',
-		'ẏ': 'y',
-		'ȳ': 'y',
-		'ỷ': 'y',
-		'ỵ': 'y',
-		'ɏ': 'y',
-		'ƴ': 'y',
-		'ʏ': 'y',
+    'ý': 'y',
+    'ỳ': 'y',
+    'ŷ': 'y',
+    'ẙ': 'y',
+    'ÿ': 'y',
+    'ỹ': 'y',
+    'ẏ': 'y',
+    'ȳ': 'y',
+    'ỷ': 'y',
+    'ỵ': 'y',
+    'ɏ': 'y',
+    'ƴ': 'y',
+    'ʏ': 'y',
 
-		'ź': 'z',
-		'ẑ': 'z',
-		'ž': 'z',
-		'ż': 'z',
-		'ẓ': 'z',
-		'ẕ': 'z',
-		'ƶ': 'z',
-		'ȥ': 'z',
-		'ⱬ': 'z',
-		'ᵶ': 'z',
-		'ᶎ': 'z',
-		'ʐ': 'z',
-		'ʑ': 'z',
-		'ɀ': 'z',
+    'ź': 'z',
+    'ẑ': 'z',
+    'ž': 'z',
+    'ż': 'z',
+    'ẓ': 'z',
+    'ẕ': 'z',
+    'ƶ': 'z',
+    'ȥ': 'z',
+    'ⱬ': 'z',
+    'ᵶ': 'z',
+    'ᶎ': 'z',
+    'ʐ': 'z',
+    'ʑ': 'z',
+    'ɀ': 'z',
 
-		// greek
-		'α': 'a',
-		'β': 'b',
-		'γ': 'g',
-		'ɣ': 'g',
-		'δ': 'd',
-		'ð': 'd',
-		'ε': 'e',
-		'ζ': 'z',
-		'η': 'i',
-		'θ': 'th',
-		'ι': 'i',
-		'κ': 'k',
-		'λ': 'l',
-		'μ': 'm',
-		'µ': 'm',
-		'ν': 'n',
-		'ξ': 'x',
-		'ο': 'o',
-		'π': 'p',
-		'ρ': 'r',
-		'σ': 's',
-		'ς': 's',
-		'τ': 't',
-		'υ': 'u', // official rule: if preceeded by 'α' OR 'ε' => 'v', by 'ο' => 'u', else => 'i'
-		'φ': 'f',
-		'χ': 'ch',
-		'ψ': 'ps',
-		'ω': 'o',
+    // greek
+    'α': 'a',
+    'β': 'b',
+    'γ': 'g',
+    'ɣ': 'g',
+    'δ': 'd',
+    'ð': 'd',
+    'ε': 'e',
+    'ζ': 'z',
+    'η': 'i',
+    'θ': 'th',
+    'ι': 'i',
+    'κ': 'k',
+    'λ': 'l',
+    'μ': 'm',
+    'µ': 'm',
+    'ν': 'n',
+    'ξ': 'x',
+    'ο': 'o',
+    'π': 'p',
+    'ρ': 'r',
+    'σ': 's',
+    'ς': 's',
+    'τ': 't',
+    'υ': 'u', // official rule: if preceeded by 'α' OR 'ε' => 'v', by 'ο' => 'u', else => 'i'
+    'φ': 'f',
+    'χ': 'ch',
+    'ψ': 'ps',
+    'ω': 'o',
 
-		// greek diacritics
-		'ᾳ': 'a',
-		'ά': 'a',
-		'ὰ': 'a',
-		'ᾴ': 'a',
-		'ᾲ': 'a',
-		'ᾶ': 'a',
-		'ᾷ': 'a',
-		'ἀ': 'a',
-		'ᾀ': 'a',
-		'ἄ': 'a',
-		'ᾄ': 'a',
-		'ἂ': 'a',
-		'ᾂ': 'a',
-		'ἆ': 'a',
-		'ᾆ': 'a',
-		'ἁ': 'a',
-		'ᾁ': 'a',
-		'ἅ': 'a',
-		'ᾅ': 'a',
-		'ἃ': 'a',
-		'ᾃ': 'a',
-		'ἇ': 'a',
-		'ᾇ': 'a',
-		'ᾱ': 'a',
-		'ᾰ': 'a',
+    // greek diacritics
+    'ᾳ': 'a',
+    'ά': 'a',
+    'ὰ': 'a',
+    'ᾴ': 'a',
+    'ᾲ': 'a',
+    'ᾶ': 'a',
+    'ᾷ': 'a',
+    'ἀ': 'a',
+    'ᾀ': 'a',
+    'ἄ': 'a',
+    'ᾄ': 'a',
+    'ἂ': 'a',
+    'ᾂ': 'a',
+    'ἆ': 'a',
+    'ᾆ': 'a',
+    'ἁ': 'a',
+    'ᾁ': 'a',
+    'ἅ': 'a',
+    'ᾅ': 'a',
+    'ἃ': 'a',
+    'ᾃ': 'a',
+    'ἇ': 'a',
+    'ᾇ': 'a',
+    'ᾱ': 'a',
+    'ᾰ': 'a',
 
-		'έ': 'e',
-		'ὲ': 'e',
-		'ἐ': 'e',
-		'ἔ': 'e',
-		'ἒ': 'e',
-		'ἑ': 'e',
-		'ἕ': 'e',
-		'ἓ': 'e',
+    'έ': 'e',
+    'ὲ': 'e',
+    'ἐ': 'e',
+    'ἔ': 'e',
+    'ἒ': 'e',
+    'ἑ': 'e',
+    'ἕ': 'e',
+    'ἓ': 'e',
 
-		'ῃ': 'i',
-		'ή': 'i',
-		'ὴ': 'i',
-		'ῄ': 'i',
-		'ῂ': 'i',
-		'ῆ': 'i',
-		'ῇ': 'i',
-		'ἠ': 'i',
-		'ᾐ': 'i',
-		'ἤ': 'i',
-		'ᾔ': 'i',
-		'ἢ': 'i',
-		'ᾒ': 'i',
-		'ἦ': 'i',
-		'ᾖ': 'i',
-		'ἡ': 'i',
-		'ᾑ': 'i',
-		'ἥ': 'i',
-		'ᾕ': 'i',
-		'ἣ': 'i',
-		'ᾓ': 'i',
-		'ἧ': 'i',
-		'ᾗ': 'i',
+    'ῃ': 'i',
+    'ή': 'i',
+    'ὴ': 'i',
+    'ῄ': 'i',
+    'ῂ': 'i',
+    'ῆ': 'i',
+    'ῇ': 'i',
+    'ἠ': 'i',
+    'ᾐ': 'i',
+    'ἤ': 'i',
+    'ᾔ': 'i',
+    'ἢ': 'i',
+    'ᾒ': 'i',
+    'ἦ': 'i',
+    'ᾖ': 'i',
+    'ἡ': 'i',
+    'ᾑ': 'i',
+    'ἥ': 'i',
+    'ᾕ': 'i',
+    'ἣ': 'i',
+    'ᾓ': 'i',
+    'ἧ': 'i',
+    'ᾗ': 'i',
 
-		'ί': 'i',
-		'ὶ': 'i',
-		'ῖ': 'i',
-		'ἰ': 'i',
-		'ἴ': 'i',
-		'ἲ': 'i',
-		'ἶ': 'i',
-		'ἱ': 'i',
-		'ἵ': 'i',
-		'ἳ': 'i',
-		'ἷ': 'i',
-		'ϊ': 'i',
-		'ΐ': 'i',
-		'ῒ': 'i',
-		'ῗ': 'i',
-		'ῑ': 'i',
-		'ῐ': 'i',
+    'ί': 'i',
+    'ὶ': 'i',
+    'ῖ': 'i',
+    'ἰ': 'i',
+    'ἴ': 'i',
+    'ἲ': 'i',
+    'ἶ': 'i',
+    'ἱ': 'i',
+    'ἵ': 'i',
+    'ἳ': 'i',
+    'ἷ': 'i',
+    'ϊ': 'i',
+    'ΐ': 'i',
+    'ῒ': 'i',
+    'ῗ': 'i',
+    'ῑ': 'i',
+    'ῐ': 'i',
 
-		'ό': 'o',
-		'ὸ': 'o',
-		'ὀ': 'o',
-		'ὄ': 'o',
-		'ὂ': 'o',
-		'ὁ': 'o',
-		'ὅ': 'o',
-		'ὃ': 'o',
+    'ό': 'o',
+    'ὸ': 'o',
+    'ὀ': 'o',
+    'ὄ': 'o',
+    'ὂ': 'o',
+    'ὁ': 'o',
+    'ὅ': 'o',
+    'ὃ': 'o',
 
-		'ύ': 'u',
-		'ὺ': 'u',
-		'ῦ': 'u',
-		'ὐ': 'u',
-		'ὔ': 'u',
-		'ὒ': 'u',
-		'ὖ': 'u',
-		'ὑ': 'u',
-		'ὕ': 'u',
-		'ὓ': 'u',
-		'ὗ': 'u',
-		'ϋ': 'u',
-		'ΰ': 'u',
-		'ῢ': 'u',
-		'ῧ': 'u',
-		'ῡ': 'u',
-		'ῠ': 'u',
+    'ύ': 'u',
+    'ὺ': 'u',
+    'ῦ': 'u',
+    'ὐ': 'u',
+    'ὔ': 'u',
+    'ὒ': 'u',
+    'ὖ': 'u',
+    'ὑ': 'u',
+    'ὕ': 'u',
+    'ὓ': 'u',
+    'ὗ': 'u',
+    'ϋ': 'u',
+    'ΰ': 'u',
+    'ῢ': 'u',
+    'ῧ': 'u',
+    'ῡ': 'u',
+    'ῠ': 'u',
 
-		'ῳ': 'o',
-		'ώ': 'o',
-		'ῴ': 'o',
-		'ὼ': 'o',
-		'ῲ': 'o',
-		'ῶ': 'o',
-		'ῷ': 'o',
-		'ὠ': 'o',
-		'ᾠ': 'o',
-		'ὤ': 'o',
-		'ᾤ': 'o',
-		'ὢ': 'o',
-		'ᾢ': 'o',
-		'ὦ': 'o',
-		'ᾦ': 'o',
-		'ὡ': 'o',
-		'ᾡ': 'o',
-		'ὥ': 'o',
-		'ᾥ': 'o',
-		'ὣ': 'o',
-		'ᾣ': 'o',
-		'ὧ': 'o',
-		'ᾧ': 'o',
+    'ῳ': 'o',
+    'ώ': 'o',
+    'ῴ': 'o',
+    'ὼ': 'o',
+    'ῲ': 'o',
+    'ῶ': 'o',
+    'ῷ': 'o',
+    'ὠ': 'o',
+    'ᾠ': 'o',
+    'ὤ': 'o',
+    'ᾤ': 'o',
+    'ὢ': 'o',
+    'ᾢ': 'o',
+    'ὦ': 'o',
+    'ᾦ': 'o',
+    'ὡ': 'o',
+    'ᾡ': 'o',
+    'ὥ': 'o',
+    'ᾥ': 'o',
+    'ὣ': 'o',
+    'ᾣ': 'o',
+    'ὧ': 'o',
+    'ᾧ': 'o',
 
-		'ῤ': 'r',
-		'ῥ': 'r',
+    'ῤ': 'r',
+    'ῥ': 'r',
 
-		// cyrillic (russian)
-		'а': 'a',
-		'б': 'b',
-		'в': 'v',
-		'г': 'g',
-		'д': 'd',
-		'е': 'e',
-		'ё': 'e',
-		'ж': 'zh',
-		'з': 'z',
-		'и': 'i',
-		'й': 'j',
-		'к': 'k',
-		'л': 'l',
-		'м': 'm',
-		'н': 'n',
-		'о': 'o',
-		'п': 'p',
-		'р': 'r',
-		'с': 's',
-		'т': 't',
-		'у': 'u',
-		'ф': 'f',
-		'х': 'h',
-		'ц': 'ts',
-		'ч': 'ch',
-		'ш': 'sh',
-		'щ': 'sh',
-		'ъ': '',
-		'ы': 'i',
-		'ь': '',
-		'э': 'e',
-		'ю': 'yu',
-		'я': 'ya',
-		// ---
-		'і': 'j',
-		'ѳ': 'f',
-		'ѣ': 'e',
-		'ѵ': 'i',
-		'ѕ': 'z',
-		'ѯ': 'ks',
-		'ѱ': 'ps',
-		'ѡ': 'o',
-		'ѫ': 'yu',
-		'ѧ': 'ya',
-		'ѭ': 'yu',
-		'ѩ': 'ya',
+    // cyrillic (russian)
+    'а': 'a',
+    'б': 'b',
+    'в': 'v',
+    'г': 'g',
+    'д': 'd',
+    'е': 'e',
+    'ё': 'e',
+    'ж': 'zh',
+    'з': 'z',
+    'и': 'i',
+    'й': 'j',
+    'к': 'k',
+    'л': 'l',
+    'м': 'm',
+    'н': 'n',
+    'о': 'o',
+    'п': 'p',
+    'р': 'r',
+    'с': 's',
+    'т': 't',
+    'у': 'u',
+    'ф': 'f',
+    'х': 'h',
+    'ц': 'ts',
+    'ч': 'ch',
+    'ш': 'sh',
+    'щ': 'sh',
+    'ъ': '',
+    'ы': 'i',
+    'ь': '',
+    'э': 'e',
+    'ю': 'yu',
+    'я': 'ya',
+    // ---
+    'і': 'j',
+    'ѳ': 'f',
+    'ѣ': 'e',
+    'ѵ': 'i',
+    'ѕ': 'z',
+    'ѯ': 'ks',
+    'ѱ': 'ps',
+    'ѡ': 'o',
+    'ѫ': 'yu',
+    'ѧ': 'ya',
+    'ѭ': 'yu',
+    'ѩ': 'ya',
 
-		// currency
-		'₳': 'ARA',
-		'฿': 'THB',
-		'₵': 'GHS',
-		'¢': 'c',
-		'₡': 'CRC',
-		'₢': 'Cr',
-		'₠': 'XEU',
-		'$': 'USD',
-		'₫': 'VND',
-		'৳': 'BDT',
-		'₯': 'GRD',
-		'€': 'EUR',
-		'₣': 'FRF',
-		'₲': 'PYG',
-		'₴': 'HRN',
-		'₭': 'LAK',
-		'₦': 'NGN',
-		'₧': 'ESP',
-		'₱': 'PhP',
-		'£': 'GBP',
-		'₤': 'GBP',
-		'₨': 'Rs',
-		'₪': 'NS',
-		'₮': 'MNT',
-		'₩': 'WON',
-		'¥': 'YEN',
-		'៛': 'KHR',
+    // currency
+    '₳': 'ARA',
+    '฿': 'THB',
+    '₵': 'GHS',
+    '¢': 'c',
+    '₡': 'CRC',
+    '₢': 'Cr',
+    '₠': 'XEU',
+    '$': 'USD',
+    '₫': 'VND',
+    '৳': 'BDT',
+    '₯': 'GRD',
+    '€': 'EUR',
+    '₣': 'FRF',
+    '₲': 'PYG',
+    '₴': 'HRN',
+    '₭': 'LAK',
+    '₦': 'NGN',
+    '₧': 'ESP',
+    '₱': 'PhP',
+    '£': 'GBP',
+    '₤': 'GBP',
+    '₨': 'Rs',
+    '₪': 'NS',
+    '₮': 'MNT',
+    '₩': 'WON',
+    '¥': 'YEN',
+    '៛': 'KHR',
 
-		// separators
-		'–': delimiter,
-		'—': delimiter,
-		'―': delimiter,
-		'~': delimiter,
-		'/': delimiter,
-		'\\': delimiter,
-		'|': delimiter,
-		'+': delimiter,
-		'‘': delimiter,
-		'’': delimiter,
-		'\'': delimiter,
-		' ': delimiter,
+    // separators
+    '–': delimiter,
+    '—': delimiter,
+    '―': delimiter,
+    '~': delimiter,
+    '/': delimiter,
+    '\\': delimiter,
+    '|': delimiter,
+    '+': delimiter,
+    '‘': delimiter,
+    '’': delimiter,
+    '\'': delimiter,
+    ' ': delimiter,
 
-		// permitted by default but can be overridden
-		'-': '-',
-		'_': '_',
-	};
+    // permitted by default but can be overridden
+    '-': '-',
+    '_': '_',
+  };
 
-	// add any user-defined separator elements
-	if (separators) {
-		for (i; i >= 0; --i) {
-			sanitizer[separators[i]] = delimiter;
-		}
-	}
+  // add any user-defined separator elements
+  if (separators) {
+    for (i; i >= 0; --i) {
+      sanitizer[separators[i]] = delimiter;
+    }
+  }
 
-	// do all the replacements
-	slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the prohibited filter
-	slug = slug.replace(prohibited, (match) => sanitizer[match] || '');
-	slug = slug.replace(consecutive, delimiter);
-	slug = slug.replace(trim, '$1');
+  // do all the replacements
+  slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the prohibited filter
+  slug = slug.replace(prohibited, (match) => sanitizer[match] || '');
+  slug = slug.replace(consecutive, delimiter);
+  slug = slug.replace(trim, '$1');
 
-	return slug;
+  return slug;
 }
 
 exports.all = all;
diff --git a/js/.eslintrc.js b/js/.eslintrc.js
index 8caa274..459f7c7 100644
--- a/js/.eslintrc.js
+++ b/js/.eslintrc.js
@@ -1,27 +1,27 @@
 
 module.exports = exports = {
-  extends: "twipped/browser",
-  env: {es6: true, jquery: true},
+  extends: 'twipped/browser',
+  env: { es6: true, jquery: true },
   rules: {
     'indent': [ 2, 2, {
       'MemberExpression': 1,
     } ],
     'prefer-arrow-callback': 0,
     'object-shorthand': 0,
-    'node/no-unsupported-features/node-builtins': 0
+    'node/no-unsupported-features/node-builtins': 0,
   },
   overrides: [
     {
       files: '$*.jsx',
-      extends: "twipped/react",
+      extends: 'twipped/react',
       rules: {
-        'react/jsx-indent': [2, 2, {checkAttributes: true}],
-        "react/no-unknown-property": [2, { ignore: ['class'] }],
+        'react/jsx-indent': [ 2, 2, { checkAttributes: true } ],
+        'react/no-unknown-property': [ 2, { ignore: [ 'class' ] } ],
         'node/no-unpublished-import': 0,
-        "node/no-missing-import": ["error", {
-          "allowModules": ["svg", 'react']
-        }]
-      }
-    }
-  ]
+        'node/no-missing-import': [ 'error', {
+          'allowModules': [ 'svg', 'react' ],
+        } ],
+      },
+    },
+  ],
 };
diff --git a/package.json b/package.json
index 6e0fe03..77dbd53 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,8 @@
   "version": "1.0.0",
   "description": "Code for construction of the GenderDysphoria.fyi website",
   "scripts": {
-    "test": "eslint ./ --fix"
+    "test": "eslint 'build/**/*.js' 'js/**/*.{js,jsx}' 'terraform/**/*.js' --fix",
+    "build": "gulp prod"
   },
   "engines": {
     "node": ">=12.14.0"
diff --git a/terraform/files/decorate/index.js b/terraform/files/decorate/index.js
index d4b23ee..0e57003 100644
--- a/terraform/files/decorate/index.js
+++ b/terraform/files/decorate/index.js
@@ -1,11 +1,10 @@
 /* eslint no-console:0 */
-/* global URLSearchParams */
 
 const AWS = require('aws-sdk');
 const zlib = require('zlib');
 const util = require('util');
 const path = require('path');
-const {URL} = require('url');
+const { URL } = require('url');
 const s3 = new AWS.S3();
 const { parse: parseLog } = require('cloudfront-log-parser');
 const parseUA = require('ua-parser-js');
@@ -56,7 +55,6 @@ exports.handler = async (event) => {
     if (!query.start) return null;
 
     const useragent = parseUA(row.cs_user_agent);
-    const { referer } = query;
 
     const sessionStart = Number(query.start);
     const sessionEnd = query.end === 'null' ? 0 : Number(query.end);
diff --git a/terraform/files/decorate/package-lock.json b/terraform/files/decorate/package-lock.json
index 748c795..262d3da 100644
--- a/terraform/files/decorate/package-lock.json
+++ b/terraform/files/decorate/package-lock.json
@@ -4,6 +4,37 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "aws-sdk": {
+      "version": "2.975.0",
+      "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.975.0.tgz",
+      "integrity": "sha512-cmRcM+gU+rfW1RZjca3bdbRTQV6WHuCI6NuqnDgd5HoqufylCrNI/wtysPK1IMJLsAhrcsY0U0YRx+Y/hxQNoQ==",
+      "requires": {
+        "buffer": "4.9.2",
+        "events": "1.1.1",
+        "ieee754": "1.1.13",
+        "jmespath": "0.15.0",
+        "querystring": "0.2.0",
+        "sax": "1.2.1",
+        "url": "0.10.3",
+        "uuid": "3.3.2",
+        "xml2js": "0.4.19"
+      }
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+    },
+    "buffer": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+      "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      }
+    },
     "cloudfront-log-parser": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/cloudfront-log-parser/-/cloudfront-log-parser-1.1.0.tgz",
@@ -14,10 +45,73 @@
       "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.9.0.tgz",
       "integrity": "sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA=="
     },
+    "events": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
+    },
+    "ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+    },
+    "jmespath": {
+      "version": "0.15.0",
+      "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
+      "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
+    },
+    "punycode": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+    },
+    "sax": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+      "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
+    },
     "ua-parser-js": {
       "version": "0.7.21",
       "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
       "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ=="
+    },
+    "url": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
+      "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      }
+    },
+    "uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+    },
+    "xml2js": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+      "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+      "requires": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~9.0.1"
+      }
+    },
+    "xmlbuilder": {
+      "version": "9.0.7",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
     }
   }
 }
diff --git a/terraform/files/decorate/package.json b/terraform/files/decorate/package.json
index 7f6a5ec..d0f5a0d 100644
--- a/terraform/files/decorate/package.json
+++ b/terraform/files/decorate/package.json
@@ -9,6 +9,7 @@
   "author": "Jocelyn Badgley <joc@twipped.com> (http://twipped.com/)",
   "license": "MIT",
   "dependencies": {
+    "aws-sdk": "~2.975.0",
     "cloudfront-log-parser": "~1.1.0",
     "date-fns": "~2.9.0",
     "ua-parser-js": "~0.7.21"
diff --git a/terraform/files/index_redirect.js b/terraform/files/index_redirect.js
index c0805ce..7341aba 100644
--- a/terraform/files/index_redirect.js
+++ b/terraform/files/index_redirect.js
@@ -3,7 +3,7 @@
 // This should be deployed as a Lambda@Edge connected to the CloudFront Distribution
 // Only Node.js 10.x Runtime supports Lambda@Edge for right now, we have to wait for AWS to support 12x and beyond
 
-exports.handler = async (event, context) => {
+exports.handler = async (event) => {
   /*
    * Expand S3 request to have index.html if it ends in /
    */
diff --git a/terraform/lambda/src/cloudfront.js b/terraform/lambda/src/cloudfront.js
index de4cf6b..be2ceb6 100644
--- a/terraform/lambda/src/cloudfront.js
+++ b/terraform/lambda/src/cloudfront.js
@@ -1,3 +1,5 @@
+/* eslint no-console: 0 */
+
 const { gunzip } = require('zlib');
 const { promisify } = require('util');
 const { S3 } = require('aws-sdk');
diff --git a/terraform/lambda/src/cloudwatch-logs.js b/terraform/lambda/src/cloudwatch-logs.js
index dca5e73..c745b8e 100644
--- a/terraform/lambda/src/cloudwatch-logs.js
+++ b/terraform/lambda/src/cloudwatch-logs.js
@@ -1,7 +1,7 @@
 const { CloudWatchLogs } = require('aws-sdk');
 
 // Split up ARN like "arn:aws:logs:eu-west-1:123456789012:log-group:example-group:*"
-const [,,, region,,, logGroupName] = process.env.CLOUDWATCH_LOGS_GROUP_ARN.split(':');
+const [ ,,, region,,, logGroupName ] = process.env.CLOUDWATCH_LOGS_GROUP_ARN.split(':');
 
 const cloudwatchlogs = new CloudWatchLogs({ region });