From d610633ec91a7a51df582108eeb30a1a2d45db82 Mon Sep 17 00:00:00 2001
From: familyfriendlymikey <ozmichaelt@icloud.com>
Date: Wed, 14 Dec 2022 23:07:37 -0500
Subject: [PATCH] switch to vite and chrome

---
 .gitignore                                    |    1 +
 .rgignore                                     |    1 +
 app/api.imba                                  |  318 --
 app/assets/community_links.imba               |   14 -
 app/assets/eye-off.svg                        |    1 -
 app/client.imba                               |  115 -
 app/components/app-bang.imba                  |  129 -
 app/components/app-community-links.imba       |  131 -
 app/components/app-edit.imba                  |   84 -
 app/components/app-home.imba                  |   73 -
 app/components/app-link.imba                  |   67 -
 app/components/app-links.imba                 |  104 -
 app/components/app-prompt.imba                |   16 -
 app/components/app-settings.imba              |  153 -
 app/components/app-tips.imba                  |   86 -
 app/config.imba                               |   59 -
 app/db.imba                                   |   51 -
 app/sw.imba                                   |   41 -
 app/utils.imba                                |   13 -
 chrome/manifest.json                          |   13 +
 app/index.html => index.html                  |    5 +-
 package-lock.json                             | 4469 +++++++++++++++--
 package.json                                  |   31 +-
 readme.md                                     |  166 +-
 scripts/api_move.sh                           |    1 -
 scripts/config_move.sh                        |    1 -
 src/api.imba                                  |  137 +
 {app => src}/assets/chevron-down.svg          |    0
 {app => src}/assets/chevron-up.svg            |    0
 {app => src}/assets/edit-2.svg                |    0
 .../eye.svg => src/assets/help-circle.svg     |    2 +-
 {app => src}/assets/search.svg                |    0
 {app => src}/assets/settings.svg              |    0
 {app => src}/assets/star.svg                  |    0
 {app => src}/assets/trash.svg                 |    0
 {app => src}/assets/x-square.svg              |    0
 {app => src}/assets/x.svg                     |    0
 src/components/app-bang.imba                  |   63 +
 src/components/app-home.imba                  |   77 +
 src/components/app-link.imba                  |   55 +
 src/components/app-links.imba                 |   55 +
 src/components/app-settings.imba              |   53 +
 src/components/app-tips.imba                  |   85 +
 src/config.imba                               |   71 +
 src/index.js                                  |    1 +
 src/main.imba                                 |   76 +
 {app => src}/state.imba                       |    3 +-
 {app => src}/styles.imba                      |   30 +-
 src/utils.imba                                |    0
 vite.config.js                                |    7 +
 50 files changed, 4764 insertions(+), 2094 deletions(-)
 create mode 120000 .rgignore
 delete mode 100644 app/api.imba
 delete mode 100644 app/assets/community_links.imba
 delete mode 100644 app/assets/eye-off.svg
 delete mode 100644 app/client.imba
 delete mode 100644 app/components/app-bang.imba
 delete mode 100644 app/components/app-community-links.imba
 delete mode 100644 app/components/app-edit.imba
 delete mode 100644 app/components/app-home.imba
 delete mode 100644 app/components/app-link.imba
 delete mode 100644 app/components/app-links.imba
 delete mode 100644 app/components/app-prompt.imba
 delete mode 100644 app/components/app-settings.imba
 delete mode 100644 app/components/app-tips.imba
 delete mode 100644 app/config.imba
 delete mode 100644 app/db.imba
 delete mode 100644 app/sw.imba
 delete mode 100644 app/utils.imba
 create mode 100644 chrome/manifest.json
 rename app/index.html => index.html (69%)
 delete mode 100755 scripts/api_move.sh
 delete mode 100755 scripts/config_move.sh
 create mode 100644 src/api.imba
 rename {app => src}/assets/chevron-down.svg (100%)
 rename {app => src}/assets/chevron-up.svg (100%)
 rename {app => src}/assets/edit-2.svg (100%)
 rename app/assets/eye.svg => src/assets/help-circle.svg (52%)
 rename {app => src}/assets/search.svg (100%)
 rename {app => src}/assets/settings.svg (100%)
 rename {app => src}/assets/star.svg (100%)
 rename {app => src}/assets/trash.svg (100%)
 rename {app => src}/assets/x-square.svg (100%)
 rename {app => src}/assets/x.svg (100%)
 create mode 100644 src/components/app-bang.imba
 create mode 100644 src/components/app-home.imba
 create mode 100644 src/components/app-link.imba
 create mode 100644 src/components/app-links.imba
 create mode 100644 src/components/app-settings.imba
 create mode 100644 src/components/app-tips.imba
 create mode 100644 src/config.imba
 create mode 100644 src/index.js
 create mode 100644 src/main.imba
 rename {app => src}/state.imba (81%)
 rename {app => src}/styles.imba (82%)
 create mode 100644 src/utils.imba
 create mode 100644 vite.config.js

diff --git a/.gitignore b/.gitignore
index 19385f9..61f02ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ node_modules
 dist
 *.swp
 .fdignore
+*.zip
diff --git a/.rgignore b/.rgignore
new file mode 120000
index 0000000..f781cab
--- /dev/null
+++ b/.rgignore
@@ -0,0 +1 @@
+.fdignore
\ No newline at end of file
diff --git a/app/api.imba b/app/api.imba
deleted file mode 100644
index 4200bc2..0000000
--- a/app/api.imba
+++ /dev/null
@@ -1,318 +0,0 @@
-let p = console.log
-import { err } from './utils'
-
-import db from './db'
-import state from './state'
-
-import config from './config'
-import { find, omit, orderBy } from 'lodash'
-import { nanoid } from 'nanoid'
-import fzi from 'fzi'
-import { evaluate as eval_math } from 'mathjs'
-import { cloneDeep } from 'lodash'
-
-export default new class api
-
-	def add_link text
-		let link = await create_link_from_text text
-		link.id = nanoid!
-		await db.links.add link
-		await reload_db!
-		imba.commit!
-		p omit(link, "icon")
-		return link
-
-	def update_link old_link, new_link_text
-		let new_link = await create_link_from_text new_link_text
-		new_link.frequency = old_link.frequency
-		let result = await db.links.update old_link.id, new_link
-		throw "Link id not found." if result is 0
-		await reload_db!
-		imba.commit!
-		p omit(old_link, "icon")
-		p omit(new_link, "icon")
-		return new_link
-
-	def put_link link
-		try
-			await db.links.update link.id, link
-			if link.is_bang and config.data.default_bang.id is link.id
-				config.set_default_bang link
-			await reload_db!
-		catch e
-			err "putting link", e
-
-	def delete_link link
-		def go
-			try
-				await db.links.delete(link.id)
-			catch e
-				return err "deleting link", e
-			try
-				await reload_db!
-			catch e
-				return err "reloading db after successful delete", e
-		state.loading = yes
-		await go!
-		state.link_selection_index = Math.min state.link_selection_index, state.sorted_links.length - 1
-		state.loading = no
-
-	def pin_link link
-		link.is_pinned = !link.is_pinned
-		try
-			let result = await db.links.update link.id, link
-			throw "Link id not found." if result is 0
-		catch e
-			return err "pinning link", e
-		await reload_db!
-		imba.commit!
-
-	def reload_db
-		state.links = await db.links.toArray()
-		if state.active_bang
-			let id = state.active_bang.id
-			state.active_bang = find state.links, { id }
-		let id = config.data.default_bang.id
-		let link = find state.links, { id }
-		if link
-			config.data.default_bang = link
-			config.save!
-		sort_links!
-
-	def increment_link_frequency link
-		link.frequency += 1
-		try
-			await put_link link
-		catch e
-			err "putting link", e
-
-	def sort_links
-		if state.query.trim!.length <= 0
-			state.sorted_links = orderBy(state.links, ['is_pinned', 'frequency'], ['desc', 'desc'])
-		elif config.data.enable_effective_names
-			state.sorted_links = fzi.sort state.query, state.links, do |x| x.name
-		else
-			state.sorted_links = fzi.sort state.query, state.links, do |x| x.display_name
-
-	def name_exists new_name
-		state.links.some! do |{name}| new_name is name
-
-	def add_initial_links
-		let initial_links = [
-			"tutorial github.com/familyfriendlymikey/fuzzyhome"
-			"!brave search `b search.brave.com/search?q="
-			"!youtube youtube.com/results?search_query="
-			"photopea photopea.com"
-			"twitch twitch.tv"
-			"messenger `me messenger.com"
-			"instagram `in instagram.com"
-			"localhost `3000 http://localhost:3000"
-		]
-		for link_text in initial_links
-			try
-				add_link link_text
-			catch e
-				err "adding link", e
-
-	def create_link_from_text text, get_icon=yes
-		text = text.trim!
-		throw "Text is empty." if text is ''
-		let split_text = text.split(/\s+/)
-		throw "No url provided." if split_text.length < 2
-		let url = split_text.pop!
-		let host
-		{ href:url, host } = parse_url url
-		let name
-		if split_text[-1].startsWith "`"
-			name = split_text.pop!.slice(1)
-		let display_name = split_text.join(" ")
-		let is_bang = no
-		let is_pinned = no
-		if display_name.startsWith "!"
-			is_bang = yes
-			display_name = display_name.slice(1)
-		name ||= display_name
-		let link = { name, display_name, is_bang, is_pinned, url, frequency:0, history:[] }
-		if get_icon
-			link.icon = await fetch_image_as_base_64 host
-		return link
-
-	def fetch_image_as_base_64 host
-		let fallback = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAH0lEQVR42mO8seXffwYqAsZRA0cNHDVw1MBRA0eqgQCDRkbJSQHxEQAAAABJRU5ErkJggg=='
-		return new Promise! do |resolve|
-			let res
-			try
-				res = await global.fetch("https://icon.horse/icon/{host}")
-			catch
-				p "Failed to get icon from icon horse."
-				return resolve fallback
-			# todo: can i use .text() on this or something
-			let blob = await res.blob!
-			let reader = new FileReader!
-			reader.onload = do
-				resolve this.result
-			reader.onerror = do
-				p "Failed to get data from reader."
-				resolve fallback
-				return
-			reader.readAsDataURL(blob)
-
-	def toggle_effective_names
-		config.data.enable_effective_names = !config.data.enable_effective_names
-		config.save!
-		sort_links!
-
-	def construct_link_text link
-		link.display_name = link.display_name.trim!
-		link.name = link.name.trim!
-		link.url = link.url.trim!
-		let link_text = ""
-		link_text += "!" if link.is_bang
-		link_text += link.display_name
-		link_text += " `{link.name}" if link.name isnt link.display_name
-		link_text += " {link.url}"
-		link_text
-
-	def parse_url url
-		throw "invalid url" if url === null
-		let get_url = do |s|
-			let url = new URL s
-			throw _ unless (url.host and url.href)
-			url
-		try
-			return get_url url
-		try
-			return get_url "https://{url}"
-		throw "invalid url"
-
-	def get_pretty_date
-		Date!.toString!.split(" ").slice(0, 4).join(" ")
-
-	get selected_link
-		state.sorted_links[state.link_selection_index]
-
-	def set_link_selection_index index
-		state.link_selection_index = index
-
-	def increment_link_selection_index
-		set_link_selection_index Math.min(state.sorted_links.length - 1, state.link_selection_index + 1)
-
-	def decrement_link_selection_index
-		set_link_selection_index Math.max(0, state.link_selection_index - 1)
-
-	def navigate link
-		await increment_link_frequency link
-		window.location.href = link.url
-
-	get math_result
-		try
-			let result = Number(eval_math state.query)
-			throw _ if isNaN result
-			throw _ if result.toString! is state.query.trim!
-			result
-		catch
-			no
-
-	def handle_cut e
-		return unless e.target.selectionStart == e.target.selectionEnd
-		let s = math_result
-		s ||= state.query
-		await window.navigator.clipboard.writeText(s)
-		state.query = ''
-		sort_links!
-
-	def handle_add_link
-		state.loading = yes
-		try
-			await add_link state.query
-			state.query = ''
-			sort_links!
-		catch e
-			err "adding link", e
-		state.loading = no
-
-	def handle_click_link
-		let link = selected_link
-		if link.is_bang
-			state.query = ''
-			state.active_bang = link
-		else
-			navigate link
-
-	get bang
-		state.active_bang or config.data.default_bang
-
-	get encoded_bang_query
-		"{bang.url}{window.encodeURIComponent(state.query)}"
-
-	get encoded_bang_query_nourl
-		"{window.encodeURIComponent(state.query)}"
-
-	def update_history bang
-		let text
-		if state.bang_selection_index > -1
-			text = sorted_bang_history.splice(state.bang_selection_index, 1)[0]
-		text ||= state.query.trim!
-		return unless text
-		let i = bang.history.indexOf(text)
-		if i > -1
-			bang.history.splice(i, 1)
-		bang.history.unshift text
-		try
-			await put_link bang
-		catch e
-			err "updating bang history", e
-
-	def delete_bang_history_item
-		let text = sorted_bang_history[state.bang_selection_index]
-		return unless text
-		let i = bang.history.indexOf(text)
-		return unless i > -1
-		bang.history.splice(i, 1)
-		try
-			await put_link bang
-			state.bang_selection_index = Math.min state.bang_selection_index, sorted_bang_history.length - 1
-		catch e
-			err "updating bang history", e
-
-	def handle_bang
-		return if state.loading
-		if state.bang_selection_index > -1
-			state.query = sorted_bang_history[state.bang_selection_index]
-			state.bang_selection_index = -1
-			return
-		await increment_link_frequency bang
-		await update_history bang
-		window.location.href = encoded_bang_query
-
-	def unset_active_bang
-		state.active_bang = no
-		sort_links!
-
-	def increment_bang_selection_index
-		state.bang_selection_index = Math.min(sorted_bang_history.length - 1, state.bang_selection_index + 1)
-
-	def decrement_bang_selection_index
-		state.bang_selection_index = Math.max(-1, state.bang_selection_index - 1)
-
-	get sorted_bang_history
-		fzi.sort state.query, bang.history
-
-	def delete_bang_history
-		bang.history = []
-		try
-			await put_link bang
-			state.bang_selection_index = -1
-		catch e
-			err "deleting bang history", e
-		config.data.default_bang.history = []
-		config.save!
-
-	def delete_all_bang_history
-		return unless window.confirm "Are you sure you want to delete all bang history?"
-		try
-			await db.links.toCollection!.modify! do |link| link.history = []
-			await reload_db!
-		catch e
-			err "deleting some link histories", e
-		imba.commit!
diff --git a/app/assets/community_links.imba b/app/assets/community_links.imba
deleted file mode 100644
index af41c6f..0000000
--- a/app/assets/community_links.imba
+++ /dev/null
@@ -1,14 +0,0 @@
-export default """
-!google search google.com/search?q=
-!youtube search youtube.com/results?search_query=
-!brave search search.brave.com/search?q=
-!amazon search amazon.com/s?k=
-!google site:reddit google.com/search?q=site%3Areddit.com%20
-!google site:stackoverflow google.com/search?q=site%3Astackoverflow.com%20
-twitch twitch.tv
-instagram instagram.com
-messenger messenger.com
-photopea photopea.com
-youtube youtube.com
-localhost:3000 http://localhost:3000
-""".split '\n'
diff --git a/app/assets/eye-off.svg b/app/assets/eye-off.svg
deleted file mode 100644
index 77c54cb..0000000
--- a/app/assets/eye-off.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye-off"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
\ No newline at end of file
diff --git a/app/client.imba b/app/client.imba
deleted file mode 100644
index 9b3043f..0000000
--- a/app/client.imba
+++ /dev/null
@@ -1,115 +0,0 @@
-let p = console.log
-import pkg from '../package.json'
-let version = pkg.version
-p "fuzzyhome version {version}"
-
-# import sw from './sw.imba?serviceworker'
-# navigator..serviceWorker..register(sw).then! do |reg| reg.update!
-
-import { nanoid } from 'nanoid'
-import { err } from './utils'
-
-import db from './db'
-import state from './state'
-let refs = {}
-import api from './api'
-import config from './config'
-
-import './components/app-home'
-import './components/app-community-links'
-import './components/app-settings'
-import './components/app-prompt'
-import './components/app-edit'
-import './components/app-links'
-import './components/app-link'
-import './components/app-bang'
-import './components/app-tips'
-import './styles'
-
-extend tag element
-	get state
-		state
-	get api
-		api
-	get config
-		config
-	get refs
-		refs
-	get err
-		err
-	get version
-		version
-	get p
-		console.log
-
-tag app
-
-	fatal_error = no
-
-	get render? do mounted?
-
-	def mount
-
-		refs.settings = $as
-		refs.edit = $ae
-		refs.community-links = $acl
-		refs.links = $ah
-
-		unless global.localStorage.fuzzyhome_visited
-			await api.add_initial_links!
-			try
-				let default_bang = await api.add_link '!google search https://www.google.com/search?q='
-				config.data.default_bang = default_bang
-			global.localStorage.fuzzyhome_visited = yes
-
-		try
-			await api.reload_db!
-			p "links:", state.links
-		catch e
-			err "state.loading database", e
-			fatal_error = yes
-			return
-
-	def render
-
-		<self
-			.light=(config.theme is "light")
-			.dark=(config.theme is "dark")
-			.disabled=state.loading
-		>
-			css d:flex fld:column jc:start ai:center
-				m:0 w:100% h:100% bg:$bodybg
-				ff:sans-serif fw:1
-				user-select:none
-
-			<.main>
-				css d:flex fld:column jc:start ai:center
-					bg:$appbg
-					w:80vw max-width:700px max-height:80vh
-					bxs:0px 0px 10px rgba(0,0,0,0.35)
-					box-sizing:border-box p:30px rd:10px mt:10vh
-
-				if fatal_error
-					<.fatal>
-						css c:$text-c
-						"""
-							There was an error state.loading the database.
-							This could be due to a user setting
-							disallowing local storage, or a random error.
-							Consider refreshing.
-							Check developer console for more information.
-						"""
-
-				elif $acl.active
-					<app-community-links$acl>
-
-				elif $as.active
-					<app-settings$as>
-
-				elif $ae.active
-					<app-edit$ae>
-
-				else
-					<app-home$ah>
-
-imba.mount <app>
diff --git a/app/components/app-bang.imba b/app/components/app-bang.imba
deleted file mode 100644
index f86ff9b..0000000
--- a/app/components/app-bang.imba
+++ /dev/null
@@ -1,129 +0,0 @@
-tag app-bang
-
-	def unmount
-		state.bang_selection_index = -1
-
-	get tips
-		let result = []
-		let temp
-
-		temp = {
-				click_handler: api.handle_bang.bind(api)
-				hotkey_handler: api.handle_bang.bind(api)
-				hotkey: 'return'
-				hotkey_display_name: "Return"
-		}
-		if state.bang_selection_index > -1
-			temp.content = "Use History Item"
-		else
-			temp.content = "Search"
-		result.push temp
-
-		temp = {
-			click_handler: api.handle_add_link.bind(api)
-			hotkey_handler: api.handle_add_link.bind(api)
-			hotkey: 'shift+return'
-			hotkey_display_name: 'Shift + Return'
-			content: "Create Link \"{state.query.trim!}\""
-		}
-		result.push temp
-
-		if state.bang_selection_index > -1
-			temp = {
-					click_handler: api.delete_bang_history_item.bind(api)
-					hotkey_handler: api.delete_bang_history_item.bind(api)
-					hotkey: 'shift+backspace'
-					hotkey_display_name: "Shift + Backspace"
-					content: "Delete History Item"
-			}
-			result.push temp
-
-		if state.active_bang
-			temp = {
-					click_handler: api.unset_active_bang.bind(api)
-					hotkey_handler: api.unset_active_bang.bind(api)
-					hotkey: 'esc'
-					hotkey_display_name: "Esc"
-					content: "Back"
-			}
-			result.push temp
-
-		def handle_delete_bang_history
-			api.delete_bang_history!
-			$tips.show_more = no
-		temp = {
-				click_handler: handle_delete_bang_history
-				hotkey_display_name: "Click"
-				content: "Delete Bang History"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: api.handle_cut.bind(api)
-		}
-		if api.math_result
-			temp.hotkey_display_name = "Cut (If No Selection)"
-			temp.content = "Cut All Text"
-		else
-			temp.hotkey_display_name = "Cut (Math, If No Selection)"
-			temp.content = "Cut Math Result"
-		result.push temp
-
-		temp = {
-				hotkey_display_name: "Paste (If Input Empty)"
-				content: "Instant Search"
-		}
-		result.push temp
-
-		result
-
-	def render
-
-		<self
-			@hotkey("tab").force=api.increment_bang_selection_index
-			@hotkey("up").force=api.decrement_bang_selection_index
-			@hotkey("down").force=api.increment_bang_selection_index
-			@hotkey("shift+tab").force=api.decrement_bang_selection_index
-		>
-			css w:100% d:flex fld:column gap:15px ofy:hidden
-
-			<app-tips$tips tips=tips>
-
-			unless $tips.show_more
-
-				<.bang
-					.selected=(state.bang_selection_index is -1)
-					[c:$bang-c]=(state.bang_selection_index is -1)
-					@pointerover=(state.bang_selection_index = -1)
-					@click=api.handle_bang
-				>
-					css d:flex fld:row jc:space-between ai:center
-						px:16px py:11px rd:5px cursor:pointer c:$text-c
-
-					<.link-left>
-						css d:flex fl:1 ofy:hidden
-
-						<img.link-icon src=api.bang.icon>
-							css w:20px h:20px mr:10px rd:3px
-
-						<.display-name> "...{api.encoded_bang_query_nourl}"
-							css fs:20px of:hidden text-overflow:ellipsis
-
-					<.link-right>
-						css d:flex fld:row jc:space-between ai:center
-
-						<.frequency> api.bang.frequency
-							css fs:15px ml:7px
-
-				<.history>
-					css d:flex fld:column jc:start ai:center ofy:auto
-
-					for item, index in api.sorted_bang_history
-						<.item
-							@pointerover=(state.bang_selection_index = index)
-							@click=api.handle_bang
-							[c:$bang-c]=(state.bang_selection_index is index)
-							.selected=(state.bang_selection_index is index)
-						> item
-							css w:100% fs:17px c:$text-c rd:5px p:10px 10px
-								box-sizing:border-box cursor:pointer
diff --git a/app/components/app-community-links.imba b/app/components/app-community-links.imba
deleted file mode 100644
index 40dc541..0000000
--- a/app/components/app-community-links.imba
+++ /dev/null
@@ -1,131 +0,0 @@
-let p = console.log
-import all_links from '../assets/community_links'
-import fzi from 'fzi'
-import api from '../api'
-
-tag app-community-links
-
-	active = no
-	selection_index = 0
-	query = ""
-
-	get render? do mounted?
-
-	def mount
-		$cli.focus!
-		links = await get_links!
-		render!
-
-	def get_links
-		let result = []
-		for link_text in all_links
-			let link = await api.create_link_from_text(link_text, no)
-			link.link_text = link_text
-			result.push link
-		result
-
-	get filtered_links
-		links.filter! do |link| !api.name_exists(link.name)
-
-	get sorted_links
-		fzi.sort query, filtered_links, do |x| x.name
-
-	get selected_link
-		sorted_links[selection_index]
-
-	def open
-		active = yes
-
-	def close
-		active = no
-
-	def increment_selection_index
-		selection_index = Math.min(links.length - 1, selection_index + 1)
-
-	def decrement_selection_index
-		selection_index = Math.max(0, selection_index - 1)
-
-	def add_community_link
-		return if state.loading
-		state.loading = yes
-		try
-			await api.add_link selected_link.link_text
-		catch e
-			err "adding link", e
-		state.loading = no
-
-	get tips
-		let result = []
-		let temp
-
-		temp = {
-				click_handler: close.bind(this)
-				hotkey_handler: close.bind(this)
-				hotkey: "esc"
-				hotkey_display_name: "Esc"
-				content: "Exit Community Links"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: add_community_link.bind(this)
-				hotkey_handler: add_community_link.bind(this)
-				hotkey: "shift+return"
-				hotkey_display_name: "Shift + Return Or Click"
-				content: "Add To Your Links"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: increment_selection_index.bind(this)
-				hotkey_handler: increment_selection_index.bind(this)
-				hotkey: 'down'
-				hotkey_display_name: "Down Arrow"
-				content: "Move Selection Down"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: decrement_selection_index.bind(this)
-				hotkey_handler: decrement_selection_index.bind(this)
-				hotkey: 'up'
-				hotkey_display_name: "Up Arrow"
-				content: "Move Selection Up"
-		}
-		result.push temp
-
-		result
-
-	def render
-
-		<self>
-			css d:flex fld:column jc:start gap:15px fl:1 w:100% ofy:hidden
-
-			<div>
-				<input$cli
-					autofocus
-					bind=query
-				>
-
-			<app-tips tips=tips>
-
-			<.links>
-				css ofy:auto
-
-				for link, index in sorted_links
-					<.link
-						.selected=(selection_index == index)
-						@pointerover=(selection_index = index)
-						@click=add_community_link
-					>
-						css d:flex fld:row jc:space-between ai:center px:16px
-							py:2px rd:5px cursor:pointer c:$text-c min-height:35px
-
-						if link.is_bang
-							css c:$bang-c
-
-						<.link-left> link.name
-							css fl:1
-
-						<link-right.ellipsis> link.url
-							css fl:1 c:inherit
diff --git a/app/components/app-edit.imba b/app/components/app-edit.imba
deleted file mode 100644
index efbf377..0000000
--- a/app/components/app-edit.imba
+++ /dev/null
@@ -1,84 +0,0 @@
-tag app-edit
-
-	active = no
-
-	def mount
-		$dn.setSelectionRange 0, 0
-		$dn.focus!
-
-	def open data
-		link = data
-		new_link_text = value=api.construct_link_text(link)
-		active = yes
-
-	def close
-		active = no
-
-	def handle_click_set_default_bang
-		config.set_default_bang link
-		close!
-
-	def handle_delete
-		try
-			await api.delete_link link
-			close!
-		catch e
-			err "deleting link", e
-
-	def save
-		try
-			api.update_link link, new_link_text
-			close!
-		catch e
-			err "saving link", e
-
-	get tips
-		let result = []
-		let temp
-
-		temp = {
-				click_handler: handle_delete.bind(this)
-				hotkey_handler: handle_delete.bind(this)
-				hotkey: 'shift+backspace'
-				hotkey_display_name: "Shift + Backspace"
-				content: "Delete Link"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: save.bind(this)
-				hotkey_handler: save.bind(this)
-				hotkey: 'return'
-				hotkey_display_name: "Return"
-				content: "Update Link"
-		}
-		result.push temp
-
-		if link.is_bang
-			temp = {
-					click_handler: handle_click_set_default_bang.bind(this)
-					hotkey_display_name: "Click"
-					content: "Set Default Bang"
-			}
-			result.push temp
-
-		temp = {
-				click_handler: close.bind(this)
-				hotkey_handler: close.bind(this)
-				hotkey: 'esc'
-				hotkey_display_name: "Esc"
-				content: "Cancel"
-		}
-		result.push temp
-
-		result
-
-	def render
-
-		<self>
-			css d:flex fld:column gap:20px w:100%
-
-			<div>
-				<input$dn autofocus bind=new_link_text>
-
-			<app-tips tips=tips>
diff --git a/app/components/app-home.imba b/app/components/app-home.imba
deleted file mode 100644
index 672d30f..0000000
--- a/app/components/app-home.imba
+++ /dev/null
@@ -1,73 +0,0 @@
-tag app-home
-
-	def mount
-		$home-input.focus!
-
-	def blur
-		setTimeout(&, 100) do $home-input.focus!
-
-	def handle_paste e
-		return unless config.data.enable_search_on_paste
-		return if state.query.length > 0
-		global.setTimeout(&, 0) do
-			return if api.math_result isnt no
-			bang ||= config.data.default_bang
-			api.handle_bang!
-
-	def handle_click_copy s
-		try
-			await window.navigator.clipboard.writeText(s)
-			state.query = ''
-			api.sort_links!
-
-	def handle_input
-		state.bang_selection_index = -1
-		api.set_link_selection_index 0
-		api.sort_links!
-
-	def render
-
-		<self>
-			css w:100% d:flex fld:column ofy:hidden gap:20px
-
-			<.header>
-				css d:flex fld:row w:100%
-				css .side c:$button-c fs:15px d:flex ja:center w:30px cursor:pointer
-				css .side svg w:15px d:flex
-				css .left jc:left
-				css .right jc:right
-
-				<.side.left@click=api.toggle_effective_names>
-
-					if config.data.enable_effective_names
-						<svg src="../assets/eye.svg">
-
-					else
-						<svg src="../assets/eye-off.svg">
-
-				<input$home-input
-					autofocus
-					bind=state.query
-					@input=handle_input
-					@paste=handle_paste
-					@cut=api.handle_cut
-					disabled=state.loading
-					@blur=blur
-				>
-					if state.query.startsWith "!"
-						css c:$bang-c
-
-				if (let m = api.math_result) isnt no
-					<.side.right@click=handle_click_copy(m)>
-						"= {Math.round(m * 100)/100}"
-						css c:$text-c fs:20px ml:10px w:unset
-
-				else
-					<.side.right @click=refs.settings.open>
-						<svg src="../assets/settings.svg">
-
-			if state.active_bang or state.sorted_links.length < 1
-				<app-bang>
-
-			else
-				<app-links>
diff --git a/app/components/app-link.imba b/app/components/app-link.imba
deleted file mode 100644
index 2265215..0000000
--- a/app/components/app-link.imba
+++ /dev/null
@@ -1,67 +0,0 @@
-tag app-link
-
-	def handle_delete link
-		return unless window.confirm "Do you really want to delete {link..display_name}?"
-		api.delete_link link
-
-	def handle_pin link
-		api.pin_link link
-
-	def render
-		<self
-			@pointerover=api.set_link_selection_index(index)
-			@click=api.handle_click_link
-			.selected=(index is state.link_selection_index)
-		>
-			css d:flex fld:row jc:space-between ai:center
-				px:16px py:11px rd:5px cursor:pointer c:$text-c
-			if link.is_bang
-				css c:$bang-c
-
-			<.link-left>
-				css d:flex fl:3
-
-				<img.link-icon src=link.icon>
-					css w:20px h:20px mr:10px rd:3px
-
-				<.display-name> link.display_name
-					css tt:capitalize fs:20px overflow-wrap:anywhere
-
-				if link.display_name isnt link.name and config.data.enable_effective_names
-					<.name>
-						css d:flex ja:center c:$effective-name-c ml:10px fs:14px
-						css .parens fs:10px c:$effective-name-parens-c
-
-						<span.parens> "("
-						<span> link.name
-						<span.parens> ")"
-
-			<.link-right>
-				css fl:1 d:flex fld:row jc:space-between ai:center
-
-				css .buttons-disabled .link-button visibility:hidden
-				css .selected .link-button visibility:visible
-
-				<.link-buttons .buttons-disabled=!config.data.enable_buttons>
-					css d:flex fld:row jc:start ai:center gap:5px
-
-					css .link-button visibility:hidden rd:3px c:$button-c fs:15px cursor:pointer px:3px
-					if index is state.link_selection_index
-						css .link-button visibility:visible
-
-					css .link-button svg w:15px
-
-					<.link-button@click.prevent.stop=handle_edit>
-						<svg src='../assets/edit-2.svg'>
-
-					<.link-button@click.prevent.stop=handle_delete(link)>
-						<svg src='../assets/trash.svg'>
-
-					<.link-button @click.prevent.stop=handle_pin(link)>
-						if link.is_pinned
-							css visibility:visible c:$button-dim-c
-
-						<svg src='../assets/star.svg'>
-
-				<.frequency> link.frequency
-					css fs:15px ml:7px
diff --git a/app/components/app-links.imba b/app/components/app-links.imba
deleted file mode 100644
index 6b757ad..0000000
--- a/app/components/app-links.imba
+++ /dev/null
@@ -1,104 +0,0 @@
-tag app-links
-
-	def handle_edit
-		return unless state.sorted_links.length > 0
-		refs.edit.open api.selected_link
-
-	get tips
-		let result = []
-		let temp
-
-		temp = {
-			click_handler: api.handle_click_link.bind(api)
-			hotkey_handler: api.handle_click_link.bind(api)
-			hotkey: 'return'
-			hotkey_display_name: 'Return'
-		}
-		temp.content = api.selected_link.is_bang ? "Use Bang" : "Navigate To Link"
-		result.push temp
-
-		temp = {
-			click_handler: api.handle_add_link.bind(api)
-			hotkey_handler: api.handle_add_link.bind(api)
-			hotkey: 'shift+return'
-			hotkey_display_name: 'Shift + Return'
-			content: "Create Link \"{state.query.trim!}\""
-		}
-		result.push temp
-
-		temp = {
-				click_handler: handle_edit.bind(this)
-				hotkey_handler: handle_edit.bind(this)
-				hotkey: 'shift+backspace'
-				hotkey_display_name: "Shift + Backspace"
-				content: "Edit Link"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: api.toggle_effective_names.bind(api)
-				hotkey_handler: api.toggle_effective_names.bind(api)
-				hotkey: 'tab'
-				hotkey_display_name: "Tab"
-				content: "Toggle Effective Names"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: (do refs.settings.open!).bind(this)
-				hotkey_handler: (do refs.settings.open!).bind(this)
-				hotkey: 'shift+tab'
-				hotkey_display_name: "Shift + Tab"
-				content: "Toggle Settings"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: api.handle_cut.bind(api)
-		}
-		if api.math_result
-			temp.hotkey_display_name = "Cut (If No Selection)"
-			temp.content = "Cut All Text"
-		else
-			temp.hotkey_display_name = "Cut (Math, If No Selection)"
-			temp.content = "Cut Math Result"
-		result.push temp
-
-		temp = {
-				click_handler: api.increment_link_selection_index.bind(api)
-				hotkey_handler: api.increment_link_selection_index.bind(api)
-				hotkey: 'down'
-				hotkey_display_name: "Down Arrow"
-				content: "Move Selection Down"
-		}
-		result.push temp
-
-		temp = {
-				click_handler: api.decrement_link_selection_index.bind(api)
-				hotkey_handler: api.decrement_link_selection_index.bind(api)
-				hotkey: 'up'
-				hotkey_display_name: "Up Arrow"
-				content: "Move Selection Up"
-		}
-		result.push temp
-
-		temp = {
-				hotkey_display_name: "Paste (If Input Empty)"
-				content: "Instant Search"
-		}
-		result.push temp
-
-		result
-
-	def render
-
-		<self>
-			css w:100% d:flex fld:column gap:15px ofy:hidden
-
-			<app-tips$tips tips=tips>
-
-			<.links>
-				css ofy:auto
-				for link, index in state.sorted_links
-					<app-link link=link index=index handle_edit=handle_edit>
-
diff --git a/app/components/app-prompt.imba b/app/components/app-prompt.imba
deleted file mode 100644
index 0b20da4..0000000
--- a/app/components/app-prompt.imba
+++ /dev/null
@@ -1,16 +0,0 @@
-import { cloneDeep } from 'lodash'
-
-tag app-prompt
-
-	def get_input d
-		data = cloneDeep d
-		active = yes
-		let result = await new Promise! do |resolve|
-			self.addEventListener('end') do |e|
-				self.removeEventListener('end', this)
-				resolve(e.detail)
-		active = no
-		result
-
-	def end
-		emit('end', data)
diff --git a/app/components/app-settings.imba b/app/components/app-settings.imba
deleted file mode 100644
index 45ddc26..0000000
--- a/app/components/app-settings.imba
+++ /dev/null
@@ -1,153 +0,0 @@
-import download from 'downloadjs'
-
-tag app-settings
-
-	active = no
-
-	def close
-		active = no
-
-	def open
-		active = yes
-
-	def handle_click_github
-		global.location.href = "https://github.com/familyfriendlymikey/fuzzyhome"
-
-	def handle_click_toggle_tips
-		config.data.enable_tips = not config.data.enable_tips
-		config.save!
-		active = no
-
-	def handle_click_toggle_buttons
-		config.data.enable_buttons = not config.data.enable_buttons
-		config.save!
-		active = no
-
-	def handle_click_toggle_search_on_paste
-		config.data.enable_search_on_paste = not config.data.enable_search_on_paste
-		config.save!
-		active = no
-
-	def handle_toggle_light_theme
-		config.data.enable_light_theme = not config.data.enable_light_theme
-		config.save!
-		active = no
-
-	def handle_import e
-
-		def handle_import
-			let errors = []
-			try
-				let text = await e.target.files[0].text!
-				var links = text.split "\n"
-			catch e
-				return err "importing db", e
-			for link_text in links
-				try
-					let link = await api.create_link_from_text link_text
-					if api.name_exists link.name
-						throw "Name already exists, add manually if you don't mind duplicates."
-					api.add_link link_text
-				catch e
-					errors.push "{link_text}\n{e}"
-			if errors.length > 0
-				err "importing some links", errors.join("\n\n")
-
-		state.loading = yes
-		await handle_import!
-		active = no
-		state.loading = no
-		close!
-
-	def handle_click_export
-		state.loading = yes
-		await api.reload_db!
-		let links = state.links.map do |link|
-			api.construct_link_text link
-		let datetime = new Date!.toString!.split(" ")
-		let date = datetime.slice(1, 4).join("-").toLowerCase!
-		let time = datetime[4].split(":").join("-")
-		let filename = "fuzzyhome_v{version}_{date}_{time}.txt"
-		download(links.join("\n"), filename, "text/plain")
-		active = no
-		state.loading = no
-
-	def render
-
-		<self>
-			css w:100%
-
-			css .settings-container
-				d:flex fld:row jc:space-around ai:center
-				w:100% h:50px
-				mt:10px
-				gap:10px
-
-			css .settings-button, .settings-container button
-				d:flex fld:column jc:center ai:center fl:1
-				bg:none bd:none cursor:pointer fs:14px
-				rd:5px
-				transition:background 100ms
-				h:100%
-				bg:$button-bg c:$button-c
-				@hover bg:$button-hover-bg
-
-			if refs.community-links.active
-				<app-community-links>
-
-			else
-				<.settings-container>
-
-					<.settings-button
-						@click=close
-						@hotkey("esc")=close
-						@hotkey("shift+tab")=close
-					> "BACK"
-
-				<.settings-container>
-
-					<.settings-button @click=(refs.community-links.open! and close!)>
-						"VIEW COMMUNITY LINKS"
-
-				<.settings-container>
-
-					<label.settings-button>
-						"IMPORT"
-						<input[d:none]
-							disabled=state.loading
-							@change=handle_import
-							@click=(this.value = '')
-							type="file"
-						>
-
-					<.settings-button @click=handle_click_export>
-						"EXPORT"
-
-				<.settings-container>
-
-					<.settings-button @click=handle_click_github>
-						"TUTORIAL"
-
-					<.settings-button @click=handle_click_github>
-						"GITHUB"
-
-				<.settings-container>
-
-					<.settings-button @click=handle_click_toggle_tips>
-						config.data.enable_tips ? "DISABLE TIPS" : "ENABLE TIPS"
-
-					<.settings-button @click=handle_click_toggle_buttons>
-						config.data.enable_buttons ? "DISABLE BUTTONS" : "ENABLE BUTTONS"
-
-				<.settings-container>
-
-					<.settings-button @click=handle_click_toggle_search_on_paste>
-						config.data.enable_search_on_paste ? "DISABLE SEARCH ON PASTE" : "ENABLE SEARCH ON PASTE"
-
-					<.settings-button @click=config.cycle_theme>
-						"THEME: {config.data.theme.toUpperCase!}"
-
-				<.settings-container>
-
-					<.settings-button @click=(api.delete_all_bang_history! and close!)>
-						"DELETE ALL BANG HISTORY"
diff --git a/app/components/app-tips.imba b/app/components/app-tips.imba
deleted file mode 100644
index ed7400f..0000000
--- a/app/components/app-tips.imba
+++ /dev/null
@@ -1,86 +0,0 @@
-import { chunk, fill } from 'lodash'
-
-tag app-tip
-
-	<self
-		@click.if(tip.click_handler)=tip.click_handler
-	>
-		css d:flex fld:column jc:start fl:1
-			bdr:1px solid
-			bc:$tip-bc
-			min-width:0 ta:center p:10px
-			cursor:pointer transition:background 100ms
-			@first ta:left rdl:3px
-			@last ta:right bd:none rdr:3px
-			@hover bg:$tip-hover-c
-		if tip.placeholder or not tip.click_handler
-			css
-				@hover @important cursor:auto bg:none
-
-		if tip.hotkey_handler and tip.hotkey
-			<@hotkey(tip.hotkey).force=tip.hotkey_handler>
-				css d:none
-
-		<.tip-hotkey> tip.hotkey_display_name
-			css fs:12px c:$tip-hotkey-c
-
-		<.tip-content> tip.content
-			css pt:2px fs:14px c:$tip-content-c
-
-tag app-tips
-
-	def unmount
-		show_more = no
-
-	def toggle
-		show_more = not show_more
-
-	def pad arr
-		let i = arr.length
-		while i < 3
-			arr.push { placeholder: yes }
-			i += 1
-
-	def get_chunks
-		let chunks = chunk(tips, 3)
-		pad(chunks[-1])
-		chunks
-
-	def render
-		let chunks = get_chunks!
-
-		<self[d:none]=!config.data.enable_tips>
-			css d:flex fld:column gap:15px max-height:75%
-
-			css .tip-row
-				d:flex fld:row w:100% fl:1
-				fs:20px fs:14px
-				jc:end ta:center
-
-			<.tip-row>
-				for tip in chunks[0]
-					<app-tip tip=tip>
-
-			if chunks.length > 1
-
-				<@click=toggle>
-					css w:100% d:flex ja:center c:$button-c rdb:4px cursor:pointer
-						transition:background 100ms
-						@hover bg:$tip-hover-c
-					if show_more
-						css rd:0
-
-					<svg src="../assets/chevron-down.svg">
-						css w:15px transition:transform 150ms
-						if show_more
-							css transform:rotate(180deg)
-
-				<.more>
-					css d:flex fld:column gap:15px ofy:auto 
-					unless show_more
-						css d:none
-
-					for row in chunks.slice(1)
-						<.tip-row>
-							for tip in row
-								<app-tip tip=tip>
diff --git a/app/config.imba b/app/config.imba
deleted file mode 100644
index a877e64..0000000
--- a/app/config.imba
+++ /dev/null
@@ -1,59 +0,0 @@
-let p = console.log
-
-import { err } from './utils'
-
-export default new class config
-
-	def constructor
-		this.data = {}
-		try
-			this.data = JSON.parse(global.localStorage.fuzzyhome_config)
-
-		this.data.enable_tips ??= yes
-		this.data.enable_buttons ??= yes
-		this.data.enable_search_on_paste ??= yes
-		this.data.enable_dark_theme ??= yes
-		this.data.enable_effective_names ??= yes
-		this.data.theme ??= "timed"
-
-		this.data.default_bang ??= {}
-		this.data.default_bang.name ??= "!google"
-		this.data.default_bang.display_name ??= "google"
-		this.data.default_bang.url ??= "https://www.google.com/search?q="
-		this.data.default_bang.frequency ??= 0
-		this.data.default_bang.icon ??= "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///zD9/f2W/f392P39/fn9/f35/f391/39/ZT+/v4uAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Cf39/Zn///////////////////////////////////////////39/ZX///8IAAAAAAAAAAAAAAAA/v7+Cf39/cH/////+v35/7TZp/92ul3/WKs6/1iqOv9yuFn/rNWd//j79v///////f39v////wgAAAAAAAAAAP39/Zn/////7PXp/3G3WP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP+Or1j//vDo///////9/f2VAAAAAP///zD/////+vz5/3G3V/9TqDT/WKo6/6LQkf/U6cz/1urO/6rUm/+Zo0r/8IZB//adZ////v7///////7+/i79/f2Y/////4nWzf9Lqkj/Vqo4/9Xqzv///////////////////////ebY//SHRv/0hUL//NjD///////9/f2U/f392v////8sxPH/Ebzt/43RsP/////////////////////////////////4roL/9IVC//i1jf///////f391/39/fr/////Cr37/wW8+/+16/7/////////////////9IVC//SFQv/0hUL/9IVC//SFQv/3pnX///////39/fn9/f36/////wu++/8FvPv/tuz+//////////////////SFQv/0hUL/9IVC//SFQv/0hUL/96p7///////9/f35/f392/////81yfz/CrL5/2uk9v///////////////////////////////////////////////////////f392P39/Zn/////ks/7/zdS7P84Rur/0NT6///////////////////////9/f////////////////////////39/Zb+/v4y//////n5/v9WYu3/NUPq/ztJ6/+VnPT/z9L6/9HU+v+WnfT/Ul7t/+Hj/P////////////////////8wAAAAAP39/Z3/////6Or9/1hj7v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9sdvD////////////9/f2YAAAAAAAAAAD///8K/f39w//////5+f7/paz2/11p7v88Suv/Okfq/1pm7v+iqfX/+fn+///////9/f3B/v7+CQAAAAAAAAAAAAAAAP///wr9/f2d///////////////////////////////////////////9/f2Z/v7+CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f2Z/f392/39/fr9/f36/f392v39/Zj///8wAAAAAAAAAAAAAAAAAAAAAPAPAADAAwAAgAEAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAACAAQAAwAMAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/g3+/v5X/f39mf39/cj9/f3q/f39+f39/fn9/f3q/f39yP39/Zn+/v5W////DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f2c/f399f/////////////////////////////////////////////////////9/f31/f39mv7+/iMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/gn9/f2K/f39+////////////////////////////////////////////////////////////////////////////f39+v39/Yf///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4k/f390v////////////////////////////////////////////////////////////////////////////////////////////////39/dD///8iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////MP39/er//////////////////////////+r05v+v16H/gsBs/2WxSf9Wqjj/Vqk3/2OwRv99vWX/pdKV/97u2P////////////////////////////39/ej+/v4vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/iT9/f3q/////////////////////+v15/+Pxnv/VKk2/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/36+Z//d7tf///////////////////////39/ej///8iAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K/f390//////////////////////E4bn/XKw+/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1apN/+x0pv///////////////////////39/dD///8IAAAAAAAAAAAAAAAAAAAAAP39/Yv/////////////////////sdij/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9TqDT/YKU1/8qOPv/5wZ////////////////////////39/YcAAAAAAAAAAAAAAAD+/v4l/f39+////////////////8Lgt/9TqDT/U6g0/1OoNP9TqDT/U6g0/1OoNP9utlT/n86N/7faqv+426v/pdKV/3u8ZP9UqDX/U6g0/3egN//jiUH/9IVC//SFQv/82MP//////////////////f39+v7+/iMAAAAAAAAAAP39/Z3////////////////q9Ob/W6w+/1OoNP9TqDT/U6g0/1OoNP9nskz/zOXC/////////////////////////////////+Dv2v+osWP/8YVC//SFQv/0hUL/9IVC//WQVP/++fb//////////////////f39mgAAAAD+/v4O/f399v///////////////4LHj/9TqDT/U6g0/1OoNP9TqDT/dblc//L58P/////////////////////////////////////////////8+v/3p3f/9IVC//SFQv/0hUL/9IVC//rIqf/////////////////9/f31////DP7+/ln////////////////f9v7/Cbz2/zOwhv9TqDT/U6g0/2KwRv/v9+z///////////////////////////////////////////////////////738//1kFT/9IVC//SFQv/0hUL/9plg///////////////////////+/v5W/f39nP///////////////4jf/f8FvPv/Bbz7/yG1s/9QqDz/vN2w//////////////////////////////////////////////////////////////////rHqP/0hUL/9IVC//SFQv/0hUL//vDn//////////////////39/Zn9/f3L////////////////R878/wW8+/8FvPv/Bbz7/y7C5P/7/fr//////////////////////////////////////////////////////////////////ere//SFQv/0hUL/9IVC//SFQv/718H//////////////////f39yP39/ez///////////////8cwvv/Bbz7/wW8+/8FvPv/WNL8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rIqv/////////////////9/f3q/f39+v///////////////we9+/8FvPv/Bbz7/wW8+/993P3///////////////////////////////////////SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+cGf//////////////////39/fn9/f36////////////////B737/wW8+/8FvPv/Bbz7/33c/f//////////////////////////////////////9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6xaX//////////////////f39+f39/e3///////////////8cwvv/Bbz7/wW8+/8FvPv/WdP8///////////////////////////////////////0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vVv//////////////////9/f3q/f39y////////////////0bN/P8FvPv/Bbz7/wW8+/8hrvn/+/v///////////////////////////////////////////////////////////////////////////////////////////////////////////////////39/cj9/f2c////////////////ht/9/wW8+/8FvPv/FZP1/zRJ6/+zuPf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////f39mf7+/lr////////////////d9v7/B7n7/yB38f81Q+r/NUPq/0hV7P/u8P3////////////////////////////////////////////////////////////////////////////////////////////////////////////+/v5X////D/39/ff///////////////9tkPT/NUPq/zVD6v81Q+r/NUPq/2Fs7//y8v7////////////////////////////////////////////09f7//////////////////////////////////////////////////f399f7+/g0AAAAA/f39n////////////////+Tm/P89Suv/NUPq/zVD6v81Q+r/NUPq/1Bc7f/IzPn/////////////////////////////////x8v5/0xY7P+MlPP////////////////////////////////////////////9/f2cAAAAAAAAAAD+/v4n/f39/P///////////////7W69/81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v9ZZe7/k5v0/6609/+vtff/lJv0/1pm7v81Q+r/NUPq/zVD6v+GjvL//v7//////////////////////////////f39+/7+/iQAAAAAAAAAAAAAAAD9/f2N/////////////////////6Cn9f81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v+BivL////////////////////////////9/f2KAAAAAAAAAAAAAAAAAAAAAP7+/gv9/f3V/////////////////////7W69/8+S+v/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/P0zr/7q/+P///////////////////////f390v7+/gkAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3r/////////////////////+Xn/P94gfH/NkTq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NUPq/zVD6v81Q+r/NkTq/3Z/8f/l5/z///////////////////////39/er+/v4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/jL9/f3r///////////////////////////k5vz/nqX1/2p08P9IVez/OEbq/zdF6v9GU+z/aHLv/5qh9f/i5Pz////////////////////////////9/f3q////MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/ib9/f3V/////////////////////////////////////////////////////////////////////////////////////////////////f390v7+/iQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr9/f2N/f39/P///////////////////////////////////////////////////////////////////////////f39+/39/Yv+/v4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/v4n/f39n/39/ff//////////////////////////////////////////////////////f399v39/Z3+/v4lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+Dv7+/lr9/f2c/f39y/39/e39/f36/f39+v39/ez9/f3L/f39nP7+/ln+/v4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPAAAAD4AAAB/AAAA/4AAAf/AAAP/8AAP//wAP/"
-		this.data.default_bang.id ??= "FEJbsKLUMwHbazbqW3c4i"
-		this.data.default_bang.history ??= []
-		this.data.default_bang.is_bang ??= yes
-
-		p "config:", this.data
-
-	def cycle_theme
-		if this.data.theme is "dark"
-			this.data.theme = "light"
-		elif this.data.theme is "light"
-			this.data.theme = "timed"
-		else
-			this.data.theme = "dark"
-		save!
-
-	get theme
-		if this.data.theme is "light"
-			"light"
-		elif this.data.theme is "timed"
-			let hour = new Date!.getHours!
-			if hour > 18 or hour < 8
-				"dark"
-			else
-				"light"
-		else
-			"dark"
-
-	def set_default_bang link
-		unless link.is_bang
-			return err "setting default bang", "Link is not a bang."
-		data.default_bang = link
-		save!
-
-	def save
-		global.localStorage.fuzzyhome_config = JSON.stringify(this.data)
diff --git a/app/db.imba b/app/db.imba
deleted file mode 100644
index a9127c5..0000000
--- a/app/db.imba
+++ /dev/null
@@ -1,51 +0,0 @@
-let p = console.log
-import Dexie from 'dexie'
-import 'dexie-export-import'
-import { nanoid } from 'nanoid'
-import api from './api'
-
-let db = new Dexie 'fuzzyhome'
-
-db.version(1).stores({
-	links: "++id,name,link"
-})
-
-db.version(2).stores({
-	links: "++id,name,url,frequency,img"
-}).upgrade! do |trans|
-	p "upgrading to fuzzyhome db version 2"
-	trans.links.toCollection!.modify! do |link|
-		let id = nanoid!
-		let name = link.name
-		let url = link.link
-		let frequency = link.frequency
-		let img = link.img
-		this.value = { id, name, url, frequency, img }
-
-db.version(3).stores({
-	links: "++id,name,url,frequency,img"
-}).upgrade! do |trans|
-	p "upgrading to fuzzyhome db version 3"
-	trans.links.toCollection!.modify! do |link|
-		try
-			link.url = api.parse_url(link.url).href
-
-db.version(4).stores({
-	links: "++id,display_name,name,is_bang,url,frequency,icon"
-}).upgrade! do |trans|
-	p "upgrading to fuzzyhome db version 4"
-	trans.links.toCollection!.modify! do |link|
-		link.display_name = link.name
-		link.is_bang = no
-		link.icon = link.img
-		delete link.img
-
-db.version(5).stores({
-	links: "++id,display_name,name,is_bang,is_pinned,url,frequency,history,icon"
-}).upgrade! do |trans|
-	p "upgrading to fuzzyhome db version 5"
-	trans.links.toCollection!.modify! do |link|
-		link.is_pinned = no
-		link.history = []
-
-export default db
diff --git a/app/sw.imba b/app/sw.imba
deleted file mode 100644
index d46bfc6..0000000
--- a/app/sw.imba
+++ /dev/null
@@ -1,41 +0,0 @@
-const app_name = "fuzzyhome"
-import { version } from '../package.json'
-const app_prefix = "{app_name}_cache"
-const cache_name = "sw-{app_prefix}-{version}"
-let p = do |s| console.log "{cache_name} {s}"
-p "loaded"
-
-let urls = [
-	'./'
-]
-
-self.addEventListener('fetch') do |e|
-	p "fetch"
-	def intercept request
-		if request
-			p "responding with cache {e.request.url}"
-			request
-		else
-			p "not cached, fetching {e.request.url}"
-			fetch e.request
-	e.respondWith(caches.match(e.request.url).then(intercept))
-
-self.addEventListener('install') do |e|
-	p "install"
-	def add_urls_to_cache cache
-		p "adding urls to cache"
-		cache.addAll urls
-		skipWaiting!
-	e.waitUntil(caches.open(cache_name).then(add_urls_to_cache))
-
-self.addEventListener('activate') do |e|
-	p "activate"
-	def delete_cached keys
-		let temp = keys.map! do |key, i|
-			p "checking cache {key}"
-			if key !== cache_name
-				p "deleting cache {key}"
-				let result = await caches.delete key
-				p "deletion of {key} result: {result}"
-		Promise.all(temp)
-	e.waitUntil(caches.keys().then(delete_cached))
diff --git a/app/utils.imba b/app/utils.imba
deleted file mode 100644
index a963b69..0000000
--- a/app/utils.imba
+++ /dev/null
@@ -1,13 +0,0 @@
-let p = console.log
-
-export def err s, e
-	p "error:"
-	p e
-	window.alert("Error {s}:\n\n{e}")
-
-global._fuzzyhome_delete_everything = do |prompt=yes|
-	return if prompt and window.confirm "This will delete everything. Are you sure?"
-	indexedDB.deleteDatabase("fuzzyhome")
-	delete localStorage.fuzzyhome_config
-	delete localStorage.fuzzyhome_visited
-	location.reload!
diff --git a/chrome/manifest.json b/chrome/manifest.json
new file mode 100644
index 0000000..f38db13
--- /dev/null
+++ b/chrome/manifest.json
@@ -0,0 +1,13 @@
+{
+	"name": "fuzzyhome",
+	"description": "A power user oriented new-tab page that enables lightning speed navigation through the dark magic of fuzzy finding.",
+	"version": "2.1.0",
+	"manifest_version": 3,
+	"permissions": [
+		"bookmarks",
+		"storage"
+	],
+	"chrome_url_overrides": {
+		"newtab": "dist/index.html"
+	}
+}
diff --git a/app/index.html b/index.html
similarity index 69%
rename from app/index.html
rename to index.html
index e18eca8..424f819 100644
--- a/app/index.html
+++ b/index.html
@@ -4,9 +4,8 @@
 		<title>&lrm;</title>
 		<meta charset="UTF-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<style src='*'></style>
 	</head>
-	<body>
-		<script type="module" src="./client.imba"></script>
+	<body style="background:#20222f">
+		<script type="module" src="/src/index.js"></script>
 	</body>
 </html>
diff --git a/package-lock.json b/package-lock.json
index 81f5c22..fc6bbf9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,38 +1,176 @@
 {
 	"name": "fuzzyhome",
-	"version": "0.1.43",
+	"version": "0.2.1",
 	"lockfileVersion": 2,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "fuzzyhome",
-			"version": "0.1.43",
+			"version": "0.2.1",
 			"dependencies": {
-				"dexie": "^3.2.2",
-				"dexie-export-import": "^1.0.3",
-				"downloadjs": "^1.4.7",
-				"fzi": "^1.1.0",
-				"imba": "^2.0.0-alpha.220",
+				"fzi": "^1.5.0",
+				"imba": "^2.0.0-alpha.225",
 				"lodash": "^4.17.21",
-				"mathjs": "^11.1.0",
-				"nanoid": "^4.0.0"
+				"math-expression-evaluator": "^1.4.0",
+				"vite": "^3.2.5",
+				"vite-plugin-imba": "^0.10.1"
+			}
+		},
+		"node_modules/@adobe/css-tools": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.1.tgz",
+			"integrity": "sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==",
+			"peer": true
+		},
+		"node_modules/@antfu/install-pkg": {
+			"version": "0.1.1",
+			"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.1.1.tgz",
+			"integrity": "sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==",
+			"dependencies": {
+				"execa": "^5.1.1",
+				"find-up": "^5.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
+		"node_modules/@babel/code-frame": {
+			"version": "7.18.6",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+			"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+			"peer": true,
+			"dependencies": {
+				"@babel/highlight": "^7.18.6"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-validator-identifier": {
+			"version": "7.19.1",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+			"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+			"peer": true,
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/highlight": {
+			"version": "7.18.6",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+			"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+			"peer": true,
+			"dependencies": {
+				"@babel/helper-validator-identifier": "^7.18.6",
+				"chalk": "^2.0.0",
+				"js-tokens": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/highlight/node_modules/ansi-styles": {
+			"version": "3.2.1",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+			"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+			"peer": true,
+			"dependencies": {
+				"color-convert": "^1.9.0"
+			},
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/@babel/highlight/node_modules/chalk": {
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+			"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+			"peer": true,
+			"dependencies": {
+				"ansi-styles": "^3.2.1",
+				"escape-string-regexp": "^1.0.5",
+				"supports-color": "^5.3.0"
+			},
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/@babel/highlight/node_modules/color-convert": {
+			"version": "1.9.3",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+			"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+			"peer": true,
+			"dependencies": {
+				"color-name": "1.1.3"
+			}
+		},
+		"node_modules/@babel/highlight/node_modules/color-name": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+			"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+			"peer": true
+		},
+		"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+			"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+			"peer": true,
+			"engines": {
+				"node": ">=0.8.0"
+			}
+		},
+		"node_modules/@babel/highlight/node_modules/has-flag": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+			"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+			"peer": true,
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/@babel/highlight/node_modules/supports-color": {
+			"version": "5.5.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+			"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+			"peer": true,
+			"dependencies": {
+				"has-flag": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=4"
 			}
 		},
 		"node_modules/@babel/runtime": {
-			"version": "7.18.9",
-			"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
-			"integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
+			"version": "7.20.6",
+			"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz",
+			"integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==",
+			"peer": true,
 			"dependencies": {
-				"regenerator-runtime": "^0.13.4"
+				"regenerator-runtime": "^0.13.11"
 			},
 			"engines": {
 				"node": ">=6.9.0"
 			}
 		},
+		"node_modules/@esbuild/android-arm": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+			"integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
+			"cpu": [
+				"arm"
+			],
+			"optional": true,
+			"os": [
+				"android"
+			],
+			"engines": {
+				"node": ">=12"
+			}
+		},
 		"node_modules/@esbuild/linux-loong64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.5.tgz",
-			"integrity": "sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+			"integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
 			"cpu": [
 				"loong64"
 			],
@@ -44,10 +182,291 @@
 				"node": ">=12"
 			}
 		},
+		"node_modules/@jest/expect-utils": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
+			"integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
+			"peer": true,
+			"dependencies": {
+				"jest-get-type": "^29.2.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/@jest/schemas": {
+			"version": "29.0.0",
+			"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
+			"integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
+			"peer": true,
+			"dependencies": {
+				"@sinclair/typebox": "^0.24.1"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/@jest/types": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
+			"integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
+			"peer": true,
+			"dependencies": {
+				"@jest/schemas": "^29.0.0",
+				"@types/istanbul-lib-coverage": "^2.0.0",
+				"@types/istanbul-reports": "^3.0.0",
+				"@types/node": "*",
+				"@types/yargs": "^17.0.8",
+				"chalk": "^4.0.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"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==",
+			"dependencies": {
+				"estree-walker": "^2.0.1",
+				"picomatch": "^2.2.2"
+			},
+			"engines": {
+				"node": ">= 8.0.0"
+			}
+		},
+		"node_modules/@sinclair/typebox": {
+			"version": "0.24.51",
+			"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+			"integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+			"peer": true
+		},
+		"node_modules/@testing-library/dom": {
+			"version": "8.19.0",
+			"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
+			"integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==",
+			"peer": true,
+			"dependencies": {
+				"@babel/code-frame": "^7.10.4",
+				"@babel/runtime": "^7.12.5",
+				"@types/aria-query": "^4.2.0",
+				"aria-query": "^5.0.0",
+				"chalk": "^4.1.0",
+				"dom-accessibility-api": "^0.5.9",
+				"lz-string": "^1.4.4",
+				"pretty-format": "^27.0.2"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/@testing-library/jest-dom": {
+			"version": "5.16.5",
+			"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz",
+			"integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==",
+			"peer": true,
+			"dependencies": {
+				"@adobe/css-tools": "^4.0.1",
+				"@babel/runtime": "^7.9.2",
+				"@types/testing-library__jest-dom": "^5.9.1",
+				"aria-query": "^5.0.0",
+				"chalk": "^3.0.0",
+				"css.escape": "^1.5.1",
+				"dom-accessibility-api": "^0.5.6",
+				"lodash": "^4.17.15",
+				"redent": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=8",
+				"npm": ">=6",
+				"yarn": ">=1"
+			}
+		},
+		"node_modules/@testing-library/jest-dom/node_modules/chalk": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+			"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+			"peer": true,
+			"dependencies": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/@types/aria-query": {
+			"version": "4.2.2",
+			"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
+			"integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==",
+			"peer": true
+		},
+		"node_modules/@types/chai": {
+			"version": "4.3.4",
+			"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz",
+			"integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==",
+			"peer": true
+		},
+		"node_modules/@types/chai-subset": {
+			"version": "1.3.3",
+			"resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz",
+			"integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==",
+			"peer": true,
+			"dependencies": {
+				"@types/chai": "*"
+			}
+		},
+		"node_modules/@types/istanbul-lib-coverage": {
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+			"integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+			"peer": true
+		},
+		"node_modules/@types/istanbul-lib-report": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+			"integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+			"peer": true,
+			"dependencies": {
+				"@types/istanbul-lib-coverage": "*"
+			}
+		},
+		"node_modules/@types/istanbul-reports": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+			"integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+			"peer": true,
+			"dependencies": {
+				"@types/istanbul-lib-report": "*"
+			}
+		},
+		"node_modules/@types/jest": {
+			"version": "29.2.4",
+			"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.4.tgz",
+			"integrity": "sha512-PipFB04k2qTRPePduVLTRiPzQfvMeLwUN3Z21hsAKaB/W9IIzgB2pizCL466ftJlcyZqnHoC9ZHpxLGl3fS86A==",
+			"peer": true,
+			"dependencies": {
+				"expect": "^29.0.0",
+				"pretty-format": "^29.0.0"
+			}
+		},
+		"node_modules/@types/jest/node_modules/ansi-styles": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+			"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+			"peer": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/@types/jest/node_modules/pretty-format": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+			"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+			"peer": true,
+			"dependencies": {
+				"@jest/schemas": "^29.0.0",
+				"ansi-styles": "^5.0.0",
+				"react-is": "^18.0.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/@types/jest/node_modules/react-is": {
+			"version": "18.2.0",
+			"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+			"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+			"peer": true
+		},
+		"node_modules/@types/node": {
+			"version": "18.11.17",
+			"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz",
+			"integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==",
+			"peer": true
+		},
+		"node_modules/@types/stack-utils": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+			"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+			"peer": true
+		},
+		"node_modules/@types/testing-library__jest-dom": {
+			"version": "5.14.5",
+			"resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz",
+			"integrity": "sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==",
+			"peer": true,
+			"dependencies": {
+				"@types/jest": "*"
+			}
+		},
+		"node_modules/@types/yargs": {
+			"version": "17.0.17",
+			"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz",
+			"integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==",
+			"peer": true,
+			"dependencies": {
+				"@types/yargs-parser": "*"
+			}
+		},
+		"node_modules/@types/yargs-parser": {
+			"version": "21.0.0",
+			"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+			"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+			"peer": true
+		},
+		"node_modules/acorn": {
+			"version": "8.8.1",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+			"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+			"peer": true,
+			"bin": {
+				"acorn": "bin/acorn"
+			},
+			"engines": {
+				"node": ">=0.4.0"
+			}
+		},
+		"node_modules/acorn-walk": {
+			"version": "8.2.0",
+			"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+			"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+			"peer": true,
+			"engines": {
+				"node": ">=0.4.0"
+			}
+		},
+		"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==",
+			"peer": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"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==",
+			"peer": true,
+			"dependencies": {
+				"color-convert": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
 		"node_modules/anymatch": {
-			"version": "3.1.2",
-			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-			"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+			"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
 			"dependencies": {
 				"normalize-path": "^3.0.0",
 				"picomatch": "^2.0.4"
@@ -56,6 +475,36 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/aria-query": {
+			"version": "5.1.3",
+			"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
+			"integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
+			"peer": true,
+			"dependencies": {
+				"deep-equal": "^2.0.5"
+			}
+		},
+		"node_modules/assertion-error": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+			"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+			"peer": true,
+			"engines": {
+				"node": "*"
+			}
+		},
+		"node_modules/available-typed-arrays": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+			"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+			"peer": true,
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/binary-extensions": {
 			"version": "2.2.0",
 			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -75,6 +524,68 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/buffer-from": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+			"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+			"peer": true
+		},
+		"node_modules/call-bind": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+			"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+			"peer": true,
+			"dependencies": {
+				"function-bind": "^1.1.1",
+				"get-intrinsic": "^1.0.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/chai": {
+			"version": "4.3.7",
+			"resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz",
+			"integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==",
+			"peer": true,
+			"dependencies": {
+				"assertion-error": "^1.1.0",
+				"check-error": "^1.0.2",
+				"deep-eql": "^4.1.2",
+				"get-func-name": "^2.0.0",
+				"loupe": "^2.3.1",
+				"pathval": "^1.1.1",
+				"type-detect": "^4.0.5"
+			},
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/chalk": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+			"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+			"peer": 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/check-error": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+			"integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+			"peer": true,
+			"engines": {
+				"node": "*"
+			}
+		},
 		"node_modules/chokidar": {
 			"version": "3.5.3",
 			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -101,48 +612,201 @@
 				"fsevents": "~2.3.2"
 			}
 		},
-		"node_modules/complex.js": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz",
-			"integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==",
+		"node_modules/ci-info": {
+			"version": "3.7.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz",
+			"integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==",
+			"peer": true,
 			"engines": {
-				"node": "*"
+				"node": ">=8"
+			}
+		},
+		"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==",
+			"peer": true,
+			"dependencies": {
+				"color-name": "~1.1.4"
 			},
-			"funding": {
-				"type": "patreon",
-				"url": "https://www.patreon.com/infusion"
+			"engines": {
+				"node": ">=7.0.0"
+			}
+		},
+		"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==",
+			"peer": true
+		},
+		"node_modules/colors": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+			"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+			"engines": {
+				"node": ">=0.1.90"
+			}
+		},
+		"node_modules/cross-env": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+			"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+			"dependencies": {
+				"cross-spawn": "^7.0.1"
+			},
+			"bin": {
+				"cross-env": "src/bin/cross-env.js",
+				"cross-env-shell": "src/bin/cross-env-shell.js"
+			},
+			"engines": {
+				"node": ">=10.14",
+				"npm": ">=6",
+				"yarn": ">=1"
+			}
+		},
+		"node_modules/cross-spawn": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+			"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+			"dependencies": {
+				"path-key": "^3.1.0",
+				"shebang-command": "^2.0.0",
+				"which": "^2.0.1"
+			},
+			"engines": {
+				"node": ">= 8"
 			}
 		},
-		"node_modules/decimal.js": {
-			"version": "10.4.0",
-			"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz",
-			"integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg=="
+		"node_modules/css.escape": {
+			"version": "1.5.1",
+			"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+			"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+			"peer": true
 		},
-		"node_modules/dexie": {
-			"version": "3.2.2",
-			"resolved": "https://registry.npmjs.org/dexie/-/dexie-3.2.2.tgz",
-			"integrity": "sha512-q5dC3HPmir2DERlX+toCBbHQXW5MsyrFqPFcovkH9N2S/UW/H3H5AWAB6iEOExeraAu+j+zRDG+zg/D7YhH0qg==",
+		"node_modules/debug": {
+			"version": "4.3.4",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+			"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+			"dependencies": {
+				"ms": "2.1.2"
+			},
 			"engines": {
 				"node": ">=6.0"
+			},
+			"peerDependenciesMeta": {
+				"supports-color": {
+					"optional": true
+				}
 			}
 		},
-		"node_modules/dexie-export-import": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/dexie-export-import/-/dexie-export-import-1.0.3.tgz",
-			"integrity": "sha512-oun27bUUEaeOfSZ8Cv3Nvj5s0LeANYBYQ7ROpF/3Zg1X/IALUnrX0hk5ZUMlYC3s99kFHimXX57ac5AlOdMzWw==",
-			"peerDependencies": {
-				"dexie": "^3.0.0 || ^2.0.4"
+		"node_modules/deep-eql": {
+			"version": "4.1.3",
+			"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
+			"integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
+			"peer": true,
+			"dependencies": {
+				"type-detect": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=6"
 			}
 		},
-		"node_modules/downloadjs": {
-			"version": "1.4.7",
-			"resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
-			"integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="
+		"node_modules/deep-equal": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz",
+			"integrity": "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"es-get-iterator": "^1.1.2",
+				"get-intrinsic": "^1.1.3",
+				"is-arguments": "^1.1.1",
+				"is-date-object": "^1.0.5",
+				"is-regex": "^1.1.4",
+				"isarray": "^2.0.5",
+				"object-is": "^1.1.5",
+				"object-keys": "^1.1.1",
+				"object.assign": "^4.1.4",
+				"regexp.prototype.flags": "^1.4.3",
+				"side-channel": "^1.0.4",
+				"which-boxed-primitive": "^1.0.2",
+				"which-collection": "^1.0.1",
+				"which-typed-array": "^1.1.8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/deepmerge": {
+			"version": "4.2.2",
+			"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+			"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/define-properties": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+			"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+			"peer": true,
+			"dependencies": {
+				"has-property-descriptors": "^1.0.0",
+				"object-keys": "^1.1.1"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/diff": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+			"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+			"engines": {
+				"node": ">=0.3.1"
+			}
+		},
+		"node_modules/diff-sequences": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+			"integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+			"peer": true,
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/dom-accessibility-api": {
+			"version": "0.5.14",
+			"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz",
+			"integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==",
+			"peer": true
+		},
+		"node_modules/es-get-iterator": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz",
+			"integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"get-intrinsic": "^1.1.0",
+				"has-symbols": "^1.0.1",
+				"is-arguments": "^1.1.0",
+				"is-map": "^2.0.2",
+				"is-set": "^2.0.2",
+				"is-string": "^1.0.5",
+				"isarray": "^2.0.5"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
 		"node_modules/esbuild": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.5.tgz",
-			"integrity": "sha512-VSf6S1QVqvxfIsSKb3UKr3VhUCis7wgDbtF4Vd9z84UJr05/Sp2fRKmzC+CSPG/dNAPPJZ0BTBLTT1Fhd6N9Gg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
+			"integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
 			"hasInstallScript": true,
 			"bin": {
 				"esbuild": "bin/esbuild"
@@ -151,33 +815,34 @@
 				"node": ">=12"
 			},
 			"optionalDependencies": {
-				"@esbuild/linux-loong64": "0.15.5",
-				"esbuild-android-64": "0.15.5",
-				"esbuild-android-arm64": "0.15.5",
-				"esbuild-darwin-64": "0.15.5",
-				"esbuild-darwin-arm64": "0.15.5",
-				"esbuild-freebsd-64": "0.15.5",
-				"esbuild-freebsd-arm64": "0.15.5",
-				"esbuild-linux-32": "0.15.5",
-				"esbuild-linux-64": "0.15.5",
-				"esbuild-linux-arm": "0.15.5",
-				"esbuild-linux-arm64": "0.15.5",
-				"esbuild-linux-mips64le": "0.15.5",
-				"esbuild-linux-ppc64le": "0.15.5",
-				"esbuild-linux-riscv64": "0.15.5",
-				"esbuild-linux-s390x": "0.15.5",
-				"esbuild-netbsd-64": "0.15.5",
-				"esbuild-openbsd-64": "0.15.5",
-				"esbuild-sunos-64": "0.15.5",
-				"esbuild-windows-32": "0.15.5",
-				"esbuild-windows-64": "0.15.5",
-				"esbuild-windows-arm64": "0.15.5"
+				"@esbuild/android-arm": "0.15.18",
+				"@esbuild/linux-loong64": "0.15.18",
+				"esbuild-android-64": "0.15.18",
+				"esbuild-android-arm64": "0.15.18",
+				"esbuild-darwin-64": "0.15.18",
+				"esbuild-darwin-arm64": "0.15.18",
+				"esbuild-freebsd-64": "0.15.18",
+				"esbuild-freebsd-arm64": "0.15.18",
+				"esbuild-linux-32": "0.15.18",
+				"esbuild-linux-64": "0.15.18",
+				"esbuild-linux-arm": "0.15.18",
+				"esbuild-linux-arm64": "0.15.18",
+				"esbuild-linux-mips64le": "0.15.18",
+				"esbuild-linux-ppc64le": "0.15.18",
+				"esbuild-linux-riscv64": "0.15.18",
+				"esbuild-linux-s390x": "0.15.18",
+				"esbuild-netbsd-64": "0.15.18",
+				"esbuild-openbsd-64": "0.15.18",
+				"esbuild-sunos-64": "0.15.18",
+				"esbuild-windows-32": "0.15.18",
+				"esbuild-windows-64": "0.15.18",
+				"esbuild-windows-arm64": "0.15.18"
 			}
 		},
 		"node_modules/esbuild-android-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.5.tgz",
-			"integrity": "sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+			"integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
 			"cpu": [
 				"x64"
 			],
@@ -190,9 +855,9 @@
 			}
 		},
 		"node_modules/esbuild-android-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.5.tgz",
-			"integrity": "sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+			"integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
 			"cpu": [
 				"arm64"
 			],
@@ -205,9 +870,9 @@
 			}
 		},
 		"node_modules/esbuild-darwin-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.5.tgz",
-			"integrity": "sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+			"integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
 			"cpu": [
 				"x64"
 			],
@@ -220,9 +885,9 @@
 			}
 		},
 		"node_modules/esbuild-darwin-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.5.tgz",
-			"integrity": "sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+			"integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
 			"cpu": [
 				"arm64"
 			],
@@ -235,9 +900,9 @@
 			}
 		},
 		"node_modules/esbuild-freebsd-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.5.tgz",
-			"integrity": "sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+			"integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
 			"cpu": [
 				"x64"
 			],
@@ -250,9 +915,9 @@
 			}
 		},
 		"node_modules/esbuild-freebsd-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.5.tgz",
-			"integrity": "sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+			"integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
 			"cpu": [
 				"arm64"
 			],
@@ -265,9 +930,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-32": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.5.tgz",
-			"integrity": "sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+			"integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
 			"cpu": [
 				"ia32"
 			],
@@ -280,9 +945,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.5.tgz",
-			"integrity": "sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+			"integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
 			"cpu": [
 				"x64"
 			],
@@ -295,9 +960,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-arm": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.5.tgz",
-			"integrity": "sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+			"integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
 			"cpu": [
 				"arm"
 			],
@@ -310,9 +975,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.5.tgz",
-			"integrity": "sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+			"integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
 			"cpu": [
 				"arm64"
 			],
@@ -325,9 +990,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-mips64le": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.5.tgz",
-			"integrity": "sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+			"integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
 			"cpu": [
 				"mips64el"
 			],
@@ -340,9 +1005,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-ppc64le": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.5.tgz",
-			"integrity": "sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+			"integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
 			"cpu": [
 				"ppc64"
 			],
@@ -355,9 +1020,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-riscv64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.5.tgz",
-			"integrity": "sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+			"integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
 			"cpu": [
 				"riscv64"
 			],
@@ -370,9 +1035,9 @@
 			}
 		},
 		"node_modules/esbuild-linux-s390x": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.5.tgz",
-			"integrity": "sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+			"integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
 			"cpu": [
 				"s390x"
 			],
@@ -385,9 +1050,9 @@
 			}
 		},
 		"node_modules/esbuild-netbsd-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.5.tgz",
-			"integrity": "sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+			"integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
 			"cpu": [
 				"x64"
 			],
@@ -400,9 +1065,9 @@
 			}
 		},
 		"node_modules/esbuild-openbsd-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.5.tgz",
-			"integrity": "sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+			"integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
 			"cpu": [
 				"x64"
 			],
@@ -415,9 +1080,9 @@
 			}
 		},
 		"node_modules/esbuild-sunos-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.5.tgz",
-			"integrity": "sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+			"integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
 			"cpu": [
 				"x64"
 			],
@@ -430,9 +1095,9 @@
 			}
 		},
 		"node_modules/esbuild-windows-32": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.5.tgz",
-			"integrity": "sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+			"integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
 			"cpu": [
 				"ia32"
 			],
@@ -445,9 +1110,9 @@
 			}
 		},
 		"node_modules/esbuild-windows-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.5.tgz",
-			"integrity": "sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+			"integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
 			"cpu": [
 				"x64"
 			],
@@ -460,9 +1125,9 @@
 			}
 		},
 		"node_modules/esbuild-windows-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.5.tgz",
-			"integrity": "sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+			"integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
 			"cpu": [
 				"arm64"
 			],
@@ -474,12 +1139,59 @@
 				"node": ">=12"
 			}
 		},
-		"node_modules/escape-latex": {
-			"version": "1.2.0",
-			"resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
-			"integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw=="
+		"node_modules/escape-string-regexp": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+			"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+			"peer": true,
+			"engines": {
+				"node": ">=8"
+			}
 		},
-		"node_modules/fill-range": {
+		"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=="
+		},
+		"node_modules/execa": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+			"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+			"dependencies": {
+				"cross-spawn": "^7.0.3",
+				"get-stream": "^6.0.0",
+				"human-signals": "^2.1.0",
+				"is-stream": "^2.0.0",
+				"merge-stream": "^2.0.0",
+				"npm-run-path": "^4.0.1",
+				"onetime": "^5.1.2",
+				"signal-exit": "^3.0.3",
+				"strip-final-newline": "^2.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sindresorhus/execa?sponsor=1"
+			}
+		},
+		"node_modules/expect": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
+			"integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
+			"peer": true,
+			"dependencies": {
+				"@jest/expect-utils": "^29.3.1",
+				"jest-get-type": "^29.2.0",
+				"jest-matcher-utils": "^29.3.1",
+				"jest-message-util": "^29.3.1",
+				"jest-util": "^29.3.1"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/fill-range": {
 			"version": "7.0.1",
 			"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 			"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
@@ -490,16 +1202,28 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/fraction.js": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
-			"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
+		"node_modules/find-up": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+			"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+			"dependencies": {
+				"locate-path": "^6.0.0",
+				"path-exists": "^4.0.0"
+			},
 			"engines": {
-				"node": "*"
+				"node": ">=10"
 			},
 			"funding": {
-				"type": "patreon",
-				"url": "https://www.patreon.com/infusion"
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/for-each": {
+			"version": "0.3.3",
+			"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+			"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+			"peer": true,
+			"dependencies": {
+				"is-callable": "^1.1.3"
 			}
 		},
 		"node_modules/fsevents": {
@@ -515,10 +1239,58 @@
 				"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
 			}
 		},
+		"node_modules/function-bind": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+		},
+		"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==",
+			"peer": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/fzi": {
-			"version": "1.1.0",
-			"resolved": "https://registry.npmjs.org/fzi/-/fzi-1.1.0.tgz",
-			"integrity": "sha512-5bqCChh+i3RQ2Acl+FGg7JnxONXLaWDl4g/JLbRJE+zV5zX0GI0ScpKr/MzgDqzRnhkqy58J6kVy+GfDv2QSFw=="
+			"version": "1.5.0",
+			"resolved": "https://registry.npmjs.org/fzi/-/fzi-1.5.0.tgz",
+			"integrity": "sha512-3544ki2jMWJYY17ob7uD5ijlEvy4FNG2MmwA4BEblmsWs0jCHGUXAVJ8eVZHbG0NvEpPkJBMZvnbF8+bR3Hj/w=="
+		},
+		"node_modules/get-func-name": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+			"integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
+			"peer": true,
+			"engines": {
+				"node": "*"
+			}
+		},
+		"node_modules/get-intrinsic": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+			"integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+			"peer": true,
+			"dependencies": {
+				"function-bind": "^1.1.1",
+				"has": "^1.0.3",
+				"has-symbols": "^1.0.3"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/get-stream": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+			"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
 		},
 		"node_modules/glob-parent": {
 			"version": "5.1.2",
@@ -531,21 +1303,164 @@
 				"node": ">= 6"
 			}
 		},
+		"node_modules/gopd": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+			"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+			"peer": true,
+			"dependencies": {
+				"get-intrinsic": "^1.1.3"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/graceful-fs": {
+			"version": "4.2.10",
+			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+			"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+			"peer": true
+		},
+		"node_modules/has": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+			"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+			"dependencies": {
+				"function-bind": "^1.1.1"
+			},
+			"engines": {
+				"node": ">= 0.4.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==",
+			"peer": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"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==",
+			"peer": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"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==",
+			"peer": true,
+			"dependencies": {
+				"get-intrinsic": "^1.1.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/has-symbols": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+			"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+			"peer": 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==",
+			"peer": true,
+			"dependencies": {
+				"has-symbols": "^1.0.2"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/human-signals": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+			"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+			"engines": {
+				"node": ">=10.17.0"
+			}
+		},
 		"node_modules/imba": {
-			"version": "2.0.0-alpha.220",
-			"resolved": "https://registry.npmjs.org/imba/-/imba-2.0.0-alpha.220.tgz",
-			"integrity": "sha512-Q2Kiqb7kLKfVZ19kje0PWgWR4K+0Nt3RmY2RD13AkhEz2Wksdr3Sj1PGJazy2gW/xC18ILB2MgPplXxzGr3dWQ==",
+			"version": "2.0.0-alpha.225",
+			"resolved": "https://registry.npmjs.org/imba/-/imba-2.0.0-alpha.225.tgz",
+			"integrity": "sha512-npYTEfAYuqlWEHTE1nFruAwTxQOtbVWPimm+V7q24GUFAokrx7d7rnVw6j5PDm2ZSMEIhT/x8vkkXwsjo3fZ5A==",
 			"dependencies": {
+				"@antfu/install-pkg": "^0.1.1",
 				"chokidar": "^3.4.3",
-				"esbuild": "^0.15.2"
+				"colors": "^1.4.0",
+				"esbuild": "^0.15.2",
+				"local-pkg": "^0.4.2",
+				"picocolors": "^1.0.0",
+				"prompts": "^2.4.2"
 			},
 			"bin": {
 				"imba": "bin/imba",
-				"imba-create": "bin/imba-create",
 				"imbac": "bin/imbac"
 			},
 			"engines": {
 				"node": ">=13.10.0"
+			},
+			"peerDependencies": {
+				"@testing-library/dom": "*",
+				"@testing-library/jest-dom": "*",
+				"vite": "*",
+				"vite-node": "*",
+				"vite-plugin-imba": "*",
+				"vitest": "*"
+			}
+		},
+		"node_modules/indent-string": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+			"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+			"peer": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/is-arguments": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+			"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+			"peer": 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-bigint": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+			"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+			"peer": true,
+			"dependencies": {
+				"has-bigints": "^1.0.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
 		"node_modules/is-binary-path": {
@@ -559,10 +1474,64 @@
 				"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==",
+			"peer": 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.2.7",
+			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+			"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+			"peer": true,
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/is-core-module": {
+			"version": "2.11.0",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+			"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+			"dependencies": {
+				"has": "^1.0.3"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/is-date-object": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+			"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+			"peer": true,
+			"dependencies": {
+				"has-tostringtag": "^1.0.0"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"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=",
+			"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
 			"engines": {
 				"node": ">=0.10.0"
 			}
@@ -578,6 +1547,15 @@
 				"node": ">=0.10.0"
 			}
 		},
+		"node_modules/is-map": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
+			"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
+			"peer": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
 		"node_modules/is-number": {
 			"version": "7.0.0",
 			"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -586,344 +1564,2018 @@
 				"node": ">=0.12.0"
 			}
 		},
-		"node_modules/javascript-natural-sort": {
-			"version": "0.7.1",
-			"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
-			"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw=="
-		},
-		"node_modules/lodash": {
-			"version": "4.17.21",
-			"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-			"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
-		},
-		"node_modules/mathjs": {
-			"version": "11.1.0",
-			"resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.1.0.tgz",
-			"integrity": "sha512-cbsEruLNoIlj5h5vOF+DUQVe4EsA/WNomSQDMnX2WafX9TLneBSCRMx2okgGnSLzLoMGWQ211KVzY55bEnQa8Q==",
-			"dependencies": {
-				"@babel/runtime": "^7.18.9",
-				"complex.js": "^2.1.1",
-				"decimal.js": "^10.4.0",
-				"escape-latex": "^1.2.0",
-				"fraction.js": "^4.2.0",
-				"javascript-natural-sort": "^0.7.1",
-				"seedrandom": "^3.0.5",
-				"tiny-emitter": "^2.1.0",
-				"typed-function": "^4.1.0"
-			},
-			"bin": {
-				"mathjs": "bin/cli.js"
+		"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==",
+			"peer": true,
+			"dependencies": {
+				"has-tostringtag": "^1.0.0"
 			},
 			"engines": {
-				"node": ">= 14"
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/nanoid": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz",
-			"integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==",
-			"bin": {
-				"nanoid": "bin/nanoid.js"
+		"node_modules/is-regex": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+			"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || >=18"
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/normalize-path": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-			"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-			"engines": {
-				"node": ">=0.10.0"
+		"node_modules/is-set": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
+			"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+			"peer": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/picomatch": {
-			"version": "2.3.1",
-			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+		"node_modules/is-stream": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+			"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
 			"engines": {
-				"node": ">=8.6"
+				"node": ">=8"
 			},
 			"funding": {
-				"url": "https://github.com/sponsors/jonschlinkert"
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/readdirp": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-			"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+		"node_modules/is-string": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+			"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+			"peer": true,
 			"dependencies": {
-				"picomatch": "^2.2.1"
+				"has-tostringtag": "^1.0.0"
 			},
 			"engines": {
-				"node": ">=8.10.0"
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/regenerator-runtime": {
-			"version": "0.13.9",
-			"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
-			"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
-		},
-		"node_modules/seedrandom": {
-			"version": "3.0.5",
-			"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
-			"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
-		},
-		"node_modules/tiny-emitter": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
-			"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
-		},
-		"node_modules/to-regex-range": {
-			"version": "5.0.1",
-			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-			"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+		"node_modules/is-symbol": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+			"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+			"peer": true,
 			"dependencies": {
-				"is-number": "^7.0.0"
+				"has-symbols": "^1.0.2"
 			},
 			"engines": {
-				"node": ">=8.0"
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/typed-function": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.1.0.tgz",
-			"integrity": "sha512-DGwUl6cioBW5gw2L+6SMupGwH/kZOqivy17E4nsh1JI9fKF87orMmlQx3KISQPmg3sfnOUGlwVkroosvgddrlg==",
+		"node_modules/is-typed-array": {
+			"version": "1.1.10",
+			"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+			"integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+			"peer": true,
+			"dependencies": {
+				"available-typed-arrays": "^1.0.5",
+				"call-bind": "^1.0.2",
+				"for-each": "^0.3.3",
+				"gopd": "^1.0.1",
+				"has-tostringtag": "^1.0.0"
+			},
 			"engines": {
-				"node": ">= 14"
-			}
-		}
-	},
-	"dependencies": {
-		"@babel/runtime": {
-			"version": "7.18.9",
-			"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz",
-			"integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==",
-			"requires": {
-				"regenerator-runtime": "^0.13.4"
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"@esbuild/linux-loong64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.5.tgz",
-			"integrity": "sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==",
-			"optional": true
+		"node_modules/is-weakmap": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
+			"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+			"peer": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
-		"anymatch": {
-			"version": "3.1.2",
-			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-			"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
-			"requires": {
-				"normalize-path": "^3.0.0",
-				"picomatch": "^2.0.4"
+		"node_modules/is-weakset": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
+			"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"get-intrinsic": "^1.1.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"binary-extensions": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-			"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
+		"node_modules/isarray": {
+			"version": "2.0.5",
+			"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+			"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+			"peer": true
 		},
-		"braces": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-			"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-			"requires": {
-				"fill-range": "^7.0.1"
-			}
+		"node_modules/isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
 		},
-		"chokidar": {
-			"version": "3.5.3",
-			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-			"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-			"requires": {
-				"anymatch": "~3.1.2",
-				"braces": "~3.0.2",
-				"fsevents": "~2.3.2",
-				"glob-parent": "~5.1.2",
-				"is-binary-path": "~2.1.0",
-				"is-glob": "~4.0.1",
-				"normalize-path": "~3.0.0",
-				"readdirp": "~3.6.0"
+		"node_modules/jest-diff": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+			"integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+			"peer": true,
+			"dependencies": {
+				"chalk": "^4.0.0",
+				"diff-sequences": "^29.3.1",
+				"jest-get-type": "^29.2.0",
+				"pretty-format": "^29.3.1"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
 			}
 		},
-		"complex.js": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz",
-			"integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg=="
+		"node_modules/jest-diff/node_modules/ansi-styles": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+			"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+			"peer": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
 		},
-		"decimal.js": {
-			"version": "10.4.0",
-			"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.0.tgz",
-			"integrity": "sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg=="
+		"node_modules/jest-diff/node_modules/pretty-format": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+			"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+			"peer": true,
+			"dependencies": {
+				"@jest/schemas": "^29.0.0",
+				"ansi-styles": "^5.0.0",
+				"react-is": "^18.0.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
 		},
-		"dexie": {
-			"version": "3.2.2",
-			"resolved": "https://registry.npmjs.org/dexie/-/dexie-3.2.2.tgz",
-			"integrity": "sha512-q5dC3HPmir2DERlX+toCBbHQXW5MsyrFqPFcovkH9N2S/UW/H3H5AWAB6iEOExeraAu+j+zRDG+zg/D7YhH0qg=="
+		"node_modules/jest-diff/node_modules/react-is": {
+			"version": "18.2.0",
+			"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+			"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+			"peer": true
 		},
-		"dexie-export-import": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/dexie-export-import/-/dexie-export-import-1.0.3.tgz",
-			"integrity": "sha512-oun27bUUEaeOfSZ8Cv3Nvj5s0LeANYBYQ7ROpF/3Zg1X/IALUnrX0hk5ZUMlYC3s99kFHimXX57ac5AlOdMzWw==",
-			"requires": {}
+		"node_modules/jest-get-type": {
+			"version": "29.2.0",
+			"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+			"integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+			"peer": true,
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
 		},
-		"downloadjs": {
-			"version": "1.4.7",
-			"resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz",
-			"integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="
+		"node_modules/jest-matcher-utils": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
+			"integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
+			"peer": true,
+			"dependencies": {
+				"chalk": "^4.0.0",
+				"jest-diff": "^29.3.1",
+				"jest-get-type": "^29.2.0",
+				"pretty-format": "^29.3.1"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
 		},
-		"esbuild": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.5.tgz",
-			"integrity": "sha512-VSf6S1QVqvxfIsSKb3UKr3VhUCis7wgDbtF4Vd9z84UJr05/Sp2fRKmzC+CSPG/dNAPPJZ0BTBLTT1Fhd6N9Gg==",
-			"requires": {
-				"@esbuild/linux-loong64": "0.15.5",
-				"esbuild-android-64": "0.15.5",
-				"esbuild-android-arm64": "0.15.5",
-				"esbuild-darwin-64": "0.15.5",
-				"esbuild-darwin-arm64": "0.15.5",
-				"esbuild-freebsd-64": "0.15.5",
-				"esbuild-freebsd-arm64": "0.15.5",
-				"esbuild-linux-32": "0.15.5",
-				"esbuild-linux-64": "0.15.5",
-				"esbuild-linux-arm": "0.15.5",
-				"esbuild-linux-arm64": "0.15.5",
-				"esbuild-linux-mips64le": "0.15.5",
-				"esbuild-linux-ppc64le": "0.15.5",
-				"esbuild-linux-riscv64": "0.15.5",
-				"esbuild-linux-s390x": "0.15.5",
-				"esbuild-netbsd-64": "0.15.5",
-				"esbuild-openbsd-64": "0.15.5",
-				"esbuild-sunos-64": "0.15.5",
-				"esbuild-windows-32": "0.15.5",
-				"esbuild-windows-64": "0.15.5",
-				"esbuild-windows-arm64": "0.15.5"
+		"node_modules/jest-matcher-utils/node_modules/ansi-styles": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+			"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+			"peer": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
 			}
 		},
-		"esbuild-android-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.5.tgz",
-			"integrity": "sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==",
-			"optional": true
+		"node_modules/jest-matcher-utils/node_modules/pretty-format": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+			"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+			"peer": true,
+			"dependencies": {
+				"@jest/schemas": "^29.0.0",
+				"ansi-styles": "^5.0.0",
+				"react-is": "^18.0.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
 		},
-		"esbuild-android-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.5.tgz",
-			"integrity": "sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==",
-			"optional": true
+		"node_modules/jest-matcher-utils/node_modules/react-is": {
+			"version": "18.2.0",
+			"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+			"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+			"peer": true
 		},
-		"esbuild-darwin-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.5.tgz",
-			"integrity": "sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==",
+		"node_modules/jest-message-util": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
+			"integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
+			"peer": true,
+			"dependencies": {
+				"@babel/code-frame": "^7.12.13",
+				"@jest/types": "^29.3.1",
+				"@types/stack-utils": "^2.0.0",
+				"chalk": "^4.0.0",
+				"graceful-fs": "^4.2.9",
+				"micromatch": "^4.0.4",
+				"pretty-format": "^29.3.1",
+				"slash": "^3.0.0",
+				"stack-utils": "^2.0.3"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/jest-message-util/node_modules/ansi-styles": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+			"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+			"peer": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/jest-message-util/node_modules/pretty-format": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+			"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+			"peer": true,
+			"dependencies": {
+				"@jest/schemas": "^29.0.0",
+				"ansi-styles": "^5.0.0",
+				"react-is": "^18.0.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/jest-message-util/node_modules/react-is": {
+			"version": "18.2.0",
+			"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+			"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+			"peer": true
+		},
+		"node_modules/jest-util": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
+			"integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
+			"peer": true,
+			"dependencies": {
+				"@jest/types": "^29.3.1",
+				"@types/node": "*",
+				"chalk": "^4.0.0",
+				"ci-info": "^3.2.0",
+				"graceful-fs": "^4.2.9",
+				"picomatch": "^2.2.3"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			}
+		},
+		"node_modules/js-tokens": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+			"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+			"peer": true
+		},
+		"node_modules/jsonc-parser": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+			"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+			"peer": true
+		},
+		"node_modules/kleur": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+			"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/local-pkg": {
+			"version": "0.4.2",
+			"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz",
+			"integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==",
+			"engines": {
+				"node": ">=14"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
+		"node_modules/locate-path": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+			"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+			"dependencies": {
+				"p-locate": "^5.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/lodash": {
+			"version": "4.17.21",
+			"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+			"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+		},
+		"node_modules/loupe": {
+			"version": "2.3.6",
+			"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
+			"integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
+			"peer": true,
+			"dependencies": {
+				"get-func-name": "^2.0.0"
+			}
+		},
+		"node_modules/lz-string": {
+			"version": "1.4.4",
+			"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
+			"integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==",
+			"peer": true,
+			"bin": {
+				"lz-string": "bin/bin.js"
+			}
+		},
+		"node_modules/magic-string": {
+			"version": "0.26.7",
+			"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
+			"integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==",
+			"dependencies": {
+				"sourcemap-codec": "^1.4.8"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/math-expression-evaluator": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz",
+			"integrity": "sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw=="
+		},
+		"node_modules/merge-stream": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+			"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+		},
+		"node_modules/micromatch": {
+			"version": "4.0.5",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+			"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+			"peer": true,
+			"dependencies": {
+				"braces": "^3.0.2",
+				"picomatch": "^2.3.1"
+			},
+			"engines": {
+				"node": ">=8.6"
+			}
+		},
+		"node_modules/mimic-fn": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+			"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/min-indent": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+			"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+			"peer": true,
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/mlly": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.0.0.tgz",
+			"integrity": "sha512-QL108Hwt+u9bXdWgOI0dhzZfACovn5Aen4Xvc8Jasd9ouRH4NjnrXEiyP3nVvJo91zPlYjVRckta0Nt2zfoR6g==",
+			"peer": true,
+			"dependencies": {
+				"acorn": "^8.8.1",
+				"pathe": "^1.0.0",
+				"pkg-types": "^1.0.0",
+				"ufo": "^1.0.0"
+			}
+		},
+		"node_modules/mlly/node_modules/pathe": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz",
+			"integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==",
+			"peer": true
+		},
+		"node_modules/ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+		},
+		"node_modules/nanoid": {
+			"version": "3.3.4",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+			"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
+			"bin": {
+				"nanoid": "bin/nanoid.cjs"
+			},
+			"engines": {
+				"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+			}
+		},
+		"node_modules/normalize-path": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+			"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/npm-run-path": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+			"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+			"dependencies": {
+				"path-key": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/object-inspect": {
+			"version": "1.12.2",
+			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+			"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+			"peer": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/object-is": {
+			"version": "1.1.5",
+			"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
+			"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/object-keys": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+			"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+			"peer": true,
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
+		"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==",
+			"peer": 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/onetime": {
+			"version": "5.1.2",
+			"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+			"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+			"dependencies": {
+				"mimic-fn": "^2.1.0"
+			},
+			"engines": {
+				"node": ">=6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/p-limit": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+			"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+			"dependencies": {
+				"yocto-queue": "^0.1.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/p-locate": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+			"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+			"dependencies": {
+				"p-limit": "^3.0.2"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/path-exists": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+			"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/path-key": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+			"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/path-parse": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+		},
+		"node_modules/pathe": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz",
+			"integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==",
+			"peer": true
+		},
+		"node_modules/pathval": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+			"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+			"peer": true,
+			"engines": {
+				"node": "*"
+			}
+		},
+		"node_modules/picocolors": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+			"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+		},
+		"node_modules/picomatch": {
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
+		"node_modules/pkg-types": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.1.tgz",
+			"integrity": "sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==",
+			"peer": true,
+			"dependencies": {
+				"jsonc-parser": "^3.2.0",
+				"mlly": "^1.0.0",
+				"pathe": "^1.0.0"
+			}
+		},
+		"node_modules/pkg-types/node_modules/pathe": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz",
+			"integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==",
+			"peer": true
+		},
+		"node_modules/postcss": {
+			"version": "8.4.20",
+			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz",
+			"integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==",
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/postcss/"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/postcss"
+				}
+			],
+			"dependencies": {
+				"nanoid": "^3.3.4",
+				"picocolors": "^1.0.0",
+				"source-map-js": "^1.0.2"
+			},
+			"engines": {
+				"node": "^10 || ^12 || >=14"
+			}
+		},
+		"node_modules/pretty-format": {
+			"version": "27.5.1",
+			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+			"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+			"peer": true,
+			"dependencies": {
+				"ansi-regex": "^5.0.1",
+				"ansi-styles": "^5.0.0",
+				"react-is": "^17.0.1"
+			},
+			"engines": {
+				"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+			}
+		},
+		"node_modules/pretty-format/node_modules/ansi-styles": {
+			"version": "5.2.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+			"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+			"peer": true,
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/prompts": {
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+			"integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+			"dependencies": {
+				"kleur": "^3.0.3",
+				"sisteransi": "^1.0.5"
+			},
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/react-is": {
+			"version": "17.0.2",
+			"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+			"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+			"peer": true
+		},
+		"node_modules/readdirp": {
+			"version": "3.6.0",
+			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+			"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+			"dependencies": {
+				"picomatch": "^2.2.1"
+			},
+			"engines": {
+				"node": ">=8.10.0"
+			}
+		},
+		"node_modules/redent": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+			"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+			"peer": true,
+			"dependencies": {
+				"indent-string": "^4.0.0",
+				"strip-indent": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/regenerator-runtime": {
+			"version": "0.13.11",
+			"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+			"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+			"peer": true
+		},
+		"node_modules/regexp.prototype.flags": {
+			"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==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3",
+				"functions-have-names": "^1.2.2"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/resolve": {
+			"version": "1.22.1",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+			"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+			"dependencies": {
+				"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/rollup": {
+			"version": "2.79.1",
+			"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
+			"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+			"bin": {
+				"rollup": "dist/bin/rollup"
+			},
+			"engines": {
+				"node": ">=10.0.0"
+			},
+			"optionalDependencies": {
+				"fsevents": "~2.3.2"
+			}
+		},
+		"node_modules/shebang-command": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+			"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+			"dependencies": {
+				"shebang-regex": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/shebang-regex": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+			"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/side-channel": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+			"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+			"peer": true,
+			"dependencies": {
+				"call-bind": "^1.0.0",
+				"get-intrinsic": "^1.0.2",
+				"object-inspect": "^1.9.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/signal-exit": {
+			"version": "3.0.7",
+			"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+			"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+		},
+		"node_modules/sisteransi": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+			"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
+		},
+		"node_modules/slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"peer": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"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==",
+			"peer": true,
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/source-map-js": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+			"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/source-map-support": {
+			"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==",
+			"peer": true,
+			"dependencies": {
+				"buffer-from": "^1.0.0",
+				"source-map": "^0.6.0"
+			}
+		},
+		"node_modules/sourcemap-codec": {
+			"version": "1.4.8",
+			"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+			"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+			"deprecated": "Please use @jridgewell/sourcemap-codec instead"
+		},
+		"node_modules/stack-utils": {
+			"version": "2.0.6",
+			"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+			"integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+			"peer": true,
+			"dependencies": {
+				"escape-string-regexp": "^2.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/strip-final-newline": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+			"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/strip-indent": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+			"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+			"peer": true,
+			"dependencies": {
+				"min-indent": "^1.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/strip-literal": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.0.tgz",
+			"integrity": "sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==",
+			"peer": true,
+			"dependencies": {
+				"acorn": "^8.8.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
+		"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==",
+			"peer": true,
+			"dependencies": {
+				"has-flag": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"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==",
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/tinybench": {
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.1.tgz",
+			"integrity": "sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==",
+			"peer": true
+		},
+		"node_modules/tinypool": {
+			"version": "0.3.0",
+			"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz",
+			"integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==",
+			"peer": true,
+			"engines": {
+				"node": ">=14.0.0"
+			}
+		},
+		"node_modules/tinyspy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz",
+			"integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==",
+			"peer": true,
+			"engines": {
+				"node": ">=14.0.0"
+			}
+		},
+		"node_modules/to-regex-range": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+			"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+			"dependencies": {
+				"is-number": "^7.0.0"
+			},
+			"engines": {
+				"node": ">=8.0"
+			}
+		},
+		"node_modules/type-detect": {
+			"version": "4.0.8",
+			"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+			"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+			"peer": true,
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/ufo": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz",
+			"integrity": "sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==",
+			"peer": true
+		},
+		"node_modules/vite": {
+			"version": "3.2.5",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.5.tgz",
+			"integrity": "sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==",
+			"dependencies": {
+				"esbuild": "^0.15.9",
+				"postcss": "^8.4.18",
+				"resolve": "^1.22.1",
+				"rollup": "^2.79.1"
+			},
+			"bin": {
+				"vite": "bin/vite.js"
+			},
+			"engines": {
+				"node": "^14.18.0 || >=16.0.0"
+			},
+			"optionalDependencies": {
+				"fsevents": "~2.3.2"
+			},
+			"peerDependencies": {
+				"@types/node": ">= 14",
+				"less": "*",
+				"sass": "*",
+				"stylus": "*",
+				"sugarss": "*",
+				"terser": "^5.4.0"
+			},
+			"peerDependenciesMeta": {
+				"@types/node": {
+					"optional": true
+				},
+				"less": {
+					"optional": true
+				},
+				"sass": {
+					"optional": true
+				},
+				"stylus": {
+					"optional": true
+				},
+				"sugarss": {
+					"optional": true
+				},
+				"terser": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/vite-node": {
+			"version": "0.26.1",
+			"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.26.1.tgz",
+			"integrity": "sha512-5FJSKZZJz48zFRKHE55WyevZe61hLMQEsqGn+ungfd60kxEztFybZ3yG9ToGFtOWNCCy7Vn5EVuXD8bdeHOSdw==",
+			"peer": true,
+			"dependencies": {
+				"debug": "^4.3.4",
+				"mlly": "^1.0.0",
+				"pathe": "^0.2.0",
+				"source-map": "^0.6.1",
+				"source-map-support": "^0.5.21",
+				"vite": "^3.0.0 || ^4.0.0"
+			},
+			"bin": {
+				"vite-node": "vite-node.mjs"
+			},
+			"engines": {
+				"node": ">=v14.16.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
+		"node_modules/vite-plugin-imba": {
+			"version": "0.10.1",
+			"resolved": "https://registry.npmjs.org/vite-plugin-imba/-/vite-plugin-imba-0.10.1.tgz",
+			"integrity": "sha512-L4YKjsg5h5PPJRmLFw/68beerBRzCGiSjCqe0Xxh1aavvcAL57ZgT+7Y2kvwG7rcFO1YBdWtJ/tyJEsMK7rEAg==",
+			"dependencies": {
+				"@rollup/pluginutils": "^4.2.1",
+				"cross-env": "^7.0.3",
+				"debug": "^4.3.4",
+				"deepmerge": "^4.2.2",
+				"diff": "^5.1.0",
+				"kleur": "^4.1.5",
+				"magic-string": "^0.26.2"
+			},
+			"engines": {
+				"node": "^14.18.0 || >= 16"
+			},
+			"peerDependencies": {
+				"diff-match-patch": "^1.0.5",
+				"imba": "*",
+				"vite": "^3.0.0"
+			},
+			"peerDependenciesMeta": {
+				"diff-match-patch": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/vite-plugin-imba/node_modules/kleur": {
+			"version": "4.1.5",
+			"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+			"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/vitest": {
+			"version": "0.26.1",
+			"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.26.1.tgz",
+			"integrity": "sha512-qTLRnjYmjmJpHlLUtErxtlRqGCe8WItFhGXKklpWivu7CLP9KXN9iTezROe+vf51Kb+BB/fzxK6fUG9DvFGL5Q==",
+			"peer": true,
+			"dependencies": {
+				"@types/chai": "^4.3.4",
+				"@types/chai-subset": "^1.3.3",
+				"@types/node": "*",
+				"acorn": "^8.8.1",
+				"acorn-walk": "^8.2.0",
+				"chai": "^4.3.7",
+				"debug": "^4.3.4",
+				"local-pkg": "^0.4.2",
+				"source-map": "^0.6.1",
+				"strip-literal": "^1.0.0",
+				"tinybench": "^2.3.1",
+				"tinypool": "^0.3.0",
+				"tinyspy": "^1.0.2",
+				"vite": "^3.0.0 || ^4.0.0",
+				"vite-node": "0.26.1"
+			},
+			"bin": {
+				"vitest": "vitest.mjs"
+			},
+			"engines": {
+				"node": ">=v14.16.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			},
+			"peerDependencies": {
+				"@edge-runtime/vm": "*",
+				"@vitest/browser": "*",
+				"@vitest/ui": "*",
+				"happy-dom": "*",
+				"jsdom": "*"
+			},
+			"peerDependenciesMeta": {
+				"@edge-runtime/vm": {
+					"optional": true
+				},
+				"@vitest/browser": {
+					"optional": true
+				},
+				"@vitest/ui": {
+					"optional": true
+				},
+				"happy-dom": {
+					"optional": true
+				},
+				"jsdom": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/which": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+			"dependencies": {
+				"isexe": "^2.0.0"
+			},
+			"bin": {
+				"node-which": "bin/node-which"
+			},
+			"engines": {
+				"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==",
+			"peer": 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-collection": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
+			"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+			"peer": true,
+			"dependencies": {
+				"is-map": "^2.0.1",
+				"is-set": "^2.0.1",
+				"is-weakmap": "^2.0.1",
+				"is-weakset": "^2.0.1"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/which-typed-array": {
+			"version": "1.1.9",
+			"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+			"integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+			"peer": true,
+			"dependencies": {
+				"available-typed-arrays": "^1.0.5",
+				"call-bind": "^1.0.2",
+				"for-each": "^0.3.3",
+				"gopd": "^1.0.1",
+				"has-tostringtag": "^1.0.0",
+				"is-typed-array": "^1.1.10"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/yocto-queue": {
+			"version": "0.1.0",
+			"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+			"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		}
+	},
+	"dependencies": {
+		"@adobe/css-tools": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.1.tgz",
+			"integrity": "sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==",
+			"peer": true
+		},
+		"@antfu/install-pkg": {
+			"version": "0.1.1",
+			"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.1.1.tgz",
+			"integrity": "sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==",
+			"requires": {
+				"execa": "^5.1.1",
+				"find-up": "^5.0.0"
+			}
+		},
+		"@babel/code-frame": {
+			"version": "7.18.6",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+			"integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+			"peer": true,
+			"requires": {
+				"@babel/highlight": "^7.18.6"
+			}
+		},
+		"@babel/helper-validator-identifier": {
+			"version": "7.19.1",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+			"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+			"peer": true
+		},
+		"@babel/highlight": {
+			"version": "7.18.6",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+			"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+			"peer": true,
+			"requires": {
+				"@babel/helper-validator-identifier": "^7.18.6",
+				"chalk": "^2.0.0",
+				"js-tokens": "^4.0.0"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "3.2.1",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+					"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+					"peer": true,
+					"requires": {
+						"color-convert": "^1.9.0"
+					}
+				},
+				"chalk": {
+					"version": "2.4.2",
+					"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+					"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+					"peer": true,
+					"requires": {
+						"ansi-styles": "^3.2.1",
+						"escape-string-regexp": "^1.0.5",
+						"supports-color": "^5.3.0"
+					}
+				},
+				"color-convert": {
+					"version": "1.9.3",
+					"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+					"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+					"peer": true,
+					"requires": {
+						"color-name": "1.1.3"
+					}
+				},
+				"color-name": {
+					"version": "1.1.3",
+					"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+					"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+					"peer": true
+				},
+				"escape-string-regexp": {
+					"version": "1.0.5",
+					"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+					"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+					"peer": true
+				},
+				"has-flag": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+					"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+					"peer": true
+				},
+				"supports-color": {
+					"version": "5.5.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+					"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+					"peer": true,
+					"requires": {
+						"has-flag": "^3.0.0"
+					}
+				}
+			}
+		},
+		"@babel/runtime": {
+			"version": "7.20.6",
+			"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz",
+			"integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==",
+			"peer": true,
+			"requires": {
+				"regenerator-runtime": "^0.13.11"
+			}
+		},
+		"@esbuild/android-arm": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+			"integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
+			"optional": true
+		},
+		"@esbuild/linux-loong64": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+			"integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
+			"optional": true
+		},
+		"@jest/expect-utils": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
+			"integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
+			"peer": true,
+			"requires": {
+				"jest-get-type": "^29.2.0"
+			}
+		},
+		"@jest/schemas": {
+			"version": "29.0.0",
+			"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
+			"integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
+			"peer": true,
+			"requires": {
+				"@sinclair/typebox": "^0.24.1"
+			}
+		},
+		"@jest/types": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
+			"integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
+			"peer": true,
+			"requires": {
+				"@jest/schemas": "^29.0.0",
+				"@types/istanbul-lib-coverage": "^2.0.0",
+				"@types/istanbul-reports": "^3.0.0",
+				"@types/node": "*",
+				"@types/yargs": "^17.0.8",
+				"chalk": "^4.0.0"
+			}
+		},
+		"@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==",
+			"requires": {
+				"estree-walker": "^2.0.1",
+				"picomatch": "^2.2.2"
+			}
+		},
+		"@sinclair/typebox": {
+			"version": "0.24.51",
+			"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+			"integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+			"peer": true
+		},
+		"@testing-library/dom": {
+			"version": "8.19.0",
+			"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
+			"integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==",
+			"peer": true,
+			"requires": {
+				"@babel/code-frame": "^7.10.4",
+				"@babel/runtime": "^7.12.5",
+				"@types/aria-query": "^4.2.0",
+				"aria-query": "^5.0.0",
+				"chalk": "^4.1.0",
+				"dom-accessibility-api": "^0.5.9",
+				"lz-string": "^1.4.4",
+				"pretty-format": "^27.0.2"
+			}
+		},
+		"@testing-library/jest-dom": {
+			"version": "5.16.5",
+			"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz",
+			"integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==",
+			"peer": true,
+			"requires": {
+				"@adobe/css-tools": "^4.0.1",
+				"@babel/runtime": "^7.9.2",
+				"@types/testing-library__jest-dom": "^5.9.1",
+				"aria-query": "^5.0.0",
+				"chalk": "^3.0.0",
+				"css.escape": "^1.5.1",
+				"dom-accessibility-api": "^0.5.6",
+				"lodash": "^4.17.15",
+				"redent": "^3.0.0"
+			},
+			"dependencies": {
+				"chalk": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+					"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+					"peer": true,
+					"requires": {
+						"ansi-styles": "^4.1.0",
+						"supports-color": "^7.1.0"
+					}
+				}
+			}
+		},
+		"@types/aria-query": {
+			"version": "4.2.2",
+			"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz",
+			"integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==",
+			"peer": true
+		},
+		"@types/chai": {
+			"version": "4.3.4",
+			"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz",
+			"integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==",
+			"peer": true
+		},
+		"@types/chai-subset": {
+			"version": "1.3.3",
+			"resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz",
+			"integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==",
+			"peer": true,
+			"requires": {
+				"@types/chai": "*"
+			}
+		},
+		"@types/istanbul-lib-coverage": {
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+			"integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+			"peer": true
+		},
+		"@types/istanbul-lib-report": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+			"integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+			"peer": true,
+			"requires": {
+				"@types/istanbul-lib-coverage": "*"
+			}
+		},
+		"@types/istanbul-reports": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+			"integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+			"peer": true,
+			"requires": {
+				"@types/istanbul-lib-report": "*"
+			}
+		},
+		"@types/jest": {
+			"version": "29.2.4",
+			"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.4.tgz",
+			"integrity": "sha512-PipFB04k2qTRPePduVLTRiPzQfvMeLwUN3Z21hsAKaB/W9IIzgB2pizCL466ftJlcyZqnHoC9ZHpxLGl3fS86A==",
+			"peer": true,
+			"requires": {
+				"expect": "^29.0.0",
+				"pretty-format": "^29.0.0"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+					"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+					"peer": true
+				},
+				"pretty-format": {
+					"version": "29.3.1",
+					"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+					"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+					"peer": true,
+					"requires": {
+						"@jest/schemas": "^29.0.0",
+						"ansi-styles": "^5.0.0",
+						"react-is": "^18.0.0"
+					}
+				},
+				"react-is": {
+					"version": "18.2.0",
+					"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+					"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+					"peer": true
+				}
+			}
+		},
+		"@types/node": {
+			"version": "18.11.17",
+			"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz",
+			"integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==",
+			"peer": true
+		},
+		"@types/stack-utils": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+			"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+			"peer": true
+		},
+		"@types/testing-library__jest-dom": {
+			"version": "5.14.5",
+			"resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz",
+			"integrity": "sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==",
+			"peer": true,
+			"requires": {
+				"@types/jest": "*"
+			}
+		},
+		"@types/yargs": {
+			"version": "17.0.17",
+			"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz",
+			"integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==",
+			"peer": true,
+			"requires": {
+				"@types/yargs-parser": "*"
+			}
+		},
+		"@types/yargs-parser": {
+			"version": "21.0.0",
+			"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+			"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+			"peer": true
+		},
+		"acorn": {
+			"version": "8.8.1",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+			"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+			"peer": true
+		},
+		"acorn-walk": {
+			"version": "8.2.0",
+			"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+			"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+			"peer": true
+		},
+		"ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"peer": true
+		},
+		"ansi-styles": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+			"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+			"peer": true,
+			"requires": {
+				"color-convert": "^2.0.1"
+			}
+		},
+		"anymatch": {
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+			"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+			"requires": {
+				"normalize-path": "^3.0.0",
+				"picomatch": "^2.0.4"
+			}
+		},
+		"aria-query": {
+			"version": "5.1.3",
+			"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
+			"integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
+			"peer": true,
+			"requires": {
+				"deep-equal": "^2.0.5"
+			}
+		},
+		"assertion-error": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+			"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+			"peer": true
+		},
+		"available-typed-arrays": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+			"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+			"peer": true
+		},
+		"binary-extensions": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+			"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
+		},
+		"braces": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+			"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+			"requires": {
+				"fill-range": "^7.0.1"
+			}
+		},
+		"buffer-from": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+			"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+			"peer": true
+		},
+		"call-bind": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+			"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+			"peer": true,
+			"requires": {
+				"function-bind": "^1.1.1",
+				"get-intrinsic": "^1.0.2"
+			}
+		},
+		"chai": {
+			"version": "4.3.7",
+			"resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz",
+			"integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==",
+			"peer": true,
+			"requires": {
+				"assertion-error": "^1.1.0",
+				"check-error": "^1.0.2",
+				"deep-eql": "^4.1.2",
+				"get-func-name": "^2.0.0",
+				"loupe": "^2.3.1",
+				"pathval": "^1.1.1",
+				"type-detect": "^4.0.5"
+			}
+		},
+		"chalk": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+			"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+			"peer": true,
+			"requires": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			}
+		},
+		"check-error": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+			"integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+			"peer": true
+		},
+		"chokidar": {
+			"version": "3.5.3",
+			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+			"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+			"requires": {
+				"anymatch": "~3.1.2",
+				"braces": "~3.0.2",
+				"fsevents": "~2.3.2",
+				"glob-parent": "~5.1.2",
+				"is-binary-path": "~2.1.0",
+				"is-glob": "~4.0.1",
+				"normalize-path": "~3.0.0",
+				"readdirp": "~3.6.0"
+			}
+		},
+		"ci-info": {
+			"version": "3.7.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz",
+			"integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==",
+			"peer": true
+		},
+		"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==",
+			"peer": 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==",
+			"peer": true
+		},
+		"colors": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+			"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
+		},
+		"cross-env": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+			"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+			"requires": {
+				"cross-spawn": "^7.0.1"
+			}
+		},
+		"cross-spawn": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+			"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+			"requires": {
+				"path-key": "^3.1.0",
+				"shebang-command": "^2.0.0",
+				"which": "^2.0.1"
+			}
+		},
+		"css.escape": {
+			"version": "1.5.1",
+			"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+			"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+			"peer": true
+		},
+		"debug": {
+			"version": "4.3.4",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+			"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+			"requires": {
+				"ms": "2.1.2"
+			}
+		},
+		"deep-eql": {
+			"version": "4.1.3",
+			"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
+			"integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
+			"peer": true,
+			"requires": {
+				"type-detect": "^4.0.0"
+			}
+		},
+		"deep-equal": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz",
+			"integrity": "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"es-get-iterator": "^1.1.2",
+				"get-intrinsic": "^1.1.3",
+				"is-arguments": "^1.1.1",
+				"is-date-object": "^1.0.5",
+				"is-regex": "^1.1.4",
+				"isarray": "^2.0.5",
+				"object-is": "^1.1.5",
+				"object-keys": "^1.1.1",
+				"object.assign": "^4.1.4",
+				"regexp.prototype.flags": "^1.4.3",
+				"side-channel": "^1.0.4",
+				"which-boxed-primitive": "^1.0.2",
+				"which-collection": "^1.0.1",
+				"which-typed-array": "^1.1.8"
+			}
+		},
+		"deepmerge": {
+			"version": "4.2.2",
+			"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+			"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+		},
+		"define-properties": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+			"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+			"peer": true,
+			"requires": {
+				"has-property-descriptors": "^1.0.0",
+				"object-keys": "^1.1.1"
+			}
+		},
+		"diff": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+			"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw=="
+		},
+		"diff-sequences": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+			"integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+			"peer": true
+		},
+		"dom-accessibility-api": {
+			"version": "0.5.14",
+			"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz",
+			"integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==",
+			"peer": true
+		},
+		"es-get-iterator": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz",
+			"integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"get-intrinsic": "^1.1.0",
+				"has-symbols": "^1.0.1",
+				"is-arguments": "^1.1.0",
+				"is-map": "^2.0.2",
+				"is-set": "^2.0.2",
+				"is-string": "^1.0.5",
+				"isarray": "^2.0.5"
+			}
+		},
+		"esbuild": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
+			"integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
+			"requires": {
+				"@esbuild/android-arm": "0.15.18",
+				"@esbuild/linux-loong64": "0.15.18",
+				"esbuild-android-64": "0.15.18",
+				"esbuild-android-arm64": "0.15.18",
+				"esbuild-darwin-64": "0.15.18",
+				"esbuild-darwin-arm64": "0.15.18",
+				"esbuild-freebsd-64": "0.15.18",
+				"esbuild-freebsd-arm64": "0.15.18",
+				"esbuild-linux-32": "0.15.18",
+				"esbuild-linux-64": "0.15.18",
+				"esbuild-linux-arm": "0.15.18",
+				"esbuild-linux-arm64": "0.15.18",
+				"esbuild-linux-mips64le": "0.15.18",
+				"esbuild-linux-ppc64le": "0.15.18",
+				"esbuild-linux-riscv64": "0.15.18",
+				"esbuild-linux-s390x": "0.15.18",
+				"esbuild-netbsd-64": "0.15.18",
+				"esbuild-openbsd-64": "0.15.18",
+				"esbuild-sunos-64": "0.15.18",
+				"esbuild-windows-32": "0.15.18",
+				"esbuild-windows-64": "0.15.18",
+				"esbuild-windows-arm64": "0.15.18"
+			}
+		},
+		"esbuild-android-64": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+			"integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
+			"optional": true
+		},
+		"esbuild-android-arm64": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+			"integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
+			"optional": true
+		},
+		"esbuild-darwin-64": {
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+			"integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
 			"optional": true
 		},
 		"esbuild-darwin-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.5.tgz",
-			"integrity": "sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+			"integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
 			"optional": true
 		},
 		"esbuild-freebsd-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.5.tgz",
-			"integrity": "sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+			"integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
 			"optional": true
 		},
 		"esbuild-freebsd-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.5.tgz",
-			"integrity": "sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+			"integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
 			"optional": true
 		},
 		"esbuild-linux-32": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.5.tgz",
-			"integrity": "sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+			"integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
 			"optional": true
 		},
 		"esbuild-linux-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.5.tgz",
-			"integrity": "sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+			"integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
 			"optional": true
 		},
 		"esbuild-linux-arm": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.5.tgz",
-			"integrity": "sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+			"integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
 			"optional": true
 		},
 		"esbuild-linux-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.5.tgz",
-			"integrity": "sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+			"integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
 			"optional": true
 		},
 		"esbuild-linux-mips64le": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.5.tgz",
-			"integrity": "sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+			"integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
 			"optional": true
 		},
 		"esbuild-linux-ppc64le": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.5.tgz",
-			"integrity": "sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+			"integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
 			"optional": true
 		},
 		"esbuild-linux-riscv64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.5.tgz",
-			"integrity": "sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+			"integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
 			"optional": true
 		},
 		"esbuild-linux-s390x": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.5.tgz",
-			"integrity": "sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+			"integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
 			"optional": true
 		},
 		"esbuild-netbsd-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.5.tgz",
-			"integrity": "sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+			"integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
 			"optional": true
 		},
 		"esbuild-openbsd-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.5.tgz",
-			"integrity": "sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+			"integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
 			"optional": true
 		},
 		"esbuild-sunos-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.5.tgz",
-			"integrity": "sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+			"integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
 			"optional": true
 		},
 		"esbuild-windows-32": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.5.tgz",
-			"integrity": "sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+			"integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
 			"optional": true
 		},
 		"esbuild-windows-64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.5.tgz",
-			"integrity": "sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+			"integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
 			"optional": true
 		},
 		"esbuild-windows-arm64": {
-			"version": "0.15.5",
-			"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.5.tgz",
-			"integrity": "sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==",
+			"version": "0.15.18",
+			"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+			"integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
 			"optional": true
 		},
-		"escape-latex": {
-			"version": "1.2.0",
-			"resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
-			"integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw=="
+		"escape-string-regexp": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+			"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+			"peer": true
+		},
+		"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=="
+		},
+		"execa": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+			"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+			"requires": {
+				"cross-spawn": "^7.0.3",
+				"get-stream": "^6.0.0",
+				"human-signals": "^2.1.0",
+				"is-stream": "^2.0.0",
+				"merge-stream": "^2.0.0",
+				"npm-run-path": "^4.0.1",
+				"onetime": "^5.1.2",
+				"signal-exit": "^3.0.3",
+				"strip-final-newline": "^2.0.0"
+			}
+		},
+		"expect": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
+			"integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
+			"peer": true,
+			"requires": {
+				"@jest/expect-utils": "^29.3.1",
+				"jest-get-type": "^29.2.0",
+				"jest-matcher-utils": "^29.3.1",
+				"jest-message-util": "^29.3.1",
+				"jest-util": "^29.3.1"
+			}
 		},
 		"fill-range": {
 			"version": "7.0.1",
@@ -933,10 +3585,23 @@
 				"to-regex-range": "^5.0.1"
 			}
 		},
-		"fraction.js": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
-			"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA=="
+		"find-up": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+			"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+			"requires": {
+				"locate-path": "^6.0.0",
+				"path-exists": "^4.0.0"
+			}
+		},
+		"for-each": {
+			"version": "0.3.3",
+			"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+			"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+			"peer": true,
+			"requires": {
+				"is-callable": "^1.1.3"
+			}
 		},
 		"fsevents": {
 			"version": "2.3.2",
@@ -944,10 +3609,43 @@
 			"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
 			"optional": true
 		},
+		"function-bind": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+		},
+		"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==",
+			"peer": true
+		},
 		"fzi": {
-			"version": "1.1.0",
-			"resolved": "https://registry.npmjs.org/fzi/-/fzi-1.1.0.tgz",
-			"integrity": "sha512-5bqCChh+i3RQ2Acl+FGg7JnxONXLaWDl4g/JLbRJE+zV5zX0GI0ScpKr/MzgDqzRnhkqy58J6kVy+GfDv2QSFw=="
+			"version": "1.5.0",
+			"resolved": "https://registry.npmjs.org/fzi/-/fzi-1.5.0.tgz",
+			"integrity": "sha512-3544ki2jMWJYY17ob7uD5ijlEvy4FNG2MmwA4BEblmsWs0jCHGUXAVJ8eVZHbG0NvEpPkJBMZvnbF8+bR3Hj/w=="
+		},
+		"get-func-name": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+			"integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
+			"peer": true
+		},
+		"get-intrinsic": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+			"integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+			"peer": true,
+			"requires": {
+				"function-bind": "^1.1.1",
+				"has": "^1.0.3",
+				"has-symbols": "^1.0.3"
+			}
+		},
+		"get-stream": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+			"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
 		},
 		"glob-parent": {
 			"version": "5.1.2",
@@ -957,13 +3655,107 @@
 				"is-glob": "^4.0.1"
 			}
 		},
+		"gopd": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+			"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+			"peer": true,
+			"requires": {
+				"get-intrinsic": "^1.1.3"
+			}
+		},
+		"graceful-fs": {
+			"version": "4.2.10",
+			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+			"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+			"peer": true
+		},
+		"has": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+			"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+			"requires": {
+				"function-bind": "^1.1.1"
+			}
+		},
+		"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==",
+			"peer": 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==",
+			"peer": 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==",
+			"peer": true,
+			"requires": {
+				"get-intrinsic": "^1.1.1"
+			}
+		},
+		"has-symbols": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+			"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+			"peer": true
+		},
+		"has-tostringtag": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+			"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+			"peer": true,
+			"requires": {
+				"has-symbols": "^1.0.2"
+			}
+		},
+		"human-signals": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+			"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
+		},
 		"imba": {
-			"version": "2.0.0-alpha.220",
-			"resolved": "https://registry.npmjs.org/imba/-/imba-2.0.0-alpha.220.tgz",
-			"integrity": "sha512-Q2Kiqb7kLKfVZ19kje0PWgWR4K+0Nt3RmY2RD13AkhEz2Wksdr3Sj1PGJazy2gW/xC18ILB2MgPplXxzGr3dWQ==",
+			"version": "2.0.0-alpha.225",
+			"resolved": "https://registry.npmjs.org/imba/-/imba-2.0.0-alpha.225.tgz",
+			"integrity": "sha512-npYTEfAYuqlWEHTE1nFruAwTxQOtbVWPimm+V7q24GUFAokrx7d7rnVw6j5PDm2ZSMEIhT/x8vkkXwsjo3fZ5A==",
 			"requires": {
+				"@antfu/install-pkg": "^0.1.1",
 				"chokidar": "^3.4.3",
-				"esbuild": "^0.15.2"
+				"colors": "^1.4.0",
+				"esbuild": "^0.15.2",
+				"local-pkg": "^0.4.2",
+				"picocolors": "^1.0.0",
+				"prompts": "^2.4.2"
+			}
+		},
+		"indent-string": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+			"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+			"peer": true
+		},
+		"is-arguments": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+			"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-bigint": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+			"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+			"peer": true,
+			"requires": {
+				"has-bigints": "^1.0.1"
 			}
 		},
 		"is-binary-path": {
@@ -974,10 +3766,43 @@
 				"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==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-callable": {
+			"version": "1.2.7",
+			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+			"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+			"peer": true
+		},
+		"is-core-module": {
+			"version": "2.11.0",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+			"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+			"requires": {
+				"has": "^1.0.3"
+			}
+		},
+		"is-date-object": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+			"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+			"peer": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
 		"is-extglob": {
 			"version": "2.1.1",
 			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-			"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+			"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
 		},
 		"is-glob": {
 			"version": "4.0.3",
@@ -987,52 +3812,531 @@
 				"is-extglob": "^2.1.1"
 			}
 		},
+		"is-map": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
+			"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
+			"peer": true
+		},
 		"is-number": {
 			"version": "7.0.0",
 			"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 			"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
 		},
-		"javascript-natural-sort": {
-			"version": "0.7.1",
-			"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
-			"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw=="
+		"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==",
+			"peer": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-regex": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+			"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-set": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
+			"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+			"peer": true
+		},
+		"is-stream": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+			"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+		},
+		"is-string": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+			"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+			"peer": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-symbol": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+			"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+			"peer": true,
+			"requires": {
+				"has-symbols": "^1.0.2"
+			}
+		},
+		"is-typed-array": {
+			"version": "1.1.10",
+			"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+			"integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+			"peer": true,
+			"requires": {
+				"available-typed-arrays": "^1.0.5",
+				"call-bind": "^1.0.2",
+				"for-each": "^0.3.3",
+				"gopd": "^1.0.1",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-weakmap": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
+			"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+			"peer": true
+		},
+		"is-weakset": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
+			"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"get-intrinsic": "^1.1.1"
+			}
+		},
+		"isarray": {
+			"version": "2.0.5",
+			"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+			"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+			"peer": true
+		},
+		"isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+		},
+		"jest-diff": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+			"integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+			"peer": true,
+			"requires": {
+				"chalk": "^4.0.0",
+				"diff-sequences": "^29.3.1",
+				"jest-get-type": "^29.2.0",
+				"pretty-format": "^29.3.1"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+					"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+					"peer": true
+				},
+				"pretty-format": {
+					"version": "29.3.1",
+					"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+					"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+					"peer": true,
+					"requires": {
+						"@jest/schemas": "^29.0.0",
+						"ansi-styles": "^5.0.0",
+						"react-is": "^18.0.0"
+					}
+				},
+				"react-is": {
+					"version": "18.2.0",
+					"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+					"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+					"peer": true
+				}
+			}
+		},
+		"jest-get-type": {
+			"version": "29.2.0",
+			"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+			"integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+			"peer": true
+		},
+		"jest-matcher-utils": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
+			"integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
+			"peer": true,
+			"requires": {
+				"chalk": "^4.0.0",
+				"jest-diff": "^29.3.1",
+				"jest-get-type": "^29.2.0",
+				"pretty-format": "^29.3.1"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+					"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+					"peer": true
+				},
+				"pretty-format": {
+					"version": "29.3.1",
+					"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+					"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+					"peer": true,
+					"requires": {
+						"@jest/schemas": "^29.0.0",
+						"ansi-styles": "^5.0.0",
+						"react-is": "^18.0.0"
+					}
+				},
+				"react-is": {
+					"version": "18.2.0",
+					"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+					"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+					"peer": true
+				}
+			}
+		},
+		"jest-message-util": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
+			"integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
+			"peer": true,
+			"requires": {
+				"@babel/code-frame": "^7.12.13",
+				"@jest/types": "^29.3.1",
+				"@types/stack-utils": "^2.0.0",
+				"chalk": "^4.0.0",
+				"graceful-fs": "^4.2.9",
+				"micromatch": "^4.0.4",
+				"pretty-format": "^29.3.1",
+				"slash": "^3.0.0",
+				"stack-utils": "^2.0.3"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+					"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+					"peer": true
+				},
+				"pretty-format": {
+					"version": "29.3.1",
+					"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+					"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+					"peer": true,
+					"requires": {
+						"@jest/schemas": "^29.0.0",
+						"ansi-styles": "^5.0.0",
+						"react-is": "^18.0.0"
+					}
+				},
+				"react-is": {
+					"version": "18.2.0",
+					"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+					"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+					"peer": true
+				}
+			}
+		},
+		"jest-util": {
+			"version": "29.3.1",
+			"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
+			"integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
+			"peer": true,
+			"requires": {
+				"@jest/types": "^29.3.1",
+				"@types/node": "*",
+				"chalk": "^4.0.0",
+				"ci-info": "^3.2.0",
+				"graceful-fs": "^4.2.9",
+				"picomatch": "^2.2.3"
+			}
+		},
+		"js-tokens": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+			"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+			"peer": true
+		},
+		"jsonc-parser": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+			"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+			"peer": true
+		},
+		"kleur": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+			"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="
+		},
+		"local-pkg": {
+			"version": "0.4.2",
+			"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.2.tgz",
+			"integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg=="
+		},
+		"locate-path": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+			"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+			"requires": {
+				"p-locate": "^5.0.0"
+			}
 		},
 		"lodash": {
 			"version": "4.17.21",
 			"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
 			"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
 		},
-		"mathjs": {
-			"version": "11.1.0",
-			"resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.1.0.tgz",
-			"integrity": "sha512-cbsEruLNoIlj5h5vOF+DUQVe4EsA/WNomSQDMnX2WafX9TLneBSCRMx2okgGnSLzLoMGWQ211KVzY55bEnQa8Q==",
+		"loupe": {
+			"version": "2.3.6",
+			"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
+			"integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==",
+			"peer": true,
+			"requires": {
+				"get-func-name": "^2.0.0"
+			}
+		},
+		"lz-string": {
+			"version": "1.4.4",
+			"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
+			"integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==",
+			"peer": true
+		},
+		"magic-string": {
+			"version": "0.26.7",
+			"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
+			"integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==",
+			"requires": {
+				"sourcemap-codec": "^1.4.8"
+			}
+		},
+		"math-expression-evaluator": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz",
+			"integrity": "sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw=="
+		},
+		"merge-stream": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+			"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+		},
+		"micromatch": {
+			"version": "4.0.5",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+			"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+			"peer": true,
+			"requires": {
+				"braces": "^3.0.2",
+				"picomatch": "^2.3.1"
+			}
+		},
+		"mimic-fn": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+			"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
+		},
+		"min-indent": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+			"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+			"peer": true
+		},
+		"mlly": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.0.0.tgz",
+			"integrity": "sha512-QL108Hwt+u9bXdWgOI0dhzZfACovn5Aen4Xvc8Jasd9ouRH4NjnrXEiyP3nVvJo91zPlYjVRckta0Nt2zfoR6g==",
+			"peer": true,
 			"requires": {
-				"@babel/runtime": "^7.18.9",
-				"complex.js": "^2.1.1",
-				"decimal.js": "^10.4.0",
-				"escape-latex": "^1.2.0",
-				"fraction.js": "^4.2.0",
-				"javascript-natural-sort": "^0.7.1",
-				"seedrandom": "^3.0.5",
-				"tiny-emitter": "^2.1.0",
-				"typed-function": "^4.1.0"
+				"acorn": "^8.8.1",
+				"pathe": "^1.0.0",
+				"pkg-types": "^1.0.0",
+				"ufo": "^1.0.0"
+			},
+			"dependencies": {
+				"pathe": {
+					"version": "1.0.0",
+					"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz",
+					"integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==",
+					"peer": true
+				}
 			}
 		},
+		"ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+		},
 		"nanoid": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz",
-			"integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg=="
+			"version": "3.3.4",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+			"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
 		},
 		"normalize-path": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
 			"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
 		},
+		"npm-run-path": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+			"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+			"requires": {
+				"path-key": "^3.0.0"
+			}
+		},
+		"object-inspect": {
+			"version": "1.12.2",
+			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+			"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+			"peer": true
+		},
+		"object-is": {
+			"version": "1.1.5",
+			"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
+			"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3"
+			}
+		},
+		"object-keys": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+			"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+			"peer": true
+		},
+		"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==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.4",
+				"has-symbols": "^1.0.3",
+				"object-keys": "^1.1.1"
+			}
+		},
+		"onetime": {
+			"version": "5.1.2",
+			"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+			"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+			"requires": {
+				"mimic-fn": "^2.1.0"
+			}
+		},
+		"p-limit": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+			"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+			"requires": {
+				"yocto-queue": "^0.1.0"
+			}
+		},
+		"p-locate": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+			"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+			"requires": {
+				"p-limit": "^3.0.2"
+			}
+		},
+		"path-exists": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+			"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+		},
+		"path-key": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+			"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
+		},
+		"path-parse": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+		},
+		"pathe": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz",
+			"integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==",
+			"peer": true
+		},
+		"pathval": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+			"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+			"peer": true
+		},
+		"picocolors": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+			"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+		},
 		"picomatch": {
 			"version": "2.3.1",
 			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
 		},
+		"pkg-types": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.1.tgz",
+			"integrity": "sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==",
+			"peer": true,
+			"requires": {
+				"jsonc-parser": "^3.2.0",
+				"mlly": "^1.0.0",
+				"pathe": "^1.0.0"
+			},
+			"dependencies": {
+				"pathe": {
+					"version": "1.0.0",
+					"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.0.0.tgz",
+					"integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==",
+					"peer": true
+				}
+			}
+		},
+		"postcss": {
+			"version": "8.4.20",
+			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz",
+			"integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==",
+			"requires": {
+				"nanoid": "^3.3.4",
+				"picocolors": "^1.0.0",
+				"source-map-js": "^1.0.2"
+			}
+		},
+		"pretty-format": {
+			"version": "27.5.1",
+			"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+			"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+			"peer": true,
+			"requires": {
+				"ansi-regex": "^5.0.1",
+				"ansi-styles": "^5.0.0",
+				"react-is": "^17.0.1"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+					"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+					"peer": true
+				}
+			}
+		},
+		"prompts": {
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+			"integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+			"requires": {
+				"kleur": "^3.0.3",
+				"sisteransi": "^1.0.5"
+			}
+		},
+		"react-is": {
+			"version": "17.0.2",
+			"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+			"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+			"peer": true
+		},
 		"readdirp": {
 			"version": "3.6.0",
 			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -1041,20 +4345,180 @@
 				"picomatch": "^2.2.1"
 			}
 		},
+		"redent": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+			"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+			"peer": true,
+			"requires": {
+				"indent-string": "^4.0.0",
+				"strip-indent": "^3.0.0"
+			}
+		},
 		"regenerator-runtime": {
-			"version": "0.13.9",
-			"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
-			"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+			"version": "0.13.11",
+			"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+			"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+			"peer": true
 		},
-		"seedrandom": {
-			"version": "3.0.5",
-			"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
-			"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
+		"regexp.prototype.flags": {
+			"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==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3",
+				"functions-have-names": "^1.2.2"
+			}
 		},
-		"tiny-emitter": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
-			"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
+		"resolve": {
+			"version": "1.22.1",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+			"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+			"requires": {
+				"is-core-module": "^2.9.0",
+				"path-parse": "^1.0.7",
+				"supports-preserve-symlinks-flag": "^1.0.0"
+			}
+		},
+		"rollup": {
+			"version": "2.79.1",
+			"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
+			"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+			"requires": {
+				"fsevents": "~2.3.2"
+			}
+		},
+		"shebang-command": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+			"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+			"requires": {
+				"shebang-regex": "^3.0.0"
+			}
+		},
+		"shebang-regex": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+			"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
+		},
+		"side-channel": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+			"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+			"peer": true,
+			"requires": {
+				"call-bind": "^1.0.0",
+				"get-intrinsic": "^1.0.2",
+				"object-inspect": "^1.9.0"
+			}
+		},
+		"signal-exit": {
+			"version": "3.0.7",
+			"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+			"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+		},
+		"sisteransi": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+			"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
+		},
+		"slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"peer": true
+		},
+		"source-map": {
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+			"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+			"peer": true
+		},
+		"source-map-js": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+			"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
+		},
+		"source-map-support": {
+			"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==",
+			"peer": true,
+			"requires": {
+				"buffer-from": "^1.0.0",
+				"source-map": "^0.6.0"
+			}
+		},
+		"sourcemap-codec": {
+			"version": "1.4.8",
+			"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+			"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
+		},
+		"stack-utils": {
+			"version": "2.0.6",
+			"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+			"integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+			"peer": true,
+			"requires": {
+				"escape-string-regexp": "^2.0.0"
+			}
+		},
+		"strip-final-newline": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+			"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
+		},
+		"strip-indent": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+			"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+			"peer": true,
+			"requires": {
+				"min-indent": "^1.0.0"
+			}
+		},
+		"strip-literal": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.0.tgz",
+			"integrity": "sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==",
+			"peer": true,
+			"requires": {
+				"acorn": "^8.8.1"
+			}
+		},
+		"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==",
+			"peer": true,
+			"requires": {
+				"has-flag": "^4.0.0"
+			}
+		},
+		"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=="
+		},
+		"tinybench": {
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.3.1.tgz",
+			"integrity": "sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==",
+			"peer": true
+		},
+		"tinypool": {
+			"version": "0.3.0",
+			"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz",
+			"integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==",
+			"peer": true
+		},
+		"tinyspy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-1.0.2.tgz",
+			"integrity": "sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==",
+			"peer": true
 		},
 		"to-regex-range": {
 			"version": "5.0.1",
@@ -1064,10 +4528,139 @@
 				"is-number": "^7.0.0"
 			}
 		},
-		"typed-function": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.1.0.tgz",
-			"integrity": "sha512-DGwUl6cioBW5gw2L+6SMupGwH/kZOqivy17E4nsh1JI9fKF87orMmlQx3KISQPmg3sfnOUGlwVkroosvgddrlg=="
+		"type-detect": {
+			"version": "4.0.8",
+			"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+			"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+			"peer": true
+		},
+		"ufo": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.0.1.tgz",
+			"integrity": "sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==",
+			"peer": true
+		},
+		"vite": {
+			"version": "3.2.5",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.5.tgz",
+			"integrity": "sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==",
+			"requires": {
+				"esbuild": "^0.15.9",
+				"fsevents": "~2.3.2",
+				"postcss": "^8.4.18",
+				"resolve": "^1.22.1",
+				"rollup": "^2.79.1"
+			}
+		},
+		"vite-node": {
+			"version": "0.26.1",
+			"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.26.1.tgz",
+			"integrity": "sha512-5FJSKZZJz48zFRKHE55WyevZe61hLMQEsqGn+ungfd60kxEztFybZ3yG9ToGFtOWNCCy7Vn5EVuXD8bdeHOSdw==",
+			"peer": true,
+			"requires": {
+				"debug": "^4.3.4",
+				"mlly": "^1.0.0",
+				"pathe": "^0.2.0",
+				"source-map": "^0.6.1",
+				"source-map-support": "^0.5.21",
+				"vite": "^3.0.0 || ^4.0.0"
+			}
+		},
+		"vite-plugin-imba": {
+			"version": "0.10.1",
+			"resolved": "https://registry.npmjs.org/vite-plugin-imba/-/vite-plugin-imba-0.10.1.tgz",
+			"integrity": "sha512-L4YKjsg5h5PPJRmLFw/68beerBRzCGiSjCqe0Xxh1aavvcAL57ZgT+7Y2kvwG7rcFO1YBdWtJ/tyJEsMK7rEAg==",
+			"requires": {
+				"@rollup/pluginutils": "^4.2.1",
+				"cross-env": "^7.0.3",
+				"debug": "^4.3.4",
+				"deepmerge": "^4.2.2",
+				"diff": "^5.1.0",
+				"kleur": "^4.1.5",
+				"magic-string": "^0.26.2"
+			},
+			"dependencies": {
+				"kleur": {
+					"version": "4.1.5",
+					"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+					"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="
+				}
+			}
+		},
+		"vitest": {
+			"version": "0.26.1",
+			"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.26.1.tgz",
+			"integrity": "sha512-qTLRnjYmjmJpHlLUtErxtlRqGCe8WItFhGXKklpWivu7CLP9KXN9iTezROe+vf51Kb+BB/fzxK6fUG9DvFGL5Q==",
+			"peer": true,
+			"requires": {
+				"@types/chai": "^4.3.4",
+				"@types/chai-subset": "^1.3.3",
+				"@types/node": "*",
+				"acorn": "^8.8.1",
+				"acorn-walk": "^8.2.0",
+				"chai": "^4.3.7",
+				"debug": "^4.3.4",
+				"local-pkg": "^0.4.2",
+				"source-map": "^0.6.1",
+				"strip-literal": "^1.0.0",
+				"tinybench": "^2.3.1",
+				"tinypool": "^0.3.0",
+				"tinyspy": "^1.0.2",
+				"vite": "^3.0.0 || ^4.0.0",
+				"vite-node": "0.26.1"
+			}
+		},
+		"which": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+			"requires": {
+				"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==",
+			"peer": 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-collection": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
+			"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+			"peer": true,
+			"requires": {
+				"is-map": "^2.0.1",
+				"is-set": "^2.0.1",
+				"is-weakmap": "^2.0.1",
+				"is-weakset": "^2.0.1"
+			}
+		},
+		"which-typed-array": {
+			"version": "1.1.9",
+			"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+			"integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+			"peer": true,
+			"requires": {
+				"available-typed-arrays": "^1.0.5",
+				"call-bind": "^1.0.2",
+				"for-each": "^0.3.3",
+				"gopd": "^1.0.1",
+				"has-tostringtag": "^1.0.0",
+				"is-typed-array": "^1.1.10"
+			}
+		},
+		"yocto-queue": {
+			"version": "0.1.0",
+			"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+			"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
 		}
 	}
 }
diff --git a/package.json b/package.json
index 6a78c33..ed5436b 100644
--- a/package.json
+++ b/package.json
@@ -1,26 +1,19 @@
 {
 	"name": "fuzzyhome",
-	"version": "0.1.43",
+	"version": "0.2.1",
+	"description": "A lightweight new-tab page that lets you very quickly fuzzy find links and navigate to a result.",
+	"homepage": "https://fuzzyho.me/",
+	"author": "Mikey Oz (https://github.com/familyfriendlymikey)",
 	"scripts": {
-		"build": "imba build app/index.html",
-		"publish-preview": "npx gh-pages --no-history --dotfiles --dist dist/ --branch preview",
-		"publish-release": "npx gh-pages --no-history --dotfiles --dist dist/ --branch release",
-		"start": "imba -w app/index.html",
-		"static": "npm run build && cd dist && python3 -m http.server",
-		"preview": "npm run build && npm run publish-preview",
-		"deploy-only-after-preview": "npm run publish-release"
+		"dev": "vite build -w --outDir chrome/dist --minify false",
+		"build": "vite build --outDir chrome/dist"
 	},
 	"dependencies": {
-		"dexie": "^3.2.2",
-		"dexie-export-import": "^1.0.3",
-		"downloadjs": "^1.4.7",
-		"fzi": "^1.1.0",
-		"imba": "^2.0.0-alpha.220",
+		"fzi": "^1.5.0",
+		"imba": "^2.0.0-alpha.225",
 		"lodash": "^4.17.21",
-		"mathjs": "^11.1.0",
-		"nanoid": "^4.0.0"
-	},
-	"description": "A lightweight new-tab page that lets you very quickly fuzzy find links and navigate to a result.",
-	"homepage": "https://fuzzyho.me/",
-	"author": "Mikey Oz (https://github.com/familyfriendlymikey)"
+		"math-expression-evaluator": "^1.4.0",
+		"vite": "^3.2.5",
+		"vite-plugin-imba": "^0.10.1"
+	}
 }
diff --git a/readme.md b/readme.md
index e2dce32..c9ee184 100644
--- a/readme.md
+++ b/readme.md
@@ -1,158 +1,14 @@
-<h1 align="center">
-<a href="https://fuzzyho.me/">
-fuzzyhome
-</a>
-</h1>
+useful modifications:
 
-A power user oriented new-tab page that enables lightning speed navigation through the dark magic of fuzzy finding.
+cmd+option+b for bookmark manager
+cmd+h for home instead of closing tab and opening new tab
 
-## Installation
-1. Copy this link: `https://fuzzyho.me/`:
-1. Change your homepage in your browser settings.
-1. Install a browser extension that lets you change your new-tab page url. These have worked fine for me:
-	- Firefox: [New Tab Override](https://addons.mozilla.org/en-US/firefox/addon/new-tab-override)
-	- Chrome: [New Tab Redirect](https://chrome.google.com/webstore/detail/new-tab-redirect/icpgjfneehieebagbmdbhnlpiopdcmna)
+This is the latest working preview of fuzzyhome which can be
+found at https://preview.fuzzyhome.pages.dev/
 
-	If the extension has an option for setting focus to the webpage instead of the address bar, be sure to enable it.
-
-## Usage
-
-### Create
-Create a new link by typing a name and a url separated by a space.
-For example:
-```
-imba home page https://imba.io/
-```
-The last space-separated string will be used as the url for your link.
-In most cases if you do not specify a protocol, `https` will be used.
-
-You can also use the hotkey `shift+return` to create a new link.
-
-### Fuzzy Find
-Search for a link by typing.
-The fuzzy sorting algorithm makes searching very fast,
-as you can usually just type the first letter of each word to get to a link (`ihp` to get to `imba home page`, for example).
-
-### Navigate
-Navigate to the currently selected search result by pressing `return`.
-You can also click on a link to navigate to it.
-You can also press the up or down arrow keys to move your selection up and down.
-
-### Search
-If there are no matching links, a search will be performed with your query.
-
-### Bangs
-There may be some websites you've created links for, such as amazon, where you almost always search for something.
-This means you have to go to that website, click the search bar, and type in your query.
-With fuzzyhome you can cut out the slow parts by prefixing your link name with `!` to create a "bank link":
-```
-!amazon amazon.com/s?k=
-```
-Notice the `/s?k=` at the end,
-you'll likewise have to find the proper URL for your new bang link.
-Typing instructions for that would be too verbose, so please see the video tutorial (coming soon).
-
-When you click on or press return on a selected bang link,
-instead of navigating directly to that link,
-you'll be able to enter a search query for that link.
-Pressing enter again will bring you to the link with your encoded search query appended to it.
-
-**LIST OF BANGS FOR YOUR CONVENIENCE BELOW**
-
-### Effective Names
-After using fuzzyhome enough, you may come to realize
-that there are some links you'd prefer be "hardcoded"
-with certain names so to speak.
-For example, perhaps you visit `instagram` extremely often
-but also have a link named `indeed` which gets sorted above
-`instagram` when you type `in` even though you visit it much less often.
-You could change the `instagram` link's name to `in`,
-but now it looks bad.
-To solve this, fuzzyhome allows you to add an "effective name"
-to a link:
-```
-instagram `in instagram.com
-```
-To add an effective name to a link,
-simply add the name prefixed with a backtick right before the URL.
-
-This also works for bang links.
-Let's say we wanted `a` to correspond to `!amazon`:
-```
-!amazon `a amazon.com/s?k=
-```
-Now when you type `in` or `a`,
-you can have confidence that your
-intended link will be given priority every time.
-
-Mind you, typing `am` will no longer show `amazon` in the results,
-because that's just the display name for the link.
-The actual name is `a`.
-This might seem confusing but once you
-get the hang of it won't matter to you at all.
-
-### Delete
-You can delete notes by clicking the purple `x` on the currently selected link.
-You can also use the hotkey `shift+backspace` to delete the currently selected link.
-
-### Edit
-You can edit notes by clicking the edit icon.
-
-### Move Selection
-You can move your selection up and down with the arrow keys.
-
-### Quick Search
-If you paste while the input is empty, fuzzyhome will immediately make a search with your pasted query.
-
-### Customize Search Engine
-The default search engine is Google Search, however you can customize it by clicking the three dots to go to settings,
-clicking `config`, and pasting in your search engine url, such as `https://search.brave.com/search?q=`.
-Your search query simply gets encoded and pasted to the end of your configured search engine url.
-
-### Importing / Exporting Links
-If you want to export your links to use them on another computer, go to the settings menu and click `EXPORT`.
-This downloads a `.json` file, which you can then send to your other computer and import by clicking the `IMPORT` button
-and selecting your file.
-
-### Reset Everything To Default
-Not sure why anyone except me would do this, but if for some reason you want to delete everything and restore the default config,
-you can do so by bringing up your developer console and running the function `_fuzzyhome_delete_everything()`,
-and confirming that you do indeed want to delete all your links on the prompt that pops up.
-
-## Hotkeys
-Hotkey | Action
--|-
-Return | Navigate to the currently selected link, or perform a search if there are no matching links.
-Up Arrow | Move selection up.
-Down Arrow | Move selection down.
-Paste | If input is empty, immediately search with pasted query.
-Shift + Return | Create new link.
-Shift + Backspace | Delete currently selected link.
-
-## FAQ
-
-### The Link I Want Is Showing Up Last
-Change the effective name of the link.
-Let's say you've been typing `in` for `instagram`, but recently added `indeed` as a link,
-and `indeed` keeps showing up first.
-Simply change the effective name of the `instagram` link to `in`:
-```
-instagram `in instagram.com
-```
-
-### A Link Is Blocking My Search
-This happens very rarely if at all. Just throw some spaces at the end of your query.
-
-### The Quick Search Function Is Stopping Me From Finishing My Query
-Just type a single space before you paste in text.
-
-### My Localhost Link Isn't Working
-If you want to make a link that points to `localhost`, you likely need to specify the `http` protocol when creating your link.
-
-## Bang List
-Website | Bang Text
--|-
-youtube | !youtube ~y https://www.youtube.com/results?search_query=
-amazon | !amazon amazon.com/s?k=
-google site:reddit.com | !google reddit https://www.google.com/search?q=site%3Areddit.com%20
-google site:reddit.com | !google stackoverflow https://www.google.com/search?q=site%3Astackoverflow.com%20
+I have big plans for fuzzyhome but don't have time to act on them
+right now. As things stand it works really well and is a huge
+productivity booster if you use it properly. I haven't
+experienced any runtime errors using it dozens or hundreds of
+times a day for months now, so it seems to be pretty stable.
+Export your links just in case :)
diff --git a/scripts/api_move.sh b/scripts/api_move.sh
deleted file mode 100755
index 9ab5f40..0000000
--- a/scripts/api_move.sh
+++ /dev/null
@@ -1 +0,0 @@
-printf "\033c" && rg --pcre2 -g '!api.imba' '(?<!api.)'"$1"
diff --git a/scripts/config_move.sh b/scripts/config_move.sh
deleted file mode 100755
index b2356b3..0000000
--- a/scripts/config_move.sh
+++ /dev/null
@@ -1 +0,0 @@
-printf "\033c" && rg --pcre2 -g '!config.imba' 'config\.(?!data.)'"$1"
diff --git a/src/api.imba b/src/api.imba
new file mode 100644
index 0000000..e250070
--- /dev/null
+++ b/src/api.imba
@@ -0,0 +1,137 @@
+import state from './state.imba'
+
+import config from './config.imba'
+import { find, omit, orderBy } from 'lodash'
+import fzi from 'fzi'
+import { cloneDeep } from 'lodash'
+import mexp from 'math-expression-evaluator'
+
+export default new class api
+
+	def pin_link link
+		Pins[link.url] ^= 1
+		sort_links!
+		global.chrome.storage.sync.set {pins:Pins}
+		imba.commit!
+
+	def increment_link_frequency link
+		Frequencies[link.url] ??= 0
+		Frequencies[link.url] += 1
+		global.chrome.storage.sync.set {frequencies:Frequencies}
+
+	def get-link-from-node node
+			return unless let url = node..url
+			let split_text = node.title.split	/\s+/
+			let alias
+			let last = split_text[-1]
+			if last.startsWith("(")	and	last.endsWith(")")
+				alias = split_text.pop!.slice(1,-1)
+			let name = split_text.join(" ")
+			let is_bang = no
+			if name.startsWith "!"
+				is_bang = yes
+				name = name.slice(1)
+			{ name, alias, is_bang, url }
+
+	def traverse stack
+		const links = []
+		while stack.length > 0
+				const node = stack.pop!
+				const link = get-link-from-node(node)
+				links.push(link) if link
+				node..children..forEach do stack.push $1
+		links
+
+	def bfs title, queue
+		while queue.length > 0
+			const node = queue.shift!
+			return node.children if node.title.toLowerCase! is title.toLowerCase!
+			if node.children
+				queue = queue.concat(node.children)
+
+	def sort_links
+		if state.query.trim!.length <= 0
+			const pinned = do Pins[$1.url] or no
+			const freq = do Frequencies[$1.url] or 0
+			state.sorted_links = orderBy(state.links, [pinned, freq], ['desc', 'desc'])
+		else
+			state.sorted_links = fzi.search state.query, state.links, (do $1.name), (do $1.alias)
+
+	def parse_url url
+		throw "invalid url" if url === null
+		let get_url = do |s|
+			let url = new URL s
+			throw _ unless (url.host and url.href)
+			url
+		try
+			return get_url url
+		try
+			return get_url "https://{url}"
+		throw "invalid url"
+
+	def get_pretty_date
+		Date!.toString!.split(" ").slice(0, 4).join(" ")
+
+	get selected_link
+		state.sorted_links[state.link_selection_index]
+
+	def set_link_selection_index index
+		state.link_selection_index = index
+
+	def increment_link_selection_index
+		set_link_selection_index Math.min(state.sorted_links.length - 1, state.link_selection_index + 1)
+
+	def decrement_link_selection_index
+		set_link_selection_index Math.max(0, state.link_selection_index - 1)
+
+	def navigate link
+		await increment_link_frequency link
+		window.location.href = link.url
+
+	get math_result
+		try
+			mexp.eval(state.query)
+		catch
+			no
+
+	def handle_cut e
+		return unless e.target.selectionStart == e.target.selectionEnd
+		let s = math_result
+		s ||= state.query
+		await window.navigator.clipboard.writeText(s)
+		state.query = ''
+		sort_links!
+
+	def handle_click_link
+		let link = selected_link
+		if link.is_bang
+			state.query = ''
+			state.active_bang = link
+		else
+			navigate link
+
+	get bang
+		state.active_bang or config.data.default_bang
+
+	get encoded_bang_query
+		"{bang.url}{window.encodeURIComponent(state.query)}"
+
+	get encoded_bang_query_nourl
+		"{window.encodeURIComponent(state.query)}"
+
+	def handle_bang
+		return if state.loading
+		await increment_link_frequency bang
+		window.location.href = encoded_bang_query
+
+	def unset_active_bang
+		state.active_bang = no
+		sort_links!
+
+	def get-icon url
+		let { host } = parse_url url
+		"https://icon.horse/icon/{host}"
+
+	def help
+		let url = "https://github.com/familyfriendlymikey/fuzzyhome"
+		window.open url,'_blank'
diff --git a/app/assets/chevron-down.svg b/src/assets/chevron-down.svg
similarity index 100%
rename from app/assets/chevron-down.svg
rename to src/assets/chevron-down.svg
diff --git a/app/assets/chevron-up.svg b/src/assets/chevron-up.svg
similarity index 100%
rename from app/assets/chevron-up.svg
rename to src/assets/chevron-up.svg
diff --git a/app/assets/edit-2.svg b/src/assets/edit-2.svg
similarity index 100%
rename from app/assets/edit-2.svg
rename to src/assets/edit-2.svg
diff --git a/app/assets/eye.svg b/src/assets/help-circle.svg
similarity index 52%
rename from app/assets/eye.svg
rename to src/assets/help-circle.svg
index 9cde243..51fddd8 100644
--- a/app/assets/eye.svg
+++ b/src/assets/help-circle.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
\ No newline at end of file
diff --git a/app/assets/search.svg b/src/assets/search.svg
similarity index 100%
rename from app/assets/search.svg
rename to src/assets/search.svg
diff --git a/app/assets/settings.svg b/src/assets/settings.svg
similarity index 100%
rename from app/assets/settings.svg
rename to src/assets/settings.svg
diff --git a/app/assets/star.svg b/src/assets/star.svg
similarity index 100%
rename from app/assets/star.svg
rename to src/assets/star.svg
diff --git a/app/assets/trash.svg b/src/assets/trash.svg
similarity index 100%
rename from app/assets/trash.svg
rename to src/assets/trash.svg
diff --git a/app/assets/x-square.svg b/src/assets/x-square.svg
similarity index 100%
rename from app/assets/x-square.svg
rename to src/assets/x-square.svg
diff --git a/app/assets/x.svg b/src/assets/x.svg
similarity index 100%
rename from app/assets/x.svg
rename to src/assets/x.svg
diff --git a/src/components/app-bang.imba b/src/components/app-bang.imba
new file mode 100644
index 0000000..4c2e1c2
--- /dev/null
+++ b/src/components/app-bang.imba
@@ -0,0 +1,63 @@
+tag app-bang
+
+	get tips
+		let result = []
+		let temp
+
+		temp = {
+				click_handler: api.handle_bang.bind(api)
+				hotkey_handler: api.handle_bang.bind(api)
+				hotkey: 'return'
+				hotkey_display_name: "Return"
+				content: "Search"
+		}
+		result.push temp
+
+		temp = {
+				click_handler: api.handle_cut.bind(api)
+		}
+		if api.math_result
+			temp.hotkey_display_name = "Cut Math"
+			temp.content = "Cut Math Result"
+		else
+			temp.hotkey_display_name = "Cut"
+			temp.content = "Cut All Text"
+		result.push temp
+
+		if state.active_bang
+			temp = {
+					click_handler: api.unset_active_bang.bind(api)
+					hotkey_handler: api.unset_active_bang.bind(api)
+					hotkey: 'esc'
+					hotkey_display_name: "Esc"
+					content: "Back"
+			}
+			result.push temp
+
+		result
+
+	<self>
+		css w:100% d:flex fld:column gap:15px ofy:hidden
+
+		<app-tips$tips tips=tips>
+
+		unless $tips.show_more
+
+			<.bang .selected [c:$bang-c] @click=api.handle_bang>
+				css d:flex fld:row jc:space-between ai:center
+					px:16px py:11px rd:5px c:$text-c
+
+				<.link-left>
+					css d:flex fl:1 ofy:hidden
+
+					<img.link-icon src=api.get-icon(api.bang.url)>
+						css w:20px h:20px mr:10px rd:3px
+
+					<.display-name> "...{api.encoded_bang_query_nourl}"
+						css fs:20px of:hidden text-overflow:ellipsis
+
+				<.link-right>
+					css d:flex fld:row jc:space-between ai:center
+
+					<.frequency> api.bang.frequency
+						css fs:15px ml:7px
diff --git a/src/components/app-home.imba b/src/components/app-home.imba
new file mode 100644
index 0000000..d1151ce
--- /dev/null
+++ b/src/components/app-home.imba
@@ -0,0 +1,77 @@
+tag app-home
+
+	def mount
+		$home-input.focus!
+
+	def blur
+		setTimeout(&, 100) do $home-input.focus!
+
+	def handle_click_copy s
+		try
+			await window.navigator.clipboard.writeText(s)
+			state.query = ''
+			api.sort_links!
+
+	def handle_input
+		api.set_link_selection_index 0
+		api.sort_links!
+
+	<self>
+		css w:100% d:flex fld:column ofy:hidden gap:20px
+
+		<.header>
+			css
+				d:hflex
+
+				.side
+					c:$button-c fs:15px d:box e:300ms
+
+					>
+						w:15px d:flex
+
+				.left
+					pr:15px
+					jc:left
+
+				.right
+					pl:15px
+					jc:right
+
+			<.side.left @click=(state.view = 'settings')>
+				<svg src="../assets/settings.svg">
+
+			<input$home-input
+				autofocus
+				bind=state.query
+				@input=handle_input
+				@cut=api.handle_cut
+				disabled=state.loading
+				@blur=blur
+			>
+				css h:50px px:20px fl:1
+					fs:20px ta:center
+					bd:1px solid $input-bc
+					outline:none rd:5px
+					bg:$input-bg c:$text-c
+					caret-color:$input-caret-c
+
+			<.side.right@click=handle_click_copy(api.math_result or 0)>
+				<$math>
+					css d:box fs:17px min-width:min-content
+					"{Math.round(api.math_result * 100)/100}"
+
+				css e:200ms eaf:circ-out
+					max-width:{$math.offsetWidth or 30}px
+					min-width:{$math.offsetWidth}px
+
+		if state.loaded
+			<div ease>
+				css e:400ms of:hidden
+					@off o:0
+
+				if state.active_bang or state.sorted_links.length < 1
+					<app-bang>
+
+				else
+					<app-links>
+
diff --git a/src/components/app-link.imba b/src/components/app-link.imba
new file mode 100644
index 0000000..307cf9c
--- /dev/null
+++ b/src/components/app-link.imba
@@ -0,0 +1,55 @@
+tag app-link
+
+	frequency = 0
+
+	<self
+		@pointerover=api.set_link_selection_index(index)
+		@click=api.handle_click_link
+		.selected=(index is state.link_selection_index)
+	>
+		css d:flex fld:row jc:space-between ai:center
+			px:16px py:11px rd:5px c:$text-c
+		if link.is_bang
+			css c:$bang-c
+
+		<.link-left>
+			css d:flex w:100%
+
+			<img.link-icon src=api.get-icon(link.url)>
+
+				css w:20px h:20px mr:10px rd:3px
+
+			<.name> link.name
+				css tt:capitalize fs:20px overflow-wrap:anywhere
+
+			if link.alias
+				<.name>
+					css d:flex ja:center c:$effective-name-c ml:10px fs:14px
+					css .parens fs:10px c:$effective-name-parens-c
+
+					<span.parens> "("
+					<span> link.alias
+					<span.parens> ")"
+
+		<.link-right>
+			css d:hflex jc:space-between w:70px ai:center
+
+			css .selected .link-button visibility:visible
+
+			<.link-buttons>
+				css d:flex fld:row jc:start ai:center gap:5px
+
+				css .link-button visibility:hidden rd:3px c:$button-c fs:15px px:3px
+				if index is state.link_selection_index
+					css .link-button visibility:visible
+
+				css .link-button svg w:15px
+
+				<.link-button @click.prevent.stop=api.pin_link(link)>
+					if Pins[link.url]
+						css visibility:visible c:$button-dim-c
+
+					<svg src='../assets/star.svg'>
+
+			<.frequency> Frequencies[link.url] or 0
+				css fs:15px ml:7px
diff --git a/src/components/app-links.imba b/src/components/app-links.imba
new file mode 100644
index 0000000..7b80d60
--- /dev/null
+++ b/src/components/app-links.imba
@@ -0,0 +1,55 @@
+tag app-links
+
+	get tips
+		let result = []
+		let temp
+
+		temp = {
+			click_handler: api.handle_click_link.bind(api)
+			hotkey_handler: api.handle_click_link.bind(api)
+			hotkey: 'return'
+			hotkey_display_name: 'Return'
+		}
+		temp.content = api.selected_link.is_bang ? "Use Bang" : "Navigate To Link"
+		result.push temp
+
+		temp = {
+				click_handler: api.handle_cut.bind(api)
+		}
+		if api.math_result
+			temp.hotkey_display_name = "Cut Math"
+			temp.content = "Cut Math Result"
+		else
+			temp.hotkey_display_name = "Cut"
+			temp.content = "Cut All Text"
+		result.push temp
+
+		temp = {
+				click_handler: api.increment_link_selection_index.bind(api)
+				hotkey_handler: api.increment_link_selection_index.bind(api)
+				hotkey: 'down'
+				hotkey_display_name: "Down Arrow"
+				content: "Move Selection Down"
+		}
+		result.push temp
+
+		temp = {
+				click_handler: api.decrement_link_selection_index.bind(api)
+				hotkey_handler: api.decrement_link_selection_index.bind(api)
+				hotkey: 'up'
+				hotkey_display_name: "Up Arrow"
+				content: "Move Selection Up"
+		}
+		result.push temp
+
+		result
+
+	<self>
+		css w:100% d:flex fld:column gap:15px ofy:hidden max-height:100%
+
+		<app-tips$tips tips=tips>
+
+		<.links>
+			css ofy:auto
+			for link, index in state.sorted_links
+				<app-link link=link index=index>
diff --git a/src/components/app-settings.imba b/src/components/app-settings.imba
new file mode 100644
index 0000000..98e2b1e
--- /dev/null
+++ b/src/components/app-settings.imba
@@ -0,0 +1,53 @@
+tag app-settings
+
+	<self>
+		css w:100%
+
+		css .settings-container
+			d:flex fld:row jc:space-around ai:center
+			w:100% h:50px
+			mt:10px
+			gap:10px
+
+		css .settings-button
+			bg:none bd:none fs:14px d:box fl:1
+			rd:5px tt:uppercase
+			transition:background 100ms
+			h:100% px:5px
+			of:hidden text-overflow:ellipsis white-space:nowrap
+			bg:$button-bg c:$button-c
+			@hover bg:$button-hover-bg
+
+		<.settings-container>
+
+			<.settings-button
+				@click=(state.view = 'home')
+				@hotkey("esc")
+			> "BACK"
+
+		<.settings-container>
+
+			<.settings-button @click=api.help>
+				"HELP"
+
+			<.settings-button @click=config.cycle_theme>
+				"THEME: {config.data.theme.toUpperCase!}"
+
+		if config.data.theme is 'timed'
+
+			<.settings-container>
+
+				<.settings-button@click=config.set_timed_theme_start>
+					"light theme start: {config.data.timed_theme_start}"
+
+				<.settings-button@click=config.set_timed_theme_end>
+					"light theme end: {config.data.timed_theme_end}"
+
+		<.settings-container>
+
+			<.settings-button @click=config.toggle_focus>
+				"FOCUS ON OPEN: {config.data.focus}"
+
+			<.settings-button @click=config.set_default_bang>
+				"change default bang"
+
diff --git a/src/components/app-tips.imba b/src/components/app-tips.imba
new file mode 100644
index 0000000..07fe274
--- /dev/null
+++ b/src/components/app-tips.imba
@@ -0,0 +1,85 @@
+import { chunk, fill } from 'lodash'
+
+tag app-tip
+
+	<self
+		@click.if(tip.click_handler)=tip.click_handler
+	>
+		css d:flex fld:column jc:start fl:1
+			bdr:1px solid
+			bc:$tip-bc
+			min-width:0 ta:center p:10px
+			transition:background 100ms
+			@first ta:left rdl:3px
+			@last ta:right bd:none rdr:3px
+			@hover bg:$tip-hover-c
+		if tip.placeholder or not tip.click_handler
+			css
+				@hover @important bg:none
+
+		if tip.hotkey_handler and tip.hotkey
+			<@hotkey(tip.hotkey).force=tip.hotkey_handler>
+				css d:none
+
+		<.tip-hotkey> tip.hotkey_display_name
+			css fs:12px c:$tip-hotkey-c
+
+		<.tip-content> tip.content
+			css pt:2px fs:14px c:$tip-content-c
+
+tag app-tips
+
+	@observable tips
+
+	def unmount
+		show_more = no
+
+	def toggle
+		show_more = not show_more
+
+	def pad arr
+		let i = arr.length
+		while i < 3
+			arr.push { placeholder: yes }
+			i += 1
+
+	@computed get chunks
+		let chunks = chunk(tips, 3)
+		pad(chunks[-1])
+		chunks
+
+	<self>
+		css d:flex fld:column gap:15px max-height:75%
+
+		css .tip-row
+			d:flex fld:row w:100% fl:1
+			fs:20px fs:14px
+			jc:end ta:center
+
+		<.tip-row>
+			for tip in chunks[0]
+				<app-tip tip=tip>
+
+		if chunks.length > 1
+
+			<@click=toggle>
+				css w:100% d:flex ja:center c:$button-c rdb:4px
+					transition:background 100ms
+					@hover bg:$tip-hover-c
+				if show_more
+					css rd:0
+
+				<svg src="../assets/chevron-down.svg">
+					css w:15px transition:transform 150ms
+					if show_more
+						css transform:rotate(180deg)
+
+			# hotkeys depend on the presence of tips in the dom so
+			# can't ease this as is
+			<.more [d:none]=!show_more>
+				css d:flex fld:column gap:15px ofy:auto e:300ms
+
+				for row in chunks.slice(1)
+					<.tip-row>
+						for tip in row
+							<app-tip tip=tip>
diff --git a/src/config.imba b/src/config.imba
new file mode 100644
index 0000000..18f2bb2
--- /dev/null
+++ b/src/config.imba
@@ -0,0 +1,71 @@
+export default new class config
+
+	def save
+		global.localStorage.fuzzyhome_config = JSON.stringify(data)
+
+	def constructor
+		data = {}
+
+		try
+			data = JSON.parse(global.localStorage.fuzzyhome_config)
+
+		data.focus ??= yes
+
+		data.theme ??= "timed"
+
+		data.timed_theme_start ??= 8
+		data.timed_theme_end ??= 18
+
+		data.default_bang ??= {}
+		data.default_bang.name ??= ""
+		data.default_bang.url ??= "https://www.google.com/search?q="
+		data.default_bang.frequency ??= 0
+		data.default_bang.is_bang ??= yes
+		save!
+
+	def cycle_theme
+		if data.theme is "dark"
+			data.theme = "light"
+		elif data.theme is "light"
+			data.theme = "timed"
+		else
+			data.theme = "dark"
+		save!
+
+	def set_default_bang
+		let res = window.prompt('Insert a new search URL. For example:\nhttps://search.brave.com/search?q=')..trim!
+		return unless res
+		data.default_bang.url = res
+		save!
+
+	def toggle_focus
+		data.focus = !data.focus
+		save!
+
+	def set_timed_theme_end
+		let res = parseInt(window.prompt!)
+		return unless res
+		return unless res > 0
+		return unless res < 24
+		data.timed_theme_end = res
+		save!
+
+	def set_timed_theme_start
+		let res = parseInt(window.prompt!)
+		return unless res
+		return unless res > 0
+		return unless res < 24
+		data.timed_theme_start = res
+		save!
+
+	get theme
+		if data.theme is "light"
+			"light"
+		elif data.theme is "timed"
+			let hour = new Date!.getHours!
+			if hour > data.timed_theme_end or hour < data.timed_theme_start
+				"dark"
+			else
+				"light"
+		else
+			"dark"
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..8c406aa
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1 @@
+import "./main.imba"
diff --git a/src/main.imba b/src/main.imba
new file mode 100644
index 0000000..19b9e58
--- /dev/null
+++ b/src/main.imba
@@ -0,0 +1,76 @@
+global.L = console.log
+
+import pkg from '../package.json'
+let version = pkg.version
+L "fuzzyhome version {version}"
+
+import state from './state.imba'
+import api from './api.imba'
+import config from './config.imba'
+
+import './components/app-home.imba'
+import './components/app-settings.imba'
+import './components/app-links.imba'
+import './components/app-link.imba'
+import './components/app-bang.imba'
+import './components/app-tips.imba'
+import './styles.imba'
+
+extend tag element
+	get state
+		state
+	get api
+		api
+	get config
+		config
+
+if config.data.focus and location.search =? "?x"
+	throw new Error
+
+global.Pins = {}
+global.Frequencies = {}
+
+def init
+	let { pins } = await global.chrome.storage.sync.get 'pins'
+	Pins = pins or {}
+
+	let { frequencies } = await global.chrome.storage.sync.get 'frequencies'
+	Frequencies = frequencies or {}
+
+	global.chrome.bookmarks.getTree! do(bookmarks)
+		const folder = api.bfs 'Bookmarks Bar', bookmarks
+		state.links = api.traverse folder
+		api.sort_links!
+		state.loaded = yes
+		imba.commit!
+
+init!
+
+tag app
+
+	<self
+		.light=(config.theme is "light")
+		.dark=(config.theme is "dark")
+		.disabled=state.loading
+		ease
+	>
+		css d:flex fld:column jc:start ai:center
+			m:0 w:100% h:100% bg:$bodybg
+			ff:sans-serif fw:1
+			us:none
+			e:100ms
+			@off o:0
+
+		<.main>
+			css d:flex fld:column jc:start ai:center
+				bg:$appbg
+				w:80vw max-width:700px max-height:80vh
+				bxs:0px 0px 10px rgba(0,0,0,0.35)
+				box-sizing:border-box p:30px rd:10px mt:10vh
+
+			if state.view is 'settings'
+				<app-settings>
+			else
+				<app-home>
+
+imba.mount <app>
diff --git a/app/state.imba b/src/state.imba
similarity index 81%
rename from app/state.imba
rename to src/state.imba
index 1e78b96..59d4fd6 100644
--- a/app/state.imba
+++ b/src/state.imba
@@ -1,9 +1,10 @@
 export default {
+	view: 'home'
 	query: ''
 	links: []
 	sorted_links: []
 	loading: no
 	link_selection_index: 0
 	active_bang: no
-	bang_selection_index: -1
+	loaded:no
 }
diff --git a/app/styles.imba b/src/styles.imba
similarity index 82%
rename from app/styles.imba
rename to src/styles.imba
index f2a5c2b..ab78ac3 100644
--- a/app/styles.imba
+++ b/src/styles.imba
@@ -1,3 +1,12 @@
+global css html
+	$effective-name-c:gray4
+	$effective-name-parens-c:gray4/80
+	bg:#20222f
+
+global css body
+	m:0 bd:0 p:0
+	bg:#20222f
+
 global css .dark
 	$appbg:#20222f
 	$bodybg:#20222f
@@ -36,30 +45,11 @@ global css .light
 	$button-bg:blue4/10
 	$button-hover-bg:blue4/20
 
-global css html
-	$effective-name-c:gray4
-	$effective-name-parens-c:gray4/80
-	bg:#20222f
-
-global css body
-	m:0 bd:0 p:0
-	bg:#20222f
-
-global css input
-	w:100% h:50px px:20px fl:1
-	fs:20px ta:center
-	bd:1px solid
-	outline:none rd:5px
-	bg:$input-bg
-	bc:$input-bc
-	c:$text-c
-	caret-color:$input-caret-c
-
 global css a
 	td:none
 
 global css .disabled *
-	@important c:gray4 cursor:default user-select:none pointer-events:none
+	@important c:gray4 user-select:none pointer-events:none
 
 global css .disabled $main-input
 	@important bg:gray4/10 bc:gray4
diff --git a/src/utils.imba b/src/utils.imba
new file mode 100644
index 0000000..e69de29
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..06e3bdf
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,7 @@
+import { imba } from 'vite-plugin-imba';
+import { defineConfig } from 'vite';
+
+export default defineConfig({
+	base: '',
+	plugins: [imba()],
+});