<- all repos

reticule @ main

👝 a REST API for saving webpages to read later

log

reese sapphire committed on Dec 27 2023:
start of golang rewrite
ac240e3
reese sapphire committed on Dec 20 2023:
update stuff. try to fix. did not work.
94f90c0
reese sapphire committed on May 21 2023:
make commit hash in version string conditional. include tags in git pull step.
2ea7fc9
reese sapphire committed on May 21 2023:
ah, i do still need to copy the whole repo for the build step.
aab556a
reese sapphire committed on May 21 2023:
bump version, update packages
e8348b1
reese sapphire committed on May 21 2023:
prettify, convert line endings to unix format
0c4d884
reese sapphire committed on May 21 2023:
fix version number in build pipeline
cf8f670
reese sapphire committed on May 20 2023:
bump version to v1.2.0
e73e493
reese sapphire committed on May 20 2023:
fix generating the version string in docker pipeline
ec574e6
reese sapphire committed on May 20 2023:
refactor config. add version string to some routes.
4fe1c15
reese sapphire committed on May 20 2023:
add version to healthcheck and RSS generator field
8eced9b
reese sapphire committed on May 20 2023:
add auto-tagging to woodpecker pipeline
eca13af
reese sapphire committed on May 19 2023:
prettify
3d3d9bf
reese sapphire committed on May 19 2023:
replace package ID in examples, add more to do items
501f8ab
reese sapphire committed on May 19 2023:
update packages, fix license value, bump version
b069b6a
reese sapphire committed on May 19 2023:
slim down .*ignore files
aff7743
reese sapphire committed on May 19 2023:
version bump!
c70b2ab
reese sapphire committed on May 19 2023:
re-add woodpecker pipeline
6bfe5c6
reese sapphire committed on May 17 2023:
revert mistaken change to dockerfile
1dcbff2
reese sapphire committed on May 17 2023:
delete woodpecker pipeline for now to work on it in a new branch.
2de2cc2
reese sapphire committed on May 17 2023:
check off some more roadmap thingz
8a10519
reese sapphire committed on May 17 2023:
relicense to the Unlicense.
a94bf69
reese sapphire committed on May 15 2023:
another attempt at fixing tagging
8da747b
reese sapphire committed on May 15 2023:
set auto_tag to true
9c95942
reese sapphire committed on May 15 2023:
forgot a thing
a681956
reese sapphire committed on May 15 2023:
trying different method of retrieving secret
127c1ed
reese sapphire committed on May 15 2023:
switched to docker hub deployment
a8debcf
reese sapphire committed on May 15 2023:
hardcoded registry username
87f2112
reese sapphire committed on May 14 2023:
pls work
f5a51fa
reese sapphire committed on May 14 2023:
let's try this
f7ed887
reese sapphire committed on May 14 2023:
unable to push. does this work?
a41b19d
reese sapphire committed on May 14 2023:
i wonder if it'd work if i just commented it out
ca5f912
reese sapphire committed on May 14 2023:
remove i386
5d15775
reese sapphire committed on May 14 2023:
edit woodpecker
99622da
reese sapphire committed on May 14 2023:
remove target architecture
371e100
reese sapphire committed on May 14 2023:
edit dockerfile base image tag
ef22aad
reese sapphire committed on May 14 2023:
edit woodpecker yet again
cca770a
reese sapphire committed on May 14 2023:
edit woodpecker again
69e30a0
reese sapphire committed on May 14 2023:
edit woodpecker
2b6f2d1
reese sapphire committed on May 14 2023:
edit woodpecker
e7d3df7
reese sapphire committed on May 14 2023:
add woodpecker pipeline, fix nodemon
6393afe
reese sapphire committed on May 14 2023:
reverse DB sort, prettier formatted
c3070cb
reese sapphire committed on May 13 2023:
change name to reticule
516506b
reese sapphire committed on May 13 2023:
code cleanup, fix deduplication, sort on add
b4d52fe
reese sapphire committed on May 13 2023:
add deduplication, clean up code, fix documentation
bb1afde
reese sapphire committed on May 13 2023:
use LowDB. upgrade packages. organize docs. update typescript config
6de38d2
reese sapphire committed on Apr 27 2023:
update sample.env. add 'public' setting. update todo.md.
2220602
reese sapphire committed on Apr 27 2023:
add todo. npm update. reverse order in RSS feed.
b97dfe8
Reese Sapphire committed on Oct 18 2022:
added android instructions
diff --git a/README.md b/README.md
index 77a297b..0d6d552 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,8 @@ basic express server for saving online articles to read later.
 - [x] add docker support
 - [x] make a browser bookmarklet for quickly saving articles
 - [x] log some useful info on startup, like the bookmarklet code
+- [x] improve usage instructions (add from browser, add from phone with HTTP Shortcuts, etc)
+- [ ] sanitize articles before saving them
 - [ ] find a slightly better name

 ### Will not do
@@ -66,7 +68,17 @@ services:

 ## Usage

+### Web browser
 1. Copy the bookmarklet code from the logs and replace `<SERVER_ADDRESS>` with the IP address or domain name.
-2. Create a new bookmark in your browser (in the bookmarks bar for easy access, perhaps) with the name "Read later" (or whatever you want) and set the URL to the bookmarklet code.
+2. Create a new bookmark in your browser (in the bookmarks bar for easy access, perhaps) and set the URL to the bookmarklet code.
 3. Go to an article that you want to save, click the bookmark, et voila!
-4. Add the RSS feed endpoint (`<SERVER_ADDRESS>/feed?key=<API_KEY>`) to your feed reader of choice.
+
+### Android
+1. Install HTTP Shortcuts from [F-Droid](https://f-droid.org/en/packages/ch.rmy.android.http_shortcuts/) or the [Play Store](https://play.google.com/store/apps/details?id=ch.rmy.android.http_shortcuts).
+2. Download [`readerss_http_shortcut.json`](extra/readerss_http_shortcut.json) from this repo to your device.
+3. Open HTTP Shortcuts, tap the vertical 3 dots in the top right corner, tap "Import/Export", then tap "Import from file". Select the json file you downloaded earlier.
+4. Go back to the main page, tap the 3 dot button again, then tap "Variables", and edit the values of `readerss_instance` and `readerss_api_key` to match those of your instance.
+5. Try using the share button on an app. A new item "Send to..." should appear on the share sheet. You can also save an article by tapping the shortcut inside the HTTP Shortcuts app itself.
+
+### RSS feed reader
+The RSS feed URL is `<SERVER_ADDRESS>/feed?key=<API_KEY>`. Replace the placeholders with your proper values and add it to your feed reader of choice. If it doesn't work in your reader, open an issue and I will try my best to fix it!
diff --git a/extra/readerss_http_shortcut.json b/extra/readerss_http_shortcut.json
new file mode 100644
index 0000000..a137d6f
--- /dev/null
+++ b/extra/readerss_http_shortcut.json
@@ -0,0 +1,43 @@
+{
+	"categories": [
+		{
+			"id": "ebb3548e-4679-4a76-a0f1-eb0e272ddcf9",
+			"name": "Shortcuts",
+			"shortcuts": [
+				{
+					"description": "Save an article to read later",
+					"iconName": "flat_color_pin",
+					"id": "39fb3ee7-cb24-4c7e-beec-4e12f260c453",
+					"launcherShortcut": true,
+					"name": "Read Later",
+					"quickSettingsTileShortcut": true,
+					"responseHandling": {
+						"uiType": "toast"
+					},
+					"url": "{{46f4aa6c-36f2-4355-ae47-02d7aba12ef7}}/add?key\u003d{{21e44c15-ba2d-4be1-832f-c0ff0106325d}}\u0026url\u003d{{fd0331b6-7636-4795-a079-c7ed5ae66aca}}"
+				}
+			]
+		}
+	],
+	"variables": [
+		{
+			"id": "46f4aa6c-36f2-4355-ae47-02d7aba12ef7",
+			"key": "readerss_instance",
+			"value": "https://your.instance.url.without.trailing.slash"
+		},
+		{
+			"id": "21e44c15-ba2d-4be1-832f-c0ff0106325d",
+			"key": "readerss_api_key",
+			"value": "your_key_that_you_used_when_setting_up_your_instance"
+		},
+		{
+			"flags": 1,
+			"id": "fd0331b6-7636-4795-a079-c7ed5ae66aca",
+			"key": "readerss_url",
+			"title": "Article URL",
+			"type": "text",
+			"urlEncode": true
+		}
+	],
+	"version": 51
+}
5e5893a
Reese Sapphire committed on May 17 2022:
quick fixes

- allow reading feed even with no posts
- set default port to 80
316ebf5
Reese Sapphire committed on May 17 2022:
add usage instructions

- write bookmarklet code
- log instructions on server startup
- add instructions to readme

diff --git a/README.md b/README.md
index e352ecf..c3c29db 100644
--- a/README.md
+++ b/README.md
@@ -7,12 +7,13 @@ basic express server for saving online articles to read later.
 - [x] basic API
   - [x] add an article
   - [x] RSS endpoint so you can sync it with your feed aggregator of choice
+  - [ ] deduplicate articles
   - [ ] delete an article?
 - [x] get configuration from environment variables
 - [x] add a database (stored as JSON but i would like to use sqlite3. i just have no idea what i'm doing.)
 - [x] add docker support
-- [ ] make a browser bookmarklet for quickly saving articles
-- [ ] log some useful info on startup, like the bookmarklet code
+- [x] make a browser bookmarklet for quickly saving articles
+- [x] log some useful info on startup, like the bookmarklet code
 - [ ] find a slightly better name

 ### Will not do
@@ -62,3 +63,10 @@ services:
 | DB_FILE          | The path and filename of the database file within the container.  |
 | FEED_TITLE       | The name of your reading list feed that shows up in feed readers. |
 | FEED_DESCRIPTION | A short description to accompany the above.                       |
+
+## Usage
+
+1. Copy the bookmarklet code from the logs and replace `<SERVER_ADDRESS>` with the IP address or domain name.
+2. Create a new bookmark in your browser (in the bookmarks bar for easy access, perhaps) with the name "Read later" (or whatever you want) and set the URL to the bookmarklet code.
+3. Go to an article that you want to save, click the bookmark, et voila!
+4. Add the RSS feed endpoint (`<SERVER_ADDRESS>/feed?key=<API_KEY>`) to your feed reader of choice.
diff --git a/src/routes.ts b/src/routes.ts
index 4e92389..314c69f 100644
--- a/src/routes.ts
+++ b/src/routes.ts
@@ -45,7 +45,7 @@ router.get('/add', noCache(), (req: Request, res: Response) => {
 					id: Date.now(),
 				}) as Article
 			)
-			return res.sendStatus(200)
+			return res.status(200).send(`Successfully saved "${article.title}"!`)
 		})
 		.catch((err) => {
 			console.trace(err)
diff --git a/src/server.ts b/src/server.ts
index 2e766c0..ce85a38 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -1,4 +1,12 @@
 import config from './config'
 import { app } from './app'

-app().listen(config.port, () => console.info(`Listening on port ${config.port}`))
+app().listen(config.port, () => {
+	console.info(`Listening on port ${config.port}`)
+
+	console.info(`Here is the bookmarklet code. Make sure you replace <SERVER_ADDRESS> with this server's ip or hostname (including the protocol and port) that your browser can access!`)
+	let bookmarklet = `(()=>{window.open("<SERVER_ADDRESS>/add?key=${config.api_key}&url="+encodeURIComponent(location),"_blank","noreferrer,noopener")})()`
+	console.info(`\n    javascript:${bookmarklet}\n`)
+
+	console.info(`Then add <SERVER_ADDRESS>/feed?key=${config.api_key} to your RSS feed reader of choice.\n`)
+})
4bdc9fc
Reese Sapphire committed on May 17 2022:
update docker stuff

- change tag to 'latest' instead of 'edge'
- added instructions for running a container
- added feed info variables to the feed itself
b78dde2
Reese Sapphire committed on May 17 2022:
add docker support

- created .dockerignore
- created 2-stage dockerfile
- created github actions workflow

minor changes:

- added raw JSON api route
- removed unnecessary logging
- slightly restructured routes/app relationship
88575f5
Reese Sapphire committed on May 16 2022:
add simple JSON-based database

it's pretty much what i had before but now it saves to a file. sqlite would be better though if i knew how to use it.

diff --git a/README.md b/README.md
index 6e9651f..cdba985 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ basic express server for saving online articles to read later.
   - [x] RSS endpoint so you can sync it with your feed aggregator of choice
   - [ ] delete an article?
 - [x] get configuration from environment variables
-- [ ] add a database (sqlite, probably)
+- [x] add a database (stored as JSON but i would like to use sqlite3. i just have no idea what i'm doing.)
 - [ ] add docker support
 - [ ] make a browser bookmarklet for quickly saving articles
 - [ ] log some useful info on startup, like the bookmarklet code
diff --git a/package-lock.json b/package-lock.json
index dea3c51..16855e6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,8 +12,7 @@
 				"article-parser": "^5.0.4",
 				"dotenv": "^16.0.1",
 				"express": "^4.18.1",
-				"express-async-errors": "^3.1.1",
-				"sqlite3": "^5.0.8"
+				"express-async-errors": "^3.1.1"
 			},
 			"devDependencies": {
 				"@types/express": "^4.17.13",
@@ -46,45 +45,6 @@
 				"node": ">=12"
 			}
 		},
-		"node_modules/@gar/promisify": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
-			"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
-			"optional": true
-		},
-		"node_modules/@mapbox/node-pre-gyp": {
-			"version": "1.0.9",
-			"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz",
-			"integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==",
-			"dependencies": {
-				"detect-libc": "^2.0.0",
-				"https-proxy-agent": "^5.0.0",
-				"make-dir": "^3.1.0",
-				"node-fetch": "^2.6.7",
-				"nopt": "^5.0.0",
-				"npmlog": "^5.0.1",
-				"rimraf": "^3.0.2",
-				"semver": "^7.3.5",
-				"tar": "^6.1.11"
-			},
-			"bin": {
-				"node-pre-gyp": "bin/node-pre-gyp"
-			}
-		},
-		"node_modules/@mapbox/node-pre-gyp/node_modules/nopt": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
-			"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
-			"dependencies": {
-				"abbrev": "1"
-			},
-			"bin": {
-				"nopt": "bin/nopt.js"
-			},
-			"engines": {
-				"node": ">=6"
-			}
-		},
 		"node_modules/@mozilla/readability": {
 			"version": "0.4.2",
 			"resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.2.tgz",
@@ -93,29 +53,6 @@
 				"node": ">=10.0.0"
 			}
 		},
-		"node_modules/@npmcli/fs": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
-			"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
-			"optional": true,
-			"dependencies": {
-				"@gar/promisify": "^1.0.1",
-				"semver": "^7.3.5"
-			}
-		},
-		"node_modules/@npmcli/move-file": {
-			"version": "1.1.2",
-			"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
-			"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
-			"optional": true,
-			"dependencies": {
-				"mkdirp": "^1.0.4",
-				"rimraf": "^3.0.2"
-			},
-			"engines": {
-				"node": ">=10"
-			}
-		},
 		"node_modules/@sindresorhus/is": {
 			"version": "0.14.0",
 			"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@@ -137,15 +74,6 @@
 				"node": ">=6"
 			}
 		},
-		"node_modules/@tootallnate/once": {
-			"version": "1.1.2",
-			"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
-			"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
-			"optional": true,
-			"engines": {
-				"node": ">= 6"
-			}
-		},
 		"node_modules/@tsconfig/node10": {
 			"version": "1.0.8",
 			"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
@@ -329,7 +257,8 @@
 		"node_modules/abbrev": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-			"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+			"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+			"dev": true
 		},
 		"node_modules/accepts": {
 			"version": "1.3.8",
@@ -363,53 +292,6 @@
 				"node": ">=0.4.0"
 			}
 		},
-		"node_modules/agent-base": {
-			"version": "6.0.2",
-			"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-			"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-			"dependencies": {
-				"debug": "4"
-			},
-			"engines": {
-				"node": ">= 6.0.0"
-			}
-		},
-		"node_modules/agentkeepalive": {
-			"version": "4.2.1",
-			"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
-			"integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
-			"optional": true,
-			"dependencies": {
-				"debug": "^4.1.0",
-				"depd": "^1.1.2",
-				"humanize-ms": "^1.2.1"
-			},
-			"engines": {
-				"node": ">= 8.0.0"
-			}
-		},
-		"node_modules/agentkeepalive/node_modules/depd": {
-			"version": "1.1.2",
-			"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-			"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
-			"optional": true,
-			"engines": {
-				"node": ">= 0.6"
-			}
-		},
-		"node_modules/aggregate-error": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
-			"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
-			"optional": true,
-			"dependencies": {
-				"clean-stack": "^2.0.0",
-				"indent-string": "^4.0.0"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
 		"node_modules/ansi-align": {
 			"version": "3.0.1",
 			"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
@@ -423,6 +305,7 @@
 			"version": "5.0.1",
 			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
 			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true,
 			"engines": {
 				"node": ">=8"
 			}
@@ -455,23 +338,6 @@
 				"node": ">= 8"
 			}
 		},
-		"node_modules/aproba": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
-			"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
-		},
-		"node_modules/are-we-there-yet": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
-			"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
-			"dependencies": {
-				"delegates": "^1.0.0",
-				"readable-stream": "^3.6.0"
-			},
-			"engines": {
-				"node": ">=10"
-			}
-		},
 		"node_modules/arg": {
 			"version": "4.1.3",
 			"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -513,7 +379,8 @@
 		"node_modules/balanced-match": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+			"dev": true
 		},
 		"node_modules/bellajs": {
 			"version": "11.0.0",
@@ -611,6 +478,7 @@
 			"version": "1.1.11",
 			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
 			"dependencies": {
 				"balanced-match": "^1.0.0",
 				"concat-map": "0.0.1"
@@ -641,35 +509,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/cacache": {
-			"version": "15.3.0",
-			"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
-			"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
-			"optional": true,
-			"dependencies": {
-				"@npmcli/fs": "^1.0.0",
-				"@npmcli/move-file": "^1.0.1",
-				"chownr": "^2.0.0",
-				"fs-minipass": "^2.0.0",
-				"glob": "^7.1.4",
-				"infer-owner": "^1.0.4",
-				"lru-cache": "^6.0.0",
-				"minipass": "^3.1.1",
-				"minipass-collect": "^1.0.2",
-				"minipass-flush": "^1.0.5",
-				"minipass-pipeline": "^1.2.2",
-				"mkdirp": "^1.0.3",
-				"p-map": "^4.0.0",
-				"promise-inflight": "^1.0.1",
-				"rimraf": "^3.0.2",
-				"ssri": "^8.0.1",
-				"tar": "^6.0.2",
-				"unique-filename": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 10"
-			}
-		},
 		"node_modules/cacheable-request": {
 			"version": "6.1.0",
 			"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
@@ -952,14 +791,6 @@
 				"node": ">= 6"
 			}
 		},
-		"node_modules/chownr": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-			"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
-			"engines": {
-				"node": ">=10"
-			}
-		},
 		"node_modules/ci-info": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -977,15 +808,6 @@
 				"node": ">= 10.0"
 			}
 		},
-		"node_modules/clean-stack": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
-			"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
-			"optional": true,
-			"engines": {
-				"node": ">=6"
-			}
-		},
 		"node_modules/cli-boxes": {
 			"version": "2.2.1",
 			"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
@@ -1025,14 +847,6 @@
 			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
 			"dev": true
 		},
-		"node_modules/color-support": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
-			"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
-			"bin": {
-				"color-support": "bin.js"
-			}
-		},
 		"node_modules/commander": {
 			"version": "8.3.0",
 			"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
@@ -1044,7 +858,8 @@
 		"node_modules/concat-map": {
 			"version": "0.0.1",
 			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
 		},
 		"node_modules/configstore": {
 			"version": "5.0.1",
@@ -1063,11 +878,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/console-control-strings": {
-			"version": "1.1.0",
-			"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-			"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
-		},
 		"node_modules/content-disposition": {
 			"version": "0.5.4",
 			"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -1189,11 +999,6 @@
 			"integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
 			"dev": true
 		},
-		"node_modules/delegates": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-			"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
-		},
 		"node_modules/depd": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -1211,14 +1016,6 @@
 				"npm": "1.2.8000 || >= 1.4.16"
 			}
 		},
-		"node_modules/detect-libc": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
-			"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
-			"engines": {
-				"node": ">=8"
-			}
-		},
 		"node_modules/diff": {
 			"version": "4.0.2",
 			"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -1322,7 +1119,8 @@
 		"node_modules/emoji-regex": {
 			"version": "8.0.0",
 			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+			"dev": true
 		},
 		"node_modules/encodeurl": {
 			"version": "1.0.2",
@@ -1332,27 +1130,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/encoding": {
-			"version": "0.1.13",
-			"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
-			"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
-			"optional": true,
-			"dependencies": {
-				"iconv-lite": "^0.6.2"
-			}
-		},
-		"node_modules/encoding/node_modules/iconv-lite": {
-			"version": "0.6.3",
-			"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-			"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-			"optional": true,
-			"dependencies": {
-				"safer-buffer": ">= 2.1.2 < 3.0.0"
-			},
-			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
 		"node_modules/end-of-stream": {
 			"version": "1.4.4",
 			"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -1373,21 +1150,6 @@
 				"url": "https://github.com/fb55/entities?sponsor=1"
 			}
 		},
-		"node_modules/env-paths": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
-			"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
-			"optional": true,
-			"engines": {
-				"node": ">=6"
-			}
-		},
-		"node_modules/err-code": {
-			"version": "2.0.3",
-			"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
-			"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
-			"optional": true
-		},
 		"node_modules/escape-goat": {
 			"version": "2.1.1",
 			"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -1573,21 +1335,11 @@
 				"node": ">= 0.6"
 			}
 		},
-		"node_modules/fs-minipass": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
-			"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
-			"dependencies": {
-				"minipass": "^3.0.0"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
 		"node_modules/fs.realpath": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+			"dev": true
 		},
 		"node_modules/fsevents": {
 			"version": "2.3.2",
@@ -1608,25 +1360,6 @@
 			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
 			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
 		},
-		"node_modules/gauge": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
-			"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
-			"dependencies": {
-				"aproba": "^1.0.3 || ^2.0.0",
-				"color-support": "^1.1.2",
-				"console-control-strings": "^1.0.0",
-				"has-unicode": "^2.0.1",
-				"object-assign": "^4.1.1",
-				"signal-exit": "^3.0.0",
-				"string-width": "^4.2.3",
-				"strip-ansi": "^6.0.1",
-				"wide-align": "^1.1.2"
-			},
-			"engines": {
-				"node": ">=10"
-			}
-		},
 		"node_modules/get-intrinsic": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
@@ -1644,6 +1377,7 @@
 			"version": "7.2.0",
 			"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
 			"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+			"dev": true,
 			"dependencies": {
 				"fs.realpath": "^1.0.0",
 				"inflight": "^1.0.4",
@@ -1712,7 +1446,7 @@
 			"version": "4.2.10",
 			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
 			"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
-			"devOptional": true
+			"dev": true
 		},
 		"node_modules/has": {
 			"version": "1.0.3",
@@ -1745,11 +1479,6 @@
 				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
-		"node_modules/has-unicode": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-			"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
-		},
 		"node_modules/has-yarn": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
@@ -1814,7 +1543,7 @@
 			"version": "4.1.0",
 			"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
 			"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-			"devOptional": true
+			"dev": true
 		},
 		"node_modules/http-errors": {
 			"version": "2.0.0",
@@ -1831,41 +1560,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/http-proxy-agent": {
-			"version": "4.0.1",
-			"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
-			"integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
-			"optional": true,
-			"dependencies": {
-				"@tootallnate/once": "1",
-				"agent-base": "6",
-				"debug": "4"
-			},
-			"engines": {
-				"node": ">= 6"
-			}
-		},
-		"node_modules/https-proxy-agent": {
-			"version": "5.0.1",
-			"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
-			"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-			"dependencies": {
-				"agent-base": "6",
-				"debug": "4"
-			},
-			"engines": {
-				"node": ">= 6"
-			}
-		},
-		"node_modules/humanize-ms": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
-			"integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
-			"optional": true,
-			"dependencies": {
-				"ms": "^2.0.0"
-			}
-		},
 		"node_modules/iconv-lite": {
 			"version": "0.4.24",
 			"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -1896,30 +1590,16 @@
 			"version": "0.1.4",
 			"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
 			"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-			"devOptional": true,
+			"dev": true,
 			"engines": {
 				"node": ">=0.8.19"
 			}
 		},
-		"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==",
-			"optional": true,
-			"engines": {
-				"node": ">=8"
-			}
-		},
-		"node_modules/infer-owner": {
-			"version": "1.0.4",
-			"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
-			"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
-			"optional": true
-		},
 		"node_modules/inflight": {
 			"version": "1.0.6",
 			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
 			"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+			"dev": true,
 			"dependencies": {
 				"once": "^1.3.0",
 				"wrappy": "1"
@@ -1939,12 +1619,6 @@
 				"node": ">=10"
 			}
 		},
-		"node_modules/ip": {
-			"version": "1.1.8",
-			"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
-			"integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
-			"optional": true
-		},
 		"node_modules/ipaddr.js": {
 			"version": "1.9.1",
 			"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -1990,6 +1664,7 @@
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
 			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+			"dev": true,
 			"engines": {
 				"node": ">=8"
 			}
@@ -2022,12 +1697,6 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/is-lambda": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
-			"integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
-			"optional": true
-		},
 		"node_modules/is-npm": {
 			"version": "5.0.0",
 			"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz",
@@ -2087,12 +1756,6 @@
 			"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
 			"dev": true
 		},
-		"node_modules/isexe": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-			"optional": true
-		},
 		"node_modules/json-buffer": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
@@ -2158,6 +1821,7 @@
 			"version": "6.0.0",
 			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
 			"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+			"dev": true,
 			"dependencies": {
 				"yallist": "^4.0.0"
 			},
@@ -2169,6 +1833,7 @@
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
 			"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+			"dev": true,
 			"dependencies": {
 				"semver": "^6.0.0"
 			},
@@ -2183,6 +1848,7 @@
 			"version": "6.3.0",
 			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
 			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
 			}
@@ -2193,33 +1859,6 @@
 			"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
 			"dev": true
 		},
-		"node_modules/make-fetch-happen": {
-			"version": "9.1.0",
-			"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
-			"integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
-			"optional": true,
-			"dependencies": {
-				"agentkeepalive": "^4.1.3",
-				"cacache": "^15.2.0",
-				"http-cache-semantics": "^4.1.0",
-				"http-proxy-agent": "^4.0.1",
-				"https-proxy-agent": "^5.0.0",
-				"is-lambda": "^1.0.1",
-				"lru-cache": "^6.0.0",
-				"minipass": "^3.1.3",
-				"minipass-collect": "^1.0.2",
-				"minipass-fetch": "^1.3.2",
-				"minipass-flush": "^1.0.5",
-				"minipass-pipeline": "^1.2.4",
-				"negotiator": "^0.6.2",
-				"promise-retry": "^2.0.1",
-				"socks-proxy-agent": "^6.0.0",
-				"ssri": "^8.0.0"
-			},
-			"engines": {
-				"node": ">= 10"
-			}
-		},
 		"node_modules/media-typer": {
 			"version": "0.3.0",
 			"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -2273,6 +1912,7 @@
 			"version": "3.1.2",
 			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 			"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+			"dev": true,
 			"dependencies": {
 				"brace-expansion": "^1.1.7"
 			},
@@ -2286,105 +1926,6 @@
 			"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
 			"dev": true
 		},
-		"node_modules/minipass": {
-			"version": "3.1.6",
-			"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
-			"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
-			"dependencies": {
-				"yallist": "^4.0.0"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
-		"node_modules/minipass-collect": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
-			"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
-			"optional": true,
-			"dependencies": {
-				"minipass": "^3.0.0"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
-		"node_modules/minipass-fetch": {
-			"version": "1.4.1",
-			"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
-			"integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
-			"optional": true,
-			"dependencies": {
-				"minipass": "^3.1.0",
-				"minipass-sized": "^1.0.3",
-				"minizlib": "^2.0.0"
-			},
-			"engines": {
-				"node": ">=8"
-			},
-			"optionalDependencies": {
-				"encoding": "^0.1.12"
-			}
-		},
-		"node_modules/minipass-flush": {
-			"version": "1.0.5",
-			"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
-			"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
-			"optional": true,
-			"dependencies": {
-				"minipass": "^3.0.0"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
-		"node_modules/minipass-pipeline": {
-			"version": "1.2.4",
-			"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
-			"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
-			"optional": true,
-			"dependencies": {
-				"minipass": "^3.0.0"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
-		"node_modules/minipass-sized": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
-			"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
-			"optional": true,
-			"dependencies": {
-				"minipass": "^3.0.0"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
-		"node_modules/minizlib": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
-			"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
-			"dependencies": {
-				"minipass": "^3.0.0",
-				"yallist": "^4.0.0"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
-		"node_modules/mkdirp": {
-			"version": "1.0.4",
-			"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-			"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-			"bin": {
-				"mkdirp": "bin/cmd.js"
-			},
-			"engines": {
-				"node": ">=10"
-			}
-		},
 		"node_modules/ms": {
 			"version": "2.1.2",
 			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -2418,116 +1959,6 @@
 				"tslib": "^2.0.3"
 			}
 		},
-		"node_modules/node-addon-api": {
-			"version": "4.3.0",
-			"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
-			"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
-		},
-		"node_modules/node-fetch": {
-			"version": "2.6.7",
-			"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-			"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
-			"dependencies": {
-				"whatwg-url": "^5.0.0"
-			},
-			"engines": {
-				"node": "4.x || >=6.0.0"
-			},
-			"peerDependencies": {
-				"encoding": "^0.1.0"
-			},
-			"peerDependenciesMeta": {
-				"encoding": {
-					"optional": true
-				}
-			}
-		},
-		"node_modules/node-gyp": {
-			"version": "8.4.1",
-			"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
-			"integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
-			"optional": true,
-			"dependencies": {
-				"env-paths": "^2.2.0",
-				"glob": "^7.1.4",
-				"graceful-fs": "^4.2.6",
-				"make-fetch-happen": "^9.1.0",
-				"nopt": "^5.0.0",
-				"npmlog": "^6.0.0",
-				"rimraf": "^3.0.2",
-				"semver": "^7.3.5",
-				"tar": "^6.1.2",
-				"which": "^2.0.2"
-			},
-			"bin": {
-				"node-gyp": "bin/node-gyp.js"
-			},
-			"engines": {
-				"node": ">= 10.12.0"
-			}
-		},
-		"node_modules/node-gyp/node_modules/are-we-there-yet": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz",
-			"integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==",
-			"optional": true,
-			"dependencies": {
-				"delegates": "^1.0.0",
-				"readable-stream": "^3.6.0"
-			},
-			"engines": {
-				"node": "^12.13.0 || ^14.15.0 || >=16"
-			}
-		},
-		"node_modules/node-gyp/node_modules/gauge": {
-			"version": "4.0.4",
-			"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
-			"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
-			"optional": true,
-			"dependencies": {
-				"aproba": "^1.0.3 || ^2.0.0",
-				"color-support": "^1.1.3",
-				"console-control-strings": "^1.1.0",
-				"has-unicode": "^2.0.1",
-				"signal-exit": "^3.0.7",
-				"string-width": "^4.2.3",
-				"strip-ansi": "^6.0.1",
-				"wide-align": "^1.1.5"
-			},
-			"engines": {
-				"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
-			}
-		},
-		"node_modules/node-gyp/node_modules/nopt": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
-			"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
-			"optional": true,
-			"dependencies": {
-				"abbrev": "1"
-			},
-			"bin": {
-				"nopt": "bin/nopt.js"
-			},
-			"engines": {
-				"node": ">=6"
-			}
-		},
-		"node_modules/node-gyp/node_modules/npmlog": {
-			"version": "6.0.2",
-			"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
-			"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
-			"optional": true,
-			"dependencies": {
-				"are-we-there-yet": "^3.0.0",
-				"console-control-strings": "^1.1.0",
-				"gauge": "^4.0.3",
-				"set-blocking": "^2.0.0"
-			},
-			"engines": {
-				"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
-			}
-		},
 		"node_modules/nodemon": {
 			"version": "2.0.16",
 			"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz",
@@ -2629,17 +2060,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/npmlog": {
-			"version": "5.0.1",
-			"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
-			"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
-			"dependencies": {
-				"are-we-there-yet": "^2.0.0",
-				"console-control-strings": "^1.1.0",
-				"gauge": "^3.0.0",
-				"set-blocking": "^2.0.0"
-			}
-		},
 		"node_modules/nth-check": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
@@ -2651,14 +2071,6 @@
 				"url": "https://github.com/fb55/nth-check?sponsor=1"
 			}
 		},
-		"node_modules/object-assign": {
-			"version": "4.1.1",
-			"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-			"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
 		"node_modules/object-inspect": {
 			"version": "1.12.0",
 			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
@@ -2682,6 +2094,7 @@
 			"version": "1.4.0",
 			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
 			"dependencies": {
 				"wrappy": "1"
 			}
@@ -2695,21 +2108,6 @@
 				"node": ">=6"
 			}
 		},
-		"node_modules/p-map": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
-			"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
-			"optional": true,
-			"dependencies": {
-				"aggregate-error": "^3.0.0"
-			},
-			"engines": {
-				"node": ">=10"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
-			}
-		},
 		"node_modules/package-json": {
 			"version": "6.5.0",
 			"resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
@@ -2782,6 +2180,7 @@
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
 			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+			"dev": true,
 			"engines": {
 				"node": ">=0.10.0"
 			}
@@ -2850,25 +2249,6 @@
 				"url": "https://github.com/prettier/prettier?sponsor=1"
 			}
 		},
-		"node_modules/promise-inflight": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
-			"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
-			"optional": true
-		},
-		"node_modules/promise-retry": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
-			"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
-			"optional": true,
-			"dependencies": {
-				"err-code": "^2.0.2",
-				"retry": "^0.12.0"
-			},
-			"engines": {
-				"node": ">=10"
-			}
-		},
 		"node_modules/proxy-addr": {
 			"version": "2.0.7",
 			"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -2983,19 +2363,6 @@
 				"node": ">=0.10.0"
 			}
 		},
-		"node_modules/readable-stream": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-			"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-			"dependencies": {
-				"inherits": "^2.0.3",
-				"string_decoder": "^1.1.1",
-				"util-deprecate": "^1.0.1"
-			},
-			"engines": {
-				"node": ">= 6"
-			}
-		},
 		"node_modules/readdirp": {
 			"version": "3.6.0",
 			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -3049,19 +2416,11 @@
 				"lowercase-keys": "^1.0.0"
 			}
 		},
-		"node_modules/retry": {
-			"version": "0.12.0",
-			"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
-			"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
-			"optional": true,
-			"engines": {
-				"node": ">= 4"
-			}
-		},
 		"node_modules/rimraf": {
 			"version": "3.0.2",
 			"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
 			"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+			"dev": true,
 			"dependencies": {
 				"glob": "^7.1.3"
 			},
@@ -3179,6 +2538,7 @@
 			"version": "7.3.7",
 			"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
 			"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+			"dev": true,
 			"dependencies": {
 				"lru-cache": "^6.0.0"
 			},
@@ -3276,11 +2636,6 @@
 				"node": ">= 0.8.0"
 			}
 		},
-		"node_modules/set-blocking": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-			"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
-		},
 		"node_modules/setprototypeof": {
 			"version": "1.2.0",
 			"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -3302,45 +2657,8 @@
 		"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/smart-buffer": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
-			"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
-			"optional": true,
-			"engines": {
-				"node": ">= 6.0.0",
-				"npm": ">= 3.0.0"
-			}
-		},
-		"node_modules/socks": {
-			"version": "2.6.2",
-			"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
-			"integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
-			"optional": true,
-			"dependencies": {
-				"ip": "^1.1.5",
-				"smart-buffer": "^4.2.0"
-			},
-			"engines": {
-				"node": ">= 10.13.0",
-				"npm": ">= 3.0.0"
-			}
-		},
-		"node_modules/socks-proxy-agent": {
-			"version": "6.2.0",
-			"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz",
-			"integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==",
-			"optional": true,
-			"dependencies": {
-				"agent-base": "^6.0.2",
-				"debug": "^4.3.3",
-				"socks": "^2.6.2"
-			},
-			"engines": {
-				"node": ">= 10"
-			}
+			"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+			"dev": true
 		},
 		"node_modules/source-map": {
 			"version": "0.6.1",
@@ -3367,40 +2685,6 @@
 				"source-map": "^0.6.0"
 			}
 		},
-		"node_modules/sqlite3": {
-			"version": "5.0.8",
-			"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.8.tgz",
-			"integrity": "sha512-f2ACsbSyb2D1qFFcqIXPfFscLtPVOWJr5GmUzYxf4W+0qelu5MWrR+FAQE1d5IUArEltBrzSDxDORG8P/IkqyQ==",
-			"hasInstallScript": true,
-			"dependencies": {
-				"@mapbox/node-pre-gyp": "^1.0.0",
-				"node-addon-api": "^4.2.0",
-				"tar": "^6.1.11"
-			},
-			"optionalDependencies": {
-				"node-gyp": "8.x"
-			},
-			"peerDependencies": {
-				"node-gyp": "8.x"
-			},
-			"peerDependenciesMeta": {
-				"node-gyp": {
-					"optional": true
-				}
-			}
-		},
-		"node_modules/ssri": {
-			"version": "8.0.1",
-			"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
-			"integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
-			"optional": true,
-			"dependencies": {
-				"minipass": "^3.1.1"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
 		"node_modules/statuses": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -3409,14 +2693,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/string_decoder": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-			"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-			"dependencies": {
-				"safe-buffer": "~5.2.0"
-			}
-		},
 		"node_modules/string-comparison": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/string-comparison/-/string-comparison-1.1.0.tgz",
@@ -3426,6 +2702,7 @@
 			"version": "4.2.3",
 			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
 			"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+			"dev": true,
 			"dependencies": {
 				"emoji-regex": "^8.0.0",
 				"is-fullwidth-code-point": "^3.0.0",
@@ -3439,6 +2716,7 @@
 			"version": "6.0.1",
 			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
 			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+			"dev": true,
 			"dependencies": {
 				"ansi-regex": "^5.0.1"
 			},
@@ -3458,22 +2736,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/tar": {
-			"version": "6.1.11",
-			"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
-			"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
-			"dependencies": {
-				"chownr": "^2.0.0",
-				"fs-minipass": "^2.0.0",
-				"minipass": "^3.0.0",
-				"minizlib": "^2.1.1",
-				"mkdirp": "^1.0.3",
-				"yallist": "^4.0.0"
-			},
-			"engines": {
-				"node": ">= 10"
-			}
-		},
 		"node_modules/terser": {
 			"version": "5.13.1",
 			"resolved": "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz",
@@ -3571,11 +2833,6 @@
 				"nodetouch": "bin/nodetouch.js"
 			}
 		},
-		"node_modules/tr46": {
-			"version": "0.0.3",
-			"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-			"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
-		},
 		"node_modules/ts-node": {
 			"version": "10.7.0",
 			"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz",
@@ -3681,24 +2938,6 @@
 			"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
 			"dev": true
 		},
-		"node_modules/unique-filename": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
-			"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
-			"optional": true,
-			"dependencies": {
-				"unique-slug": "^2.0.0"
-			}
-		},
-		"node_modules/unique-slug": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
-			"integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
-			"optional": true,
-			"dependencies": {
-				"imurmurhash": "^0.1.4"
-			}
-		},
 		"node_modules/unique-string": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -3759,11 +2998,6 @@
 				"node": ">=4"
 			}
 		},
-		"node_modules/util-deprecate": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-			"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
-		},
 		"node_modules/utils-merge": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -3786,43 +3020,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/webidl-conversions": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-			"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
-		},
-		"node_modules/whatwg-url": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-			"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
-			"dependencies": {
-				"tr46": "~0.0.3",
-				"webidl-conversions": "^3.0.0"
-			}
-		},
-		"node_modules/which": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-			"optional": true,
-			"dependencies": {
-				"isexe": "^2.0.0"
-			},
-			"bin": {
-				"node-which": "bin/node-which"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
-		"node_modules/wide-align": {
-			"version": "1.1.5",
-			"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
-			"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
-			"dependencies": {
-				"string-width": "^1.0.2 || 2 || 3 || 4"
-			}
-		},
 		"node_modules/widest-line": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
@@ -3855,7 +3052,8 @@
 		"node_modules/wrappy": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
 		},
 		"node_modules/write-file-atomic": {
 			"version": "3.0.3",
@@ -3881,7 +3079,8 @@
 		"node_modules/yallist": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+			"dev": true
 		},
 		"node_modules/yn": {
 			"version": "3.1.1",
@@ -3909,63 +3108,11 @@
 				"@cspotcode/source-map-consumer": "0.8.0"
 			}
 		},
-		"@gar/promisify": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
-			"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
-			"optional": true
-		},
-		"@mapbox/node-pre-gyp": {
-			"version": "1.0.9",
-			"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz",
-			"integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==",
-			"requires": {
-				"detect-libc": "^2.0.0",
-				"https-proxy-agent": "^5.0.0",
-				"make-dir": "^3.1.0",
-				"node-fetch": "^2.6.7",
-				"nopt": "^5.0.0",
-				"npmlog": "^5.0.1",
-				"rimraf": "^3.0.2",
-				"semver": "^7.3.5",
-				"tar": "^6.1.11"
-			},
-			"dependencies": {
-				"nopt": {
-					"version": "5.0.0",
-					"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
-					"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
-					"requires": {
-						"abbrev": "1"
-					}
-				}
-			}
-		},
 		"@mozilla/readability": {
 			"version": "0.4.2",
 			"resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.2.tgz",
 			"integrity": "sha512-48MJXzi4Dhy2fJ3lGjmwdEJKoMmn3oiYew9n/1OW6cZy78hAzRIyDJDBCGrg4PBFDyY4xos+H4LCFn5QVRDcfw=="
 		},
-		"@npmcli/fs": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
-			"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
-			"optional": true,
-			"requires": {
-				"@gar/promisify": "^1.0.1",
-				"semver": "^7.3.5"
-			}
-		},
-		"@npmcli/move-file": {
-			"version": "1.1.2",
-			"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
-			"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
-			"optional": true,
-			"requires": {
-				"mkdirp": "^1.0.4",
-				"rimraf": "^3.0.2"
-			}
-		},
 		"@sindresorhus/is": {
 			"version": "0.14.0",
 			"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@@ -3981,12 +3128,6 @@
 				"defer-to-connect": "^1.0.1"
 			}
 		},
-		"@tootallnate/once": {
-			"version": "1.1.2",
-			"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
-			"integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
-			"optional": true
-		},
 		"@tsconfig/node10": {
 			"version": "1.0.8",
 			"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
@@ -4150,7 +3291,8 @@
 		"abbrev": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-			"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+			"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+			"dev": true
 		},
 		"accepts": {
 			"version": "1.3.8",
@@ -4164,50 +3306,13 @@
 		"acorn": {
 			"version": "8.7.1",
 			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-			"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
-		},
-		"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==",
-			"dev": true
-		},
-		"agent-base": {
-			"version": "6.0.2",
-			"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-			"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-			"requires": {
-				"debug": "4"
-			}
-		},
-		"agentkeepalive": {
-			"version": "4.2.1",
-			"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
-			"integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
-			"optional": true,
-			"requires": {
-				"debug": "^4.1.0",
-				"depd": "^1.1.2",
-				"humanize-ms": "^1.2.1"
-			},
-			"dependencies": {
-				"depd": {
-					"version": "1.1.2",
-					"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-					"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
-					"optional": true
-				}
-			}
-		},
-		"aggregate-error": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
-			"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
-			"optional": true,
-			"requires": {
-				"clean-stack": "^2.0.0",
-				"indent-string": "^4.0.0"
-			}
+			"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
+		},
+		"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==",
+			"dev": true
 		},
 		"ansi-align": {
 			"version": "3.0.1",
@@ -4221,7 +3326,8 @@
 		"ansi-regex": {
 			"version": "5.0.1",
 			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true
 		},
 		"ansi-styles": {
 			"version": "4.3.0",
@@ -4242,20 +3348,6 @@
 				"picomatch": "^2.0.4"
 			}
 		},
-		"aproba": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
-			"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
-		},
-		"are-we-there-yet": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
-			"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
-			"requires": {
-				"delegates": "^1.0.0",
-				"readable-stream": "^3.6.0"
-			}
-		},
 		"arg": {
 			"version": "4.1.3",
 			"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -4294,7 +3386,8 @@
 		"balanced-match": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+			"dev": true
 		},
 		"bellajs": {
 			"version": "11.0.0",
@@ -4374,6 +3467,7 @@
 			"version": "1.1.11",
 			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
 			"requires": {
 				"balanced-match": "^1.0.0",
 				"concat-map": "0.0.1"
@@ -4398,32 +3492,6 @@
 			"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
 			"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
 		},
-		"cacache": {
-			"version": "15.3.0",
-			"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
-			"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
-			"optional": true,
-			"requires": {
-				"@npmcli/fs": "^1.0.0",
-				"@npmcli/move-file": "^1.0.1",
-				"chownr": "^2.0.0",
-				"fs-minipass": "^2.0.0",
-				"glob": "^7.1.4",
-				"infer-owner": "^1.0.4",
-				"lru-cache": "^6.0.0",
-				"minipass": "^3.1.1",
-				"minipass-collect": "^1.0.2",
-				"minipass-flush": "^1.0.5",
-				"minipass-pipeline": "^1.2.2",
-				"mkdirp": "^1.0.3",
-				"p-map": "^4.0.0",
-				"promise-inflight": "^1.0.1",
-				"rimraf": "^3.0.2",
-				"ssri": "^8.0.1",
-				"tar": "^6.0.2",
-				"unique-filename": "^1.1.1"
-			}
-		},
 		"cacheable-request": {
 			"version": "6.1.0",
 			"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
@@ -4630,11 +3698,6 @@
 				}
 			}
 		},
-		"chownr": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
-			"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
-		},
 		"ci-info": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -4649,12 +3712,6 @@
 				"source-map": "~0.6.0"
 			}
 		},
-		"clean-stack": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
-			"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
-			"optional": true
-		},
 		"cli-boxes": {
 			"version": "2.2.1",
 			"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
@@ -4685,11 +3742,6 @@
 			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
 			"dev": true
 		},
-		"color-support": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
-			"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
-		},
 		"commander": {
 			"version": "8.3.0",
 			"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
@@ -4698,7 +3750,8 @@
 		"concat-map": {
 			"version": "0.0.1",
 			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
 		},
 		"configstore": {
 			"version": "5.0.1",
@@ -4714,11 +3767,6 @@
 				"xdg-basedir": "^4.0.0"
 			}
 		},
-		"console-control-strings": {
-			"version": "1.1.0",
-			"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-			"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
-		},
 		"content-disposition": {
 			"version": "0.5.4",
 			"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -4805,11 +3853,6 @@
 			"integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
 			"dev": true
 		},
-		"delegates": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-			"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
-		},
 		"depd": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -4820,11 +3863,6 @@
 			"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
 			"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
 		},
-		"detect-libc": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
-			"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w=="
-		},
 		"diff": {
 			"version": "4.0.2",
 			"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -4901,33 +3939,14 @@
 		"emoji-regex": {
 			"version": "8.0.0",
 			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+			"dev": true
 		},
 		"encodeurl": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
 			"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
 		},
-		"encoding": {
-			"version": "0.1.13",
-			"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
-			"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
-			"optional": true,
-			"requires": {
-				"iconv-lite": "^0.6.2"
-			},
-			"dependencies": {
-				"iconv-lite": {
-					"version": "0.6.3",
-					"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-					"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-					"optional": true,
-					"requires": {
-						"safer-buffer": ">= 2.1.2 < 3.0.0"
-					}
-				}
-			}
-		},
 		"end-of-stream": {
 			"version": "1.4.4",
 			"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -4942,18 +3961,6 @@
 			"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
 			"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
 		},
-		"env-paths": {
-			"version": "2.2.1",
-			"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
-			"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
-			"optional": true
-		},
-		"err-code": {
-			"version": "2.0.3",
-			"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
-			"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
-			"optional": true
-		},
 		"escape-goat": {
 			"version": "2.1.1",
 			"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -5097,18 +4104,11 @@
 			"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
 			"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
 		},
-		"fs-minipass": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
-			"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
-			"requires": {
-				"minipass": "^3.0.0"
-			}
-		},
 		"fs.realpath": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+			"dev": true
 		},
 		"fsevents": {
 			"version": "2.3.2",
@@ -5122,22 +4122,6 @@
 			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
 			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
 		},
-		"gauge": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
-			"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
-			"requires": {
-				"aproba": "^1.0.3 || ^2.0.0",
-				"color-support": "^1.1.2",
-				"console-control-strings": "^1.0.0",
-				"has-unicode": "^2.0.1",
-				"object-assign": "^4.1.1",
-				"signal-exit": "^3.0.0",
-				"string-width": "^4.2.3",
-				"strip-ansi": "^6.0.1",
-				"wide-align": "^1.1.2"
-			}
-		},
 		"get-intrinsic": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
@@ -5152,6 +4136,7 @@
 			"version": "7.2.0",
 			"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
 			"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+			"dev": true,
 			"requires": {
 				"fs.realpath": "^1.0.0",
 				"inflight": "^1.0.4",
@@ -5204,7 +4189,7 @@
 			"version": "4.2.10",
 			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
 			"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
-			"devOptional": true
+			"dev": true
 		},
 		"has": {
 			"version": "1.0.3",
@@ -5225,11 +4210,6 @@
 			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
 			"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
 		},
-		"has-unicode": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-			"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
-		},
 		"has-yarn": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
@@ -5275,7 +4255,7 @@
 			"version": "4.1.0",
 			"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
 			"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-			"devOptional": true
+			"dev": true
 		},
 		"http-errors": {
 			"version": "2.0.0",
@@ -5289,35 +4269,6 @@
 				"toidentifier": "1.0.1"
 			}
 		},
-		"http-proxy-agent": {
-			"version": "4.0.1",
-			"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
-			"integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
-			"optional": true,
-			"requires": {
-				"@tootallnate/once": "1",
-				"agent-base": "6",
-				"debug": "4"
-			}
-		},
-		"https-proxy-agent": {
-			"version": "5.0.1",
-			"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
-			"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-			"requires": {
-				"agent-base": "6",
-				"debug": "4"
-			}
-		},
-		"humanize-ms": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
-			"integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
-			"optional": true,
-			"requires": {
-				"ms": "^2.0.0"
-			}
-		},
 		"iconv-lite": {
 			"version": "0.4.24",
 			"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -5342,24 +4293,13 @@
 			"version": "0.1.4",
 			"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
 			"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-			"devOptional": true
-		},
-		"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==",
-			"optional": true
-		},
-		"infer-owner": {
-			"version": "1.0.4",
-			"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
-			"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
-			"optional": true
+			"dev": true
 		},
 		"inflight": {
 			"version": "1.0.6",
 			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
 			"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+			"dev": true,
 			"requires": {
 				"once": "^1.3.0",
 				"wrappy": "1"
@@ -5376,12 +4316,6 @@
 			"integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
 			"dev": true
 		},
-		"ip": {
-			"version": "1.1.8",
-			"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
-			"integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
-			"optional": true
-		},
 		"ipaddr.js": {
 			"version": "1.9.1",
 			"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -5414,7 +4348,8 @@
 		"is-fullwidth-code-point": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+			"dev": true
 		},
 		"is-glob": {
 			"version": "4.0.3",
@@ -5435,12 +4370,6 @@
 				"is-path-inside": "^3.0.2"
 			}
 		},
-		"is-lambda": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
-			"integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
-			"optional": true
-		},
 		"is-npm": {
 			"version": "5.0.0",
 			"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz",
@@ -5482,12 +4411,6 @@
 			"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
 			"dev": true
 		},
-		"isexe": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-			"optional": true
-		},
 		"json-buffer": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
@@ -5547,6 +4470,7 @@
 			"version": "6.0.0",
 			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
 			"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+			"dev": true,
 			"requires": {
 				"yallist": "^4.0.0"
 			}
@@ -5555,6 +4479,7 @@
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
 			"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+			"dev": true,
 			"requires": {
 				"semver": "^6.0.0"
 			},
@@ -5562,7 +4487,8 @@
 				"semver": {
 					"version": "6.3.0",
 					"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-					"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+					"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+					"dev": true
 				}
 			}
 		},
@@ -5572,30 +4498,6 @@
 			"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
 			"dev": true
 		},
-		"make-fetch-happen": {
-			"version": "9.1.0",
-			"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
-			"integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
-			"optional": true,
-			"requires": {
-				"agentkeepalive": "^4.1.3",
-				"cacache": "^15.2.0",
-				"http-cache-semantics": "^4.1.0",
-				"http-proxy-agent": "^4.0.1",
-				"https-proxy-agent": "^5.0.0",
-				"is-lambda": "^1.0.1",
-				"lru-cache": "^6.0.0",
-				"minipass": "^3.1.3",
-				"minipass-collect": "^1.0.2",
-				"minipass-fetch": "^1.3.2",
-				"minipass-flush": "^1.0.5",
-				"minipass-pipeline": "^1.2.4",
-				"negotiator": "^0.6.2",
-				"promise-retry": "^2.0.1",
-				"socks-proxy-agent": "^6.0.0",
-				"ssri": "^8.0.0"
-			}
-		},
 		"media-typer": {
 			"version": "0.3.0",
 			"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -5634,6 +4536,7 @@
 			"version": "3.1.2",
 			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 			"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+			"dev": true,
 			"requires": {
 				"brace-expansion": "^1.1.7"
 			}
@@ -5644,76 +4547,6 @@
 			"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
 			"dev": true
 		},
-		"minipass": {
-			"version": "3.1.6",
-			"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
-			"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
-			"requires": {
-				"yallist": "^4.0.0"
-			}
-		},
-		"minipass-collect": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
-			"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
-			"optional": true,
-			"requires": {
-				"minipass": "^3.0.0"
-			}
-		},
-		"minipass-fetch": {
-			"version": "1.4.1",
-			"resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
-			"integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
-			"optional": true,
-			"requires": {
-				"encoding": "^0.1.12",
-				"minipass": "^3.1.0",
-				"minipass-sized": "^1.0.3",
-				"minizlib": "^2.0.0"
-			}
-		},
-		"minipass-flush": {
-			"version": "1.0.5",
-			"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
-			"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
-			"optional": true,
-			"requires": {
-				"minipass": "^3.0.0"
-			}
-		},
-		"minipass-pipeline": {
-			"version": "1.2.4",
-			"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
-			"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
-			"optional": true,
-			"requires": {
-				"minipass": "^3.0.0"
-			}
-		},
-		"minipass-sized": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
-			"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
-			"optional": true,
-			"requires": {
-				"minipass": "^3.0.0"
-			}
-		},
-		"minizlib": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
-			"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
-			"requires": {
-				"minipass": "^3.0.0",
-				"yallist": "^4.0.0"
-			}
-		},
-		"mkdirp": {
-			"version": "1.0.4",
-			"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-			"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
-		},
 		"ms": {
 			"version": "2.1.2",
 			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -5738,86 +4571,6 @@
 				"tslib": "^2.0.3"
 			}
 		},
-		"node-addon-api": {
-			"version": "4.3.0",
-			"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
-			"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
-		},
-		"node-fetch": {
-			"version": "2.6.7",
-			"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-			"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
-			"requires": {
-				"whatwg-url": "^5.0.0"
-			}
-		},
-		"node-gyp": {
-			"version": "8.4.1",
-			"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
-			"integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
-			"optional": true,
-			"requires": {
-				"env-paths": "^2.2.0",
-				"glob": "^7.1.4",
-				"graceful-fs": "^4.2.6",
-				"make-fetch-happen": "^9.1.0",
-				"nopt": "^5.0.0",
-				"npmlog": "^6.0.0",
-				"rimraf": "^3.0.2",
-				"semver": "^7.3.5",
-				"tar": "^6.1.2",
-				"which": "^2.0.2"
-			},
-			"dependencies": {
-				"are-we-there-yet": {
-					"version": "3.0.0",
-					"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz",
-					"integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==",
-					"optional": true,
-					"requires": {
-						"delegates": "^1.0.0",
-						"readable-stream": "^3.6.0"
-					}
-				},
-				"gauge": {
-					"version": "4.0.4",
-					"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
-					"integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
-					"optional": true,
-					"requires": {
-						"aproba": "^1.0.3 || ^2.0.0",
-						"color-support": "^1.1.3",
-						"console-control-strings": "^1.1.0",
-						"has-unicode": "^2.0.1",
-						"signal-exit": "^3.0.7",
-						"string-width": "^4.2.3",
-						"strip-ansi": "^6.0.1",
-						"wide-align": "^1.1.5"
-					}
-				},
-				"nopt": {
-					"version": "5.0.0",
-					"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
-					"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
-					"optional": true,
-					"requires": {
-						"abbrev": "1"
-					}
-				},
-				"npmlog": {
-					"version": "6.0.2",
-					"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
-					"integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
-					"optional": true,
-					"requires": {
-						"are-we-there-yet": "^3.0.0",
-						"console-control-strings": "^1.1.0",
-						"gauge": "^4.0.3",
-						"set-blocking": "^2.0.0"
-					}
-				}
-			}
-		},
 		"nodemon": {
 			"version": "2.0.16",
 			"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz",
@@ -5889,17 +4642,6 @@
 			"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
 			"dev": true
 		},
-		"npmlog": {
-			"version": "5.0.1",
-			"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
-			"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
-			"requires": {
-				"are-we-there-yet": "^2.0.0",
-				"console-control-strings": "^1.1.0",
-				"gauge": "^3.0.0",
-				"set-blocking": "^2.0.0"
-			}
-		},
 		"nth-check": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
@@ -5908,11 +4650,6 @@
 				"boolbase": "^1.0.0"
 			}
 		},
-		"object-assign": {
-			"version": "4.1.1",
-			"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-			"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-		},
 		"object-inspect": {
 			"version": "1.12.0",
 			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
@@ -5930,6 +4667,7 @@
 			"version": "1.4.0",
 			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
 			"requires": {
 				"wrappy": "1"
 			}
@@ -5940,15 +4678,6 @@
 			"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
 			"dev": true
 		},
-		"p-map": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
-			"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
-			"optional": true,
-			"requires": {
-				"aggregate-error": "^3.0.0"
-			}
-		},
 		"package-json": {
 			"version": "6.5.0",
 			"resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
@@ -6013,7 +4742,8 @@
 		"path-is-absolute": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+			"dev": true
 		},
 		"picocolors": {
 			"version": "1.0.0",
@@ -6048,22 +4778,6 @@
 			"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
 			"dev": true
 		},
-		"promise-inflight": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
-			"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
-			"optional": true
-		},
-		"promise-retry": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
-			"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
-			"optional": true,
-			"requires": {
-				"err-code": "^2.0.2",
-				"retry": "^0.12.0"
-			}
-		},
 		"proxy-addr": {
 			"version": "2.0.7",
 			"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -6153,16 +4867,6 @@
 				}
 			}
 		},
-		"readable-stream": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-			"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-			"requires": {
-				"inherits": "^2.0.3",
-				"string_decoder": "^1.1.1",
-				"util-deprecate": "^1.0.1"
-			}
-		},
 		"readdirp": {
 			"version": "3.6.0",
 			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -6204,16 +4908,11 @@
 				"lowercase-keys": "^1.0.0"
 			}
 		},
-		"retry": {
-			"version": "0.12.0",
-			"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
-			"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
-			"optional": true
-		},
 		"rimraf": {
 			"version": "3.0.2",
 			"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
 			"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+			"dev": true,
 			"requires": {
 				"glob": "^7.1.3"
 			}
@@ -6291,6 +4990,7 @@
 			"version": "7.3.7",
 			"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
 			"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+			"dev": true,
 			"requires": {
 				"lru-cache": "^6.0.0"
 			}
@@ -6370,11 +5070,6 @@
 				"send": "0.18.0"
 			}
 		},
-		"set-blocking": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-			"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
-		},
 		"setprototypeof": {
 			"version": "1.2.0",
 			"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -6393,34 +5088,8 @@
 		"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=="
-		},
-		"smart-buffer": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
-			"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
-			"optional": true
-		},
-		"socks": {
-			"version": "2.6.2",
-			"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
-			"integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
-			"optional": true,
-			"requires": {
-				"ip": "^1.1.5",
-				"smart-buffer": "^4.2.0"
-			}
-		},
-		"socks-proxy-agent": {
-			"version": "6.2.0",
-			"resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz",
-			"integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==",
-			"optional": true,
-			"requires": {
-				"agent-base": "^6.0.2",
-				"debug": "^4.3.3",
-				"socks": "^2.6.2"
-			}
+			"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+			"dev": true
 		},
 		"source-map": {
 			"version": "0.6.1",
@@ -6441,39 +5110,11 @@
 				"source-map": "^0.6.0"
 			}
 		},
-		"sqlite3": {
-			"version": "5.0.8",
-			"resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.8.tgz",
-			"integrity": "sha512-f2ACsbSyb2D1qFFcqIXPfFscLtPVOWJr5GmUzYxf4W+0qelu5MWrR+FAQE1d5IUArEltBrzSDxDORG8P/IkqyQ==",
-			"requires": {
-				"@mapbox/node-pre-gyp": "^1.0.0",
-				"node-addon-api": "^4.2.0",
-				"node-gyp": "8.x",
-				"tar": "^6.1.11"
-			}
-		},
-		"ssri": {
-			"version": "8.0.1",
-			"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
-			"integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
-			"optional": true,
-			"requires": {
-				"minipass": "^3.1.1"
-			}
-		},
 		"statuses": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
 			"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
 		},
-		"string_decoder": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-			"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-			"requires": {
-				"safe-buffer": "~5.2.0"
-			}
-		},
 		"string-comparison": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/string-comparison/-/string-comparison-1.1.0.tgz",
@@ -6483,6 +5124,7 @@
 			"version": "4.2.3",
 			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
 			"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+			"dev": true,
 			"requires": {
 				"emoji-regex": "^8.0.0",
 				"is-fullwidth-code-point": "^3.0.0",
@@ -6493,6 +5135,7 @@
 			"version": "6.0.1",
 			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
 			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+			"dev": true,
 			"requires": {
 				"ansi-regex": "^5.0.1"
 			}
@@ -6506,19 +5149,6 @@
 				"has-flag": "^4.0.0"
 			}
 		},
-		"tar": {
-			"version": "6.1.11",
-			"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
-			"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
-			"requires": {
-				"chownr": "^2.0.0",
-				"fs-minipass": "^2.0.0",
-				"minipass": "^3.0.0",
-				"minizlib": "^2.1.1",
-				"mkdirp": "^1.0.3",
-				"yallist": "^4.0.0"
-			}
-		},
 		"terser": {
 			"version": "5.13.1",
 			"resolved": "https://registry.npmjs.org/terser/-/terser-5.13.1.tgz",
@@ -6597,11 +5227,6 @@
 				"nopt": "~1.0.10"
 			}
 		},
-		"tr46": {
-			"version": "0.0.3",
-			"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-			"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
-		},
 		"ts-node": {
 			"version": "10.7.0",
 			"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz",
@@ -6669,24 +5294,6 @@
 			"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
 			"dev": true
 		},
-		"unique-filename": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
-			"integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
-			"optional": true,
-			"requires": {
-				"unique-slug": "^2.0.0"
-			}
-		},
-		"unique-slug": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
-			"integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
-			"optional": true,
-			"requires": {
-				"imurmurhash": "^0.1.4"
-			}
-		},
 		"unique-string": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -6732,11 +5339,6 @@
 				"prepend-http": "^2.0.0"
 			}
 		},
-		"util-deprecate": {
-			"version": "1.0.2",
-			"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-			"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
-		},
 		"utils-merge": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -6753,37 +5355,6 @@
 			"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
 			"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
 		},
-		"webidl-conversions": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-			"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
-		},
-		"whatwg-url": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-			"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
-			"requires": {
-				"tr46": "~0.0.3",
-				"webidl-conversions": "^3.0.0"
-			}
-		},
-		"which": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-			"optional": true,
-			"requires": {
-				"isexe": "^2.0.0"
-			}
-		},
-		"wide-align": {
-			"version": "1.1.5",
-			"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
-			"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
-			"requires": {
-				"string-width": "^1.0.2 || 2 || 3 || 4"
-			}
-		},
 		"widest-line": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
@@ -6807,7 +5378,8 @@
 		"wrappy": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
 		},
 		"write-file-atomic": {
 			"version": "3.0.3",
@@ -6830,7 +5402,8 @@
 		"yallist": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+			"dev": true
 		},
 		"yn": {
 			"version": "3.1.1",
diff --git a/package.json b/package.json
index e90bf30..139c6d0 100644
--- a/package.json
+++ b/package.json
@@ -28,8 +28,7 @@
 		"article-parser": "^5.0.4",
 		"dotenv": "^16.0.1",
 		"express": "^4.18.1",
-		"express-async-errors": "^3.1.1",
-		"sqlite3": "^5.0.8"
+		"express-async-errors": "^3.1.1"
 	},
 	"prettier": {
 		"printWidth": 100,
diff --git a/src/config.ts b/src/config.ts
index 4f50f95..9522df6 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -23,7 +23,7 @@ const confSchema: Shape[] = [
 	},
 	{
 		key: 'db_file',
-		def: '/data/db',
+		def: '/data/db.json',
 		env: 'DB_FILE',
 		validate: (value) => typeof value === 'string' && value.length > 0,
 	},
diff --git a/src/database.ts b/src/database.ts
new file mode 100644
index 0000000..b27c416
--- /dev/null
+++ b/src/database.ts
@@ -0,0 +1,99 @@
+import { writeFile, existsSync, readFileSync, mkdir, PathLike } from 'fs'
+import { dirname } from 'path'
+
+import config from './config'
+import { ArticleData } from 'article-parser'
+
+interface Article extends ArticleData {
+	added: Date
+	id: number
+}
+
+let DB: Article[] = []
+let skipWriting = false
+
+let load = () => {
+	let data
+	if (existsSync(config.db_file as PathLike)) {
+		data = readFileSync(config.db_file as PathLike).toString()
+		if (data.length > 0 && data !== '[]' && !(JSON.parse(data) as Article[])) {
+			console.error('Database file exists but is not valid! DATA WILL NOT BE SAVED!!')
+			skipWriting = true
+		} else {
+			DB = JSON.parse(data) as Article[]
+		}
+	}
+}
+load()
+
+let update = () => {
+	if (!skipWriting) {
+		mkdir(dirname(config.db_file as string), { recursive: true }, (err) => {
+			if (err) {
+				console.error('Unable to create database directory!')
+				throw err
+			}
+
+			writeFile(config.db_file as PathLike, JSON.stringify(DB), (err) => {
+				if (err) {
+					console.error('Unable to update database file!')
+					throw err
+				}
+				console.log('Database written to file successfully.')
+			})
+		})
+	}
+}
+
+export default {
+	add: (article: Article) => {
+		DB.push(article)
+		update()
+	},
+	get: (index: number) => {
+		if (index < 0){
+			index += DB.length
+		}
+		return DB[index]
+	},
+	getAll: () => {
+		return DB
+	}
+}
+
+/////// Below is my attempt to use sqlite3. I failed. Please help D:
+
+// import config from './config'
+// import { ArticleData } from 'article-parser'
+
+// const db = require('better-sqlite3')(config.db_file)
+// // prettier-ignore
+// db.prepare(`
+// 	CREATE TABLE articles(
+// 		id           INT      PRIMARY KEY,
+// 		url          TEXT,
+// 		links        TEXT,
+// 		title        TEXT,
+// 		description  TEXT,
+// 		image        TEXT,
+// 		author       TEXT,
+// 		content      TEXT,
+// 		source       TEXT,
+// 		published    TEXT,
+// 		added        TEXT,
+// 		ttr          INT
+// 	)
+// `).run()
+
+// interface Article extends ArticleData {
+// 	added: Date
+// 	id: number
+// }
+
+// let insert = (article: Article) => {
+// 	db.prepare(
+// 		'INSERT INTO articles VALUES (@id, @url, @links, @title, @description, @image, @author, @content, @source, @published, @added, @ttr)'
+// 	).run(article)
+// }
+
+// export { insert }
diff --git a/src/routes.ts b/src/routes.ts
index 917e975..b06d7ec 100644
--- a/src/routes.ts
+++ b/src/routes.ts
@@ -1,16 +1,16 @@
 import { Express, Router, Request, Response } from 'express'

+import db from './database'
 import config from './config'

 import noCache from './middleware/no-cache'
 import cacheForever from './middleware/cache-forever'

 import { extract, ArticleData } from 'article-parser'
-
-interface ArticleDataWithDateAdded extends ArticleData {
+interface Article extends ArticleData {
 	added: Date
+	id: number
 }
-let fakeDB: ArticleDataWithDateAdded[] = []

 const router = Router()

@@ -22,7 +22,7 @@ router.get('/robots.txt', cacheForever(), (_: Request, res: Response) => {
 })

 router.get('/healthcheck', noCache(), (_: Request, res: Response) => {
-	res.json({ timestamp: new Date() })
+	res.json({ timestamp: Date.now() })
 })

 router.get('/add', noCache(), (req: Request, res: Response) => {
@@ -40,10 +40,11 @@ router.get('/add', noCache(), (req: Request, res: Response) => {

 	extract(url)
 		.then((article) => {
-			fakeDB.push(
+			db.add(
 				Object.assign(article, {
 					added: new Date(),
-				}) as ArticleDataWithDateAdded
+					id: Date.now(),
+				}) as Article
 			)
 			return res.sendStatus(200)
 		})
@@ -68,15 +69,15 @@ router.get('/feed', (req: Request, res: Response) => {
 	<description>Articles saved to be read later</description>
 	<generator>readerss</generator>
 	<language>en</language>
-	<pubDate>${new Date(fakeDB[0]?.added).toUTCString()}</pubDate>
+	<pubDate>${new Date(db.get(-1).added).toUTCString()}</pubDate>
 `

-	for (var entry of fakeDB) {
+	for (var entry of db.getAll()) {
 		rss += `
 	<item>
 		<title>${entry.title}</title>
 		<link>${entry.url}</link>
-		<guid>${entry.url}</guid>
+		<guid>${entry.id}</guid>
 		<pubDate>${entry.added}</pubDate>
 		<description><![CDATA[${entry.description}]]></description>
 		<content:encoded><![CDATA[${entry.content}]]></content:encoded>
0dd7575
Reese Sapphire committed on May 16 2022:
add config

- added config schema and default values
- parse config from environment variables
- moved routes/route.ts to routes.ts because it doesn't need to be in its own folder

diff --git a/README.md b/README.md
index d688dcb..6e9651f 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,9 @@ basic express server for saving online articles to read later.
   - [x] add an article
   - [x] RSS endpoint so you can sync it with your feed aggregator of choice
   - [ ] delete an article?
+- [x] get configuration from environment variables
 - [ ] add a database (sqlite, probably)
+- [ ] add docker support
 - [ ] make a browser bookmarklet for quickly saving articles
 - [ ] log some useful info on startup, like the bookmarklet code
 - [ ] find a slightly better name
diff --git a/development.env b/development.env
deleted file mode 100644
index 174795d..0000000
--- a/development.env
+++ /dev/null
@@ -1,8 +0,0 @@
-NODE_ENV=development
-
-PORT=3000
-API_KEY=PDJnWhbU2qRNPVvNfNvs3vXNlmMcbKP8dS+pd7Yay40
-DATABASE_FILE=:memory:
-
-FEED_TITLE=
-FEED_DESCRIPTION=
diff --git a/sample.env b/sample.env
index 634c77b..9e0a179 100644
--- a/sample.env
+++ b/sample.env
@@ -2,7 +2,7 @@ NODE_ENV=production

 PORT=3000
 API_KEY=change this!!
-DATABASE_FILE=/data/db.sqlite
+DB_FILE=/data/db.sqlite

 FEED_TITLE=
 FEED_DESCRIPTION=
diff --git a/src/app.ts b/src/app.ts
index cc024fc..6f17b87 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -1,7 +1,7 @@
 import express, { NextFunction, Request, Response, Express } from 'express'
 import 'express-async-errors'

-import route from './routes/route'
+import route from './routes'

 export const app = (app = express()): Express => {
 	route(app)
diff --git a/src/config.ts b/src/config.ts
index 1f357c9..4f50f95 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,6 +1,50 @@
-import dotenv from 'dotenv';
-dotenv.config();
+import dotenv from 'dotenv'
+dotenv.config()

 // TODO: do some processing on the env variables, include some sane defaults

-export default {...process.env}
+interface Shape {
+	key: string
+	def: string | number // default value ('default' is a reserved keyword, so i used 'def')
+	env: string
+	validate?: (value: any) => boolean
+}
+const confSchema: Shape[] = [
+	{
+		key: 'port',
+		def: 3000,
+		env: 'PORT',
+	},
+	{
+		key: 'api_key',
+		def: '',
+		env: 'API_KEY',
+		validate: (value) => typeof value === 'string' && value.length > 0,
+	},
+	{
+		key: 'db_file',
+		def: '/data/db',
+		env: 'DB_FILE',
+		validate: (value) => typeof value === 'string' && value.length > 0,
+	},
+	{
+		key: 'feed_title',
+		def: 'Reading list',
+		env: 'FEED_TITLE',
+	},
+	{
+		key: 'feed_desc',
+		def: 'Articles saved to be read later',
+		env: 'FEED_DESCRIPTION',
+	},
+]
+
+interface Conf {
+	[name: string]: string | number
+}
+let envConf: Conf = {}
+for (var item of confSchema) {
+	envConf[item.key] = (process.env[item.env] as string | number | undefined) || item.def
+}
+
+export default envConf
diff --git a/src/routes/route.ts b/src/routes.ts
similarity index 72%
rename from src/routes/route.ts
rename to src/routes.ts
index fd88bcd..917e975 100644
--- a/src/routes/route.ts
+++ b/src/routes.ts
@@ -1,8 +1,9 @@
 import { Express, Router, Request, Response } from 'express'

-import '../config'
-import noCache from '../middleware/no-cache'
-import cacheForever from '../middleware/cache-forever'
+import config from './config'
+
+import noCache from './middleware/no-cache'
+import cacheForever from './middleware/cache-forever'

 import { extract, ArticleData } from 'article-parser'

@@ -13,9 +14,7 @@ let fakeDB: ArticleDataWithDateAdded[] = []

 const router = Router()

-router.get('/favicon.ico', cacheForever(), (_: Request, res: Response) =>
-	res.sendStatus(204)
-)
+router.get('/favicon.ico', cacheForever(), (_: Request, res: Response) => res.sendStatus(204))

 router.get('/robots.txt', cacheForever(), (_: Request, res: Response) => {
 	res.type('text/plain')
@@ -27,32 +26,35 @@ router.get('/healthcheck', noCache(), (_: Request, res: Response) => {
 })

 router.get('/add', noCache(), (req: Request, res: Response) => {
-	if (!req.query.key || req.query.key !== process.env.API_KEY){
-		console.warn(`Unauthorized add attempt from ${req.ip} !`)
+	if (!req.query.key || req.query.key != config.api_key) {
 		return res.sendStatus(401)
 	}
 	console.info(`Authorized add from ${req.ip}`)

-	if (!req.query.url){
+	if (!req.query.url) {
 		console.error('URL not valid. Skipping...')
 		return res.sendStatus(400)
 	}
 	console.info(`Adding ${req.query.url}`)
 	let url = decodeURIComponent(req.query.url as string)

-	extract(url).then((article) => {
-		fakeDB.push(Object.assign(article, {
-			added: new Date()
-		}) as ArticleDataWithDateAdded)
-		return res.sendStatus(200)
-	}).catch((err) => {
-		console.trace(err)
-		return res.sendStatus(500)
-	})
+	extract(url)
+		.then((article) => {
+			fakeDB.push(
+				Object.assign(article, {
+					added: new Date(),
+				}) as ArticleDataWithDateAdded
+			)
+			return res.sendStatus(200)
+		})
+		.catch((err) => {
+			console.trace(err)
+			return res.sendStatus(500)
+		})
 })

 router.get('/feed', (req: Request, res: Response) => {
-	if (!req.query.key || req.query.key !== process.env.API_KEY){
+	if (!req.query.key || req.query.key != config.api_key) {
 		console.warn(`Unauthorized feed attempt from ${req.ip} !`)
 		return res.sendStatus(401)
 	}
@@ -67,9 +69,9 @@ router.get('/feed', (req: Request, res: Response) => {
 	<generator>readerss</generator>
 	<language>en</language>
 	<pubDate>${new Date(fakeDB[0]?.added).toUTCString()}</pubDate>
-`;
+`

-	for (var entry of fakeDB){
+	for (var entry of fakeDB) {
 		rss += `
 	<item>
 		<title>${entry.title}</title>
@@ -79,17 +81,16 @@ router.get('/feed', (req: Request, res: Response) => {
 		<description><![CDATA[${entry.description}]]></description>
 		<content:encoded><![CDATA[${entry.content}]]></content:encoded>
 	</item>
-`;
+`
 	}

 	rss += `
 </channel>
 </rss>
-`;
+`
 	res.send(rss)
 })

-
 export default (app: Express): void => {
 	app.use(router)
 }
diff --git a/src/server.ts b/src/server.ts
index 5b0268a..2e766c0 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -1,4 +1,4 @@
-// import config from './config';
-import { app } from './app';
+import config from './config'
+import { app } from './app'

-app().listen(3000, () => console.info(`Listening on port 3000`));
+app().listen(config.port, () => console.info(`Listening on port ${config.port}`))
116f153
Reese Sapphire committed on May 16 2022:
update readme

- added some improved documentation about where this project is headed
diff --git a/README.md b/README.md
index 1a77556..d688dcb 100644
--- a/README.md
+++ b/README.md
@@ -4,10 +4,15 @@ basic express server for saving online articles to read later.

 ### To do

-- [x] a basic API so you can save articles with a web browser bookmarklet
-- [x] an RSS endpoint so you can sync it with your feed aggregator of choice
+- [x] basic API
+  - [x] add an article
+  - [x] RSS endpoint so you can sync it with your feed aggregator of choice
+  - [ ] delete an article?
 - [ ] add a database (sqlite, probably)
+- [ ] make a browser bookmarklet for quickly saving articles
+- [ ] log some useful info on startup, like the bookmarklet code
+- [ ] find a slightly better name

 ### Will not do

-- no frontend, i'm keeping it simple. why not make one yourself? 😉
+- make a frontend. i'm keeping it simple, why not fork it and add one yourself? 😉
795cf7a
Reese Sapphire committed on May 15 2022:
start of project
7d5434e