Repository: preactjs/preact-render-to-string
Pull request #241 (2022-08-22 03:39:25)

Perf Improvements 3
This improves performance by another 5-10% compared to master (5.2.2):
<img width="442" alt="Screen Shot 2022-08-21 at 6 36 54 PM" src="https://user-images.githubusercontent.com/105127/185834293-acd2ce9c-56ab-4463-bd51-9d929c05880b.png">

It also corrects the type definitions, reduces size by ~50% and removes pretty-printing entirely from the default bundle. It can still be accessed via `preact-render-to-string/jsx`.

**Because of the exports/options change, I'm marking this as a major release.**


Patch:
diff --git a/.changeset/bright-ligers-jam.md b/.changeset/bright-ligers-jam.md
new file mode 100644
index 0000000..e27d54c
--- /dev/null
+++ b/.changeset/bright-ligers-jam.md
@@ -0,0 +1,5 @@
+---
+"preact-render-to-string": major
+---
+
+Improve performance by another 5-10% using `switch` and short-circuiting, and move pretty-printing from into `preact-render-to-string/jsx`.
diff --git a/.gitignore b/.gitignore
index 741ba4e..b56b515 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@
 /npm-debug.log
 .DS_Store
 /src/preact-render-to-string-tests.d.ts
-/benchmarks/.v8.modern.js
\ No newline at end of file
+/benchmarks/.v8.mjs
diff --git a/benchmarks/index.js b/benchmarks/index.js
index f90fb43..8066541 100644
--- a/benchmarks/index.js
+++ b/benchmarks/index.js
@@ -2,7 +2,7 @@ import { h } from 'preact';
 import Suite from 'benchmarkjs-pretty';
 import renderToStringBaseline from './lib/render-to-string';
 // import renderToString from '../src/index';
-import renderToString from '../dist/index.mjs';
+import renderToString from '../dist/index.module.js';
 import TextApp from './text';
 // import StackApp from './stack';
 import { App as IsomorphicSearchResults } from './isomorphic-ui/search-results/index';
diff --git a/benchmarks/lib/render-to-string.js b/benchmarks/lib/render-to-string.js
index 6b6f152..de44f9c 100644
--- a/benchmarks/lib/render-to-string.js
+++ b/benchmarks/lib/render-to-string.js
@@ -1,12 +1,12 @@
 /* eslint-disable */
-// preact-render-to-string@5.1.22 (7cdf4d6)
-import { Fragment as e, options as t } from 'preact';
-var r = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i,
-	n = /^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/,
-	o = /[\s\n\\/='"\0<>]/,
-	i = /^xlink:?./,
+// preact-render-to-string@5.2.6 (6a0bec2)
+import { Fragment as e, options as t, h as r } from 'preact';
+var n = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i,
+	o = /^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/,
+	i = /[\s\n\\/='"\0<>]/,
+	l = /^xlink:?./,
 	a = /["&<]/;
-function l(e) {
+function s(e) {
 	if (!1 === a.test((e += ''))) return e;
 	for (var t = 0, r = 0, n = '', o = ''; r < e.length; r++) {
 		switch (e.charCodeAt(r)) {
@@ -26,10 +26,10 @@ function l(e) {
 	}
 	return r !== t && (n += e.slice(t, r)), n;
 }
-var s = function (e, t) {
+var f = function (e, t) {
 		return String(e).replace(/(\n+)/g, '$1' + (t || '\t'));
 	},
-	f = function (e, t, r) {
+	u = function (e, t, r) {
 		return (
 			String(e).length > (t || 40) ||
 			(!r && -1 !== String(e).indexOf('\n')) ||
@@ -37,76 +37,77 @@ var s = function (e, t) {
 		);
 	},
 	c = {},
-	u = /([A-Z])/g;
+	_ = /([A-Z])/g;
 function p(e) {
 	var t = '';
-	for (var n in e) {
-		var o = e[n];
+	for (var r in e) {
+		var o = e[r];
 		null != o &&
 			'' !== o &&
 			(t && (t += ' '),
 			(t +=
-				'-' == n[0] ? n : c[n] || (c[n] = n.replace(u, '-$1').toLowerCase())),
+				'-' == r[0] ? r : c[r] || (c[r] = r.replace(_, '-$1').toLowerCase())),
 			(t =
-				'number' == typeof o && !1 === r.test(n)
+				'number' == typeof o && !1 === n.test(r)
 					? t + ': ' + o + 'px;'
 					: t + ': ' + o + ';'));
 	}
 	return t || void 0;
 }
-function _(e, t) {
+function d(e, t) {
 	return (
-		Array.isArray(t) ? t.reduce(_, e) : null != t && !1 !== t && e.push(t), e
+		Array.isArray(t) ? t.reduce(d, e) : null != t && !1 !== t && e.push(t), e
 	);
 }
-function d() {
+function v() {
 	this.__d = !0;
 }
-function v(e, t) {
+function h(e, t) {
 	return {
 		__v: e,
 		context: t,
 		props: e.props,
-		setState: d,
-		forceUpdate: d,
+		setState: v,
+		forceUpdate: v,
 		__d: !0,
 		__h: []
 	};
 }
-function h(e, t) {
+function g(e, t) {
 	var r = e.contextType,
 		n = r && t[r.__c];
 	return null != r ? (n ? n.props.value : r.__) : t;
 }
-var g = [];
-function y(r, a, c, u, d, m) {
+var y = [];
+function m(r, n, a, c, _, v) {
 	if (null == r || 'boolean' == typeof r) return '';
-	if ('object' != typeof r) return l(r);
-	var b = c.pretty,
+	if ('object' != typeof r) return 'function' == typeof r ? '' : s(r);
+	var b = a.pretty,
 		x = b && 'string' == typeof b ? b : '\t';
 	if (Array.isArray(r)) {
 		for (var k = '', S = 0; S < r.length; S++)
-			b && S > 0 && (k += '\n'), (k += y(r[S], a, c, u, d, m));
+			b && S > 0 && (k += '\n'), (k += m(r[S], n, a, c, _, v));
 		return k;
 	}
+	if (void 0 !== r.constructor) return '';
 	var w,
 		C = r.type,
 		O = r.props,
 		j = !1;
 	if ('function' == typeof C) {
-		if (((j = !0), !c.shallow || (!u && !1 !== c.renderRootComponent))) {
+		if (((j = !0), !a.shallow || (!c && !1 !== a.renderRootComponent))) {
 			if (C === e) {
 				var A = [];
 				return (
-					_(A, r.props.children), y(A, a, c, !1 !== c.shallowHighOrder, d, m)
+					d(A, r.props.children), m(A, n, a, !1 !== a.shallowHighOrder, _, v)
 				);
 			}
 			var F,
-				H = (r.__c = v(r, a));
+				H = (r.__c = h(r, n));
 			t.__b && t.__b(r);
 			var M = t.__r;
 			if (C.prototype && 'function' == typeof C.prototype.render) {
-				var L = h(C, a);
+				var L = g(C, n);
 				((H = r.__c = new C(O, L)).__v = r),
 					(H._dirty = H.__d = !0),
 					(H.props = O),
@@ -132,12 +133,12 @@ function y(r, a, c, u, d, m) {
 					M && M(r),
 					(F = H.render(H.props, H.state, H.context));
 			} else
-				for (var T = h(C, a), E = 0; H.__d && E++ < 25; )
+				for (var T = g(C, n), E = 0; H.__d && E++ < 25; )
 					(H.__d = !1), M && M(r), (F = C.call(r.__c, O, T));
 			return (
-				H.getChildContext && (a = Object.assign({}, a, H.getChildContext())),
+				H.getChildContext && (n = Object.assign({}, n, H.getChildContext())),
 				t.diffed && t.diffed(r),
-				y(F, a, c, !1 !== c.shallowHighOrder, d, m)
+				m(F, n, a, !1 !== a.shallowHighOrder, _, v)
 			);
 		}
 		C =
@@ -148,12 +149,12 @@ function y(r, a, c, u, d, m) {
 					.call(e)
 					.match(/^\s*function\s+([^( ]+)/) || '')[1];
 				if (!t) {
-					for (var r = -1, n = g.length; n--; )
-						if (g[n] === e) {
+					for (var r = -1, n = y.length; n--; )
+						if (y[n] === e) {
 							r = n;
 							break;
 						}
-					r < 0 && (r = g.push(e) - 1), (t = 'UnnamedComponent' + r);
+					r < 0 && (r = y.push(e) - 1), (t = 'UnnamedComponent' + r);
 				}
 				return t;
 			})(w);
@@ -163,14 +164,14 @@ function y(r, a, c, u, d, m) {
 		N = '<' + C;
 	if (O) {
 		var P = Object.keys(O);
-		c && !0 === c.sortAttributes && P.sort();
+		a && !0 === a.sortAttributes && P.sort();
 		for (var W = 0; W < P.length; W++) {
 			var I = P[W],
 				R = O[I];
 			if ('children' !== I) {
 				if (
-					!o.test(I) &&
-					((c && c.allAttributes) ||
+					!i.test(I) &&
+					((a && a.allAttributes) ||
 						('key' !== I && 'ref' !== I && '__self' !== I && '__source' !== I))
 				) {
 					if ('defaultValue' === I) I = 'value';
@@ -180,8 +181,8 @@ function y(r, a, c, u, d, m) {
 						if (void 0 !== O.class) continue;
 						I = 'class';
 					} else
-						d &&
-							i.test(I) &&
+						_ &&
+							l.test(I) &&
 							(I = I.toLowerCase().replace(/^xlink:?/, 'xlink:'));
 					if ('htmlFor' === I) {
 						if (O.for) continue;
@@ -192,26 +193,26 @@ function y(r, a, c, u, d, m) {
 							'r' === I[1] &&
 							'boolean' == typeof R &&
 							(R = String(R));
-					var U = c.attributeHook && c.attributeHook(I, R, a, c, j);
+					var U = a.attributeHook && a.attributeHook(I, R, n, a, j);
 					if (U || '' === U) N += U;
 					else if ('dangerouslySetInnerHTML' === I) D = R && R.__html;
 					else if ('textarea' === C && 'value' === I) $ = R;
 					else if ((R || 0 === R || '' === R) && 'function' != typeof R) {
-						if (!((!0 !== R && '' !== R) || ((R = I), c && c.xml))) {
+						if (!((!0 !== R && '' !== R) || ((R = I), a && a.xml))) {
 							N = N + ' ' + I;
 							continue;
 						}
 						if ('value' === I) {
 							if ('select' === C) {
-								m = R;
+								v = R;
 								continue;
 							}
 							'option' === C &&
-								m == R &&
+								v == R &&
 								void 0 === O.selected &&
 								(N += ' selected');
 						}
-						N = N + ' ' + I + '="' + l(R) + '"';
+						N = N + ' ' + I + '="' + s(R) + '"';
 					}
 				}
 			} else $ = R;
@@ -223,28 +224,28 @@ function y(r, a, c, u, d, m) {
 			? b && ~N.indexOf('\n') && (N += '\n')
 			: (N = V);
 	}
-	if (((N += '>'), o.test(C)))
+	if (((N += '>'), i.test(C)))
 		throw new Error(C + ' is not a valid HTML tag name in ' + N);
 	var q,
-		z = n.test(C) || (c.voidElements && c.voidElements.test(C)),
+		z = o.test(C) || (a.voidElements && a.voidElements.test(C)),
 		Z = [];
-	if (D) b && f(D) && (D = '\n' + x + s(D, x)), (N += D);
-	else if (null != $ && _((q = []), $).length) {
+	if (D) b && u(D) && (D = '\n' + x + f(D, x)), (N += D);
+	else if (null != $ && d((q = []), $).length) {
 		for (var B = b && ~N.indexOf('\n'), G = !1, J = 0; J < q.length; J++) {
 			var K = q[J];
 			if (null != K && !1 !== K) {
-				var Q = y(K, a, c, !0, 'svg' === C || ('foreignObject' !== C && d), m);
-				if ((b && !B && f(Q) && (B = !0), Q))
+				var Q = m(K, n, a, !0, 'svg' === C || ('foreignObject' !== C && _), v);
+				if ((b && !B && u(Q) && (B = !0), Q))
 					if (b) {
 						var X = Q.length > 0 && '<' != Q[0];
 						G && X ? (Z[Z.length - 1] += Q) : Z.push(Q), (G = X);
 					} else Z.push(Q);
 			}
 		}
-		if (b && B) for (var Y = Z.length; Y--; ) Z[Y] = '\n' + x + s(Z[Y], x);
+		if (b && B) for (var Y = Z.length; Y--; ) Z[Y] = '\n' + x + f(Z[Y], x);
 	}
 	if (Z.length || D) N += Z.join('');
-	else if (c && c.xml) return N.substring(0, N.length - 1) + ' />';
+	else if (a && a.xml) return N.substring(0, N.length - 1) + ' />';
 	return (
 		!z || q || D
 			? (b && ~N.indexOf('\n') && (N += '\n'), (N = N + '</' + C + '>'))
@@ -252,36 +253,45 @@ function y(r, a, c, u, d, m) {
 		N
 	);
 }
-var m = { shallow: !0 };
-k.render = k;
-var b = function (e, t) {
-		return k(e, t, m);
+var b = { shallow: !0 };
+S.render = S;
+var x = function (e, t) {
+		return S(e, t, b);
 	},
-	x = [];
-function k(e, r, n) {
-	r = r || {};
-	var o,
-		i = t.__s;
+	k = [];
+function S(n, o, i) {
+	o = o || {};
+	var l = t.__s;
+	t.__s = !0;
+	var a,
+		s = r(e, null);
 	return (
-		(t.__s = !0),
-		(o =
-			n &&
-			(n.pretty ||
-				n.voidElements ||
-				n.sortAttributes ||
-				n.shallow ||
-				n.allAttributes ||
-				n.xml ||
-				n.attributeHook)
-				? y(e, r, n)
-				: j(e, r, !1, void 0)),
-		t.__c && t.__c(e, x),
-		(t.__s = i),
-		(x.length = 0),
-		o
+		(s.__k = [n]),
+		(a =
+			i &&
+			(i.pretty ||
+				i.voidElements ||
+				i.sortAttributes ||
+				i.shallow ||
+				i.allAttributes ||
+				i.xml ||
+				i.attributeHook)
+				? m(n, o, i)
+				: F(n, o, !1, void 0, s)),
+		t.__c && t.__c(n, k),
+		(t.__s = l),
+		(k.length = 0),
+		a
 	);
 }
-function S(e, t) {
+function w(e) {
+	return null == e || 'boolean' == typeof e
+		? null
+		: 'string' == typeof e || 'number' == typeof e || 'bigint' == typeof e
+		? r(null, null, e)
+		: e;
+}
+function C(e, t) {
 	return 'className' === e
 		? 'class'
 		: 'htmlFor' === e
@@ -292,136 +302,153 @@ function S(e, t) {
 		? 'checked'
 		: 'defaultSelected' === e
 		? 'selected'
-		: t && i.test(e)
+		: t && l.test(e)
 		? e.toLowerCase().replace(/^xlink:?/, 'xlink:')
 		: e;
 }
-function w(e, t) {
+function O(e, t) {
 	return 'style' === e && null != t && 'object' == typeof t
 		? p(t)
 		: 'a' === e[0] && 'r' === e[1] && 'boolean' == typeof t
 		? String(t)
 		: t;
 }
-var C = Array.isArray,
-	O = Object.assign;
-function j(r, i, a, s) {
+var j = Array.isArray,
+	A = Object.assign;
+function F(r, n, l, a, f) {
 	if (null == r || !0 === r || !1 === r || '' === r) return '';
-	if ('object' != typeof r) return l(r);
-	if (C(r)) {
-		for (var f = '', c = 0; c < r.length; c++) f += j(r[c], i, a, s);
-		return f;
+	if ('object' != typeof r) return 'function' == typeof r ? '' : s(r);
+	if (j(r)) {
+		var u = '';
+		f.__k = r;
+		for (var c = 0; c < r.length; c++)
+			(u += F(r[c], n, l, a, f)), (r[c] = w(r[c]));
+		return u;
 	}
-	t.__b && t.__b(r);
-	var u = r.type,
+	if (void 0 !== r.constructor) return '';
+	(r.__ = f), t.__b && t.__b(r);
+	var _ = r.type,
 		p = r.props;
-	if ('function' == typeof u) {
-		if (u === e) return j(r.props.children, i, a, s);
-		var _;
-		_ =
-			u.prototype && 'function' == typeof u.prototype.render
-				? (function (e, r) {
-						var n = e.type,
-							o = h(n, r),
-							i = new n(e.props, o);
-						(e.__c = i),
-							(i.__v = e),
-							(i.__d = !0),
-							(i.props = e.props),
-							null == i.state && (i.state = {}),
-							null == i.__s && (i.__s = i.state),
-							(i.context = o),
-							n.getDerivedStateFromProps
-								? (i.state = O(
-										{},
-										i.state,
-										n.getDerivedStateFromProps(i.props, i.state)
-								  ))
-								: i.componentWillMount &&
-								  (i.componentWillMount(),
-								  (i.state = i.__s !== i.state ? i.__s : i.state));
-						var a = t.__r;
-						return a && a(e), i.render(i.props, i.state, i.context);
-				  })(r, i)
-				: (function (e, r) {
-						var n,
-							o = v(e, r),
-							i = h(e.type, r);
-						e.__c = o;
-						for (var a = t.__r, l = 0; o.__d && l++ < 25; )
-							(o.__d = !1), a && a(e), (n = e.type.call(o, e.props, i));
-						return n;
-				  })(r, i);
-		var d = r.__c;
-		d.getChildContext && (i = O({}, i, d.getChildContext()));
-		var g = j(_, i, a, s);
-		return t.diffed && t.diffed(r), g;
+	if ('function' == typeof _) {
+		var d;
+		if (_ === e) d = p.children;
+		else {
+			d =
+				_.prototype && 'function' == typeof _.prototype.render
+					? (function (e, r) {
+							var n = e.type,
+								o = g(n, r),
+								i = new n(e.props, o);
+							(e.__c = i),
+								(i.__v = e),
+								(i.__d = !0),
+								(i.props = e.props),
+								null == i.state && (i.state = {}),
+								null == i.__s && (i.__s = i.state),
+								(i.context = o),
+								n.getDerivedStateFromProps
+									? (i.state = A(
+											{},
+											i.state,
+											n.getDerivedStateFromProps(i.props, i.state)
+									  ))
+									: i.componentWillMount &&
+									  (i.componentWillMount(),
+									  (i.state = i.__s !== i.state ? i.__s : i.state));
+							var l = t.__r;
+							return l && l(e), i.render(i.props, i.state, i.context);
+					  })(r, n)
+					: (function (e, r) {
+							var n,
+								o = h(e, r),
+								i = g(e.type, r);
+							e.__c = o;
+							for (var l = t.__r, a = 0; o.__d && a++ < 25; )
+								(o.__d = !1), l && l(e), (n = e.type.call(o, e.props, i));
+							return n;
+					  })(r, n);
+			var v = r.__c;
+			v.getChildContext && (n = A({}, n, v.getChildContext()));
+		}
+		var y = F(
+			(d = null != d && d.type === e && null == d.key ? d.props.children : d),
+			n,
+			l,
+			a,
+			r
+		);
+		return (
+			t.diffed && t.diffed(r), (r.__ = void 0), t.unmount && t.unmount(r), y
+		);
 	}
-	var y,
-		m,
-		b = '<';
-	if (((b += u), p))
-		for (var x in ((y = p.children), p)) {
-			var k = p[x];
+	var m,
+		b,
+		x = '<';
+	if (((x += _), p))
+		for (var k in ((m = p.children), p)) {
+			var S = p[k];
 			if (
 				!(
-					'key' === x ||
-					'ref' === x ||
-					'__self' === x ||
-					'__source' === x ||
-					'children' === x ||
-					('className' === x && 'class' in p) ||
-					('htmlFor' === x && 'for' in p) ||
-					o.test(x)
+					'key' === k ||
+					'ref' === k ||
+					'__self' === k ||
+					'__source' === k ||
+					'children' === k ||
+					('className' === k && 'class' in p) ||
+					('htmlFor' === k && 'for' in p) ||
+					i.test(k)
 				)
 			)
-				if (((k = w((x = S(x, a)), k)), 'dangerouslySetInnerHTML' === x))
-					m = k && k.__html;
-				else if ('textarea' === u && 'value' === x) y = k;
-				else if ((k || 0 === k || '' === k) && 'function' != typeof k) {
-					if (!0 === k || '' === k) {
-						(k = x), (b = b + ' ' + x);
+				if (((S = O((k = C(k, l)), S)), 'dangerouslySetInnerHTML' === k))
+					b = S && S.__html;
+				else if ('textarea' === _ && 'value' === k) m = S;
+				else if ((S || 0 === S || '' === S) && 'function' != typeof S) {
+					if (!0 === S || '' === S) {
+						(S = k), (x = x + ' ' + k);
 						continue;
 					}
-					if ('value' === x) {
-						if ('select' === u) {
-							s = k;
+					if ('value' === k) {
+						if ('select' === _) {
+							a = S;
 							continue;
 						}
-						'option' !== u || s != k || 'selected' in p || (b += ' selected');
+						'option' !== _ || a != S || 'selected' in p || (x += ' selected');
 					}
-					b = b + ' ' + x + '="' + l(k) + '"';
+					x = x + ' ' + k + '="' + s(S) + '"';
 				}
 		}
-	var A = b;
-	if (((b += '>'), o.test(u)))
-		throw new Error(u + ' is not a valid HTML tag name in ' + b);
-	var F = '',
-		H = !1;
-	if (m) (F += m), (H = !0);
-	else if ('string' == typeof y) (F += l(y)), (H = !0);
-	else if (C(y))
-		for (var M = 0; M < y.length; M++) {
-			var L = y[M];
-			if (null != L && !1 !== L) {
-				var T = j(L, i, 'svg' === u || ('foreignObject' !== u && a), s);
-				T && ((F += T), (H = !0));
+	var H = x;
+	if (((x += '>'), i.test(_)))
+		throw new Error(_ + ' is not a valid HTML tag name in ' + x);
+	var M = '',
+		L = !1;
+	if (b) (M += b), (L = !0);
+	else if ('string' == typeof m) (M += s(m)), (L = !0);
+	else if (j(m)) {
+		r.__k = m;
+		for (var T = 0; T < m.length; T++) {
+			var E = m[T];
+			if (((m[T] = w(E)), null != E && !1 !== E)) {
+				var $ = F(E, n, 'svg' === _ || ('foreignObject' !== _ && l), a, r);
+				$ && ((M += $), (L = !0));
 			}
 		}
-	else if (null != y && !1 !== y && !0 !== y) {
-		var E = j(y, i, 'svg' === u || ('foreignObject' !== u && a), s);
-		E && ((F += E), (H = !0));
+	} else if (null != m && !1 !== m && !0 !== m) {
+		r.__k = [w(m)];
+		var D = F(m, n, 'svg' === _ || ('foreignObject' !== _ && l), a, r);
+		D && ((M += D), (L = !0));
 	}
-	if ((t.diffed && t.diffed(r), H)) b += F;
-	else if (n.test(u)) return A + ' />';
-	return b + '</' + u + '>';
+	if ((t.diffed && t.diffed(r), (r.__ = void 0), t.unmount && t.unmount(r), L))
+		x += M;
+	else if (o.test(_)) return H + ' />';
+	return x + '</' + _ + '>';
 }
-k.shallowRender = b;
-export default k;
+S.shallowRender = x;
+export default S;
 export {
-	k as render,
-	k as renderToStaticMarkup,
-	k as renderToString,
-	b as shallowRender
+	S as render,
+	S as renderToStaticMarkup,
+	S as renderToString,
+	x as shallowRender
 };
 //# sourceMappingURL=index.module.js.map
diff --git a/jsx.d.ts b/jsx.d.ts
index ee2ba58..9004230 100644
--- a/jsx.d.ts
+++ b/jsx.d.ts
@@ -1,13 +1,21 @@
 import { VNode } from 'preact';
 
 interface Options {
-  jsx?: boolean;
-  xml?: boolean;
-  functions?: boolean
-  functionNames?: boolean,
-  skipFalseAttributes?: boolean
-  pretty?: boolean | string;
+	jsx?: boolean;
+	xml?: boolean;
+	pretty?: boolean | string;
+	shallow?: boolean;
+	functions?: boolean;
+	functionNames?: boolean;
+	skipFalseAttributes?: boolean;
 }
 
-export function render(vnode: VNode, context?: any, options?: Options):string;
+export default function renderToStringPretty(
+	vnode: VNode,
+	context?: any,
+	options?: Options
+): string;
+
+export function shallowRender(vnode: VNode, context?: any): string;
+
 export default render;
diff --git a/package-lock.json b/package-lock.json
index 797b2ae..a8daf1f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,7 +23,7 @@
 				"eslint-config-developit": "^1.2.0",
 				"husky": "^4.3.6",
 				"lint-staged": "^10.5.3",
-				"microbundle": "^0.13.0",
+				"microbundle": "^0.15.1",
 				"mocha": "^8.2.1",
 				"preact": "^10.11.1",
 				"prettier": "^2.2.1",
@@ -1853,6 +1853,64 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/@jridgewell/gen-mapping": {
+			"version": "0.3.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+			"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/set-array": "^1.0.1",
+				"@jridgewell/sourcemap-codec": "^1.4.10",
+				"@jridgewell/trace-mapping": "^0.3.9"
+			},
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/resolve-uri": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+			"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/set-array": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+			"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/source-map": {
+			"version": "0.3.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+			"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/gen-mapping": "^0.3.0",
+				"@jridgewell/trace-mapping": "^0.3.9"
+			}
+		},
+		"node_modules/@jridgewell/sourcemap-codec": {
+			"version": "1.4.14",
+			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+			"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+			"dev": true
+		},
+		"node_modules/@jridgewell/trace-mapping": {
+			"version": "0.3.15",
+			"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
+			"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/resolve-uri": "^3.0.3",
+				"@jridgewell/sourcemap-codec": "^1.4.10"
+			}
+		},
 		"node_modules/@manypkg/find-root": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz",
@@ -2066,6 +2124,18 @@
 			"integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
 			"dev": true
 		},
+		"node_modules/@surma/rollup-plugin-off-main-thread": {
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
+			"integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
+			"dev": true,
+			"dependencies": {
+				"ejs": "^3.1.6",
+				"json5": "^2.2.0",
+				"magic-string": "^0.25.0",
+				"string.prototype.matchall": "^4.0.6"
+			}
+		},
 		"node_modules/@types/benchmark": {
 			"version": "1.0.33",
 			"resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-1.0.33.tgz",
@@ -2327,71 +2397,6 @@
 				"node": ">= 0.4"
 			}
 		},
-		"node_modules/array-includes/node_modules/es-abstract": {
-			"version": "1.18.0-next.1",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-			"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-			"dev": true,
-			"dependencies": {
-				"es-to-primitive": "^1.2.1",
-				"function-bind": "^1.1.1",
-				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.2.2",
-				"is-negative-zero": "^2.0.0",
-				"is-regex": "^1.1.1",
-				"object-inspect": "^1.8.0",
-				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.1",
-				"string.prototype.trimend": "^1.0.1",
-				"string.prototype.trimstart": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/array-includes/node_modules/is-callable": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-			"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-			"dev": true,
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/array-includes/node_modules/is-regex": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-			"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-			"dev": true,
-			"dependencies": {
-				"has-symbols": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/array-includes/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
-		"node_modules/array-includes/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
 		"node_modules/array-union": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -2416,71 +2421,6 @@
 				"node": ">= 0.4"
 			}
 		},
-		"node_modules/array.prototype.flatmap/node_modules/es-abstract": {
-			"version": "1.18.0-next.1",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-			"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-			"dev": true,
-			"dependencies": {
-				"es-to-primitive": "^1.2.1",
-				"function-bind": "^1.1.1",
-				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.2.2",
-				"is-negative-zero": "^2.0.0",
-				"is-regex": "^1.1.1",
-				"object-inspect": "^1.8.0",
-				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.1",
-				"string.prototype.trimend": "^1.0.1",
-				"string.prototype.trimstart": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/array.prototype.flatmap/node_modules/is-callable": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-			"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-			"dev": true,
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/array.prototype.flatmap/node_modules/is-regex": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-			"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-			"dev": true,
-			"dependencies": {
-				"has-symbols": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/array.prototype.flatmap/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
-		"node_modules/array.prototype.flatmap/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
 		"node_modules/arrify": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
@@ -2514,6 +2454,12 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/async": {
+			"version": "3.2.4",
+			"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+			"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
+			"dev": true
+		},
 		"node_modules/asyncro": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/asyncro/-/asyncro-3.0.0.tgz",
@@ -2597,9 +2543,9 @@
 			}
 		},
 		"node_modules/babel-plugin-transform-async-to-promises": {
-			"version": "0.8.15",
-			"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-promises/-/babel-plugin-transform-async-to-promises-0.8.15.tgz",
-			"integrity": "sha512-fDXP68ZqcinZO2WCiimCL9zhGjGXOnn3D33zvbh+yheZ/qOrNVVDDIBtAaM3Faz8TRvQzHiRKsu3hfrBAhEncQ==",
+			"version": "0.8.18",
+			"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-promises/-/babel-plugin-transform-async-to-promises-0.8.18.tgz",
+			"integrity": "sha512-WpOrF76nUHijnNn10eBGOHZmXQC8JYRME9rOLxStOga7Av2VO53ehVFvVNImMksVtQuL2/7ZNxEgxnx7oo/3Hw==",
 			"dev": true
 		},
 		"node_modules/babel-plugin-transform-replace-expressions": {
@@ -2958,13 +2904,16 @@
 			}
 		},
 		"node_modules/call-bind": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
-			"integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+			"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
 			"dev": true,
 			"dependencies": {
 				"function-bind": "^1.1.1",
-				"get-intrinsic": "^1.0.0"
+				"get-intrinsic": "^1.0.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/caller-callsite": {
@@ -4231,16 +4180,29 @@
 				"clone": "^1.0.2"
 			}
 		},
+		"node_modules/define-lazy-prop": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+			"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/define-properties": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-			"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+			"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
 			"dev": true,
 			"dependencies": {
-				"object-keys": "^1.0.12"
+				"has-property-descriptors": "^1.0.0",
+				"object-keys": "^1.1.1"
 			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/detect-indent": {
@@ -4353,6 +4315,21 @@
 			"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
 			"dev": true
 		},
+		"node_modules/ejs": {
+			"version": "3.1.8",
+			"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
+			"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
+			"dev": true,
+			"dependencies": {
+				"jake": "^10.8.5"
+			},
+			"bin": {
+				"ejs": "bin/cli.js"
+			},
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
 		"node_modules/electron-to-chromium": {
 			"version": "1.3.633",
 			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz",
@@ -4411,25 +4388,40 @@
 			}
 		},
 		"node_modules/es-abstract": {
-			"version": "1.17.4",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
-			"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+			"version": "1.20.1",
+			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz",
+			"integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==",
 			"dev": true,
 			"dependencies": {
+				"call-bind": "^1.0.2",
 				"es-to-primitive": "^1.2.1",
 				"function-bind": "^1.1.1",
+				"function.prototype.name": "^1.1.5",
+				"get-intrinsic": "^1.1.1",
+				"get-symbol-description": "^1.0.0",
 				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.1.5",
-				"is-regex": "^1.0.5",
-				"object-inspect": "^1.7.0",
+				"has-property-descriptors": "^1.0.0",
+				"has-symbols": "^1.0.3",
+				"internal-slot": "^1.0.3",
+				"is-callable": "^1.2.4",
+				"is-negative-zero": "^2.0.2",
+				"is-regex": "^1.1.4",
+				"is-shared-array-buffer": "^1.0.2",
+				"is-string": "^1.0.7",
+				"is-weakref": "^1.0.2",
+				"object-inspect": "^1.12.0",
 				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.0",
-				"string.prototype.trimleft": "^2.1.1",
-				"string.prototype.trimright": "^2.1.1"
+				"object.assign": "^4.1.2",
+				"regexp.prototype.flags": "^1.4.3",
+				"string.prototype.trimend": "^1.0.5",
+				"string.prototype.trimstart": "^1.0.5",
+				"unbox-primitive": "^1.0.2"
 			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/es-to-primitive": {
@@ -5009,6 +5001,36 @@
 				"node": "^10.12.0 || >=12.0.0"
 			}
 		},
+		"node_modules/filelist": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+			"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+			"dev": true,
+			"dependencies": {
+				"minimatch": "^5.0.1"
+			}
+		},
+		"node_modules/filelist/node_modules/brace-expansion": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+			"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+			"dev": true,
+			"dependencies": {
+				"balanced-match": "^1.0.0"
+			}
+		},
+		"node_modules/filelist/node_modules/minimatch": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
+			"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+			"dev": true,
+			"dependencies": {
+				"brace-expansion": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=10"
+			}
+		},
 		"node_modules/filesize": {
 			"version": "6.1.0",
 			"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
@@ -5031,9 +5053,9 @@
 			}
 		},
 		"node_modules/find-cache-dir": {
-			"version": "3.3.1",
-			"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
-			"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+			"version": "3.3.2",
+			"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+			"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
 			"dev": true,
 			"dependencies": {
 				"commondir": "^1.0.1",
@@ -5042,6 +5064,9 @@
 			},
 			"engines": {
 				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
 			}
 		},
 		"node_modules/find-up": {
@@ -5142,12 +5167,39 @@
 			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
 			"dev": true
 		},
+		"node_modules/function.prototype.name": {
+			"version": "1.1.5",
+			"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+			"integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.19.0",
+				"functions-have-names": "^1.2.2"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/functional-red-black-tree": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
 			"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
 			"dev": true
 		},
+		"node_modules/functions-have-names": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+			"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/generic-names": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz",
@@ -5185,14 +5237,17 @@
 			}
 		},
 		"node_modules/get-intrinsic": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz",
-			"integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==",
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+			"integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
 			"dev": true,
 			"dependencies": {
 				"function-bind": "^1.1.1",
 				"has": "^1.0.3",
-				"has-symbols": "^1.0.1"
+				"has-symbols": "^1.0.3"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/get-own-enumerable-property-symbols": {
@@ -5213,6 +5268,22 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/get-symbol-description": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+			"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"get-intrinsic": "^1.1.1"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/glob": {
 			"version": "7.1.6",
 			"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -5364,6 +5435,15 @@
 				"node": ">=0.10.0"
 			}
 		},
+		"node_modules/has-bigints": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+			"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/has-flag": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -5373,13 +5453,43 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/has-property-descriptors": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+			"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+			"dev": true,
+			"dependencies": {
+				"get-intrinsic": "^1.1.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/has-symbols": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
-			"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+			"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+			"dev": true,
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/has-tostringtag": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+			"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
 			"dev": true,
+			"dependencies": {
+				"has-symbols": "^1.0.2"
+			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/he": {
@@ -5658,14 +5768,14 @@
 			"dev": true
 		},
 		"node_modules/internal-slot": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz",
-			"integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==",
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+			"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
 			"dev": true,
 			"dependencies": {
-				"es-abstract": "^1.17.0-next.1",
+				"get-intrinsic": "^1.1.0",
 				"has": "^1.0.3",
-				"side-channel": "^1.0.2"
+				"side-channel": "^1.0.4"
 			},
 			"engines": {
 				"node": ">= 0.4"
@@ -5686,6 +5796,18 @@
 			"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
 			"dev": true
 		},
+		"node_modules/is-bigint": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+			"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+			"dev": true,
+			"dependencies": {
+				"has-bigints": "^1.0.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/is-binary-path": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -5698,13 +5820,32 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/is-boolean-object": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+			"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/is-callable": {
-			"version": "1.1.5",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
-			"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+			"version": "1.2.4",
+			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+			"integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
 			"dev": true,
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/is-ci": {
@@ -5734,12 +5875,15 @@
 			}
 		},
 		"node_modules/is-core-module": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
-			"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+			"version": "2.10.0",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+			"integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
 			"dev": true,
 			"dependencies": {
 				"has": "^1.0.3"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/is-date-object": {
@@ -5760,10 +5904,25 @@
 				"node": ">=0.10.0"
 			}
 		},
-		"node_modules/is-extglob": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-			"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+		"node_modules/is-docker": {
+			"version": "2.2.1",
+			"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+			"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+			"dev": true,
+			"bin": {
+				"is-docker": "cli.js"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/is-extglob": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+			"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
 			"dev": true,
 			"engines": {
 				"node": ">=0.10.0"
@@ -5797,12 +5956,15 @@
 			"dev": true
 		},
 		"node_modules/is-negative-zero": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
-			"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+			"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
 			"dev": true,
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/is-number": {
@@ -5814,6 +5976,21 @@
 				"node": ">=0.12.0"
 			}
 		},
+		"node_modules/is-number-object": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+			"integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+			"dev": true,
+			"dependencies": {
+				"has-tostringtag": "^1.0.0"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/is-obj": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
@@ -5842,15 +6019,19 @@
 			}
 		},
 		"node_modules/is-regex": {
-			"version": "1.0.5",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
-			"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+			"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
 			"dev": true,
 			"dependencies": {
-				"has": "^1.0.3"
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
 			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/is-regexp": {
@@ -5868,6 +6049,18 @@
 			"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
 			"dev": true
 		},
+		"node_modules/is-shared-array-buffer": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+			"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/is-stream": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
@@ -5878,12 +6071,18 @@
 			}
 		},
 		"node_modules/is-string": {
-			"version": "1.0.5",
-			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
-			"integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+			"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
 			"dev": true,
+			"dependencies": {
+				"has-tostringtag": "^1.0.0"
+			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/is-subdir": {
@@ -5922,6 +6121,18 @@
 				"node": ">= 0.4"
 			}
 		},
+		"node_modules/is-weakref": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+			"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/is-windows": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -5931,6 +6142,18 @@
 				"node": ">=0.10.0"
 			}
 		},
+		"node_modules/is-wsl": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+			"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+			"dev": true,
+			"dependencies": {
+				"is-docker": "^2.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/isarray": {
 			"version": "0.0.1",
 			"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -5943,6 +6166,94 @@
 			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
 			"dev": true
 		},
+		"node_modules/jake": {
+			"version": "10.8.5",
+			"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
+			"integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
+			"dev": true,
+			"dependencies": {
+				"async": "^3.2.3",
+				"chalk": "^4.0.2",
+				"filelist": "^1.0.1",
+				"minimatch": "^3.0.4"
+			},
+			"bin": {
+				"jake": "bin/cli.js"
+			},
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/jake/node_modules/ansi-styles": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+			"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+			"dev": true,
+			"dependencies": {
+				"color-convert": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/jake/node_modules/chalk": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+			"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+			"dev": true,
+			"dependencies": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/chalk?sponsor=1"
+			}
+		},
+		"node_modules/jake/node_modules/color-convert": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+			"dev": true,
+			"dependencies": {
+				"color-name": "~1.1.4"
+			},
+			"engines": {
+				"node": ">=7.0.0"
+			}
+		},
+		"node_modules/jake/node_modules/color-name": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+			"dev": true
+		},
+		"node_modules/jake/node_modules/has-flag": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+			"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/jake/node_modules/supports-color": {
+			"version": "7.2.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+			"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+			"dev": true,
+			"dependencies": {
+				"has-flag": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/jest-worker": {
 			"version": "26.6.2",
 			"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@@ -6034,13 +6345,10 @@
 			"dev": true
 		},
 		"node_modules/json5": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
-			"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+			"version": "2.2.1",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
 			"dev": true,
-			"dependencies": {
-				"minimist": "^1.2.5"
-			},
 			"bin": {
 				"json5": "lib/cli.js"
 			},
@@ -6070,21 +6378,6 @@
 				"node": ">=4.0"
 			}
 		},
-		"node_modules/jsx-ast-utils/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
 		"node_modules/just-extend": {
 			"version": "4.1.1",
 			"resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz",
@@ -6642,6 +6935,9 @@
 			},
 			"engines": {
 				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/make-dir/node_modules/semver": {
@@ -6798,9 +7094,9 @@
 			}
 		},
 		"node_modules/microbundle": {
-			"version": "0.13.0",
-			"resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.13.0.tgz",
-			"integrity": "sha512-d5glQP8nWoaZhgNF7pxmBpSI/zYMn0NfjH5tOjLudfgoceWiiq+5crwIHGqWKFDbaTcyMjD9HKowy3hNWJCHow==",
+			"version": "0.15.1",
+			"resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.15.1.tgz",
+			"integrity": "sha512-aAF+nwFbkSIJGfrJk+HyzmJOq3KFaimH6OIFBU6J2DPjQeg1jXIYlIyEv81Gyisb9moUkudn+wj7zLNYMOv75Q==",
 			"dev": true,
 			"dependencies": {
 				"@babel/core": "^7.12.10",
@@ -6818,10 +7114,11 @@
 				"@rollup/plugin-commonjs": "^17.0.0",
 				"@rollup/plugin-json": "^4.1.0",
 				"@rollup/plugin-node-resolve": "^11.0.1",
+				"@surma/rollup-plugin-off-main-thread": "^2.2.2",
 				"asyncro": "^3.0.0",
 				"autoprefixer": "^10.1.0",
 				"babel-plugin-macros": "^3.0.1",
-				"babel-plugin-transform-async-to-promises": "^0.8.15",
+				"babel-plugin-transform-async-to-promises": "^0.8.18",
 				"babel-plugin-transform-replace-expressions": "^0.2.0",
 				"brotli-size": "^4.0.0",
 				"builtin-modules": "^3.1.0",
@@ -6837,8 +7134,10 @@
 				"rollup-plugin-bundle-size": "^1.0.3",
 				"rollup-plugin-postcss": "^4.0.0",
 				"rollup-plugin-terser": "^7.0.2",
-				"rollup-plugin-typescript2": "^0.29.0",
+				"rollup-plugin-typescript2": "^0.32.0",
+				"rollup-plugin-visualizer": "^5.6.0",
 				"sade": "^1.7.4",
+				"terser": "^5.7.0",
 				"tiny-glob": "^0.2.8",
 				"tslib": "^2.0.3",
 				"typescript": "^4.1.3"
@@ -7315,9 +7614,9 @@
 			"dev": true
 		},
 		"node_modules/nanoid": {
-			"version": "3.1.20",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
-			"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
+			"version": "3.3.4",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+			"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
 			"dev": true,
 			"bin": {
 				"nanoid": "bin/nanoid.cjs"
@@ -7461,10 +7760,13 @@
 			}
 		},
 		"node_modules/object-inspect": {
-			"version": "1.7.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
-			"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
-			"dev": true
+			"version": "1.12.2",
+			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+			"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
 		"node_modules/object-keys": {
 			"version": "1.1.1",
@@ -7475,258 +7777,66 @@
 				"node": ">= 0.4"
 			}
 		},
-		"node_modules/object.assign": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
-			"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
-			"dev": true,
-			"dependencies": {
-				"define-properties": "^1.1.2",
-				"function-bind": "^1.1.1",
-				"has-symbols": "^1.0.0",
-				"object-keys": "^1.0.11"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.entries": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz",
-			"integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"es-abstract": "^1.18.0-next.1",
-				"has": "^1.0.3"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.entries/node_modules/es-abstract": {
-			"version": "1.18.0-next.1",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-			"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-			"dev": true,
-			"dependencies": {
-				"es-to-primitive": "^1.2.1",
-				"function-bind": "^1.1.1",
-				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.2.2",
-				"is-negative-zero": "^2.0.0",
-				"is-regex": "^1.1.1",
-				"object-inspect": "^1.8.0",
-				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.1",
-				"string.prototype.trimend": "^1.0.1",
-				"string.prototype.trimstart": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.entries/node_modules/is-callable": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-			"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-			"dev": true,
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.entries/node_modules/is-regex": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-			"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-			"dev": true,
-			"dependencies": {
-				"has-symbols": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.entries/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
-		"node_modules/object.entries/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.fromentries": {
-			"version": "2.0.3",
-			"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz",
-			"integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"es-abstract": "^1.18.0-next.1",
-				"has": "^1.0.3"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.fromentries/node_modules/es-abstract": {
-			"version": "1.18.0-next.1",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-			"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-			"dev": true,
-			"dependencies": {
-				"es-to-primitive": "^1.2.1",
-				"function-bind": "^1.1.1",
-				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.2.2",
-				"is-negative-zero": "^2.0.0",
-				"is-regex": "^1.1.1",
-				"object-inspect": "^1.8.0",
-				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.1",
-				"string.prototype.trimend": "^1.0.1",
-				"string.prototype.trimstart": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.fromentries/node_modules/is-callable": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-			"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-			"dev": true,
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.fromentries/node_modules/is-regex": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-			"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-			"dev": true,
-			"dependencies": {
-				"has-symbols": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.fromentries/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
-		"node_modules/object.fromentries/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/object.getownpropertydescriptors": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz",
-			"integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"es-abstract": "^1.18.0-next.1"
-			},
-			"engines": {
-				"node": ">= 0.8"
-			}
-		},
-		"node_modules/object.getownpropertydescriptors/node_modules/es-abstract": {
-			"version": "1.18.0-next.1",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-			"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-			"dev": true,
-			"dependencies": {
-				"es-to-primitive": "^1.2.1",
-				"function-bind": "^1.1.1",
-				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.2.2",
-				"is-negative-zero": "^2.0.0",
-				"is-regex": "^1.1.1",
-				"object-inspect": "^1.8.0",
-				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.1",
-				"string.prototype.trimend": "^1.0.1",
-				"string.prototype.trimstart": "^1.0.1"
+		"node_modules/object.assign": {
+			"version": "4.1.4",
+			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+			"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"has-symbols": "^1.0.3",
+				"object-keys": "^1.1.1"
 			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/object.getownpropertydescriptors/node_modules/is-callable": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-			"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
+		"node_modules/object.entries": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz",
+			"integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==",
 			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.0",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.18.0-next.1",
+				"has": "^1.0.3"
+			},
 			"engines": {
 				"node": ">= 0.4"
 			}
 		},
-		"node_modules/object.getownpropertydescriptors/node_modules/is-regex": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-			"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+		"node_modules/object.fromentries": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz",
+			"integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==",
 			"dev": true,
 			"dependencies": {
-				"has-symbols": "^1.0.1"
+				"call-bind": "^1.0.0",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.18.0-next.1",
+				"has": "^1.0.3"
 			},
 			"engines": {
 				"node": ">= 0.4"
 			}
 		},
-		"node_modules/object.getownpropertydescriptors/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
-		"node_modules/object.getownpropertydescriptors/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+		"node_modules/object.getownpropertydescriptors": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz",
+			"integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==",
 			"dev": true,
 			"dependencies": {
 				"call-bind": "^1.0.0",
 				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
+				"es-abstract": "^1.18.0-next.1"
 			},
 			"engines": {
-				"node": ">= 0.4"
+				"node": ">= 0.8"
 			}
 		},
 		"node_modules/object.values": {
@@ -7765,6 +7875,23 @@
 				"node": ">=6"
 			}
 		},
+		"node_modules/open": {
+			"version": "8.4.0",
+			"resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz",
+			"integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==",
+			"dev": true,
+			"dependencies": {
+				"define-lazy-prop": "^2.0.0",
+				"is-docker": "^2.1.1",
+				"is-wsl": "^2.2.0"
+			},
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/opencollective-postinstall": {
 			"version": "2.0.3",
 			"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
@@ -7970,9 +8097,9 @@
 			}
 		},
 		"node_modules/path-parse": {
-			"version": "1.0.6",
-			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-			"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
 			"dev": true
 		},
 		"node_modules/path-to-regexp": {
@@ -11048,16 +11175,20 @@
 			}
 		},
 		"node_modules/regexp.prototype.flags": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
-			"integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+			"version": "1.4.3",
+			"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+			"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
 			"dev": true,
 			"dependencies": {
+				"call-bind": "^1.0.2",
 				"define-properties": "^1.1.3",
-				"es-abstract": "^1.17.0-next.1"
+				"functions-have-names": "^1.2.2"
 			},
 			"engines": {
 				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/regexpp": {
@@ -11129,13 +11260,20 @@
 			"dev": true
 		},
 		"node_modules/resolve": {
-			"version": "1.19.0",
-			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-			"integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+			"version": "1.22.1",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+			"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
 			"dev": true,
 			"dependencies": {
-				"is-core-module": "^2.1.0",
-				"path-parse": "^1.0.6"
+				"is-core-module": "^2.9.0",
+				"path-parse": "^1.0.7",
+				"supports-preserve-symlinks-flag": "^1.0.0"
+			},
+			"bin": {
+				"resolve": "bin/resolve"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/resolve-from": {
@@ -11317,33 +11455,183 @@
 			}
 		},
 		"node_modules/rollup-plugin-typescript2": {
-			"version": "0.29.0",
-			"resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.29.0.tgz",
-			"integrity": "sha512-YytahBSZCIjn/elFugEGQR5qTsVhxhUwGZIsA9TmrSsC88qroGo65O5HZP/TTArH2dm0vUmYWhKchhwi2wL9bw==",
+			"version": "0.32.1",
+			"resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.32.1.tgz",
+			"integrity": "sha512-RanO8bp1WbeMv0bVlgcbsFNCn+Y3rX7wF97SQLDxf0fMLsg0B/QFF005t4AsGUcDgF3aKJHoqt4JF2xVaABeKw==",
 			"dev": true,
 			"dependencies": {
-				"@rollup/pluginutils": "^3.1.0",
-				"find-cache-dir": "^3.3.1",
-				"fs-extra": "8.1.0",
-				"resolve": "1.17.0",
-				"tslib": "2.0.1"
+				"@rollup/pluginutils": "^4.1.2",
+				"find-cache-dir": "^3.3.2",
+				"fs-extra": "^10.0.0",
+				"resolve": "^1.20.0",
+				"tslib": "^2.4.0"
+			},
+			"peerDependencies": {
+				"rollup": ">=1.26.3",
+				"typescript": ">=2.4.0"
+			}
+		},
+		"node_modules/rollup-plugin-typescript2/node_modules/@rollup/pluginutils": {
+			"version": "4.2.1",
+			"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
+			"integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
+			"dev": true,
+			"dependencies": {
+				"estree-walker": "^2.0.1",
+				"picomatch": "^2.2.2"
+			},
+			"engines": {
+				"node": ">= 8.0.0"
+			}
+		},
+		"node_modules/rollup-plugin-typescript2/node_modules/estree-walker": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+			"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+			"dev": true
+		},
+		"node_modules/rollup-plugin-typescript2/node_modules/fs-extra": {
+			"version": "10.1.0",
+			"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+			"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+			"dev": true,
+			"dependencies": {
+				"graceful-fs": "^4.2.0",
+				"jsonfile": "^6.0.1",
+				"universalify": "^2.0.0"
+			},
+			"engines": {
+				"node": ">=12"
 			}
 		},
-		"node_modules/rollup-plugin-typescript2/node_modules/resolve": {
-			"version": "1.17.0",
-			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
-			"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+		"node_modules/rollup-plugin-typescript2/node_modules/jsonfile": {
+			"version": "6.1.0",
+			"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+			"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
 			"dev": true,
 			"dependencies": {
-				"path-parse": "^1.0.6"
+				"universalify": "^2.0.0"
+			},
+			"optionalDependencies": {
+				"graceful-fs": "^4.1.6"
 			}
 		},
 		"node_modules/rollup-plugin-typescript2/node_modules/tslib": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz",
-			"integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==",
+			"version": "2.4.0",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+			"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
 			"dev": true
 		},
+		"node_modules/rollup-plugin-typescript2/node_modules/universalify": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+			"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+			"dev": true,
+			"engines": {
+				"node": ">= 10.0.0"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer": {
+			"version": "5.7.1",
+			"resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.7.1.tgz",
+			"integrity": "sha512-E/IgOMnmXKlc6ICyf53ok1b6DxPeNVUs3R0kYYPuDpGfofT4bkiG+KtSMlGjMACFmfwbbqTVDZBIF7sMZVKJbA==",
+			"dev": true,
+			"dependencies": {
+				"nanoid": "^3.3.4",
+				"open": "^8.4.0",
+				"source-map": "^0.7.3",
+				"yargs": "^17.5.1"
+			},
+			"bin": {
+				"rollup-plugin-visualizer": "dist/bin/cli.js"
+			},
+			"engines": {
+				"node": ">=14"
+			},
+			"peerDependencies": {
+				"rollup": "^2.0.0"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/is-fullwidth-code-point": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
+			"version": "0.7.4",
+			"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+			"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+			"dev": true,
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/string-width": {
+			"version": "4.2.3",
+			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+			"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+			"dev": true,
+			"dependencies": {
+				"emoji-regex": "^8.0.0",
+				"is-fullwidth-code-point": "^3.0.0",
+				"strip-ansi": "^6.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/strip-ansi": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+			"dev": true,
+			"dependencies": {
+				"ansi-regex": "^5.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/yargs": {
+			"version": "17.5.1",
+			"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+			"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+			"dev": true,
+			"dependencies": {
+				"cliui": "^7.0.2",
+				"escalade": "^3.1.1",
+				"get-caller-file": "^2.0.5",
+				"require-directory": "^2.1.1",
+				"string-width": "^4.2.3",
+				"y18n": "^5.0.5",
+				"yargs-parser": "^21.0.0"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/rollup-plugin-visualizer/node_modules/yargs-parser": {
+			"version": "21.1.1",
+			"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+			"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+			"dev": true,
+			"engines": {
+				"node": ">=12"
+			}
+		},
 		"node_modules/rollup-pluginutils": {
 			"version": "2.8.2",
 			"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
@@ -11499,14 +11787,11 @@
 				"call-bind": "^1.0.0",
 				"get-intrinsic": "^1.0.2",
 				"object-inspect": "^1.9.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/side-channel/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
 		"node_modules/signal-exit": {
 			"version": "3.0.2",
 			"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@@ -11811,12 +12096,22 @@
 			}
 		},
 		"node_modules/source-map-support": {
-			"version": "0.5.19",
-			"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
-			"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+			"version": "0.5.21",
+			"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+			"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
 			"dev": true,
 			"dependencies": {
-				"buffer-from": "^1.0.0"
+				"buffer-from": "^1.0.0",
+				"source-map": "^0.6.0"
+			}
+		},
+		"node_modules/source-map-support/node_modules/source-map": {
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+			"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+			"dev": true,
+			"engines": {
+				"node": ">=0.10.0"
 			}
 		},
 		"node_modules/sourcemap-codec": {
@@ -12004,129 +12299,50 @@
 			}
 		},
 		"node_modules/string.prototype.matchall": {
-			"version": "4.0.3",
-			"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz",
-			"integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3",
-				"es-abstract": "^1.18.0-next.1",
-				"has-symbols": "^1.0.1",
-				"internal-slot": "^1.0.2",
-				"regexp.prototype.flags": "^1.3.0",
-				"side-channel": "^1.0.3"
-			}
-		},
-		"node_modules/string.prototype.matchall/node_modules/es-abstract": {
-			"version": "1.18.0-next.1",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-			"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-			"dev": true,
-			"dependencies": {
-				"es-to-primitive": "^1.2.1",
-				"function-bind": "^1.1.1",
-				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.2.2",
-				"is-negative-zero": "^2.0.0",
-				"is-regex": "^1.1.1",
-				"object-inspect": "^1.8.0",
-				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.1",
-				"string.prototype.trimend": "^1.0.1",
-				"string.prototype.trimstart": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/string.prototype.matchall/node_modules/is-callable": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-			"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-			"dev": true,
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/string.prototype.matchall/node_modules/is-regex": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-			"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-			"dev": true,
-			"dependencies": {
-				"has-symbols": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/string.prototype.matchall/node_modules/object-inspect": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-			"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-			"dev": true
-		},
-		"node_modules/string.prototype.matchall/node_modules/object.assign": {
-			"version": "4.1.2",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+			"version": "4.0.7",
+			"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz",
+			"integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==",
 			"dev": true,
 			"dependencies": {
-				"call-bind": "^1.0.0",
+				"call-bind": "^1.0.2",
 				"define-properties": "^1.1.3",
-				"has-symbols": "^1.0.1",
-				"object-keys": "^1.1.1"
+				"es-abstract": "^1.19.1",
+				"get-intrinsic": "^1.1.1",
+				"has-symbols": "^1.0.3",
+				"internal-slot": "^1.0.3",
+				"regexp.prototype.flags": "^1.4.1",
+				"side-channel": "^1.0.4"
 			},
-			"engines": {
-				"node": ">= 0.4"
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/string.prototype.trimend": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
-			"integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
-			"dev": true,
-			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3"
-			}
-		},
-		"node_modules/string.prototype.trimleft": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
-			"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
-			"dev": true,
-			"dependencies": {
-				"define-properties": "^1.1.3",
-				"function-bind": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
-		"node_modules/string.prototype.trimright": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
-			"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
+			"integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
 			"dev": true,
 			"dependencies": {
-				"define-properties": "^1.1.3",
-				"function-bind": "^1.1.1"
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"es-abstract": "^1.19.5"
 			},
-			"engines": {
-				"node": ">= 0.4"
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/string.prototype.trimstart": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
-			"integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
+			"integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
 			"dev": true,
 			"dependencies": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3"
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"es-abstract": "^1.19.5"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/stringify-object": {
@@ -12319,6 +12535,18 @@
 				"node": ">=0.8.0"
 			}
 		},
+		"node_modules/supports-preserve-symlinks-flag": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+			"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+			"dev": true,
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/svgo": {
 			"version": "1.3.2",
 			"resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
@@ -12456,14 +12684,15 @@
 			}
 		},
 		"node_modules/terser": {
-			"version": "5.5.1",
-			"resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz",
-			"integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==",
+			"version": "5.14.2",
+			"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
+			"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
 			"dev": true,
 			"dependencies": {
+				"@jridgewell/source-map": "^0.3.2",
+				"acorn": "^8.5.0",
 				"commander": "^2.20.0",
-				"source-map": "~0.7.2",
-				"source-map-support": "~0.5.19"
+				"source-map-support": "~0.5.20"
 			},
 			"bin": {
 				"terser": "bin/terser"
@@ -12472,13 +12701,16 @@
 				"node": ">=10"
 			}
 		},
-		"node_modules/terser/node_modules/source-map": {
-			"version": "0.7.3",
-			"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-			"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+		"node_modules/terser/node_modules/acorn": {
+			"version": "8.8.0",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+			"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
 			"dev": true,
+			"bin": {
+				"acorn": "bin/acorn"
+			},
 			"engines": {
-				"node": ">= 8"
+				"node": ">=0.4.0"
 			}
 		},
 		"node_modules/text-table": {
@@ -12864,6 +13096,21 @@
 				"node": ">=4.2.0"
 			}
 		},
+		"node_modules/unbox-primitive": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+			"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+			"dev": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"has-bigints": "^1.0.2",
+				"has-symbols": "^1.0.3",
+				"which-boxed-primitive": "^1.0.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/unicode-canonical-property-names-ecmascript": {
 			"version": "1.0.4",
 			"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -13029,6 +13276,22 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/which-boxed-primitive": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+			"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+			"dev": true,
+			"dependencies": {
+				"is-bigint": "^1.0.1",
+				"is-boolean-object": "^1.1.0",
+				"is-number-object": "^1.0.4",
+				"is-string": "^1.0.5",
+				"is-symbol": "^1.0.3"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/which-module": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
@@ -15036,6 +15299,55 @@
 				}
 			}
 		},
+		"@jridgewell/gen-mapping": {
+			"version": "0.3.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+			"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+			"dev": true,
+			"requires": {
+				"@jridgewell/set-array": "^1.0.1",
+				"@jridgewell/sourcemap-codec": "^1.4.10",
+				"@jridgewell/trace-mapping": "^0.3.9"
+			}
+		},
+		"@jridgewell/resolve-uri": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+			"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+			"dev": true
+		},
+		"@jridgewell/set-array": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+			"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+			"dev": true
+		},
+		"@jridgewell/source-map": {
+			"version": "0.3.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+			"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+			"dev": true,
+			"requires": {
+				"@jridgewell/gen-mapping": "^0.3.0",
+				"@jridgewell/trace-mapping": "^0.3.9"
+			}
+		},
+		"@jridgewell/sourcemap-codec": {
+			"version": "1.4.14",
+			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+			"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+			"dev": true
+		},
+		"@jridgewell/trace-mapping": {
+			"version": "0.3.15",
+			"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
+			"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+			"dev": true,
+			"requires": {
+				"@jridgewell/resolve-uri": "^3.0.3",
+				"@jridgewell/sourcemap-codec": "^1.4.10"
+			}
+		},
 		"@manypkg/find-root": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz",
@@ -15226,6 +15538,18 @@
 			"integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
 			"dev": true
 		},
+		"@surma/rollup-plugin-off-main-thread": {
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
+			"integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
+			"dev": true,
+			"requires": {
+				"ejs": "^3.1.6",
+				"json5": "^2.2.0",
+				"magic-string": "^0.25.0",
+				"string.prototype.matchall": "^4.0.6"
+			}
+		},
 		"@types/benchmark": {
 			"version": "1.0.33",
 			"resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-1.0.33.tgz",
@@ -15445,61 +15769,6 @@
 				"es-abstract": "^1.18.0-next.1",
 				"get-intrinsic": "^1.0.1",
 				"is-string": "^1.0.5"
-			},
-			"dependencies": {
-				"es-abstract": {
-					"version": "1.18.0-next.1",
-					"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-					"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-					"dev": true,
-					"requires": {
-						"es-to-primitive": "^1.2.1",
-						"function-bind": "^1.1.1",
-						"has": "^1.0.3",
-						"has-symbols": "^1.0.1",
-						"is-callable": "^1.2.2",
-						"is-negative-zero": "^2.0.0",
-						"is-regex": "^1.1.1",
-						"object-inspect": "^1.8.0",
-						"object-keys": "^1.1.1",
-						"object.assign": "^4.1.1",
-						"string.prototype.trimend": "^1.0.1",
-						"string.prototype.trimstart": "^1.0.1"
-					}
-				},
-				"is-callable": {
-					"version": "1.2.2",
-					"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-					"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-					"dev": true
-				},
-				"is-regex": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-					"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-					"dev": true,
-					"requires": {
-						"has-symbols": "^1.0.1"
-					}
-				},
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				},
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
 			}
 		},
 		"array-union": {
@@ -15518,61 +15787,6 @@
 				"define-properties": "^1.1.3",
 				"es-abstract": "^1.18.0-next.1",
 				"function-bind": "^1.1.1"
-			},
-			"dependencies": {
-				"es-abstract": {
-					"version": "1.18.0-next.1",
-					"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-					"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-					"dev": true,
-					"requires": {
-						"es-to-primitive": "^1.2.1",
-						"function-bind": "^1.1.1",
-						"has": "^1.0.3",
-						"has-symbols": "^1.0.1",
-						"is-callable": "^1.2.2",
-						"is-negative-zero": "^2.0.0",
-						"is-regex": "^1.1.1",
-						"object-inspect": "^1.8.0",
-						"object-keys": "^1.1.1",
-						"object.assign": "^4.1.1",
-						"string.prototype.trimend": "^1.0.1",
-						"string.prototype.trimstart": "^1.0.1"
-					}
-				},
-				"is-callable": {
-					"version": "1.2.2",
-					"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-					"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-					"dev": true
-				},
-				"is-regex": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-					"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-					"dev": true,
-					"requires": {
-						"has-symbols": "^1.0.1"
-					}
-				},
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				},
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
 			}
 		},
 		"arrify": {
@@ -15599,6 +15813,12 @@
 			"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
 			"dev": true
 		},
+		"async": {
+			"version": "3.2.4",
+			"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+			"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
+			"dev": true
+		},
 		"asyncro": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/asyncro/-/asyncro-3.0.0.tgz",
@@ -15670,9 +15890,9 @@
 			}
 		},
 		"babel-plugin-transform-async-to-promises": {
-			"version": "0.8.15",
-			"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-promises/-/babel-plugin-transform-async-to-promises-0.8.15.tgz",
-			"integrity": "sha512-fDXP68ZqcinZO2WCiimCL9zhGjGXOnn3D33zvbh+yheZ/qOrNVVDDIBtAaM3Faz8TRvQzHiRKsu3hfrBAhEncQ==",
+			"version": "0.8.18",
+			"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-promises/-/babel-plugin-transform-async-to-promises-0.8.18.tgz",
+			"integrity": "sha512-WpOrF76nUHijnNn10eBGOHZmXQC8JYRME9rOLxStOga7Av2VO53ehVFvVNImMksVtQuL2/7ZNxEgxnx7oo/3Hw==",
 			"dev": true
 		},
 		"babel-plugin-transform-replace-expressions": {
@@ -15969,13 +16189,13 @@
 			"dev": true
 		},
 		"call-bind": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
-			"integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+			"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
 			"dev": true,
 			"requires": {
 				"function-bind": "^1.1.1",
-				"get-intrinsic": "^1.0.0"
+				"get-intrinsic": "^1.0.2"
 			}
 		},
 		"caller-callsite": {
@@ -17013,13 +17233,20 @@
 				"clone": "^1.0.2"
 			}
 		},
+		"define-lazy-prop": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+			"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+			"dev": true
+		},
 		"define-properties": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-			"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+			"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
 			"dev": true,
 			"requires": {
-				"object-keys": "^1.0.12"
+				"has-property-descriptors": "^1.0.0",
+				"object-keys": "^1.1.1"
 			}
 		},
 		"detect-indent": {
@@ -17115,6 +17342,15 @@
 			"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
 			"dev": true
 		},
+		"ejs": {
+			"version": "3.1.8",
+			"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
+			"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
+			"dev": true,
+			"requires": {
+				"jake": "^10.8.5"
+			}
+		},
 		"electron-to-chromium": {
 			"version": "1.3.633",
 			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz",
@@ -17167,22 +17403,34 @@
 			}
 		},
 		"es-abstract": {
-			"version": "1.17.4",
-			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
-			"integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+			"version": "1.20.1",
+			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz",
+			"integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==",
 			"dev": true,
 			"requires": {
+				"call-bind": "^1.0.2",
 				"es-to-primitive": "^1.2.1",
 				"function-bind": "^1.1.1",
+				"function.prototype.name": "^1.1.5",
+				"get-intrinsic": "^1.1.1",
+				"get-symbol-description": "^1.0.0",
 				"has": "^1.0.3",
-				"has-symbols": "^1.0.1",
-				"is-callable": "^1.1.5",
-				"is-regex": "^1.0.5",
-				"object-inspect": "^1.7.0",
+				"has-property-descriptors": "^1.0.0",
+				"has-symbols": "^1.0.3",
+				"internal-slot": "^1.0.3",
+				"is-callable": "^1.2.4",
+				"is-negative-zero": "^2.0.2",
+				"is-regex": "^1.1.4",
+				"is-shared-array-buffer": "^1.0.2",
+				"is-string": "^1.0.7",
+				"is-weakref": "^1.0.2",
+				"object-inspect": "^1.12.0",
 				"object-keys": "^1.1.1",
-				"object.assign": "^4.1.0",
-				"string.prototype.trimleft": "^2.1.1",
-				"string.prototype.trimright": "^2.1.1"
+				"object.assign": "^4.1.2",
+				"regexp.prototype.flags": "^1.4.3",
+				"string.prototype.trimend": "^1.0.5",
+				"string.prototype.trimstart": "^1.0.5",
+				"unbox-primitive": "^1.0.2"
 			}
 		},
 		"es-to-primitive": {
@@ -17649,6 +17897,35 @@
 				"flat-cache": "^3.0.4"
 			}
 		},
+		"filelist": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+			"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+			"dev": true,
+			"requires": {
+				"minimatch": "^5.0.1"
+			},
+			"dependencies": {
+				"brace-expansion": {
+					"version": "2.0.1",
+					"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+					"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+					"dev": true,
+					"requires": {
+						"balanced-match": "^1.0.0"
+					}
+				},
+				"minimatch": {
+					"version": "5.1.0",
+					"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
+					"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+					"dev": true,
+					"requires": {
+						"brace-expansion": "^2.0.1"
+					}
+				}
+			}
+		},
 		"filesize": {
 			"version": "6.1.0",
 			"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
@@ -17665,9 +17942,9 @@
 			}
 		},
 		"find-cache-dir": {
-			"version": "3.3.1",
-			"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
-			"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+			"version": "3.3.2",
+			"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+			"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
 			"dev": true,
 			"requires": {
 				"commondir": "^1.0.1",
@@ -17755,12 +18032,30 @@
 			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
 			"dev": true
 		},
+		"function.prototype.name": {
+			"version": "1.1.5",
+			"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+			"integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.19.0",
+				"functions-have-names": "^1.2.2"
+			}
+		},
 		"functional-red-black-tree": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
 			"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
 			"dev": true
 		},
+		"functions-have-names": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+			"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+			"dev": true
+		},
 		"generic-names": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz",
@@ -17789,14 +18084,14 @@
 			"dev": true
 		},
 		"get-intrinsic": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz",
-			"integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==",
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+			"integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
 			"dev": true,
 			"requires": {
 				"function-bind": "^1.1.1",
 				"has": "^1.0.3",
-				"has-symbols": "^1.0.1"
+				"has-symbols": "^1.0.3"
 			}
 		},
 		"get-own-enumerable-property-symbols": {
@@ -17814,6 +18109,16 @@
 				"pump": "^3.0.0"
 			}
 		},
+		"get-symbol-description": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+			"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"get-intrinsic": "^1.1.1"
+			}
+		},
 		"glob": {
 			"version": "7.1.6",
 			"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -17936,18 +18241,42 @@
 				"ansi-regex": "^2.0.0"
 			}
 		},
+		"has-bigints": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+			"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+			"dev": true
+		},
 		"has-flag": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
 			"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
 			"dev": true
 		},
+		"has-property-descriptors": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+			"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+			"dev": true,
+			"requires": {
+				"get-intrinsic": "^1.1.1"
+			}
+		},
 		"has-symbols": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
-			"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+			"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
 			"dev": true
 		},
+		"has-tostringtag": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+			"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+			"dev": true,
+			"requires": {
+				"has-symbols": "^1.0.2"
+			}
+		},
 		"he": {
 			"version": "1.2.0",
 			"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -18171,14 +18500,14 @@
 			"dev": true
 		},
 		"internal-slot": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz",
-			"integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==",
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+			"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
 			"dev": true,
 			"requires": {
-				"es-abstract": "^1.17.0-next.1",
+				"get-intrinsic": "^1.1.0",
 				"has": "^1.0.3",
-				"side-channel": "^1.0.2"
+				"side-channel": "^1.0.4"
 			}
 		},
 		"is-absolute-url": {
@@ -18193,6 +18522,15 @@
 			"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
 			"dev": true
 		},
+		"is-bigint": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+			"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+			"dev": true,
+			"requires": {
+				"has-bigints": "^1.0.1"
+			}
+		},
 		"is-binary-path": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -18202,10 +18540,20 @@
 				"binary-extensions": "^2.0.0"
 			}
 		},
+		"is-boolean-object": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+			"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
 		"is-callable": {
-			"version": "1.1.5",
-			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
-			"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+			"version": "1.2.4",
+			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+			"integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
 			"dev": true
 		},
 		"is-ci": {
@@ -18232,9 +18580,9 @@
 			}
 		},
 		"is-core-module": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
-			"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+			"version": "2.10.0",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+			"integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
 			"dev": true,
 			"requires": {
 				"has": "^1.0.3"
@@ -18252,6 +18600,12 @@
 			"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
 			"dev": true
 		},
+		"is-docker": {
+			"version": "2.2.1",
+			"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+			"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+			"dev": true
+		},
 		"is-extglob": {
 			"version": "2.1.1",
 			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -18280,9 +18634,9 @@
 			"dev": true
 		},
 		"is-negative-zero": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
-			"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+			"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
 			"dev": true
 		},
 		"is-number": {
@@ -18291,6 +18645,15 @@
 			"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 			"dev": true
 		},
+		"is-number-object": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+			"integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+			"dev": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
 		"is-obj": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
@@ -18313,12 +18676,13 @@
 			}
 		},
 		"is-regex": {
-			"version": "1.0.5",
-			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
-			"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+			"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
 			"dev": true,
 			"requires": {
-				"has": "^1.0.3"
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
 			}
 		},
 		"is-regexp": {
@@ -18333,6 +18697,15 @@
 			"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
 			"dev": true
 		},
+		"is-shared-array-buffer": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+			"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2"
+			}
+		},
 		"is-stream": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
@@ -18340,10 +18713,13 @@
 			"dev": true
 		},
 		"is-string": {
-			"version": "1.0.5",
-			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
-			"integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
-			"dev": true
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+			"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+			"dev": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
 		},
 		"is-subdir": {
 			"version": "1.2.0",
@@ -18372,24 +18748,105 @@
 				"has-symbols": "^1.0.1"
 			}
 		},
-		"is-windows": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
-			"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
-			"dev": true
-		},
-		"isarray": {
-			"version": "0.0.1",
-			"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-			"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-			"dev": true
-		},
-		"isexe": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-			"dev": true
-		},
+		"is-weakref": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+			"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2"
+			}
+		},
+		"is-windows": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+			"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+			"dev": true
+		},
+		"is-wsl": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+			"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+			"dev": true,
+			"requires": {
+				"is-docker": "^2.0.0"
+			}
+		},
+		"isarray": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+			"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+			"dev": true
+		},
+		"isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+			"dev": true
+		},
+		"jake": {
+			"version": "10.8.5",
+			"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
+			"integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
+			"dev": true,
+			"requires": {
+				"async": "^3.2.3",
+				"chalk": "^4.0.2",
+				"filelist": "^1.0.1",
+				"minimatch": "^3.0.4"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "4.3.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+					"dev": true,
+					"requires": {
+						"color-convert": "^2.0.1"
+					}
+				},
+				"chalk": {
+					"version": "4.1.2",
+					"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+					"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+					"dev": true,
+					"requires": {
+						"ansi-styles": "^4.1.0",
+						"supports-color": "^7.1.0"
+					}
+				},
+				"color-convert": {
+					"version": "2.0.1",
+					"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+					"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+					"dev": true,
+					"requires": {
+						"color-name": "~1.1.4"
+					}
+				},
+				"color-name": {
+					"version": "1.1.4",
+					"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+					"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+					"dev": true
+				},
+				"has-flag": {
+					"version": "4.0.0",
+					"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+					"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+					"dev": true
+				},
+				"supports-color": {
+					"version": "7.2.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+					"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+					"dev": true,
+					"requires": {
+						"has-flag": "^4.0.0"
+					}
+				}
+			}
+		},
 		"jest-worker": {
 			"version": "26.6.2",
 			"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@@ -18465,13 +18922,10 @@
 			"dev": true
 		},
 		"json5": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
-			"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
-			"dev": true,
-			"requires": {
-				"minimist": "^1.2.5"
-			}
+			"version": "2.2.1",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+			"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+			"dev": true
 		},
 		"jsonfile": {
 			"version": "4.0.0",
@@ -18490,20 +18944,6 @@
 			"requires": {
 				"array-includes": "^3.1.2",
 				"object.assign": "^4.1.2"
-			},
-			"dependencies": {
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
 			}
 		},
 		"just-extend": {
@@ -19081,9 +19521,9 @@
 			"dev": true
 		},
 		"microbundle": {
-			"version": "0.13.0",
-			"resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.13.0.tgz",
-			"integrity": "sha512-d5glQP8nWoaZhgNF7pxmBpSI/zYMn0NfjH5tOjLudfgoceWiiq+5crwIHGqWKFDbaTcyMjD9HKowy3hNWJCHow==",
+			"version": "0.15.1",
+			"resolved": "https://registry.npmjs.org/microbundle/-/microbundle-0.15.1.tgz",
+			"integrity": "sha512-aAF+nwFbkSIJGfrJk+HyzmJOq3KFaimH6OIFBU6J2DPjQeg1jXIYlIyEv81Gyisb9moUkudn+wj7zLNYMOv75Q==",
 			"dev": true,
 			"requires": {
 				"@babel/core": "^7.12.10",
@@ -19101,10 +19541,11 @@
 				"@rollup/plugin-commonjs": "^17.0.0",
 				"@rollup/plugin-json": "^4.1.0",
 				"@rollup/plugin-node-resolve": "^11.0.1",
+				"@surma/rollup-plugin-off-main-thread": "^2.2.2",
 				"asyncro": "^3.0.0",
 				"autoprefixer": "^10.1.0",
 				"babel-plugin-macros": "^3.0.1",
-				"babel-plugin-transform-async-to-promises": "^0.8.15",
+				"babel-plugin-transform-async-to-promises": "^0.8.18",
 				"babel-plugin-transform-replace-expressions": "^0.2.0",
 				"brotli-size": "^4.0.0",
 				"builtin-modules": "^3.1.0",
@@ -19120,8 +19561,10 @@
 				"rollup-plugin-bundle-size": "^1.0.3",
 				"rollup-plugin-postcss": "^4.0.0",
 				"rollup-plugin-terser": "^7.0.2",
-				"rollup-plugin-typescript2": "^0.29.0",
+				"rollup-plugin-typescript2": "^0.32.0",
+				"rollup-plugin-visualizer": "^5.6.0",
 				"sade": "^1.7.4",
+				"terser": "^5.7.0",
 				"tiny-glob": "^0.2.8",
 				"tslib": "^2.0.3",
 				"typescript": "^4.1.3"
@@ -19500,9 +19943,9 @@
 			"dev": true
 		},
 		"nanoid": {
-			"version": "3.1.20",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
-			"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
+			"version": "3.3.4",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+			"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
 			"dev": true
 		},
 		"natural-compare": {
@@ -19616,9 +20059,9 @@
 			"dev": true
 		},
 		"object-inspect": {
-			"version": "1.7.0",
-			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
-			"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+			"version": "1.12.2",
+			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+			"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
 			"dev": true
 		},
 		"object-keys": {
@@ -19628,15 +20071,15 @@
 			"dev": true
 		},
 		"object.assign": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
-			"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+			"version": "4.1.4",
+			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+			"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
 			"dev": true,
 			"requires": {
-				"define-properties": "^1.1.2",
-				"function-bind": "^1.1.1",
-				"has-symbols": "^1.0.0",
-				"object-keys": "^1.0.11"
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"has-symbols": "^1.0.3",
+				"object-keys": "^1.1.1"
 			}
 		},
 		"object.entries": {
@@ -19649,61 +20092,6 @@
 				"define-properties": "^1.1.3",
 				"es-abstract": "^1.18.0-next.1",
 				"has": "^1.0.3"
-			},
-			"dependencies": {
-				"es-abstract": {
-					"version": "1.18.0-next.1",
-					"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-					"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-					"dev": true,
-					"requires": {
-						"es-to-primitive": "^1.2.1",
-						"function-bind": "^1.1.1",
-						"has": "^1.0.3",
-						"has-symbols": "^1.0.1",
-						"is-callable": "^1.2.2",
-						"is-negative-zero": "^2.0.0",
-						"is-regex": "^1.1.1",
-						"object-inspect": "^1.8.0",
-						"object-keys": "^1.1.1",
-						"object.assign": "^4.1.1",
-						"string.prototype.trimend": "^1.0.1",
-						"string.prototype.trimstart": "^1.0.1"
-					}
-				},
-				"is-callable": {
-					"version": "1.2.2",
-					"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-					"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-					"dev": true
-				},
-				"is-regex": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-					"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-					"dev": true,
-					"requires": {
-						"has-symbols": "^1.0.1"
-					}
-				},
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				},
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
 			}
 		},
 		"object.fromentries": {
@@ -19716,61 +20104,6 @@
 				"define-properties": "^1.1.3",
 				"es-abstract": "^1.18.0-next.1",
 				"has": "^1.0.3"
-			},
-			"dependencies": {
-				"es-abstract": {
-					"version": "1.18.0-next.1",
-					"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-					"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-					"dev": true,
-					"requires": {
-						"es-to-primitive": "^1.2.1",
-						"function-bind": "^1.1.1",
-						"has": "^1.0.3",
-						"has-symbols": "^1.0.1",
-						"is-callable": "^1.2.2",
-						"is-negative-zero": "^2.0.0",
-						"is-regex": "^1.1.1",
-						"object-inspect": "^1.8.0",
-						"object-keys": "^1.1.1",
-						"object.assign": "^4.1.1",
-						"string.prototype.trimend": "^1.0.1",
-						"string.prototype.trimstart": "^1.0.1"
-					}
-				},
-				"is-callable": {
-					"version": "1.2.2",
-					"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-					"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-					"dev": true
-				},
-				"is-regex": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-					"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-					"dev": true,
-					"requires": {
-						"has-symbols": "^1.0.1"
-					}
-				},
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				},
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
 			}
 		},
 		"object.getownpropertydescriptors": {
@@ -19782,61 +20115,6 @@
 				"call-bind": "^1.0.0",
 				"define-properties": "^1.1.3",
 				"es-abstract": "^1.18.0-next.1"
-			},
-			"dependencies": {
-				"es-abstract": {
-					"version": "1.18.0-next.1",
-					"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-					"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-					"dev": true,
-					"requires": {
-						"es-to-primitive": "^1.2.1",
-						"function-bind": "^1.1.1",
-						"has": "^1.0.3",
-						"has-symbols": "^1.0.1",
-						"is-callable": "^1.2.2",
-						"is-negative-zero": "^2.0.0",
-						"is-regex": "^1.1.1",
-						"object-inspect": "^1.8.0",
-						"object-keys": "^1.1.1",
-						"object.assign": "^4.1.1",
-						"string.prototype.trimend": "^1.0.1",
-						"string.prototype.trimstart": "^1.0.1"
-					}
-				},
-				"is-callable": {
-					"version": "1.2.2",
-					"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-					"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-					"dev": true
-				},
-				"is-regex": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-					"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-					"dev": true,
-					"requires": {
-						"has-symbols": "^1.0.1"
-					}
-				},
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				},
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
 			}
 		},
 		"object.values": {
@@ -19869,6 +20147,17 @@
 				"mimic-fn": "^2.1.0"
 			}
 		},
+		"open": {
+			"version": "8.4.0",
+			"resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz",
+			"integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==",
+			"dev": true,
+			"requires": {
+				"define-lazy-prop": "^2.0.0",
+				"is-docker": "^2.1.1",
+				"is-wsl": "^2.2.0"
+			}
+		},
 		"opencollective-postinstall": {
 			"version": "2.0.3",
 			"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
@@ -20024,9 +20313,9 @@
 			"dev": true
 		},
 		"path-parse": {
-			"version": "1.0.6",
-			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-			"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
 			"dev": true
 		},
 		"path-to-regexp": {
@@ -22502,13 +22791,14 @@
 			}
 		},
 		"regexp.prototype.flags": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
-			"integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+			"version": "1.4.3",
+			"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+			"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
 			"dev": true,
 			"requires": {
+				"call-bind": "^1.0.2",
 				"define-properties": "^1.1.3",
-				"es-abstract": "^1.17.0-next.1"
+				"functions-have-names": "^1.2.2"
 			}
 		},
 		"regexpp": {
@@ -22567,13 +22857,14 @@
 			"dev": true
 		},
 		"resolve": {
-			"version": "1.19.0",
-			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
-			"integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+			"version": "1.22.1",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+			"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
 			"dev": true,
 			"requires": {
-				"is-core-module": "^2.1.0",
-				"path-parse": "^1.0.6"
+				"is-core-module": "^2.9.0",
+				"path-parse": "^1.0.7",
+				"supports-preserve-symlinks-flag": "^1.0.0"
 			}
 		},
 		"resolve-from": {
@@ -22720,31 +23011,138 @@
 			}
 		},
 		"rollup-plugin-typescript2": {
-			"version": "0.29.0",
-			"resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.29.0.tgz",
-			"integrity": "sha512-YytahBSZCIjn/elFugEGQR5qTsVhxhUwGZIsA9TmrSsC88qroGo65O5HZP/TTArH2dm0vUmYWhKchhwi2wL9bw==",
+			"version": "0.32.1",
+			"resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.32.1.tgz",
+			"integrity": "sha512-RanO8bp1WbeMv0bVlgcbsFNCn+Y3rX7wF97SQLDxf0fMLsg0B/QFF005t4AsGUcDgF3aKJHoqt4JF2xVaABeKw==",
 			"dev": true,
 			"requires": {
-				"@rollup/pluginutils": "^3.1.0",
-				"find-cache-dir": "^3.3.1",
-				"fs-extra": "8.1.0",
-				"resolve": "1.17.0",
-				"tslib": "2.0.1"
+				"@rollup/pluginutils": "^4.1.2",
+				"find-cache-dir": "^3.3.2",
+				"fs-extra": "^10.0.0",
+				"resolve": "^1.20.0",
+				"tslib": "^2.4.0"
 			},
 			"dependencies": {
-				"resolve": {
-					"version": "1.17.0",
-					"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
-					"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+				"@rollup/pluginutils": {
+					"version": "4.2.1",
+					"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
+					"integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==",
+					"dev": true,
+					"requires": {
+						"estree-walker": "^2.0.1",
+						"picomatch": "^2.2.2"
+					}
+				},
+				"estree-walker": {
+					"version": "2.0.2",
+					"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+					"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+					"dev": true
+				},
+				"fs-extra": {
+					"version": "10.1.0",
+					"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+					"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+					"dev": true,
+					"requires": {
+						"graceful-fs": "^4.2.0",
+						"jsonfile": "^6.0.1",
+						"universalify": "^2.0.0"
+					}
+				},
+				"jsonfile": {
+					"version": "6.1.0",
+					"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+					"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
 					"dev": true,
 					"requires": {
-						"path-parse": "^1.0.6"
+						"graceful-fs": "^4.1.6",
+						"universalify": "^2.0.0"
 					}
 				},
 				"tslib": {
-					"version": "2.0.1",
-					"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz",
-					"integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==",
+					"version": "2.4.0",
+					"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+					"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+					"dev": true
+				},
+				"universalify": {
+					"version": "2.0.0",
+					"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+					"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+					"dev": true
+				}
+			}
+		},
+		"rollup-plugin-visualizer": {
+			"version": "5.7.1",
+			"resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.7.1.tgz",
+			"integrity": "sha512-E/IgOMnmXKlc6ICyf53ok1b6DxPeNVUs3R0kYYPuDpGfofT4bkiG+KtSMlGjMACFmfwbbqTVDZBIF7sMZVKJbA==",
+			"dev": true,
+			"requires": {
+				"nanoid": "^3.3.4",
+				"open": "^8.4.0",
+				"source-map": "^0.7.3",
+				"yargs": "^17.5.1"
+			},
+			"dependencies": {
+				"ansi-regex": {
+					"version": "5.0.1",
+					"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+					"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+					"dev": true
+				},
+				"is-fullwidth-code-point": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+					"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+					"dev": true
+				},
+				"source-map": {
+					"version": "0.7.4",
+					"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+					"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+					"dev": true
+				},
+				"string-width": {
+					"version": "4.2.3",
+					"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+					"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+					"dev": true,
+					"requires": {
+						"emoji-regex": "^8.0.0",
+						"is-fullwidth-code-point": "^3.0.0",
+						"strip-ansi": "^6.0.1"
+					}
+				},
+				"strip-ansi": {
+					"version": "6.0.1",
+					"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+					"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+					"dev": true,
+					"requires": {
+						"ansi-regex": "^5.0.1"
+					}
+				},
+				"yargs": {
+					"version": "17.5.1",
+					"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+					"integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+					"dev": true,
+					"requires": {
+						"cliui": "^7.0.2",
+						"escalade": "^3.1.1",
+						"get-caller-file": "^2.0.5",
+						"require-directory": "^2.1.1",
+						"string-width": "^4.2.3",
+						"y18n": "^5.0.5",
+						"yargs-parser": "^21.0.0"
+					}
+				},
+				"yargs-parser": {
+					"version": "21.1.1",
+					"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+					"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
 					"dev": true
 				}
 			}
@@ -22874,14 +23272,6 @@
 				"call-bind": "^1.0.0",
 				"get-intrinsic": "^1.0.2",
 				"object-inspect": "^1.9.0"
-			},
-			"dependencies": {
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				}
 			}
 		},
 		"signal-exit": {
@@ -23135,12 +23525,21 @@
 			"dev": true
 		},
 		"source-map-support": {
-			"version": "0.5.19",
-			"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
-			"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+			"version": "0.5.21",
+			"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+			"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
 			"dev": true,
 			"requires": {
-				"buffer-from": "^1.0.0"
+				"buffer-from": "^1.0.0",
+				"source-map": "^0.6.0"
+			},
+			"dependencies": {
+				"source-map": {
+					"version": "0.6.1",
+					"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+					"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+					"dev": true
+				}
 			}
 		},
 		"sourcemap-codec": {
@@ -23311,113 +23710,41 @@
 			}
 		},
 		"string.prototype.matchall": {
-			"version": "4.0.3",
-			"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz",
-			"integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==",
+			"version": "4.0.7",
+			"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz",
+			"integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==",
 			"dev": true,
 			"requires": {
-				"call-bind": "^1.0.0",
+				"call-bind": "^1.0.2",
 				"define-properties": "^1.1.3",
-				"es-abstract": "^1.18.0-next.1",
-				"has-symbols": "^1.0.1",
-				"internal-slot": "^1.0.2",
-				"regexp.prototype.flags": "^1.3.0",
-				"side-channel": "^1.0.3"
-			},
-			"dependencies": {
-				"es-abstract": {
-					"version": "1.18.0-next.1",
-					"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
-					"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
-					"dev": true,
-					"requires": {
-						"es-to-primitive": "^1.2.1",
-						"function-bind": "^1.1.1",
-						"has": "^1.0.3",
-						"has-symbols": "^1.0.1",
-						"is-callable": "^1.2.2",
-						"is-negative-zero": "^2.0.0",
-						"is-regex": "^1.1.1",
-						"object-inspect": "^1.8.0",
-						"object-keys": "^1.1.1",
-						"object.assign": "^4.1.1",
-						"string.prototype.trimend": "^1.0.1",
-						"string.prototype.trimstart": "^1.0.1"
-					}
-				},
-				"is-callable": {
-					"version": "1.2.2",
-					"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
-					"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
-					"dev": true
-				},
-				"is-regex": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
-					"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
-					"dev": true,
-					"requires": {
-						"has-symbols": "^1.0.1"
-					}
-				},
-				"object-inspect": {
-					"version": "1.9.0",
-					"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
-					"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
-					"dev": true
-				},
-				"object.assign": {
-					"version": "4.1.2",
-					"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
-					"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
-					"dev": true,
-					"requires": {
-						"call-bind": "^1.0.0",
-						"define-properties": "^1.1.3",
-						"has-symbols": "^1.0.1",
-						"object-keys": "^1.1.1"
-					}
-				}
+				"es-abstract": "^1.19.1",
+				"get-intrinsic": "^1.1.1",
+				"has-symbols": "^1.0.3",
+				"internal-slot": "^1.0.3",
+				"regexp.prototype.flags": "^1.4.1",
+				"side-channel": "^1.0.4"
 			}
 		},
 		"string.prototype.trimend": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
-			"integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
-			"dev": true,
-			"requires": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3"
-			}
-		},
-		"string.prototype.trimleft": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
-			"integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
-			"dev": true,
-			"requires": {
-				"define-properties": "^1.1.3",
-				"function-bind": "^1.1.1"
-			}
-		},
-		"string.prototype.trimright": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
-			"integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
+			"integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
 			"dev": true,
 			"requires": {
-				"define-properties": "^1.1.3",
-				"function-bind": "^1.1.1"
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"es-abstract": "^1.19.5"
 			}
 		},
 		"string.prototype.trimstart": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
-			"integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
+			"integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
 			"dev": true,
 			"requires": {
-				"call-bind": "^1.0.0",
-				"define-properties": "^1.1.3"
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"es-abstract": "^1.19.5"
 			}
 		},
 		"stringify-object": {
@@ -23566,6 +23893,12 @@
 			"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
 			"dev": true
 		},
+		"supports-preserve-symlinks-flag": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+			"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+			"dev": true
+		},
 		"svgo": {
 			"version": "1.3.2",
 			"resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
@@ -23671,20 +24004,21 @@
 			"dev": true
 		},
 		"terser": {
-			"version": "5.5.1",
-			"resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz",
-			"integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==",
+			"version": "5.14.2",
+			"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
+			"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
 			"dev": true,
 			"requires": {
+				"@jridgewell/source-map": "^0.3.2",
+				"acorn": "^8.5.0",
 				"commander": "^2.20.0",
-				"source-map": "~0.7.2",
-				"source-map-support": "~0.5.19"
+				"source-map-support": "~0.5.20"
 			},
 			"dependencies": {
-				"source-map": {
-					"version": "0.7.3",
-					"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
-					"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+				"acorn": {
+					"version": "8.8.0",
+					"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+					"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
 					"dev": true
 				}
 			}
@@ -23997,6 +24331,18 @@
 			"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
 			"dev": true
 		},
+		"unbox-primitive": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+			"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-bigints": "^1.0.2",
+				"has-symbols": "^1.0.3",
+				"which-boxed-primitive": "^1.0.2"
+			}
+		},
 		"unicode-canonical-property-names-ecmascript": {
 			"version": "1.0.4",
 			"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -24138,6 +24484,19 @@
 				"isexe": "^2.0.0"
 			}
 		},
+		"which-boxed-primitive": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+			"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+			"dev": true,
+			"requires": {
+				"is-bigint": "^1.0.1",
+				"is-boolean-object": "^1.1.0",
+				"is-number-object": "^1.0.4",
+				"is-string": "^1.0.5",
+				"is-symbol": "^1.0.3"
+			}
+		},
 		"which-module": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
diff --git a/package.json b/package.json
index bc4f9f9..a439330 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
 	},
 	"scripts": {
 		"bench": "BABEL_ENV=test node -r @babel/register benchmarks index.js",
-		"bench:v8": "BABEL_ENV=test microbundle benchmarks/index.js -f modern --alias benchmarkjs-pretty=benchmarks/lib/benchmark-lite.js --external none --target node --no-compress --no-sourcemap --raw -o benchmarks/.v8.js && v8 --module benchmarks/.v8.modern.js",
+		"bench:v8": "BABEL_ENV=test microbundle benchmarks/index.js -f modern --alias benchmarkjs-pretty=benchmarks/lib/benchmark-lite.js --external none --target node --no-compress --no-sourcemap --raw -o benchmarks/.v8.mjs && v8 --module benchmarks/.v8.mjs",
 		"build": "npm run -s transpile && npm run -s transpile:jsx && npm run -s copy-typescript-definition",
 		"postbuild": "node ./config/node-13-exports.js && node ./config/node-commonjs.js",
 		"transpile": "microbundle src/index.js -f es,umd --target web --external preact",
@@ -33,8 +33,8 @@
 		"copy-typescript-definition": "copyfiles -f src/*.d.ts dist",
 		"test": "eslint src test && tsc && npm run test:mocha && npm run test:mocha:compat && npm run test:mocha:debug && npm run bench",
 		"test:mocha": "BABEL_ENV=test mocha -r @babel/register -r test/setup.js test/*.test.js",
-		"test:mocha:compat": "BABEL_ENV=test mocha -r @babel/register -r test/setup.js test/compat.test.js 'test/compat/index.test.js'",
-		"test:mocha:debug": "BABEL_ENV=test mocha -r @babel/register -r test/setup.js test/debug.test.js 'test/debug/index.test.js'",
+		"test:mocha:compat": "BABEL_ENV=test mocha -r @babel/register -r test/setup.js 'test/compat/index.test.js'",
+		"test:mocha:debug": "BABEL_ENV=test mocha -r @babel/register -r test/setup.js 'test/debug/index.test.js'",
 		"format": "prettier src/**/*.{d.ts,js} test/**/*.js --write",
 		"prepublishOnly": "npm run build",
 		"release": "npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish"
@@ -93,6 +93,11 @@
 			}
 		}
 	},
+	"minify": {
+		"compress": {
+			"reduce_funcs": false
+		}
+	},
 	"author": "Jason Miller <jason@developit.ca>",
 	"license": "MIT",
 	"repository": "developit/preact-render-to-string",
@@ -105,8 +110,8 @@
 		"@babel/plugin-transform-react-jsx": "^7.12.12",
 		"@babel/preset-env": "^7.12.11",
 		"@babel/register": "^7.12.10",
-		"@changesets/cli": "^2.18.0",
 		"@changesets/changelog-github": "^0.4.1",
+		"@changesets/cli": "^2.18.0",
 		"benchmarkjs-pretty": "^2.0.1",
 		"chai": "^4.2.0",
 		"copyfiles": "^2.4.1",
@@ -114,7 +119,7 @@
 		"eslint-config-developit": "^1.2.0",
 		"husky": "^4.3.6",
 		"lint-staged": "^10.5.3",
-		"microbundle": "^0.13.0",
+		"microbundle": "^0.15.1",
 		"mocha": "^8.2.1",
 		"preact": "^10.11.1",
 		"prettier": "^2.2.1",
@@ -140,10 +145,5 @@
 		"hooks": {
 			"pre-commit": "lint-staged"
 		}
-	},
-	"mangle": {
-		"compress": {
-			"reduce_funcs": false
-		}
 	}
 }
diff --git a/src/index.d.ts b/src/index.d.ts
index 221d349..3c397d4 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1,16 +1,3 @@
 import { VNode } from 'preact';
 
-interface Options {
-	shallow?: boolean;
-	xml?: boolean;
-	pretty?: boolean | string;
-}
-
-export function render(vnode: VNode, context?: any, options?: Options): string;
-export function renderToString(
-	vnode: VNode,
-	context?: any,
-	options?: Options
-): string;
-export function shallowRender(vnode: VNode, context?: any): string;
-export default render;
+export default function renderToString(vnode: VNode, context?: any): string;
diff --git a/src/index.js b/src/index.js
index 9d816d6..8095473 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,15 +1,7 @@
-import {
-	encodeEntities,
-	styleObjToCss,
-	getContext,
-	createComponent,
-	UNSAFE_NAME,
-	XLINK,
-	VOID_ELEMENTS
-} from './util';
+import { encodeEntities, styleObjToCss, UNSAFE_NAME, XLINK } from './util';
 import { options, h, Fragment } from 'preact';
-import { _renderToStringPretty } from './pretty';
 import {
+	CHILDREN,
 	COMMIT,
 	COMPONENT,
 	DIFF,
@@ -19,40 +11,25 @@ import {
 	PARENT,
 	RENDER,
 	SKIP_EFFECTS,
-	VNODE,
-	CHILDREN
+	VNODE
 } from './constants';
 
 /** @typedef {import('preact').VNode} VNode */
 
-const SHALLOW = { shallow: true };
-
-/** Render Preact JSX + Components to an HTML string.
- *	@name render
- *	@function
- *	@param {VNode} vnode	JSX VNode to render.
- *	@param {Object} [context={}]	Optionally pass an initial context object through the render path.
- *	@param {Object} [options={}]	Rendering options
- *	@param {Boolean} [options.shallow=false]	If `true`, renders nested Components as HTML elements (`<Foo a="b" />`).
- *	@param {Boolean} [options.xml=false]		If `true`, uses self-closing tags for elements without children.
- *	@param {Boolean} [options.pretty=false]		If `true`, adds whitespace for readability
- *	@param {RegExp|undefined} [options.voidElements]       RegeEx that matches elements that are considered void (self-closing)
- */
-renderToString.render = renderToString;
-
-/** Only render elements, leaving Components inline as `<ComponentName ... />`.
- *	This method is just a convenience alias for `render(vnode, context, { shallow:true })`
- *	@name shallow
- *	@function
- *	@param {VNode} vnode	JSX VNode to render.
- *	@param {Object} [context={}]	Optionally pass an initial context object through the render path.
- */
-let shallowRender = (vnode, context) => renderToString(vnode, context, SHALLOW);
-
 const EMPTY_ARR = [];
-function renderToString(vnode, context, opts) {
-	context = context || {};
+const isArray = Array.isArray;
+const assign = Object.assign;
+
+// Global state for the current render pass
+let beforeDiff, afterDiff, renderHook;
 
+/**
+ * Render Preact JSX + Components to an HTML string.
+ * @param {VNode} vnode	JSX Element / VNode to render
+ * @param {Object} [context={}] Initial root context object
+ * @returns {string} serialized HTML
+ */
+export default function renderToString(vnode, context) {
 	// Performance optimization: `renderToString` is synchronous and we
 	// therefore don't execute any effects. To do that we pass an empty
 	// array to `options._commit` (`__c`). But we can go one step further
@@ -61,95 +38,58 @@ function renderToString(vnode, context, opts) {
 	const previousSkipEffects = options[SKIP_EFFECTS];
 	options[SKIP_EFFECTS] = true;
 
+	// store options hooks once before each synchronous render call
+	beforeDiff = options[DIFF];
+	afterDiff = options[DIFFED];
+	renderHook = options[RENDER];
+
 	const parent = h(Fragment, null);
 	parent[CHILDREN] = [vnode];
 
-	let res;
-	if (
-		opts &&
-		(opts.pretty ||
-			opts.voidElements ||
-			opts.sortAttributes ||
-			opts.shallow ||
-			opts.allAttributes ||
-			opts.xml ||
-			opts.attributeHook)
-	) {
-		res = _renderToStringPretty(vnode, context, opts);
-	} else {
-		res = _renderToString(vnode, context, false, undefined, parent);
+	try {
+		return _renderToString(vnode, context || {}, false, undefined, parent);
+	} finally {
+		// options._commit, we don't schedule any effects in this library right now,
+		// so we can pass an empty queue to this hook.
+		if (options[COMMIT]) options[COMMIT](vnode, EMPTY_ARR);
+		options[SKIP_EFFECTS] = previousSkipEffects;
+		EMPTY_ARR.length = 0;
 	}
-
-	// options._commit, we don't schedule any effects in this library right now,
-	// so we can pass an empty queue to this hook.
-	if (options[COMMIT]) options[COMMIT](vnode, EMPTY_ARR);
-	options[SKIP_EFFECTS] = previousSkipEffects;
-	EMPTY_ARR.length = 0;
-
-	return res;
 }
 
-/**
- * @param {VNode} vnode
- * @param {Record<string, unknown>} context
- * @returns {string}
- */
-function renderFunctionComponent(vnode, context) {
-	// eslint-disable-next-line lines-around-comment
-	/** @type {string} */
-	let rendered,
-		c = createComponent(vnode, context),
-		cctx = getContext(vnode.type, context);
-
-	vnode[COMPONENT] = c;
-
-	// If a hook invokes setState() to invalidate the component during rendering,
-	// re-render it up to 25 times to allow "settling" of memoized states.
-	// Note:
-	//   This will need to be updated for Preact 11 to use internal.flags rather than component._dirty:
-	//   https://github.com/preactjs/preact/blob/d4ca6fdb19bc715e49fd144e69f7296b2f4daa40/src/diff/component.js#L35-L44
-	let renderHook = options[RENDER];
-	let count = 0;
-	while (c[DIRTY] && count++ < 25) {
-		c[DIRTY] = false;
-
-		if (renderHook) renderHook(vnode);
-
-		// stateless functional components
-		rendered = vnode.type.call(c, vnode.props, cctx);
-	}
-
-	return rendered;
+// Installed as setState/forceUpdate for function components
+function markAsDirty() {
+	this.__d = true;
 }
 
 /**
  * @param {VNode} vnode
  * @param {Record<string, unknown>} context
- * @returns {VNode}
  */
 function renderClassComponent(vnode, context) {
-	let nodeName = vnode.type,
-		cctx = getContext(nodeName, context);
+	let type = /** @type {import("preact").ComponentClass<typeof vnode.props>} */ (vnode.type);
+
+	let c = new type(vnode.props, context);
 
-	/** @type {import("preact").Component} */
-	let c = new nodeName(vnode.props, cctx);
 	vnode[COMPONENT] = c;
 	c[VNODE] = vnode;
+
+	c.props = vnode.props;
+	c.context = context;
 	// turn off stateful re-rendering:
 	c[DIRTY] = true;
-	c.props = vnode.props;
+
 	if (c.state == null) c.state = {};
 
 	if (c[NEXT_STATE] == null) {
 		c[NEXT_STATE] = c.state;
 	}
 
-	c.context = cctx;
-	if (nodeName.getDerivedStateFromProps) {
+	if (type.getDerivedStateFromProps) {
 		c.state = assign(
 			{},
 			c.state,
-			nodeName.getDerivedStateFromProps(c.props, c.state)
+			type.getDerivedStateFromProps(c.props, c.state)
 		);
 	} else if (c.componentWillMount) {
 		c.componentWillMount();
@@ -159,79 +99,18 @@ function renderClassComponent(vnode, context) {
 		c.state = c[NEXT_STATE] !== c.state ? c[NEXT_STATE] : c.state;
 	}
 
-	let renderHook = options[RENDER];
 	if (renderHook) renderHook(vnode);
 
-	return c.render(c.props, c.state, c.context);
-}
-
-/**
- * @param {any} vnode
- * @returns {VNode}
- */
-function normalizeVNode(vnode) {
-	if (vnode == null || typeof vnode == 'boolean') {
-		return null;
-	} else if (
-		typeof vnode == 'string' ||
-		typeof vnode == 'number' ||
-		typeof vnode == 'bigint'
-	) {
-		return h(null, null, vnode);
-	}
-	return vnode;
+	return c.render(c.props, c.state, context);
 }
 
 /**
- * @param {string} name
- * @param {boolean} isSvgMode
- * @returns {string}
- */
-function normalizePropName(name, isSvgMode) {
-	if (name === 'className') {
-		return 'class';
-	} else if (name === 'htmlFor') {
-		return 'for';
-	} else if (name === 'defaultValue') {
-		return 'value';
-	} else if (name === 'defaultChecked') {
-		return 'checked';
-	} else if (name === 'defaultSelected') {
-		return 'selected';
-	} else if (isSvgMode && XLINK.test(name)) {
-		return name.toLowerCase().replace(/^xlink:?/, 'xlink:');
-	}
-
-	return name;
-}
-
-/**
- * @param {string} name
- * @param {string | Record<string, unknown>} v
- * @returns {string}
- */
-function normalizePropValue(name, v) {
-	if (name === 'style' && v != null && typeof v === 'object') {
-		return styleObjToCss(v);
-	} else if (name[0] === 'a' && name[1] === 'r' && typeof v === 'boolean') {
-		// always use string values instead of booleans for aria attributes
-		// also see https://github.com/preactjs/preact/pull/2347/files
-		return String(v);
-	}
-
-	return v;
-}
-
-const isArray = Array.isArray;
-const assign = Object.assign;
-
-/**
- * The default export is an alias of `render()`.
- * @param {any} vnode
- * @param {Record<string, unknown>} context
+ * Recursively render VNodes to HTML.
+ * @param {VNode|any} vnode
+ * @param {any} context
  * @param {boolean} isSvgMode
  * @param {any} selectValue
- * @param {VNode | null} parent
+ * @param {VNode} parent
  * @returns {string}
  */
 function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
@@ -243,7 +122,7 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
 	// Text VNodes: escape as HTML
 	if (typeof vnode !== 'object') {
 		if (typeof vnode === 'function') return '';
-		return encodeEntities(vnode);
+		return encodeEntities(vnode + '');
 	}
 
 	// Recurse into children / Arrays
@@ -251,11 +130,21 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
 		let rendered = '';
 		parent[CHILDREN] = vnode;
 		for (let i = 0; i < vnode.length; i++) {
+			let child = vnode[i];
+			if (child == null || typeof child === 'boolean') continue;
+
 			rendered =
 				rendered +
-				_renderToString(vnode[i], context, isSvgMode, selectValue, parent);
+				_renderToString(child, context, isSvgMode, selectValue, parent);
 
-			vnode[i] = normalizeVNode(vnode[i]);
+			if (
+				typeof child === 'string' ||
+				typeof child === 'number' ||
+				typeof child === 'bigint'
+			) {
+				// @ts-ignore manually constructing a Text vnode
+				vnode[i] = h(null, null, child);
+			}
 		}
 		return rendered;
 	}
@@ -264,26 +153,61 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
 	if (vnode.constructor !== undefined) return '';
 
 	vnode[PARENT] = parent;
-	if (options[DIFF]) options[DIFF](vnode);
+	if (beforeDiff) beforeDiff(vnode);
 
 	let type = vnode.type,
-		props = vnode.props;
+		props = vnode.props,
+		cctx = context,
+		contextType,
+		rendered,
+		component;
 
 	// Invoke rendering on Components
-	const isComponent = typeof type === 'function';
+	let isComponent = typeof type === 'function';
 	if (isComponent) {
-		let rendered;
 		if (type === Fragment) {
 			rendered = props.children;
 		} else {
+			contextType = type.contextType;
+			if (contextType != null) {
+				let provider = context[contextType.__c];
+				cctx = provider ? provider.props.value : contextType.__;
+			}
+
 			if (type.prototype && typeof type.prototype.render === 'function') {
-				rendered = renderClassComponent(vnode, context);
+				rendered = /**#__NOINLINE__**/ renderClassComponent(vnode, cctx);
+				component = vnode[COMPONENT];
 			} else {
-				rendered = renderFunctionComponent(vnode, context);
+				component = {
+					__v: vnode,
+					props,
+					context: cctx,
+					// silently drop state updates
+					setState: markAsDirty,
+					forceUpdate: markAsDirty,
+					__d: true,
+					// hooks
+					__h: []
+				};
+				vnode[COMPONENT] = component;
+
+				// If a hook invokes setState() to invalidate the component during rendering,
+				// re-render it up to 25 times to allow "settling" of memoized states.
+				// Note:
+				//   This will need to be updated for Preact 11 to use internal.flags rather than component._dirty:
+				//   https://github.com/preactjs/preact/blob/d4ca6fdb19bc715e49fd144e69f7296b2f4daa40/src/diff/component.js#L35-L44
+				let count = 0;
+				while (component[DIRTY] && count++ < 25) {
+					component[DIRTY] = false;
+
+					if (renderHook) renderHook(vnode);
+
+					rendered = type.call(component, props, cctx);
+				}
+				component[DIRTY] = true;
 			}
 
-			let component = vnode[COMPONENT];
-			if (component.getChildContext) {
+			if (component.getChildContext != null) {
 				context = assign({}, context, component.getChildContext());
 			}
 		}
@@ -302,8 +226,7 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
 			selectValue,
 			vnode
 		);
-
-		if (options[DIFFED]) options[DIFFED](vnode);
+		if (afterDiff) afterDiff(vnode);
 		vnode[PARENT] = undefined;
 
 		if (options.unmount) options.unmount(vnode);
@@ -312,146 +235,139 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) {
 	}
 
 	// Serialize Element VNodes to HTML
-	let s = '<',
-		children,
-		html;
+	let s = '<' + type,
+		html = '',
+		children;
 
-	s = s + type;
+	for (let name in props) {
+		let v = props[name];
 
-	if (props) {
-		children = props.children;
-		for (let name in props) {
-			let v = props[name];
+		switch (name) {
+			case 'children':
+				children = v;
+				continue;
 
-			if (
-				name === 'key' ||
-				name === 'ref' ||
-				name === '__self' ||
-				name === '__source' ||
-				name === 'children' ||
-				(name === 'className' && 'class' in props) ||
-				(name === 'htmlFor' && 'for' in props)
-			) {
+			// VDOM-specific props
+			case 'key':
+			case 'ref':
+			case '__self':
+			case '__source':
 				continue;
-			}
 
-			if (UNSAFE_NAME.test(name)) continue;
+			// prefer for/class over htmlFor/className
+			case 'htmlFor':
+				if ('for' in props) continue;
+				name = 'for';
+				break;
+			case 'className':
+				if ('class' in props) continue;
+				name = 'class';
+				break;
+
+			// Form element reflected properties
+			case 'defaultChecked':
+				name = 'checked';
+				break;
+			case 'defaultSelected':
+				name = 'selected';
+				break;
+
+			// Special value attribute handling
+			case 'defaultValue':
+			case 'value':
+				name = 'value';
+				switch (type) {
+					// <textarea value="a&b"> --> <textarea>a&amp;b</textarea>
+					case 'textarea':
+						children = v;
+						continue;
+
+					// <select value> is serialized as a selected attribute on the matching option child
+					case 'select':
+						selectValue = v;
+						continue;
 
-			name = normalizePropName(name, isSvgMode);
-			v = normalizePropValue(name, v);
+					// Add a selected attribute to <option> if its value matches the parent <select> value
+					case 'option':
+						if (selectValue == v && !('selected' in props)) {
+							s = s + ' selected';
+						}
+						break;
+				}
+				break;
 
-			if (name === 'dangerouslySetInnerHTML') {
+			case 'dangerouslySetInnerHTML':
 				html = v && v.__html;
-			} else if (type === 'textarea' && name === 'value') {
-				// <textarea value="a&b"> --> <textarea>a&amp;b</textarea>
-				children = v;
-			} else if ((v || v === 0 || v === '') && typeof v !== 'function') {
-				if (v === true || v === '') {
-					v = name;
-					s = s + ' ' + name;
-					continue;
+				continue;
+
+			// serialize object styles to a CSS string
+			case 'style':
+				if (typeof v === 'object') {
+					v = styleObjToCss(v);
 				}
+				break;
 
-				if (name === 'value') {
-					if (type === 'select') {
-						selectValue = v;
-						continue;
-					} else if (
-						// If we're looking at an <option> and it's the currently selected one
-						type === 'option' &&
-						selectValue == v &&
-						// and the <option> doesn't already have a selected attribute on it
-						!('selected' in props)
-					) {
-						s = s + ' selected';
-					}
+			default:
+				if (isSvgMode && XLINK.test(name)) {
+					name = name.toLowerCase().replace(/^xlink:?/, 'xlink:');
+				} else if (UNSAFE_NAME.test(name)) {
+					continue;
+				} else if (name[0] === 'a' && name[1] === 'r' && v != null) {
+					// serialize boolean aria-xyz attribute values as strings
+					v += '';
 				}
-				s = s + ' ' + name + '="' + encodeEntities(v) + '"';
+		}
+
+		// write this attribute to the buffer
+		if (v != null && v !== false && typeof v !== 'function') {
+			if (v === true || v === '') {
+				s = s + ' ' + name;
+			} else {
+				s = s + ' ' + name + '="' + encodeEntities(v + '') + '"';
 			}
 		}
 	}
 
-	let startElement = s;
-	s = s + '>';
-
 	if (UNSAFE_NAME.test(type)) {
-		throw new Error(`${type} is not a valid HTML tag name in ${s}`);
+		throw new Error(`${type} is not a valid HTML tag name in ${s}>`);
 	}
 
-	let pieces = '';
-	let hasChildren = false;
-
 	if (html) {
-		pieces = pieces + html;
-		hasChildren = true;
+		// dangerouslySetInnerHTML defined this node's contents
 	} else if (typeof children === 'string') {
-		pieces = pieces + encodeEntities(children);
-		hasChildren = true;
-	} else if (isArray(children)) {
-		vnode[CHILDREN] = children;
-		for (let i = 0; i < children.length; i++) {
-			let child = children[i];
-			children[i] = normalizeVNode(child);
-
-			if (child != null && child !== false) {
-				let childSvgMode =
-					type === 'svg' || (type !== 'foreignObject' && isSvgMode);
-				let ret = _renderToString(
-					child,
-					context,
-					childSvgMode,
-					selectValue,
-					vnode
-				);
-
-				// Skip if we received an empty string
-				if (ret) {
-					pieces = pieces + ret;
-					hasChildren = true;
-				}
-			}
-		}
+		// single text child
+		html = encodeEntities(children);
 	} else if (children != null && children !== false && children !== true) {
-		vnode[CHILDREN] = [normalizeVNode(children)];
+		// recurse into this element VNode's children
 		let childSvgMode =
 			type === 'svg' || (type !== 'foreignObject' && isSvgMode);
-		let ret = _renderToString(
-			children,
-			context,
-			childSvgMode,
-			selectValue,
-			vnode
-		);
-
-		// Skip if we received an empty string
-		if (ret) {
-			pieces = pieces + ret;
-			hasChildren = true;
-		}
+		html = _renderToString(children, context, childSvgMode, selectValue, vnode);
 	}
 
-	if (options[DIFFED]) options[DIFFED](vnode);
+	if (afterDiff) afterDiff(vnode);
 	vnode[PARENT] = undefined;
 	if (options.unmount) options.unmount(vnode);
 
-	if (hasChildren) {
-		s = s + pieces;
-	} else if (VOID_ELEMENTS.test(type)) {
-		return startElement + ' />';
+	// Emit self-closing tag for empty void elements:
+	if (!html) {
+		switch (type) {
+			case 'area':
+			case 'base':
+			case 'br':
+			case 'col':
+			case 'embed':
+			case 'hr':
+			case 'img':
+			case 'input':
+			case 'link':
+			case 'meta':
+			case 'param':
+			case 'source':
+			case 'track':
+			case 'wbr':
+				return s + ' />';
+		}
 	}
 
-	return s + '</' + type + '>';
+	return s + '>' + html + '</' + type + '>';
 }
-
-/** The default export is an alias of `render()`. */
-
-renderToString.shallowRender = shallowRender;
-
-export default renderToString;
-
-export {
-	renderToString as render,
-	renderToString as renderToStaticMarkup,
-	renderToString,
-	shallowRender
-};
diff --git a/src/jsx.d.ts b/src/jsx.d.ts
index 98fad55..9004230 100644
--- a/src/jsx.d.ts
+++ b/src/jsx.d.ts
@@ -3,11 +3,19 @@ import { VNode } from 'preact';
 interface Options {
 	jsx?: boolean;
 	xml?: boolean;
+	pretty?: boolean | string;
+	shallow?: boolean;
 	functions?: boolean;
 	functionNames?: boolean;
 	skipFalseAttributes?: boolean;
-	pretty?: boolean | string;
 }
 
-export function render(vnode: VNode, context?: any, options?: Options): string;
+export default function renderToStringPretty(
+	vnode: VNode,
+	context?: any,
+	options?: Options
+): string;
+
+export function shallowRender(vnode: VNode, context?: any): string;
+
 export default render;
diff --git a/src/jsx.js b/src/jsx.js
index 64e6e15..2afe9a7 100644
--- a/src/jsx.js
+++ b/src/jsx.js
@@ -1,8 +1,10 @@
 import './polyfills';
-import renderToString from './index';
+import renderToString from './pretty';
 import { indent, encodeEntities } from './util';
 import prettyFormat from 'pretty-format';
 
+/** @typedef {import('preact').VNode} VNode */
+
 // we have to patch in Array support, Possible issue in npm.im/pretty-format
 let preactPlugin = {
 	test(object) {
@@ -67,10 +69,36 @@ let defaultOpts = {
 	pretty: '  '
 };
 
-function renderToJsxString(vnode, context, opts, inner) {
-	opts = Object.assign({}, defaultOpts, opts || {});
-	return renderToString(vnode, context, opts, inner);
+/**
+ * Render Preact JSX + Components to a pretty-printed HTML-like string.
+ * @param {VNode} vnode	JSX Element / VNode to render
+ * @param {Object} [context={}] Initial root context object
+ * @param {Object} [options={}] Rendering options
+ * @param {Boolean} [options.jsx=true] Generate JSX/XML output instead of HTML
+ * @param {Boolean} [options.xml=false] Use self-closing tags for elements without children
+ * @param {Boolean} [options.shallow=false] Serialize nested Components (`<Foo a="b" />`) instead of rendering
+ * @param {Boolean} [options.pretty=false] Add whitespace for readability
+ * @param {RegExp|undefined} [options.voidElements] RegeEx to define which element types are self-closing
+ * @returns {String} a pretty-printed HTML-like string
+ */
+export default function renderToStringPretty(vnode, context, options) {
+	const opts = Object.assign({}, defaultOpts, options || {});
+	if (!opts.jsx) opts.attributeHook = null;
+	return renderToString(vnode, context, opts);
 }
+export { renderToStringPretty as render };
+
+const SHALLOW = { shallow: true };
 
-export default renderToJsxString;
-export { renderToJsxString as render };
+/** Only render elements, leaving Components inline as `<ComponentName ... />`.
+ *	This method is just a convenience alias for `render(vnode, context, { shallow:true })`
+ *	@name shallow
+ *	@function
+ *	@param {VNode} vnode	JSX VNode to render.
+ *	@param {Object} [context={}]	Optionally pass an initial context object through the render path.
+ *	@param {Parameters<typeof renderToStringPretty>[2]} [options]	Optionally pass an initial context object through the render path.
+ */
+export function shallowRender(vnode, context, options) {
+	const opts = Object.assign({}, SHALLOW, options || {});
+	return renderToStringPretty(vnode, context, opts);
+}
diff --git a/src/pretty.js b/src/pretty.js
index 1c97798..fd73431 100644
--- a/src/pretty.js
+++ b/src/pretty.js
@@ -5,17 +5,53 @@ import {
 	styleObjToCss,
 	getChildren,
 	createComponent,
-	getContext,
 	UNSAFE_NAME,
 	XLINK,
 	VOID_ELEMENTS
 } from './util';
+import { COMMIT, DIFF, DIFFED, RENDER, SKIP_EFFECTS } from './constants';
 import { options, Fragment } from 'preact';
 
+/** @typedef {import('preact').VNode} VNode */
+
 // components without names, kept as a hash for later comparison to return consistent UnnamedComponentXX names.
 const UNNAMED = [];
 
-export function _renderToStringPretty(
+const EMPTY_ARR = [];
+
+/**
+ * Render Preact JSX + Components to a pretty-printed HTML-like string.
+ * @param {VNode} vnode	JSX Element / VNode to render
+ * @param {Object} [context={}] Initial root context object
+ * @param {Object} [opts={}] Rendering options
+ * @param {Boolean} [opts.shallow=false] Serialize nested Components (`<Foo a="b" />`) instead of rendering
+ * @param {Boolean} [opts.xml=false] Use self-closing tags for elements without children
+ * @param {Boolean} [opts.pretty=false] Add whitespace for readability
+ * @param {RegExp|undefined} [opts.voidElements] RegeEx to define which element types are self-closing
+ * @param {boolean} [_inner]
+ * @returns {String} a pretty-printed HTML-like string
+ */
+export default function renderToStringPretty(vnode, context, opts, _inner) {
+	// Performance optimization: `renderToString` is synchronous and we
+	// therefore don't execute any effects. To do that we pass an empty
+	// array to `options._commit` (`__c`). But we can go one step further
+	// and avoid a lot of dirty checks and allocations by setting
+	// `options._skipEffects` (`__s`) too.
+	const previousSkipEffects = options[SKIP_EFFECTS];
+	options[SKIP_EFFECTS] = true;
+
+	try {
+		return _renderToStringPretty(vnode, context || {}, opts, _inner);
+	} finally {
+		// options._commit, we don't schedule any effects in this library right now,
+		// so we can pass an empty queue to this hook.
+		if (options[COMMIT]) options[COMMIT](vnode, EMPTY_ARR);
+		options[SKIP_EFFECTS] = previousSkipEffects;
+		EMPTY_ARR.length = 0;
+	}
+}
+
+function _renderToStringPretty(
 	vnode,
 	context,
 	opts,
@@ -30,7 +66,7 @@ export function _renderToStringPretty(
 	// #text nodes
 	if (typeof vnode !== 'object') {
 		if (typeof vnode === 'function') return '';
-		return encodeEntities(vnode);
+		return encodeEntities(vnode + '');
 	}
 
 	let pretty = opts.pretty,
@@ -57,6 +93,8 @@ export function _renderToStringPretty(
 	// VNodes have {constructor:undefined} to prevent JSON injection:
 	if (vnode.constructor !== undefined) return '';
 
+	if (options[DIFF]) options[DIFF](vnode);
+
 	let nodeName = vnode.type,
 		props = vnode.props,
 		isComponent = false;
@@ -82,17 +120,19 @@ export function _renderToStringPretty(
 
 			let c = (vnode.__c = createComponent(vnode, context));
 
-			// options._diff
-			if (options.__b) options.__b(vnode);
+			let renderHook = options[RENDER];
 
-			// options._render
-			let renderHook = options.__r;
+			let cctx = context;
+			let cxType = nodeName.contextType;
+			if (cxType != null) {
+				let provider = context[cxType.__c];
+				cctx = provider ? provider.props.value : cxType.__;
+			}
 
 			if (
 				!nodeName.prototype ||
 				typeof nodeName.prototype.render !== 'function'
 			) {
-				let cctx = getContext(nodeName, context);
 
 				// If a hook invokes setState() to invalidate the component during rendering,
 				// re-render it up to 25 times to allow "settling" of memoized states.
@@ -109,7 +149,6 @@ export function _renderToStringPretty(
 					rendered = nodeName.call(vnode.__c, props, cctx);
 				}
 			} else {
-				let cctx = getContext(nodeName, context);
 
 				// c = new nodeName(props, context);
 				c = vnode.__c = new nodeName(props, cctx);
@@ -152,8 +191,7 @@ export function _renderToStringPretty(
 				context = Object.assign({}, context, c.getChildContext());
 			}
 
-			if (options.diffed) options.diffed(vnode);
-			return _renderToStringPretty(
+			const res = _renderToStringPretty(
 				rendered,
 				context,
 				opts,
@@ -161,6 +199,10 @@ export function _renderToStringPretty(
 				isSvgMode,
 				selectValue
 			);
+
+			if (options[DIFFED]) options[DIFFED](vnode);
+
+			return res;
 		}
 	}
 
@@ -259,7 +301,7 @@ export function _renderToStringPretty(
 						s = s + ` selected`;
 					}
 				}
-				s = s + ` ${name}="${encodeEntities(v)}"`;
+				s = s + ` ${name}="${encodeEntities(v + '')}"`;
 			}
 		}
 	}
@@ -343,6 +385,8 @@ export function _renderToStringPretty(
 		}
 	}
 
+	if (options[DIFFED]) options[DIFFED](vnode);
+
 	if (pieces.length || html) {
 		s = s + pieces.join('');
 	} else if (opts && opts.xml) {
diff --git a/src/util.js b/src/util.js
index 5da7f18..78a0a6a 100644
--- a/src/util.js
+++ b/src/util.js
@@ -1,17 +1,15 @@
 // DOM properties that should NOT have "px" added when numeric
 export const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i;
-export const VOID_ELEMENTS = /^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/;
+export const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/;
 export const UNSAFE_NAME = /[\s\n\\/='"\0<>]/;
 export const XLINK = /^xlink:?./;
 
 const ENCODED_ENTITIES = /["&<]/;
 
+/** @param {string} str */
 export function encodeEntities(str) {
-	// Ensure we're always parsing and returning a string:
-	str += '';
-
 	// Skip all work for strings with no entities needing encoding:
-	if (ENCODED_ENTITIES.test(str) === false) return str;
+	if (str.length === 0 || ENCODED_ENTITIES.test(str) === false) return str;
 
 	let last = 0,
 		i = 0,
@@ -60,19 +58,20 @@ export function styleObjToCss(s) {
 	for (let prop in s) {
 		let val = s[prop];
 		if (val != null && val !== '') {
-			if (str) str += ' ';
-			// str += jsToCss(prop);
-			str +=
+			const name =
 				prop[0] == '-'
 					? prop
 					: JS_TO_CSS[prop] ||
 					  (JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$1').toLowerCase());
 
-			if (typeof val === 'number' && IS_NON_DIMENSIONAL.test(prop) === false) {
-				str = str + ': ' + val + 'px;';
-			} else {
-				str = str + ': ' + val + ';';
-			}
+			str =
+				str +
+				name +
+				':' +
+				val +
+				(typeof val === 'number' && IS_NON_DIMENSIONAL.test(prop) === false
+					? 'px;'
+					: ';');
 		}
 	}
 	return str || undefined;
@@ -111,15 +110,3 @@ export function createComponent(vnode, context) {
 		__h: []
 	};
 }
-
-// Necessary for createContext api. Setting this property will pass
-// the context value as `this.context` just for this component.
-export function getContext(nodeName, context) {
-	let cxType = nodeName.contextType;
-	let provider = cxType && context[cxType.__c];
-	return cxType != null
-		? provider
-			? provider.props.value
-			: cxType.__
-		: context;
-}


Test patch:
diff --git a/test/compat/index.test.js b/test/compat/index.test.js
index e2ed151..83b63a4 100644
--- a/test/compat/index.test.js
+++ b/test/compat/index.test.js
@@ -1,4 +1,4 @@
-import { render } from '../../src';
+import render from '../../src';
 import { createElement } from 'preact/compat';
 import { expect } from 'chai';
 
diff --git a/test/debug/index.test.js b/test/debug/index.test.js
index 228ca8b..b0bd205 100644
--- a/test/debug/index.test.js
+++ b/test/debug/index.test.js
@@ -1,5 +1,5 @@
 import 'preact/debug';
-import { render } from '../../src';
+import render from '../../src';
 import { h } from 'preact';
 import { expect } from 'chai';
 
diff --git a/test/index.test.js b/test/index.test.js
index 32fcaf1..bd05764 100644
--- a/test/index.test.js
+++ b/test/index.test.js
@@ -1,9 +1,5 @@
-import renderToString, {
-	render,
-	shallowRender,
-	renderToStaticMarkup,
-	renderToString as _renderToString
-} from '../src';
+import renderToString from '../src';
+import { default as renderToStringPretty, shallowRender } from '../src/jsx';
 import { expect } from 'chai';
 
 describe('render-to-string', () => {
@@ -11,24 +7,15 @@ describe('render-to-string', () => {
 		it('exposes renderToString as default', () => {
 			expect(renderToString).to.be.a('function');
 		});
+	});
+});
 
-		it('exposes render as a named export', () => {
-			expect(render).to.be.a('function');
-			expect(render).to.equal(renderToString);
-		});
-
-		it('exposes renderToString as a named export', () => {
-			expect(_renderToString).to.be.a('function');
-			expect(_renderToString).to.equal(renderToString);
-		});
-
-		it('exposes renderToStaticMarkup as a named export', () => {
-			expect(renderToStaticMarkup).to.be.a('function');
-			expect(renderToStaticMarkup).to.equal(renderToStaticMarkup);
-		});
+describe('render-to-string/jsx', () => {
+	it('exposes renderToStringPretty as default export', () => {
+		expect(renderToStringPretty).to.be.a('function');
+	});
 
-		it('exposes shallowRender as a named export', () => {
-			expect(shallowRender).to.be.a('function');
-		});
+	it('exposes shallowRender as a named export', () => {
+		expect(shallowRender).to.be.a('function');
 	});
 });
diff --git a/test/pretty.test.js b/test/pretty.test.js
index 4ee901e..b4d288f 100644
--- a/test/pretty.test.js
+++ b/test/pretty.test.js
@@ -1,4 +1,4 @@
-import { render as basicRender } from '../src';
+import basicRender from '../src';
 import { render } from '../src/jsx';
 import { h, Fragment } from 'preact';
 import { expect } from 'chai';
@@ -120,35 +120,19 @@ describe('pretty', () => {
 		// prettier-ignore
 		expect(prettyRender(
 			<div>hello{' '} <b /></div>
-		)).to.equal(dedent`
-			<div>
-				hello  
-				<b></b>
-			</div>
-		`);
+		)).to.equal(`<div>\n\thello  \n\t<b></b>\n</div>`);
 
 		// prettier-ignore
 		expect(prettyRender(
 			<div>hello{' '} <b />{'a'}{'b'}</div>
-		)).to.equal(dedent`
-			<div>
-				hello  
-				<b></b>
-				ab
-			</div>
-		`);
+		)).to.equal(`<div>\n\thello  \n\t<b></b>\n\tab\n</div>`);
 	});
 
 	it('should join adjacent text nodeswith Fragments', () => {
 		// prettier-ignore
 		expect(prettyRender(
 			<div><Fragment>foo</Fragment>bar{' '} <b /></div>
-		)).to.equal(dedent`
-			<div>
-				foobar  
-				<b></b>
-			</div>
-		`);
+		)).to.equal(`<div>\n\tfoobar  \n\t<b></b>\n</div>`);
 	});
 
 	it('should collapse whitespace', () => {
@@ -158,12 +142,7 @@ describe('pretty', () => {
 					a<a>b</a>
 				</p>
 			)
-		).to.equal(dedent`
-			<p>
-				a
-				<a>b</a>
-			</p>
-		`);
+		).to.equal(`<p>\n\ta\n\t<a>b</a>\n</p>`);
 
 		expect(
 			prettyRender(
@@ -171,12 +150,7 @@ describe('pretty', () => {
 					a <a>b</a>
 				</p>
 			)
-		).to.equal(dedent`
-			<p>
-				a 
-				<a>b</a>
-			</p>
-		`);
+		).to.equal(`<p>\n\ta \n\t<a>b</a>\n</p>`);
 
 		expect(
 			prettyRender(
@@ -198,12 +172,7 @@ describe('pretty', () => {
 					a <a>b</a>
 				</p>
 			)
-		).to.equal(dedent`
-			<p>
-				a\ 
-				<a>b</a>
-			</p>
-		`);
+		).to.equal(`<p>\n\ta \n\t<a>b</a>\n</p>`);
 
 		expect(prettyRender(<a> b </a>)).to.equal(dedent`
 			<a> b </a>
@@ -215,12 +184,7 @@ describe('pretty', () => {
 					<b /> a{' '}
 				</p>
 			)
-		).to.equal(dedent`
-			<p>
-				<b></b>
-				\ a\ 
-			</p>
-		`);
+		).to.equal(`<p>\n\t<b></b>\n\t a \n</p>`);
 	});
 
 	it('should prevent JSON injection', () => {
diff --git a/test/render.test.js b/test/render.test.js
index 7e3dc78..17391c3 100644
--- a/test/render.test.js
+++ b/test/render.test.js
@@ -1,5 +1,14 @@
-import { render, shallowRender } from '../src';
-import { h, Component, createContext, Fragment, options } from 'preact';
+import render from '../src';
+import renderToStringPretty from '../src/pretty';
+import renderToStringJSX from '../src/jsx';
+import {
+	h,
+	Component,
+	createContext,
+	Fragment,
+	options,
+	createRef
+} from 'preact';
 import {
 	useState,
 	useContext,
@@ -11,6 +20,15 @@ import {
 import { expect } from 'chai';
 import { spy, stub, match } from 'sinon';
 
+function shallowRender(vnode) {
+	return renderToStringJSX(vnode, context, {
+		jsx: false,
+		xml: false,
+		pretty: '  ',
+		shallow: true
+	});
+}
+
 describe('render', () => {
 	describe('Basic JSX', () => {
 		it('should render JSX', () => {
@@ -69,7 +87,7 @@ describe('render', () => {
 		});
 
 		it('should omit ref attribute', () => {
-			let rendered = render(<div ref="test" />),
+			let rendered = render(<div ref={createRef()} />),
 				expected = `<div></div>`;
 
 			expect(rendered).to.equal(expected);
@@ -228,7 +246,7 @@ describe('render', () => {
 		});
 
 		it('should self-close custom void elements', () => {
-			let rendered = render(
+			let rendered = renderToStringPretty(
 					<div>
 						<hello-world />
 					</div>,
@@ -258,14 +276,14 @@ describe('render', () => {
 
 		it('should serialize object styles', () => {
 			let rendered = render(<div style={{ color: 'red', border: 'none' }} />),
-				expected = `<div style="color: red; border: none;"></div>`;
+				expected = `<div style="color:red;border:none;"></div>`;
 
 			expect(rendered).to.equal(expected);
 		});
 
 		it('should preserve CSS Custom Properties', () => {
 			let rendered = render(<div style={{ '--foo': 1, '--foo-bar': '2' }} />),
-				expected = `<div style="--foo: 1; --foo-bar: 2;"></div>`;
+				expected = `<div style="--foo:1;--foo-bar:2;"></div>`;
 
 			expect(rendered).to.equal(expected);
 		});
@@ -735,7 +753,7 @@ describe('render', () => {
 				</Outer>
 			);
 			expect(rendered).to.equal(
-				'<Inner a="b" b="b" p="1">child <span>foo</span></Inner>'
+				`<Inner a="b" b="b" p="1">\n  child \n  <span>foo</span>\n</Inner>`
 			);
 		});
 
@@ -758,10 +776,10 @@ describe('render', () => {
 			let rendered = render(<Outer />);
 			expect(rendered).to.equal('<div>hi</div>');
 
-			rendered = render(<Outer />, null, { shallow: true });
+			rendered = renderToStringPretty(<Outer />, null, { shallow: true });
 			expect(rendered, '{shallow:true}').to.equal('<Middle></Middle>');
 
-			rendered = render(<Outer />, null, {
+			rendered = renderToStringPretty(<Outer />, null, {
 				shallow: true,
 				shallowHighOrder: false
 			});
@@ -833,15 +851,19 @@ describe('render', () => {
 		});
 
 		it('should sort attributes lexicographically if enabled', () => {
-			let rendered = render(<div b1="b1" c="c" a="a" b="b" />, null, {
-				sortAttributes: true
-			});
+			let rendered = renderToStringPretty(
+				<div b1="b1" c="c" a="a" b="b" />,
+				null,
+				{
+					sortAttributes: true
+				}
+			);
 			expect(rendered).to.equal('<div a="a" b="b" b1="b1" c="c"></div>');
 		});
 	});
 
 	describe('xml:true', () => {
-		let renderXml = (jsx) => render(jsx, null, { xml: true });
+		let renderXml = (jsx) => renderToStringPretty(jsx, null, { xml: true });
 
 		it('should render end-tags', () => {
 			expect(renderXml(<div />)).to.equal(`<div />`);
@@ -945,7 +967,7 @@ describe('render', () => {
 		});
 
 		it('should indent Fragment children when pretty printing', () => {
-			let html = render(
+			let html = renderToStringPretty(
 				<div>
 					<Fragment>
 						<div>foo</div>
diff --git a/test/shallowRender.test.js b/test/shallowRender.test.js
index 5da311b..e35a07d 100644
--- a/test/shallowRender.test.js
+++ b/test/shallowRender.test.js
@@ -1,4 +1,4 @@
-import { shallowRender } from '../src';
+import { shallowRender } from '../src/jsx';
 import { h, Fragment } from 'preact';
 import { expect } from 'chai';
 import { spy } from 'sinon';
@@ -18,7 +18,9 @@ describe('shallowRender()', () => {
 				<Test foo={1}>
 					<span>asdf</span>
 				</Test>
-			</section>
+			</section>,
+			null,
+			{ pretty: false, jsx: false }
 		);
 
 		expect(rendered).to.equal(
@@ -39,7 +41,9 @@ describe('shallowRender()', () => {
 		let rendered = shallowRender(
 			<Test foo={1}>
 				<span>asdf</span>
-			</Test>
+			</Test>,
+			null,
+			{ pretty: false, jsx: false }
 		);
 
 		expect(rendered).to.equal(