mirror of
				https://github.com/C4illin/ConvertX.git
				synced 2025-11-04 14:03:32 +00:00 
			
		
		
		
	Compare commits
	
		
			68 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5b6e70eb3a | ||
| 
						 | 
					cdae798fcf | ||
| 
						 | 
					bcc827a81b | ||
| 
						 | 
					84274b9c55 | ||
| 
						 | 
					20c6f8249e | ||
| 
						 | 
					8f0ea2a592 | ||
| 
						 | 
					a29e4a930a | ||
| 
						 | 
					4549c96ae3 | ||
| 
						 | 
					bc64094c04 | ||
| 
						 | 
					fa58827ad5 | ||
| 
						 | 
					8f27be0e3d | ||
| 
						 | 
					df43df1178 | ||
| 
						 | 
					c2beb4a227 | ||
| 
						 | 
					9277c27a50 | ||
| 
						 | 
					171ecd6884 | ||
| 
						 | 
					dca29f7e5a | ||
| 
						 | 
					318acc20bd | ||
| 
						 | 
					f433493d57 | ||
| 
						 | 
					19970fc132 | ||
| 
						 | 
					24394ca3c5 | ||
| 
						 | 
					10ff0b464a | ||
| 
						 | 
					9263d17609 | ||
| 
						 | 
					c1b75a13fd | ||
| 
						 | 
					a8ed60d48f | ||
| 
						 | 
					dc82a438d4 | ||
| 
						 | 
					cc54bdcbe7 | ||
| 
						 | 
					ae4bbc8baa | ||
| 
						 | 
					ad98499da0 | ||
| 
						 | 
					db60f355b2 | ||
| 
						 | 
					eb91d8b298 | ||
| 
						 | 
					b8312be4b7 | ||
| 
						 | 
					326a8e3404 | ||
| 
						 | 
					f017e13ac1 | ||
| 
						 | 
					67a5fe353e | ||
| 
						 | 
					51d49d7ff3 | ||
| 
						 | 
					d42b820b36 | ||
| 
						 | 
					07d32776d3 | ||
| 
						 | 
					ef027e81b5 | ||
| 
						 | 
					a75e4b495d | ||
| 
						 | 
					fba5e212e8 | ||
| 
						 | 
					62f44fb052 | ||
| 
						 | 
					6b9254047c | ||
| 
						 | 
					decfea5dc9 | ||
| 
						 | 
					eacded6848 | ||
| 
						 | 
					279ca72c64 | ||
| 
						 | 
					b8fc9383ca | ||
| 
						 | 
					bec58ac59f | ||
| 
						 | 
					83d7126820 | ||
| 
						 | 
					f0e9c6d794 | ||
| 
						 | 
					0e61051fc6 | ||
| 
						 | 
					480ba77ebe | ||
| 
						 | 
					16f27c13bb | ||
| 
						 | 
					afe5c50d66 | ||
| 
						 | 
					72ea859ebb | ||
| 
						 | 
					8edf3834c4 | ||
| 
						 | 
					e595014fcd | ||
| 
						 | 
					8bebf7e569 | ||
| 
						 | 
					c825ec06e2 | ||
| 
						 | 
					8c75f273fb | ||
| 
						 | 
					0ba776c129 | ||
| 
						 | 
					2bbbd03554 | ||
| 
						 | 
					0a5d0487b1 | ||
| 
						 | 
					583cd2dd3b | ||
| 
						 | 
					e1f7fc1ecb | ||
| 
						 | 
					961a55cbe5 | ||
| 
						 | 
					cdf9bad903 | ||
| 
						 | 
					6769fa2f83 | ||
| 
						 | 
					3b7ea88b73 | 
@@ -1,20 +1,19 @@
 | 
			
		||||
.dockerignore
 | 
			
		||||
.editorconfig
 | 
			
		||||
.env
 | 
			
		||||
.git
 | 
			
		||||
.gitignore
 | 
			
		||||
.idea
 | 
			
		||||
.vscode
 | 
			
		||||
CHANGELOG.md
 | 
			
		||||
coverage*
 | 
			
		||||
data
 | 
			
		||||
docker-compose*
 | 
			
		||||
Dockerfile*
 | 
			
		||||
eslint.config.js
 | 
			
		||||
helm-charts
 | 
			
		||||
LICENSE
 | 
			
		||||
Makefile
 | 
			
		||||
node_modules
 | 
			
		||||
prettier.config.js
 | 
			
		||||
README.md
 | 
			
		||||
.dockerignore
 | 
			
		||||
.editorconfig
 | 
			
		||||
.env
 | 
			
		||||
.git
 | 
			
		||||
.idea
 | 
			
		||||
.vscode
 | 
			
		||||
CHANGELOG.md
 | 
			
		||||
coverage*
 | 
			
		||||
data
 | 
			
		||||
docker-compose*
 | 
			
		||||
Dockerfile*
 | 
			
		||||
eslint.config.js
 | 
			
		||||
helm-charts
 | 
			
		||||
LICENSE
 | 
			
		||||
Makefile
 | 
			
		||||
node_modules
 | 
			
		||||
prettier.config.js
 | 
			
		||||
README.md
 | 
			
		||||
renovate.json
 | 
			
		||||
							
								
								
									
										53
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,58 @@
 | 
			
		||||
# Changelog
 | 
			
		||||
 | 
			
		||||
## [0.12.1](https://github.com/C4illin/ConvertX/compare/v0.12.0...v0.12.1) (2025-03-20)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Bug Fixes
 | 
			
		||||
 | 
			
		||||
* change to canary bun ([20c6f82](https://github.com/C4illin/ConvertX/commit/20c6f8249e03e03f4517e5b8b0d421cb6291bc1a))
 | 
			
		||||
* change to canary bun ([8f0ea2a](https://github.com/C4illin/ConvertX/commit/8f0ea2a592f01af176caa745020f0a3514945357)), closes [#235](https://github.com/C4illin/ConvertX/issues/235)
 | 
			
		||||
 | 
			
		||||
## [0.12.0](https://github.com/C4illin/ConvertX/compare/v0.11.1...v0.12.0) (2025-03-06)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
 | 
			
		||||
* added progress bar for file upload ([db60f35](https://github.com/C4illin/ConvertX/commit/db60f355b2973f43f8e5990e6fe4e351b959b659))
 | 
			
		||||
* made every upload file independent ([cc54bdc](https://github.com/C4illin/ConvertX/commit/cc54bdcbe764c41cc3273485d072fd3178ad2dca))
 | 
			
		||||
* replace exec with execFile ([9263d17](https://github.com/C4illin/ConvertX/commit/9263d17609dc4b2b367eb7fee67b3182e283b3a3))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Bug Fixes
 | 
			
		||||
 | 
			
		||||
* add libheif ([6b92540](https://github.com/C4illin/ConvertX/commit/6b9254047c0598963aee1d99e20ba1650a0368bf))
 | 
			
		||||
* add libheif ([decfea5](https://github.com/C4illin/ConvertX/commit/decfea5dc9627b216bb276a9e1578c32cfa1deb6)), closes [#202](https://github.com/C4illin/ConvertX/issues/202)
 | 
			
		||||
* added onerror log ([ae4bbc8](https://github.com/C4illin/ConvertX/commit/ae4bbc8baacbaf67763c62ea44140bb21cc17230))
 | 
			
		||||
* refactored uploadFile to only accept a single file instead of multiple ([dc82a43](https://github.com/C4illin/ConvertX/commit/dc82a438d4104b79ff423d502a6779a43928968a))
 | 
			
		||||
* update libheif to 1.19.5 ([fba5e21](https://github.com/C4illin/ConvertX/commit/fba5e212e8d0eaba8971e239e35aeb521f3cd813)), closes [#202](https://github.com/C4illin/ConvertX/issues/202)
 | 
			
		||||
 | 
			
		||||
## [0.11.1](https://github.com/C4illin/ConvertX/compare/v0.11.0...v0.11.1) (2025-02-07)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Bug Fixes
 | 
			
		||||
 | 
			
		||||
* mobile view overflow ([bec58ac](https://github.com/C4illin/ConvertX/commit/bec58ac59f9600e35385b9e21d174f3ab1b42b1d))
 | 
			
		||||
 | 
			
		||||
## [0.11.0](https://github.com/C4illin/ConvertX/compare/v0.10.1...v0.11.0) (2025-02-05)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
 | 
			
		||||
* add deps for vaapi ([2bbbd03](https://github.com/C4illin/ConvertX/commit/2bbbd03554d384a4488143f29e5fc863cfdf333b)), closes [#192](https://github.com/C4illin/ConvertX/issues/192)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Bug Fixes
 | 
			
		||||
 | 
			
		||||
* don't crash if file is not found ([16f27c1](https://github.com/C4illin/ConvertX/commit/16f27c13bbc1c0e5fa2316f3db11d0918524053b))
 | 
			
		||||
* install numpy for inkscape ([0e61051](https://github.com/C4illin/ConvertX/commit/0e61051fc6be188164c3865b4fb579c140859fdc))
 | 
			
		||||
 | 
			
		||||
## [0.10.1](https://github.com/C4illin/ConvertX/compare/v0.10.0...v0.10.1) (2025-01-21)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Bug Fixes
 | 
			
		||||
 | 
			
		||||
* ffmpeg works without ffmpeg_args ([3b7ea88](https://github.com/C4illin/ConvertX/commit/3b7ea88b7382f7c21b120bdc9bda5bb10547f55d)), closes [#212](https://github.com/C4illin/ConvertX/issues/212)
 | 
			
		||||
 | 
			
		||||
## [0.10.0](https://github.com/C4illin/ConvertX/compare/v0.9.0...v0.10.0) (2025-01-18)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
FROM oven/bun:1.1.45-alpine AS base
 | 
			
		||||
FROM oven/bun:1.2.2-alpine AS base
 | 
			
		||||
LABEL org.opencontainers.image.source="https://github.com/C4illin/ConvertX"
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
 | 
			
		||||
@@ -6,12 +6,12 @@ WORKDIR /app
 | 
			
		||||
# this will cache them and speed up future builds
 | 
			
		||||
FROM base AS install
 | 
			
		||||
RUN mkdir -p /temp/dev
 | 
			
		||||
COPY package.json bun.lockb /temp/dev/
 | 
			
		||||
COPY package.json bun.lock /temp/dev/
 | 
			
		||||
RUN cd /temp/dev && bun install --frozen-lockfile
 | 
			
		||||
 | 
			
		||||
# install with --production (exclude devDependencies)
 | 
			
		||||
RUN mkdir -p /temp/prod
 | 
			
		||||
COPY package.json bun.lockb /temp/prod/
 | 
			
		||||
COPY package.json bun.lock /temp/prod/
 | 
			
		||||
RUN cd /temp/prod && bun install --frozen-lockfile --production
 | 
			
		||||
 | 
			
		||||
FROM base AS builder
 | 
			
		||||
@@ -20,22 +20,18 @@ ENV PATH=/root/.cargo/bin:$PATH
 | 
			
		||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
 | 
			
		||||
RUN cargo install resvg
 | 
			
		||||
 | 
			
		||||
# copy node_modules from temp directory
 | 
			
		||||
# then copy all (non-ignored) project files into the image
 | 
			
		||||
FROM base AS prerelease
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
COPY --from=install /temp/dev/node_modules node_modules
 | 
			
		||||
COPY . .
 | 
			
		||||
 | 
			
		||||
# # [optional] tests & build
 | 
			
		||||
ENV NODE_ENV=production
 | 
			
		||||
# RUN bun test
 | 
			
		||||
# ENV NODE_ENV=production
 | 
			
		||||
RUN bun run build
 | 
			
		||||
 | 
			
		||||
# copy production dependencies and source code into final image
 | 
			
		||||
FROM base AS release
 | 
			
		||||
LABEL maintainer="Emrik Östling (C4illin)"
 | 
			
		||||
LABEL description="ConvertX: self-hosted online file converter supporting 700+ file formats."
 | 
			
		||||
LABEL repo="https://github.com/C4illin/ConvertX"
 | 
			
		||||
 | 
			
		||||
RUN apk --no-cache add qt6-qtbase-private-dev libheif-tools --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community/
 | 
			
		||||
 | 
			
		||||
# install additional dependencies
 | 
			
		||||
RUN apk --no-cache add  \
 | 
			
		||||
@@ -49,12 +45,15 @@ RUN apk --no-cache add  \
 | 
			
		||||
  vips-tools \
 | 
			
		||||
  vips-poppler \
 | 
			
		||||
  vips-jxl \
 | 
			
		||||
  vips-heif \
 | 
			
		||||
  vips-magick \
 | 
			
		||||
  libjxl-tools \
 | 
			
		||||
  assimp \
 | 
			
		||||
  inkscape \
 | 
			
		||||
  poppler-utils
 | 
			
		||||
 | 
			
		||||
RUN apk --no-cache add qt6-qtbase-private-dev --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community/
 | 
			
		||||
  poppler-utils \
 | 
			
		||||
  gcompat \
 | 
			
		||||
  libva-utils \
 | 
			
		||||
  py3-numpy
 | 
			
		||||
 | 
			
		||||
RUN apk --no-cache add calibre --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
 | 
			
		||||
 | 
			
		||||
@@ -64,8 +63,6 @@ RUN apk --no-cache add calibre --repository=http://dl-cdn.alpinelinux.org/alpine
 | 
			
		||||
COPY --from=install /temp/prod/node_modules node_modules
 | 
			
		||||
COPY --from=builder /root/.cargo/bin/resvg /usr/local/bin/resvg
 | 
			
		||||
COPY --from=prerelease /app/public/generated.css /app/public/
 | 
			
		||||
# COPY --from=prerelease /app/src/index.tsx /app/src/
 | 
			
		||||
# COPY --from=prerelease /app/package.json .
 | 
			
		||||
COPY . .
 | 
			
		||||
 | 
			
		||||
EXPOSE 3000/tcp
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ A self-hosted online file converter. Supports over a thousand different formats.
 | 
			
		||||
| [libjxl](https://github.com/libjxl/libjxl)                                   | JPEG XL       | 11            | 11          |
 | 
			
		||||
| [resvg](https://github.com/RazrFalcon/resvg)                                 | SVG           | 1             | 1           |
 | 
			
		||||
| [Vips](https://github.com/libvips/libvips)                                   | Images        | 45            | 23          |
 | 
			
		||||
| [libheif](https://github.com/strukturag/libheif)                             | HEIF          | 2             | 4           |
 | 
			
		||||
| [XeLaTeX](https://tug.org/xetex/)                                            | LaTeX         | 1             | 1           |
 | 
			
		||||
| [Calibre](https://calibre-ebook.com/)                                        | E-books       | 26            | 19          |
 | 
			
		||||
| [Pandoc](https://pandoc.org/)                                                | Documents     | 43            | 65          |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								SECURITY.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								SECURITY.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
# Security Policy
 | 
			
		||||
 | 
			
		||||
## Supported Versions
 | 
			
		||||
 | 
			
		||||
Only the latest release is supported
 | 
			
		||||
 | 
			
		||||
## Reporting a Vulnerability
 | 
			
		||||
 | 
			
		||||
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/C4illin/ConvertX/security/advisories/new) tab.
 | 
			
		||||
							
								
								
									
										936
									
								
								bun.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										936
									
								
								bun.lock
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,936 @@
 | 
			
		||||
{
 | 
			
		||||
  "lockfileVersion": 1,
 | 
			
		||||
  "workspaces": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "name": "convertx-frontend",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@elysiajs/html": "^1.2.0",
 | 
			
		||||
        "@elysiajs/jwt": "^1.2.0",
 | 
			
		||||
        "@elysiajs/static": "^1.2.0",
 | 
			
		||||
        "@kitajs/html": "^4.2.7",
 | 
			
		||||
        "elysia": "^1.2.12",
 | 
			
		||||
        "sanitize-filename": "^1.6.3",
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@eslint/js": "^9.19.0",
 | 
			
		||||
        "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
 | 
			
		||||
        "@kitajs/ts-html-plugin": "^4.1.1",
 | 
			
		||||
        "@tailwindcss/cli": "^4.0.4",
 | 
			
		||||
        "@tailwindcss/postcss": "^4.0.4",
 | 
			
		||||
        "@total-typescript/ts-reset": "^0.6.1",
 | 
			
		||||
        "@types/bun": "^1.2.2",
 | 
			
		||||
        "@types/eslint-plugin-tailwindcss": "^3.17.0",
 | 
			
		||||
        "@types/node": "^22.13.1",
 | 
			
		||||
        "autoprefixer": "^10.4.20",
 | 
			
		||||
        "cssnano": "^7.0.6",
 | 
			
		||||
        "eslint": "^9.19.0",
 | 
			
		||||
        "eslint-plugin-readable-tailwind": "^2.0.0-beta.4",
 | 
			
		||||
        "eslint-plugin-simple-import-sort": "^12.1.1",
 | 
			
		||||
        "eslint-plugin-tailwindcss": "4.0.0-alpha.0",
 | 
			
		||||
        "globals": "^16.0.0",
 | 
			
		||||
        "knip": "^5.43.6",
 | 
			
		||||
        "npm-run-all2": "^7.0.2",
 | 
			
		||||
        "postcss": "^8.5.1",
 | 
			
		||||
        "postcss-cli": "^11.0.0",
 | 
			
		||||
        "prettier": "^3.4.2",
 | 
			
		||||
        "tailwind-scrollbar": "^4.0.0",
 | 
			
		||||
        "tailwindcss": "^4.0.4",
 | 
			
		||||
        "typescript": "^5.7.3",
 | 
			
		||||
        "typescript-eslint": "^8.23.0",
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  "packages": {
 | 
			
		||||
    "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/generator": ["@babel/generator@7.26.5", "", { "dependencies": { "@babel/parser": "^7.26.5", "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/parser": ["@babel/parser@7.26.7", "", { "dependencies": { "@babel/types": "^7.26.7" }, "bin": "./bin/babel-parser.js" }, "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/template": ["@babel/template@7.25.9", "", { "dependencies": { "@babel/code-frame": "^7.25.9", "@babel/parser": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/traverse": ["@babel/traverse@7.26.7", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.5", "@babel/parser": "^7.26.7", "@babel/template": "^7.25.9", "@babel/types": "^7.26.7", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/types": ["@babel/types@7.26.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg=="],
 | 
			
		||||
 | 
			
		||||
    "@elysiajs/html": ["@elysiajs/html@1.2.0", "", { "dependencies": { "@kitajs/html": "^4.1.0", "@kitajs/ts-html-plugin": "^4.0.1" }, "peerDependencies": { "elysia": ">= 1.2.0" } }, "sha512-j/exB9TLn2/KOMWRfPcJ7MNOsmr85uHRjC+kKPLyb1lRtNDWzgab4deUQrxtIv4gt4PDSKmywNnhyD+GrdnH3w=="],
 | 
			
		||||
 | 
			
		||||
    "@elysiajs/jwt": ["@elysiajs/jwt@1.2.0", "", { "dependencies": { "jose": "^4.14.4" }, "peerDependencies": { "elysia": ">= 1.2.0" } }, "sha512-5iMoZucIKNAqPKW3n6RBIyCnDWG3kOcqA4WZKtqEff+IjV6AN3dlMSE2XsS0xjIvusLD0UBXS8cxQ9NwIcj6ew=="],
 | 
			
		||||
 | 
			
		||||
    "@elysiajs/static": ["@elysiajs/static@1.2.0", "", { "dependencies": { "node-cache": "^5.1.2" }, "peerDependencies": { "elysia": ">= 1.2.0" } }, "sha512-oLpAi8c+maPpA0XhhK3BELaIjIG+nXg/K9p8cFfW4q5ayRD59a3MOMOOGgpiXZkHJzLPWcouhhyyLAYtaANW4g=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/config-array": ["@eslint/config-array@0.19.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/core": ["@eslint/core@0.10.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/eslintrc": ["@eslint/eslintrc@3.2.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/js": ["@eslint/js@9.19.0", "", {}, "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.5", "", { "dependencies": { "@eslint/core": "^0.10.0", "levn": "^0.4.1" } }, "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A=="],
 | 
			
		||||
 | 
			
		||||
    "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
 | 
			
		||||
 | 
			
		||||
    "@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
 | 
			
		||||
 | 
			
		||||
    "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="],
 | 
			
		||||
 | 
			
		||||
    "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
 | 
			
		||||
 | 
			
		||||
    "@humanwhocodes/object-schema": ["@humanwhocodes/object-schema@2.0.3", "", {}, "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="],
 | 
			
		||||
 | 
			
		||||
    "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.1", "", {}, "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA=="],
 | 
			
		||||
 | 
			
		||||
    "@ianvs/prettier-plugin-sort-imports": ["@ianvs/prettier-plugin-sort-imports@4.4.1", "", { "dependencies": { "@babel/generator": "^7.26.2", "@babel/parser": "^7.26.2", "@babel/traverse": "^7.25.9", "@babel/types": "^7.26.0", "semver": "^7.5.2" }, "peerDependencies": { "@vue/compiler-sfc": "2.7.x || 3.x", "prettier": "2 || 3" }, "optionalPeers": ["@vue/compiler-sfc"] }, "sha512-F0/Hrcfpy8WuxlQyAWJTEren/uxKhYonOGY4OyWmwRdeTvkh9mMSCxowZLjNkhwi/2ipqCgtXwwOk7tW0mWXkA=="],
 | 
			
		||||
 | 
			
		||||
    "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
 | 
			
		||||
 | 
			
		||||
    "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
 | 
			
		||||
 | 
			
		||||
    "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
 | 
			
		||||
 | 
			
		||||
    "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
 | 
			
		||||
 | 
			
		||||
    "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
 | 
			
		||||
 | 
			
		||||
    "@kitajs/html": ["@kitajs/html@4.2.7", "", { "dependencies": { "csstype": "^3.1.3" } }, "sha512-HMAHy0GLH7i7wY1o0W1TeugNhtWefUkhb9l6zx6v2fIkR1cPlUtQQdkTt/jkBA7723yO7uBERcXFPZpWT7HWPQ=="],
 | 
			
		||||
 | 
			
		||||
    "@kitajs/ts-html-plugin": ["@kitajs/ts-html-plugin@4.1.1", "", { "dependencies": { "chalk": "^4.1.2", "tslib": "^2.8.1", "yargs": "^17.7.2" }, "peerDependencies": { "@kitajs/html": "^4.2.5", "typescript": "^5.6.2" }, "bin": { "ts-html-plugin": "dist/cli.js", "xss-scan": "dist/cli.js" } }, "sha512-wmjyV8hmJmDOnUM/ZyPkc0UBYgUYmf32/93rkW8wr8h+HiHVMU0tEKFnmRdBjTcy9jwoC9Bnt2NuzS9l67lq5g=="],
 | 
			
		||||
 | 
			
		||||
    "@nodelib/fs.scandir": ["@nodelib/fs.scandir@4.0.1", "", { "dependencies": { "@nodelib/fs.stat": "4.0.0", "run-parallel": "^1.2.0" } }, "sha512-vAkI715yhnmiPupY+dq+xenu5Tdf2TBQ66jLvBIcCddtz+5Q8LbMKaf9CIJJreez8fQ8fgaY+RaywQx8RJIWpw=="],
 | 
			
		||||
 | 
			
		||||
    "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
 | 
			
		||||
 | 
			
		||||
    "@nodelib/fs.walk": ["@nodelib/fs.walk@3.0.1", "", { "dependencies": { "@nodelib/fs.scandir": "4.0.1", "fastq": "^1.15.0" } }, "sha512-nIh/M6Kh3ZtOmlY00DaUYB4xeeV6F3/ts1l29iwl3/cfyY/OuCfUx+v08zgx8TKPTifXRcjjqVQ4KB2zOYSbyw=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ=="],
 | 
			
		||||
 | 
			
		||||
    "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
 | 
			
		||||
 | 
			
		||||
    "@pkgr/core": ["@pkgr/core@0.1.1", "", {}, "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="],
 | 
			
		||||
 | 
			
		||||
    "@sinclair/typebox": ["@sinclair/typebox@0.34.15", "", {}, "sha512-xeIzl3h1Znn9w/LTITqpiwag0gXjA+ldi2ZkXIBxGEppGCW211Tza+eL6D4pKqs10bj5z2umBWk5WL6spQ2OCQ=="],
 | 
			
		||||
 | 
			
		||||
    "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="],
 | 
			
		||||
 | 
			
		||||
    "@snyk/github-codeowners": ["@snyk/github-codeowners@1.1.0", "", { "dependencies": { "commander": "^4.1.1", "ignore": "^5.1.8", "p-map": "^4.0.0" }, "bin": { "github-codeowners": "dist/cli.js" } }, "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/cli": ["@tailwindcss/cli@4.0.4", "", { "dependencies": { "@parcel/watcher": "^2.5.1", "@tailwindcss/node": "^4.0.4", "@tailwindcss/oxide": "^4.0.4", "enhanced-resolve": "^5.18.0", "lightningcss": "^1.29.1", "mri": "^1.2.0", "picocolors": "^1.1.1", "tailwindcss": "4.0.4" }, "bin": { "tailwindcss": "dist/index.mjs" } }, "sha512-GhdVjJUrzpjN8aGbtoq5te4G/Xh6XKiIjnDEZT6cefL+bX+CiXiOdrRs+Rjxi9A3oObXRsqa93mPYLhTTfc62w=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/node": ["@tailwindcss/node@4.0.4", "", { "dependencies": { "enhanced-resolve": "^5.18.0", "jiti": "^2.4.2", "tailwindcss": "4.0.4" } }, "sha512-VLFq80IyoV1hsHPcCm1mmlyPyUT6NlovQLoO2y7PGm84mW94ZrNJ7ax5H6K4M7Aj/fdMfem5IX7Ka+LXWZpDGg=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide": ["@tailwindcss/oxide@4.0.4", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.0.4", "@tailwindcss/oxide-darwin-arm64": "4.0.4", "@tailwindcss/oxide-darwin-x64": "4.0.4", "@tailwindcss/oxide-freebsd-x64": "4.0.4", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.4", "@tailwindcss/oxide-linux-arm64-gnu": "4.0.4", "@tailwindcss/oxide-linux-arm64-musl": "4.0.4", "@tailwindcss/oxide-linux-x64-gnu": "4.0.4", "@tailwindcss/oxide-linux-x64-musl": "4.0.4", "@tailwindcss/oxide-win32-arm64-msvc": "4.0.4", "@tailwindcss/oxide-win32-x64-msvc": "4.0.4" } }, "sha512-vPpu30KFLiGyPOoElkYt8WRvzGKVrrOz49KpfiGGtnQGmyUpL8VCbJzzEEcpKT5BpaaQidhFok+OXscf6hHjOQ=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.0.4", "", { "os": "android", "cpu": "arm64" }, "sha512-hiGUA8d15ynH/LdurQNObnuTjri7i4ApAzhesusNxoz4br7vhZ6QO5CFgniYAYNZvf8Q8wCTBg0nj61RalBeVQ=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vTca+ysNl8BYmYJTni9pLC+L3S4bvrj0ai1eUV3yYXYa5Cpugr5Fni6ylV0gcTZOyETm2RCCJ/0azU6MgqE6HA=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-rxPWb5AQJ/aAM/5UDCjaQaMYIcrZHe/Dr9xZu9+P9nJf3WAweNsGi+e+SW9EYGRiF3hkBtP2dvxVNAkTiEbNQQ=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.0.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UOnRHzlS5V5cxaMgBo6rk1E92tTDUtO/falc9vOpNiRdWhNcofYNN9zvZP63Wuo5FC6/XCyAnJo6OXUm18TwrQ=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-0Ry9Qfnf22rmJwHxsCFmHQIl5RZw+yOUUGHaqNT42REL8r308cU/bi4UqdrjqVRfAlu51gOGxTRf2NRueczuIA=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-5a7WD30nVdI7Rl1ohZ0Ojj9t5yRnZkJBizvh3uIW52h9UeNpon8TfoknF6rU/TwD32dQ0Cjo5CcCHtQ2wW9PCA=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-m6s5jKSqos07l6NtHFd49Ljcaw4jIWHE7jq6eNPNz9SCzQqRzs4esP1t7jH8UljQ7JffKOl7yZPwK5Nf+irliw=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-K5dBjGHzby9eyUBwy9YHFhKY+5i8fzIBZM1NBWp6L2xpM7OzW9WJDgNcgESkZami9g+EozkQLt3ZmMZHAieXkw=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-J8sskt+fA5ooq+kxy0Tf4E2TRWZD9Y8j3K+pnBwp9zdilLmSd8OHrB3e0/rO78KveZ6BE9ae75cKOWrT6wONmw=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.0.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-flFaaMc77NQbz0Fq73wBs9EH2lX1Oc2Z/3JuxoewpnGHpAGJ/j05tvBNMyTaGrKcHvf/+dk+mCDxb6+PmzGgnQ=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-WzMA0aL/24/JyNrv2Yhr/Og24QGRPWJMjRyCJ4HRoGMs6/8svOQKrnnZ/9LUFwn56irAndFBjWWnlaqykH+g5Q=="],
 | 
			
		||||
 | 
			
		||||
    "@tailwindcss/postcss": ["@tailwindcss/postcss@4.0.4", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "^4.0.4", "@tailwindcss/oxide": "^4.0.4", "lightningcss": "^1.29.1", "postcss": "^8.4.41", "tailwindcss": "4.0.4" } }, "sha512-Up8fB+DUhy8qvDqlHgZAWaL5iVEbypcuOjzlW4K6EyU+aGEvXK0/wrcKBKOTvg3KKP5givJMexJ0aG1hDPOuRg=="],
 | 
			
		||||
 | 
			
		||||
    "@total-typescript/ts-reset": ["@total-typescript/ts-reset@0.6.1", "", {}, "sha512-cka47fVSo6lfQDIATYqb/vO1nvFfbPw7uWLayIXIhGETj0wcOOlrlkobOMDNQOFr9QOafegUPq13V2+6vtD7yg=="],
 | 
			
		||||
 | 
			
		||||
    "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
 | 
			
		||||
 | 
			
		||||
    "@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="],
 | 
			
		||||
 | 
			
		||||
    "@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="],
 | 
			
		||||
 | 
			
		||||
    "@types/eslint-plugin-tailwindcss": ["@types/eslint-plugin-tailwindcss@3.17.0", "", { "dependencies": { "@types/eslint": "*" } }, "sha512-ucQGf2YIdTcndYcxRU3UdZgmhUHsOlbIF4BaRtl0op+7k2JmqM2i3aXZ6XIcfZgVq1ZKov7VM5c/BR81ukmkyg=="],
 | 
			
		||||
 | 
			
		||||
    "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
 | 
			
		||||
 | 
			
		||||
    "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
 | 
			
		||||
 | 
			
		||||
    "@types/node": ["@types/node@22.13.1", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew=="],
 | 
			
		||||
 | 
			
		||||
    "@types/prismjs": ["@types/prismjs@1.26.5", "", {}, "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ=="],
 | 
			
		||||
 | 
			
		||||
    "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.23.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/type-utils": "8.23.0", "@typescript-eslint/utils": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/parser": ["@typescript-eslint/parser@8.23.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/types": "8.23.0", "@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0" } }, "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.23.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/utils": "8.23.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/types": ["@typescript-eslint/types@7.18.0", "", {}, "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" } }, "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/utils": ["@typescript-eslint/utils@7.18.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", "@typescript-eslint/typescript-estree": "7.18.0" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ=="],
 | 
			
		||||
 | 
			
		||||
    "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
 | 
			
		||||
 | 
			
		||||
    "acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
 | 
			
		||||
 | 
			
		||||
    "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
 | 
			
		||||
 | 
			
		||||
    "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
 | 
			
		||||
 | 
			
		||||
    "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
 | 
			
		||||
 | 
			
		||||
    "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
 | 
			
		||||
 | 
			
		||||
    "ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
 | 
			
		||||
 | 
			
		||||
    "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
 | 
			
		||||
 | 
			
		||||
    "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
 | 
			
		||||
 | 
			
		||||
    "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="],
 | 
			
		||||
 | 
			
		||||
    "autoprefixer": ["autoprefixer@10.4.20", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g=="],
 | 
			
		||||
 | 
			
		||||
    "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
 | 
			
		||||
 | 
			
		||||
    "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
 | 
			
		||||
 | 
			
		||||
    "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
 | 
			
		||||
 | 
			
		||||
    "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
 | 
			
		||||
 | 
			
		||||
    "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
 | 
			
		||||
 | 
			
		||||
    "browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="],
 | 
			
		||||
 | 
			
		||||
    "bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="],
 | 
			
		||||
 | 
			
		||||
    "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
 | 
			
		||||
 | 
			
		||||
    "caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="],
 | 
			
		||||
 | 
			
		||||
    "caniuse-lite": ["caniuse-lite@1.0.30001696", "", {}, "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ=="],
 | 
			
		||||
 | 
			
		||||
    "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
 | 
			
		||||
 | 
			
		||||
    "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
 | 
			
		||||
 | 
			
		||||
    "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="],
 | 
			
		||||
 | 
			
		||||
    "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
 | 
			
		||||
 | 
			
		||||
    "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="],
 | 
			
		||||
 | 
			
		||||
    "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
 | 
			
		||||
 | 
			
		||||
    "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
 | 
			
		||||
 | 
			
		||||
    "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
 | 
			
		||||
 | 
			
		||||
    "colord": ["colord@2.9.3", "", {}, "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="],
 | 
			
		||||
 | 
			
		||||
    "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
 | 
			
		||||
 | 
			
		||||
    "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
 | 
			
		||||
 | 
			
		||||
    "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
 | 
			
		||||
 | 
			
		||||
    "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
 | 
			
		||||
 | 
			
		||||
    "css-declaration-sorter": ["css-declaration-sorter@7.2.0", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow=="],
 | 
			
		||||
 | 
			
		||||
    "css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="],
 | 
			
		||||
 | 
			
		||||
    "css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="],
 | 
			
		||||
 | 
			
		||||
    "css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="],
 | 
			
		||||
 | 
			
		||||
    "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
 | 
			
		||||
 | 
			
		||||
    "cssnano": ["cssnano@7.0.6", "", { "dependencies": { "cssnano-preset-default": "^7.0.6", "lilconfig": "^3.1.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw=="],
 | 
			
		||||
 | 
			
		||||
    "cssnano-preset-default": ["cssnano-preset-default@7.0.6", "", { "dependencies": { "browserslist": "^4.23.3", "css-declaration-sorter": "^7.2.0", "cssnano-utils": "^5.0.0", "postcss-calc": "^10.0.2", "postcss-colormin": "^7.0.2", "postcss-convert-values": "^7.0.4", "postcss-discard-comments": "^7.0.3", "postcss-discard-duplicates": "^7.0.1", "postcss-discard-empty": "^7.0.0", "postcss-discard-overridden": "^7.0.0", "postcss-merge-longhand": "^7.0.4", "postcss-merge-rules": "^7.0.4", "postcss-minify-font-values": "^7.0.0", "postcss-minify-gradients": "^7.0.0", "postcss-minify-params": "^7.0.2", "postcss-minify-selectors": "^7.0.4", "postcss-normalize-charset": "^7.0.0", "postcss-normalize-display-values": "^7.0.0", "postcss-normalize-positions": "^7.0.0", "postcss-normalize-repeat-style": "^7.0.0", "postcss-normalize-string": "^7.0.0", "postcss-normalize-timing-functions": "^7.0.0", "postcss-normalize-unicode": "^7.0.2", "postcss-normalize-url": "^7.0.0", "postcss-normalize-whitespace": "^7.0.0", "postcss-ordered-values": "^7.0.1", "postcss-reduce-initial": "^7.0.2", "postcss-reduce-transforms": "^7.0.0", "postcss-svgo": "^7.0.1", "postcss-unique-selectors": "^7.0.3" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ=="],
 | 
			
		||||
 | 
			
		||||
    "cssnano-utils": ["cssnano-utils@5.0.0", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ=="],
 | 
			
		||||
 | 
			
		||||
    "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
 | 
			
		||||
 | 
			
		||||
    "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
 | 
			
		||||
 | 
			
		||||
    "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
 | 
			
		||||
 | 
			
		||||
    "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
 | 
			
		||||
 | 
			
		||||
    "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="],
 | 
			
		||||
 | 
			
		||||
    "dependency-graph": ["dependency-graph@0.11.0", "", {}, "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg=="],
 | 
			
		||||
 | 
			
		||||
    "detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
 | 
			
		||||
 | 
			
		||||
    "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="],
 | 
			
		||||
 | 
			
		||||
    "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="],
 | 
			
		||||
 | 
			
		||||
    "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
 | 
			
		||||
 | 
			
		||||
    "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
 | 
			
		||||
 | 
			
		||||
    "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
 | 
			
		||||
 | 
			
		||||
    "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
 | 
			
		||||
 | 
			
		||||
    "easy-table": ["easy-table@1.2.0", "", { "dependencies": { "ansi-regex": "^5.0.1" }, "optionalDependencies": { "wcwidth": "^1.0.1" } }, "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww=="],
 | 
			
		||||
 | 
			
		||||
    "electron-to-chromium": ["electron-to-chromium@1.5.90", "", {}, "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug=="],
 | 
			
		||||
 | 
			
		||||
    "elysia": ["elysia@1.2.12", "", { "dependencies": { "@sinclair/typebox": "^0.34.15", "cookie": "^1.0.2", "memoirist": "^0.3.0", "openapi-types": "^12.1.3" }, "peerDependencies": { "typescript": ">= 5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-X1bZo09qe8/Poa/5tz08Y+sE/77B/wLwnA5xDDENU3FCrsUtYJuBVcy6BPXGRCgnJ1fPQpc0Ov2ZU5MYJXluTg=="],
 | 
			
		||||
 | 
			
		||||
    "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
 | 
			
		||||
 | 
			
		||||
    "enhanced-resolve": ["enhanced-resolve@5.18.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ=="],
 | 
			
		||||
 | 
			
		||||
    "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
 | 
			
		||||
 | 
			
		||||
    "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
 | 
			
		||||
 | 
			
		||||
    "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
 | 
			
		||||
 | 
			
		||||
    "eslint": ["eslint@9.19.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.19.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-readable-tailwind": ["eslint-plugin-readable-tailwind@2.0.0-beta.4", "", { "dependencies": { "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "postcss": "^8.5.3", "postcss-import": "^16.1.0", "synckit": "^0.9.2" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "tailwindcss": "^3.3.0 || ^4.0.0" } }, "sha512-lBCT6YtH4pqi3VHRYjGE4uMrtkRx1PrArRdFcpK+a5E8jrkGxOZDgjgOf3/k2k2E50yFKG+T9sxnS/4rFe0TWg=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-simple-import-sort": ["eslint-plugin-simple-import-sort@12.1.1", "", { "peerDependencies": { "eslint": ">=5.0.0" } }, "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss": ["eslint-plugin-tailwindcss@4.0.0-alpha.0", "", { "dependencies": { "@typescript-eslint/types": "^7.13.0", "@typescript-eslint/utils": "^7.13.0", "eslint": "^8.56.0" }, "peerDependencies": { "tailwindcss": "next" } }, "sha512-0903c/da8CP5AlHWsmHRFq/YxGdcRgSg4AzvLKXHhnPN/f7wP0/RHYaaIVcJcoEF6NUZ2gTeui7Qhi34wn01Og=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-scope": ["eslint-scope@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
 | 
			
		||||
 | 
			
		||||
    "espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
 | 
			
		||||
 | 
			
		||||
    "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
 | 
			
		||||
 | 
			
		||||
    "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
 | 
			
		||||
 | 
			
		||||
    "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
 | 
			
		||||
 | 
			
		||||
    "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
 | 
			
		||||
 | 
			
		||||
    "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
 | 
			
		||||
 | 
			
		||||
    "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
 | 
			
		||||
 | 
			
		||||
    "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
 | 
			
		||||
 | 
			
		||||
    "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
 | 
			
		||||
 | 
			
		||||
    "fastq": ["fastq@1.19.0", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA=="],
 | 
			
		||||
 | 
			
		||||
    "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
 | 
			
		||||
 | 
			
		||||
    "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
 | 
			
		||||
 | 
			
		||||
    "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
 | 
			
		||||
 | 
			
		||||
    "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
 | 
			
		||||
 | 
			
		||||
    "flatted": ["flatted@3.3.2", "", {}, "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA=="],
 | 
			
		||||
 | 
			
		||||
    "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
 | 
			
		||||
 | 
			
		||||
    "fs-extra": ["fs-extra@11.3.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew=="],
 | 
			
		||||
 | 
			
		||||
    "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
 | 
			
		||||
 | 
			
		||||
    "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
 | 
			
		||||
 | 
			
		||||
    "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
 | 
			
		||||
 | 
			
		||||
    "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
 | 
			
		||||
 | 
			
		||||
    "get-stdin": ["get-stdin@9.0.0", "", {}, "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA=="],
 | 
			
		||||
 | 
			
		||||
    "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
 | 
			
		||||
 | 
			
		||||
    "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
 | 
			
		||||
 | 
			
		||||
    "globals": ["globals@16.0.0", "", {}, "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="],
 | 
			
		||||
 | 
			
		||||
    "globby": ["globby@14.0.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.2", "ignore": "^5.2.4", "path-type": "^5.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.1.0" } }, "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw=="],
 | 
			
		||||
 | 
			
		||||
    "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
 | 
			
		||||
 | 
			
		||||
    "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
 | 
			
		||||
 | 
			
		||||
    "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
 | 
			
		||||
 | 
			
		||||
    "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
 | 
			
		||||
 | 
			
		||||
    "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
 | 
			
		||||
 | 
			
		||||
    "import-fresh": ["import-fresh@3.3.0", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="],
 | 
			
		||||
 | 
			
		||||
    "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
 | 
			
		||||
 | 
			
		||||
    "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
 | 
			
		||||
 | 
			
		||||
    "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
 | 
			
		||||
 | 
			
		||||
    "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
 | 
			
		||||
 | 
			
		||||
    "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
 | 
			
		||||
 | 
			
		||||
    "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
 | 
			
		||||
 | 
			
		||||
    "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
 | 
			
		||||
 | 
			
		||||
    "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
 | 
			
		||||
 | 
			
		||||
    "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
 | 
			
		||||
 | 
			
		||||
    "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
 | 
			
		||||
 | 
			
		||||
    "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="],
 | 
			
		||||
 | 
			
		||||
    "isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="],
 | 
			
		||||
 | 
			
		||||
    "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
 | 
			
		||||
 | 
			
		||||
    "jose": ["jose@4.15.9", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="],
 | 
			
		||||
 | 
			
		||||
    "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
 | 
			
		||||
 | 
			
		||||
    "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
 | 
			
		||||
 | 
			
		||||
    "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
 | 
			
		||||
 | 
			
		||||
    "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
 | 
			
		||||
 | 
			
		||||
    "json-parse-even-better-errors": ["json-parse-even-better-errors@4.0.0", "", {}, "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA=="],
 | 
			
		||||
 | 
			
		||||
    "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
 | 
			
		||||
 | 
			
		||||
    "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
 | 
			
		||||
 | 
			
		||||
    "jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="],
 | 
			
		||||
 | 
			
		||||
    "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
 | 
			
		||||
 | 
			
		||||
    "knip": ["knip@5.43.6", "", { "dependencies": { "@nodelib/fs.walk": "3.0.1", "@snyk/github-codeowners": "1.1.0", "easy-table": "1.2.0", "enhanced-resolve": "^5.18.0", "fast-glob": "^3.3.3", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "minimist": "^1.2.8", "picocolors": "^1.1.0", "picomatch": "^4.0.1", "pretty-ms": "^9.0.0", "smol-toml": "^1.3.1", "strip-json-comments": "5.0.1", "summary": "2.1.0", "zod": "^3.22.4", "zod-validation-error": "^3.0.3" }, "peerDependencies": { "@types/node": ">=18", "typescript": ">=5.0.4" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-bUCFlg44imdV5vayYxu0pIAB373S8Ufjda0qaI9oRZDH6ltJFwUoAO2j7nafxDmo5G0ZeP4IiLAHqlc3wYIONQ=="],
 | 
			
		||||
 | 
			
		||||
    "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss": ["lightningcss@1.29.1", "", { "dependencies": { "detect-libc": "^1.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.29.1", "lightningcss-darwin-x64": "1.29.1", "lightningcss-freebsd-x64": "1.29.1", "lightningcss-linux-arm-gnueabihf": "1.29.1", "lightningcss-linux-arm64-gnu": "1.29.1", "lightningcss-linux-arm64-musl": "1.29.1", "lightningcss-linux-x64-gnu": "1.29.1", "lightningcss-linux-x64-musl": "1.29.1", "lightningcss-win32-arm64-msvc": "1.29.1", "lightningcss-win32-x64-msvc": "1.29.1" } }, "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.29.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.29.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.29.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.29.1", "", { "os": "linux", "cpu": "arm" }, "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.29.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.29.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.29.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.29.1", "", { "os": "linux", "cpu": "x64" }, "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.29.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog=="],
 | 
			
		||||
 | 
			
		||||
    "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.1", "", { "os": "win32", "cpu": "x64" }, "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q=="],
 | 
			
		||||
 | 
			
		||||
    "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
 | 
			
		||||
 | 
			
		||||
    "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
 | 
			
		||||
 | 
			
		||||
    "lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="],
 | 
			
		||||
 | 
			
		||||
    "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
 | 
			
		||||
 | 
			
		||||
    "lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="],
 | 
			
		||||
 | 
			
		||||
    "mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="],
 | 
			
		||||
 | 
			
		||||
    "memoirist": ["memoirist@0.3.0", "", {}, "sha512-wR+4chMgVPq+T6OOsk40u9Wlpw1Pjx66NMNiYxCQQ4EUJ7jDs3D9kTCeKdBOkvAiqXlHLVJlvYL01PvIJ1MPNg=="],
 | 
			
		||||
 | 
			
		||||
    "memorystream": ["memorystream@0.3.1", "", {}, "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw=="],
 | 
			
		||||
 | 
			
		||||
    "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
 | 
			
		||||
 | 
			
		||||
    "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
 | 
			
		||||
 | 
			
		||||
    "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
 | 
			
		||||
 | 
			
		||||
    "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
 | 
			
		||||
 | 
			
		||||
    "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
 | 
			
		||||
 | 
			
		||||
    "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
 | 
			
		||||
 | 
			
		||||
    "nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
 | 
			
		||||
 | 
			
		||||
    "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
 | 
			
		||||
 | 
			
		||||
    "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
 | 
			
		||||
 | 
			
		||||
    "node-cache": ["node-cache@5.1.2", "", { "dependencies": { "clone": "2.x" } }, "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg=="],
 | 
			
		||||
 | 
			
		||||
    "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="],
 | 
			
		||||
 | 
			
		||||
    "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
 | 
			
		||||
 | 
			
		||||
    "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
 | 
			
		||||
 | 
			
		||||
    "npm-normalize-package-bin": ["npm-normalize-package-bin@4.0.0", "", {}, "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w=="],
 | 
			
		||||
 | 
			
		||||
    "npm-run-all2": ["npm-run-all2@7.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "cross-spawn": "^7.0.6", "memorystream": "^0.3.1", "minimatch": "^9.0.0", "pidtree": "^0.6.0", "read-package-json-fast": "^4.0.0", "shell-quote": "^1.7.3", "which": "^5.0.0" }, "bin": { "run-p": "bin/run-p/index.js", "run-s": "bin/run-s/index.js", "npm-run-all": "bin/npm-run-all/index.js", "npm-run-all2": "bin/npm-run-all/index.js" } }, "sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA=="],
 | 
			
		||||
 | 
			
		||||
    "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
 | 
			
		||||
 | 
			
		||||
    "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
 | 
			
		||||
 | 
			
		||||
    "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
 | 
			
		||||
 | 
			
		||||
    "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
 | 
			
		||||
 | 
			
		||||
    "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
 | 
			
		||||
 | 
			
		||||
    "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
 | 
			
		||||
 | 
			
		||||
    "p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="],
 | 
			
		||||
 | 
			
		||||
    "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
 | 
			
		||||
 | 
			
		||||
    "parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="],
 | 
			
		||||
 | 
			
		||||
    "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
 | 
			
		||||
 | 
			
		||||
    "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
 | 
			
		||||
 | 
			
		||||
    "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
 | 
			
		||||
 | 
			
		||||
    "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
 | 
			
		||||
 | 
			
		||||
    "path-type": ["path-type@5.0.0", "", {}, "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg=="],
 | 
			
		||||
 | 
			
		||||
    "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
 | 
			
		||||
 | 
			
		||||
    "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
 | 
			
		||||
 | 
			
		||||
    "pidtree": ["pidtree@0.6.0", "", { "bin": { "pidtree": "bin/pidtree.js" } }, "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g=="],
 | 
			
		||||
 | 
			
		||||
    "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
 | 
			
		||||
 | 
			
		||||
    "postcss": ["postcss@8.5.1", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-calc": ["postcss-calc@10.1.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.38" } }, "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-cli": ["postcss-cli@11.0.0", "", { "dependencies": { "chokidar": "^3.3.0", "dependency-graph": "^0.11.0", "fs-extra": "^11.0.0", "get-stdin": "^9.0.0", "globby": "^14.0.0", "picocolors": "^1.0.0", "postcss-load-config": "^5.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", "slash": "^5.0.0", "yargs": "^17.0.0" }, "peerDependencies": { "postcss": "^8.0.0" }, "bin": { "postcss": "index.js" } }, "sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-colormin": ["postcss-colormin@7.0.2", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-api": "^3.0.0", "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-convert-values": ["postcss-convert-values@7.0.4", "", { "dependencies": { "browserslist": "^4.23.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-discard-comments": ["postcss-discard-comments@7.0.3", "", { "dependencies": { "postcss-selector-parser": "^6.1.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-discard-duplicates": ["postcss-discard-duplicates@7.0.1", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-discard-empty": ["postcss-discard-empty@7.0.0", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-discard-overridden": ["postcss-discard-overridden@7.0.0", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-import": ["postcss-import@16.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-load-config": ["postcss-load-config@5.1.0", "", { "dependencies": { "lilconfig": "^3.1.1", "yaml": "^2.4.2" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1" }, "optionalPeers": ["jiti", "postcss", "tsx"] }, "sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-merge-longhand": ["postcss-merge-longhand@7.0.4", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^7.0.4" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-merge-rules": ["postcss-merge-rules@7.0.4", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-api": "^3.0.0", "cssnano-utils": "^5.0.0", "postcss-selector-parser": "^6.1.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-minify-font-values": ["postcss-minify-font-values@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-minify-gradients": ["postcss-minify-gradients@7.0.0", "", { "dependencies": { "colord": "^2.9.3", "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-minify-params": ["postcss-minify-params@7.0.2", "", { "dependencies": { "browserslist": "^4.23.3", "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-minify-selectors": ["postcss-minify-selectors@7.0.4", "", { "dependencies": { "cssesc": "^3.0.0", "postcss-selector-parser": "^6.1.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-charset": ["postcss-normalize-charset@7.0.0", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-display-values": ["postcss-normalize-display-values@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-positions": ["postcss-normalize-positions@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-repeat-style": ["postcss-normalize-repeat-style@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-string": ["postcss-normalize-string@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-timing-functions": ["postcss-normalize-timing-functions@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-unicode": ["postcss-normalize-unicode@7.0.2", "", { "dependencies": { "browserslist": "^4.23.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-url": ["postcss-normalize-url@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-normalize-whitespace": ["postcss-normalize-whitespace@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-ordered-values": ["postcss-ordered-values@7.0.1", "", { "dependencies": { "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-reduce-initial": ["postcss-reduce-initial@7.0.2", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-api": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-reduce-transforms": ["postcss-reduce-transforms@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-reporter": ["postcss-reporter@7.1.0", "", { "dependencies": { "picocolors": "^1.0.0", "thenby": "^1.3.4" }, "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-selector-parser": ["postcss-selector-parser@7.0.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-svgo": ["postcss-svgo@7.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^3.3.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-unique-selectors": ["postcss-unique-selectors@7.0.3", "", { "dependencies": { "postcss-selector-parser": "^6.1.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
 | 
			
		||||
 | 
			
		||||
    "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
 | 
			
		||||
 | 
			
		||||
    "prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="],
 | 
			
		||||
 | 
			
		||||
    "pretty-hrtime": ["pretty-hrtime@1.0.3", "", {}, "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A=="],
 | 
			
		||||
 | 
			
		||||
    "pretty-ms": ["pretty-ms@9.2.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg=="],
 | 
			
		||||
 | 
			
		||||
    "prism-react-renderer": ["prism-react-renderer@2.4.1", "", { "dependencies": { "@types/prismjs": "^1.26.0", "clsx": "^2.0.0" }, "peerDependencies": { "react": ">=16.0.0" } }, "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig=="],
 | 
			
		||||
 | 
			
		||||
    "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
 | 
			
		||||
 | 
			
		||||
    "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
 | 
			
		||||
 | 
			
		||||
    "react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="],
 | 
			
		||||
 | 
			
		||||
    "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
 | 
			
		||||
 | 
			
		||||
    "read-package-json-fast": ["read-package-json-fast@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" } }, "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg=="],
 | 
			
		||||
 | 
			
		||||
    "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
 | 
			
		||||
 | 
			
		||||
    "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
 | 
			
		||||
 | 
			
		||||
    "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
 | 
			
		||||
 | 
			
		||||
    "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
 | 
			
		||||
 | 
			
		||||
    "reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="],
 | 
			
		||||
 | 
			
		||||
    "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
 | 
			
		||||
 | 
			
		||||
    "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
 | 
			
		||||
 | 
			
		||||
    "sanitize-filename": ["sanitize-filename@1.6.3", "", { "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg=="],
 | 
			
		||||
 | 
			
		||||
    "semver": ["semver@7.7.0", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ=="],
 | 
			
		||||
 | 
			
		||||
    "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
 | 
			
		||||
 | 
			
		||||
    "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
 | 
			
		||||
 | 
			
		||||
    "shell-quote": ["shell-quote@1.8.2", "", {}, "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA=="],
 | 
			
		||||
 | 
			
		||||
    "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="],
 | 
			
		||||
 | 
			
		||||
    "smol-toml": ["smol-toml@1.3.1", "", {}, "sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ=="],
 | 
			
		||||
 | 
			
		||||
    "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
 | 
			
		||||
 | 
			
		||||
    "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
 | 
			
		||||
 | 
			
		||||
    "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
 | 
			
		||||
 | 
			
		||||
    "strip-json-comments": ["strip-json-comments@5.0.1", "", {}, "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw=="],
 | 
			
		||||
 | 
			
		||||
    "stylehacks": ["stylehacks@7.0.4", "", { "dependencies": { "browserslist": "^4.23.3", "postcss-selector-parser": "^6.1.2" }, "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww=="],
 | 
			
		||||
 | 
			
		||||
    "summary": ["summary@2.1.0", "", {}, "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw=="],
 | 
			
		||||
 | 
			
		||||
    "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
 | 
			
		||||
 | 
			
		||||
    "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
 | 
			
		||||
 | 
			
		||||
    "svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
 | 
			
		||||
 | 
			
		||||
    "synckit": ["synckit@0.9.2", "", { "dependencies": { "@pkgr/core": "^0.1.0", "tslib": "^2.6.2" } }, "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw=="],
 | 
			
		||||
 | 
			
		||||
    "tailwind-scrollbar": ["tailwind-scrollbar@4.0.0", "", { "dependencies": { "prism-react-renderer": "^2.4.1" }, "peerDependencies": { "tailwindcss": "4.x" } }, "sha512-elqx9m09VHY8gkrMiyimFO09JlS3AyLFXT0eaLaWPi7ImwHlbZj1ce/AxSis2LtR+ewBGEyUV7URNEMcjP1Z2w=="],
 | 
			
		||||
 | 
			
		||||
    "tailwindcss": ["tailwindcss@4.0.4", "", {}, "sha512-/ezDLEkOLf1lXkr9F2iI5BHJbexJpty5zkV2B8bGHCqAdbc9vk85Jgdkq+ZOvNkNPa3yAaqJ8DjRt584Bc84kw=="],
 | 
			
		||||
 | 
			
		||||
    "tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
 | 
			
		||||
 | 
			
		||||
    "text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="],
 | 
			
		||||
 | 
			
		||||
    "thenby": ["thenby@1.3.4", "", {}, "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ=="],
 | 
			
		||||
 | 
			
		||||
    "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
 | 
			
		||||
 | 
			
		||||
    "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "", { "dependencies": { "utf8-byte-length": "^1.0.1" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="],
 | 
			
		||||
 | 
			
		||||
    "ts-api-utils": ["ts-api-utils@2.0.1", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w=="],
 | 
			
		||||
 | 
			
		||||
    "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
 | 
			
		||||
 | 
			
		||||
    "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
 | 
			
		||||
 | 
			
		||||
    "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
 | 
			
		||||
 | 
			
		||||
    "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint": ["typescript-eslint@8.23.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.23.0", "@typescript-eslint/parser": "8.23.0", "@typescript-eslint/utils": "8.23.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ=="],
 | 
			
		||||
 | 
			
		||||
    "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
 | 
			
		||||
 | 
			
		||||
    "unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="],
 | 
			
		||||
 | 
			
		||||
    "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
 | 
			
		||||
 | 
			
		||||
    "update-browserslist-db": ["update-browserslist-db@1.1.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg=="],
 | 
			
		||||
 | 
			
		||||
    "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
 | 
			
		||||
 | 
			
		||||
    "utf8-byte-length": ["utf8-byte-length@1.0.5", "", {}, "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA=="],
 | 
			
		||||
 | 
			
		||||
    "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
 | 
			
		||||
 | 
			
		||||
    "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="],
 | 
			
		||||
 | 
			
		||||
    "which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="],
 | 
			
		||||
 | 
			
		||||
    "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
 | 
			
		||||
 | 
			
		||||
    "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
 | 
			
		||||
 | 
			
		||||
    "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
 | 
			
		||||
 | 
			
		||||
    "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
 | 
			
		||||
 | 
			
		||||
    "yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
 | 
			
		||||
 | 
			
		||||
    "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
 | 
			
		||||
 | 
			
		||||
    "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
 | 
			
		||||
 | 
			
		||||
    "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
 | 
			
		||||
 | 
			
		||||
    "zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
 | 
			
		||||
 | 
			
		||||
    "zod-validation-error": ["zod-validation-error@3.4.0", "", { "peerDependencies": { "zod": "^3.18.0" } }, "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ=="],
 | 
			
		||||
 | 
			
		||||
    "@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
 | 
			
		||||
 | 
			
		||||
    "@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
 | 
			
		||||
 | 
			
		||||
    "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
 | 
			
		||||
 | 
			
		||||
    "@nodelib/fs.scandir/@nodelib/fs.stat": ["@nodelib/fs.stat@4.0.0", "", {}, "sha512-ctr6bByzksKRCV0bavi8WoQevU6plSp2IkllIsEqaiKe2mwNNnaluhnRhcsgGZHrrHk57B3lf95MkLMO3STYcg=="],
 | 
			
		||||
 | 
			
		||||
    "@types/ws/@types/node": ["@types/node@22.13.0", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0" } }, "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.23.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/types": "8.23.0", "@typescript-eslint/typescript-estree": "8.23.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0" } }, "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/parser/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" } }, "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/utils": ["@typescript-eslint/utils@8.23.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/types": "8.23.0", "@typescript-eslint/typescript-estree": "8.23.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" } }, "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
 | 
			
		||||
 | 
			
		||||
    "bun-types/@types/node": ["@types/node@22.13.0", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA=="],
 | 
			
		||||
 | 
			
		||||
    "chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
 | 
			
		||||
 | 
			
		||||
    "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
 | 
			
		||||
 | 
			
		||||
    "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
 | 
			
		||||
 | 
			
		||||
    "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="],
 | 
			
		||||
 | 
			
		||||
    "defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
 | 
			
		||||
 | 
			
		||||
    "dir-glob/path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-readable-tailwind/enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-readable-tailwind/postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint": ["eslint@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.1", "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA=="],
 | 
			
		||||
 | 
			
		||||
    "fast-glob/@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
 | 
			
		||||
 | 
			
		||||
    "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
 | 
			
		||||
 | 
			
		||||
    "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
 | 
			
		||||
 | 
			
		||||
    "npm-run-all2/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-discard-comments/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-merge-rules/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-minify-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
 | 
			
		||||
 | 
			
		||||
    "postcss-unique-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
 | 
			
		||||
 | 
			
		||||
    "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
 | 
			
		||||
 | 
			
		||||
    "stylehacks/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
 | 
			
		||||
 | 
			
		||||
    "svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.23.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/types": "8.23.0", "@typescript-eslint/typescript-estree": "8.23.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA=="],
 | 
			
		||||
 | 
			
		||||
    "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0" } }, "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
 | 
			
		||||
 | 
			
		||||
    "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
 | 
			
		||||
 | 
			
		||||
    "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/@eslint/eslintrc": ["@eslint/eslintrc@2.1.4", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="],
 | 
			
		||||
 | 
			
		||||
    "fast-glob/@nodelib/fs.walk/@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
 | 
			
		||||
 | 
			
		||||
    "npm-run-all2/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0" } }, "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/@nodelib/fs.walk/@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
 | 
			
		||||
 | 
			
		||||
    "eslint-plugin-tailwindcss/eslint/file-entry-cache/flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
 | 
			
		||||
 | 
			
		||||
    "@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
 | 
			
		||||
 | 
			
		||||
    "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
import { fixupPluginRules } from "@eslint/compat";
 | 
			
		||||
import eslint from "@eslint/js";
 | 
			
		||||
import deprecationPlugin from "eslint-plugin-deprecation";
 | 
			
		||||
import eslintPluginReadableTailwind from "eslint-plugin-readable-tailwind";
 | 
			
		||||
import simpleImportSortPlugin from "eslint-plugin-simple-import-sort";
 | 
			
		||||
import tailwind from "eslint-plugin-tailwindcss";
 | 
			
		||||
import globals from "globals";
 | 
			
		||||
import tseslint from "typescript-eslint";
 | 
			
		||||
 | 
			
		||||
export default tseslint.config(
 | 
			
		||||
  eslint.configs.recommended,
 | 
			
		||||
  ...tseslint.configs.recommended,
 | 
			
		||||
  ...tailwind.configs["flat/recommended"],
 | 
			
		||||
  {
 | 
			
		||||
    plugins: {
 | 
			
		||||
      deprecation: fixupPluginRules(deprecationPlugin),
 | 
			
		||||
      "simple-import-sort": simpleImportSortPlugin,
 | 
			
		||||
      "readable-tailwind": eslintPluginReadableTailwind,
 | 
			
		||||
    },
 | 
			
		||||
    ignores: ["**/node_modules/**"],
 | 
			
		||||
    languageOptions: {
 | 
			
		||||
      parserOptions: {
 | 
			
		||||
        projectService: true,
 | 
			
		||||
        tsconfigRootDir: import.meta.dirname,
 | 
			
		||||
        ecmaVersion: "latest",
 | 
			
		||||
        sourceType: "module",
 | 
			
		||||
        project: ["./tsconfig.json"],
 | 
			
		||||
      },
 | 
			
		||||
      globals: {
 | 
			
		||||
        ...globals.node,
 | 
			
		||||
        ...globals.browser,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    files: ["**/*.{js,mjs,cjs,tsx,ts}"],
 | 
			
		||||
    rules: {
 | 
			
		||||
      ...eslintPluginReadableTailwind.configs.warning.rules,
 | 
			
		||||
      "tailwindcss/classnames-order": "off",
 | 
			
		||||
      "readable-tailwind/multiline": [
 | 
			
		||||
        "warn",
 | 
			
		||||
        {
 | 
			
		||||
          group: "newLine",
 | 
			
		||||
          printWidth: 100,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
      "tailwindcss/no-custom-classname": [
 | 
			
		||||
        "warn",
 | 
			
		||||
        {
 | 
			
		||||
          whitelist: [
 | 
			
		||||
            "select_container",
 | 
			
		||||
            "convert_to_popup",
 | 
			
		||||
            "convert_to_group",
 | 
			
		||||
            "target",
 | 
			
		||||
            "convert_to_target",
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										57
									
								
								eslint.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								eslint.config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
import js from "@eslint/js";
 | 
			
		||||
import eslintParserTypeScript from "@typescript-eslint/parser";
 | 
			
		||||
import type { Linter } from "eslint";
 | 
			
		||||
import eslintPluginReadableTailwind from "eslint-plugin-readable-tailwind";
 | 
			
		||||
import simpleImportSortPlugin from "eslint-plugin-simple-import-sort";
 | 
			
		||||
import globals from "globals";
 | 
			
		||||
import tseslint from "typescript-eslint";
 | 
			
		||||
 | 
			
		||||
export default [
 | 
			
		||||
  js.configs.recommended,
 | 
			
		||||
  ...tseslint.configs.recommended,
 | 
			
		||||
  // ...tailwind.configs["flat/recommended"],
 | 
			
		||||
  {
 | 
			
		||||
    plugins: {
 | 
			
		||||
      "simple-import-sort": simpleImportSortPlugin,
 | 
			
		||||
      "readable-tailwind": eslintPluginReadableTailwind,
 | 
			
		||||
    },
 | 
			
		||||
    ignores: ["**/node_modules/**"],
 | 
			
		||||
    languageOptions: {
 | 
			
		||||
      parser: eslintParserTypeScript,
 | 
			
		||||
      parserOptions: {
 | 
			
		||||
        project: true,
 | 
			
		||||
        ecmaFeatures: {
 | 
			
		||||
          jsx: true,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      globals: {
 | 
			
		||||
        ...globals.node,
 | 
			
		||||
        ...globals.browser,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    files: ["**/*.{js,mjs,cjs,jsx,tsx,ts}"],
 | 
			
		||||
    rules: {
 | 
			
		||||
      ...eslintPluginReadableTailwind.configs.warning.rules,
 | 
			
		||||
      // "tailwindcss/classnames-order": "off",
 | 
			
		||||
      "readable-tailwind/multiline": [
 | 
			
		||||
        "warn",
 | 
			
		||||
        {
 | 
			
		||||
          group: "newLine",
 | 
			
		||||
          printWidth: 100,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
      // "tailwindcss/no-custom-classname": [
 | 
			
		||||
      //   "warn",
 | 
			
		||||
      //   {
 | 
			
		||||
      //     whitelist: [
 | 
			
		||||
      //       "select_container",
 | 
			
		||||
      //       "convert_to_popup",
 | 
			
		||||
      //       "convert_to_group",
 | 
			
		||||
      //       "target",
 | 
			
		||||
      //       "convert_to_target",
 | 
			
		||||
      //     ],
 | 
			
		||||
      //   },
 | 
			
		||||
      // ],
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
] as Linter.Config[];
 | 
			
		||||
							
								
								
									
										35
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								package.json
									
									
									
									
									
								
							@@ -1,23 +1,23 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "convertx-frontend",
 | 
			
		||||
  "version": "0.10.0",
 | 
			
		||||
  "version": "0.12.1",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "bun run --watch src/index.tsx",
 | 
			
		||||
    "hot": "bun run --hot src/index.tsx",
 | 
			
		||||
    "format": "eslint --fix .",
 | 
			
		||||
    "build": "postcss ./src/main.css -o ./public/generated.css",
 | 
			
		||||
    "build": "bunx @tailwindcss/cli -i ./src/main.css -o ./public/generated.css",
 | 
			
		||||
    "lint": "run-p 'lint:*'",
 | 
			
		||||
    "lint:tsc": "tsc --noEmit",
 | 
			
		||||
    "lint:knip": "knip",
 | 
			
		||||
    "lint:eslint": "eslint ."
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@elysiajs/cookie": "^0.8.0",
 | 
			
		||||
    "@elysiajs/html": "^1.2.0",
 | 
			
		||||
    "@elysiajs/jwt": "^1.2.0",
 | 
			
		||||
    "@elysiajs/static": "^1.2.0",
 | 
			
		||||
    "@kitajs/html": "^4.2.7",
 | 
			
		||||
    "elysia": "^1.2.10"
 | 
			
		||||
    "elysia": "^1.2.12",
 | 
			
		||||
    "sanitize-filename": "^1.6.3"
 | 
			
		||||
  },
 | 
			
		||||
  "module": "src/index.tsx",
 | 
			
		||||
  "type": "module",
 | 
			
		||||
@@ -25,31 +25,30 @@
 | 
			
		||||
    "start": "bun run src/index.tsx"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@eslint/compat": "^1.2.5",
 | 
			
		||||
    "@eslint/js": "^9.18.0",
 | 
			
		||||
    "@eslint/js": "^9.19.0",
 | 
			
		||||
    "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
 | 
			
		||||
    "@kitajs/ts-html-plugin": "^4.1.1",
 | 
			
		||||
    "@tailwindcss/cli": "^4.0.4",
 | 
			
		||||
    "@tailwindcss/postcss": "^4.0.4",
 | 
			
		||||
    "@total-typescript/ts-reset": "^0.6.1",
 | 
			
		||||
    "@types/bun": "^1.1.16",
 | 
			
		||||
    "@types/bun": "^1.2.2",
 | 
			
		||||
    "@types/eslint-plugin-tailwindcss": "^3.17.0",
 | 
			
		||||
    "@types/eslint__js": "^8.42.3",
 | 
			
		||||
    "@types/node": "^22.10.7",
 | 
			
		||||
    "@types/node": "^22.13.1",
 | 
			
		||||
    "autoprefixer": "^10.4.20",
 | 
			
		||||
    "cssnano": "^7.0.6",
 | 
			
		||||
    "eslint": "^9.18.0",
 | 
			
		||||
    "eslint-plugin-deprecation": "^3.0.0",
 | 
			
		||||
    "eslint-plugin-readable-tailwind": "^1.8.2",
 | 
			
		||||
    "eslint": "^9.19.0",
 | 
			
		||||
    "eslint-plugin-readable-tailwind": "^2.0.0-beta.4",
 | 
			
		||||
    "eslint-plugin-simple-import-sort": "^12.1.1",
 | 
			
		||||
    "eslint-plugin-tailwindcss": "^3.17.5",
 | 
			
		||||
    "globals": "^15.14.0",
 | 
			
		||||
    "knip": "^5.42.1",
 | 
			
		||||
    "eslint-plugin-tailwindcss": "4.0.0-alpha.0",
 | 
			
		||||
    "globals": "^16.0.0",
 | 
			
		||||
    "knip": "^5.43.6",
 | 
			
		||||
    "npm-run-all2": "^7.0.2",
 | 
			
		||||
    "postcss": "^8.5.1",
 | 
			
		||||
    "postcss-cli": "^11.0.0",
 | 
			
		||||
    "prettier": "^3.4.2",
 | 
			
		||||
    "tailwind-scrollbar": "^3.1.0",
 | 
			
		||||
    "tailwindcss": "^3.4.17",
 | 
			
		||||
    "tailwind-scrollbar": "^4.0.0",
 | 
			
		||||
    "tailwindcss": "^4.0.4",
 | 
			
		||||
    "typescript": "^5.7.3",
 | 
			
		||||
    "typescript-eslint": "^8.20.0"
 | 
			
		||||
    "typescript-eslint": "^8.23.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,5 @@
 | 
			
		||||
import autoprefixer from "autoprefixer";
 | 
			
		||||
import cssnano from "cssnano";
 | 
			
		||||
import tailwind from "tailwindcss";
 | 
			
		||||
import tailwindConfig from "./tailwind.config.js";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  plugins: [autoprefixer, tailwind(tailwindConfig), cssnano],
 | 
			
		||||
};
 | 
			
		||||
  plugins: {
 | 
			
		||||
    "@tailwindcss/postcss": {},
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										493
									
								
								public/script.js
									
									
									
									
									
								
							
							
						
						
									
										493
									
								
								public/script.js
									
									
									
									
									
								
							@@ -1,236 +1,257 @@
 | 
			
		||||
const webroot = document.querySelector("meta[name='webroot']").content;
 | 
			
		||||
const fileInput = document.querySelector('input[type="file"]');
 | 
			
		||||
const dropZone = document.getElementById("dropzone");
 | 
			
		||||
const convertButton = document.querySelector("input[type='submit']");
 | 
			
		||||
const fileNames = [];
 | 
			
		||||
let fileType;
 | 
			
		||||
let pendingFiles = 0;
 | 
			
		||||
let formatSelected = false;
 | 
			
		||||
 | 
			
		||||
dropZone.addEventListener("dragover", () => {
 | 
			
		||||
  dropZone.classList.add("dragover");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
dropZone.addEventListener("dragleave", () => {
 | 
			
		||||
  dropZone.classList.remove("dragover");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
dropZone.addEventListener("drop", () => {
 | 
			
		||||
  dropZone.classList.remove("dragover");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const selectContainer = document.querySelector("form .select_container");
 | 
			
		||||
 | 
			
		||||
const updateSearchBar = () => {
 | 
			
		||||
  const convertToInput = document.querySelector(
 | 
			
		||||
    "input[name='convert_to_search']",
 | 
			
		||||
  );
 | 
			
		||||
  const convertToPopup = document.querySelector(".convert_to_popup");
 | 
			
		||||
  const convertToGroupElements = document.querySelectorAll(".convert_to_group");
 | 
			
		||||
  const convertToGroups = {};
 | 
			
		||||
  const convertToElement = document.querySelector("select[name='convert_to']");
 | 
			
		||||
 | 
			
		||||
  const showMatching = (search) => {
 | 
			
		||||
    for (const [targets, groupElement] of Object.values(convertToGroups)) {
 | 
			
		||||
      let matchingTargetsFound = 0;
 | 
			
		||||
      for (const target of targets) {
 | 
			
		||||
        if (target.dataset.target.includes(search)) {
 | 
			
		||||
          matchingTargetsFound++;
 | 
			
		||||
          target.classList.remove("hidden");
 | 
			
		||||
          target.classList.add("flex");
 | 
			
		||||
        } else {
 | 
			
		||||
          target.classList.add("hidden");
 | 
			
		||||
          target.classList.remove("flex");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (matchingTargetsFound === 0) {
 | 
			
		||||
        groupElement.classList.add("hidden");
 | 
			
		||||
        groupElement.classList.remove("flex");
 | 
			
		||||
      } else {
 | 
			
		||||
        groupElement.classList.remove("hidden");
 | 
			
		||||
        groupElement.classList.add("flex");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  for (const groupElement of convertToGroupElements) {
 | 
			
		||||
    const groupName = groupElement.dataset.converter;
 | 
			
		||||
 | 
			
		||||
    const targetElements = groupElement.querySelectorAll(".target");
 | 
			
		||||
    const targets = Array.from(targetElements);
 | 
			
		||||
 | 
			
		||||
    for (const target of targets) {
 | 
			
		||||
      target.onmousedown = () => {
 | 
			
		||||
        convertToElement.value = target.dataset.value;
 | 
			
		||||
        convertToInput.value = `${target.dataset.target} using ${target.dataset.converter}`;
 | 
			
		||||
        formatSelected = true;
 | 
			
		||||
        if (pendingFiles === 0 && fileNames.length > 0) {
 | 
			
		||||
          convertButton.disabled = false;
 | 
			
		||||
        }
 | 
			
		||||
        showMatching("");
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertToGroups[groupName] = [targets, groupElement];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("input", (e) => {
 | 
			
		||||
    showMatching(e.target.value.toLowerCase());
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("search", () => {
 | 
			
		||||
    // when the user clears the search bar using the 'x' button
 | 
			
		||||
    convertButton.disabled = true;
 | 
			
		||||
    formatSelected = false;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("blur", (e) => {
 | 
			
		||||
    // Keep the popup open even when clicking on a target button
 | 
			
		||||
    // for a split second to allow the click to go through
 | 
			
		||||
    if (e?.relatedTarget?.classList?.contains("target")) {
 | 
			
		||||
      convertToPopup.classList.add("hidden");
 | 
			
		||||
      convertToPopup.classList.remove("flex");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertToPopup.classList.add("hidden");
 | 
			
		||||
    convertToPopup.classList.remove("flex");
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("focus", () => {
 | 
			
		||||
    convertToPopup.classList.remove("hidden");
 | 
			
		||||
    convertToPopup.classList.add("flex");
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Add a 'change' event listener to the file input element
 | 
			
		||||
fileInput.addEventListener("change", (e) => {
 | 
			
		||||
  // Get the selected files from the event target
 | 
			
		||||
  const files = e.target.files;
 | 
			
		||||
 | 
			
		||||
  // Select the file-list table
 | 
			
		||||
  const fileList = document.querySelector("#file-list");
 | 
			
		||||
 | 
			
		||||
  // Loop through the selected files
 | 
			
		||||
  for (const file of files) {
 | 
			
		||||
    // Create a new table row for each file
 | 
			
		||||
    const row = document.createElement("tr");
 | 
			
		||||
    row.innerHTML = `
 | 
			
		||||
      <td>${file.name}</td>
 | 
			
		||||
      <td>${(file.size / 1024).toFixed(2)} kB</td>
 | 
			
		||||
      <td><a onclick="deleteRow(this)">Remove</a></td>
 | 
			
		||||
    `;
 | 
			
		||||
 | 
			
		||||
    if (!fileType) {
 | 
			
		||||
      fileType = file.name.split(".").pop();
 | 
			
		||||
      fileInput.setAttribute("accept", `.${fileType}`);
 | 
			
		||||
      setTitle();
 | 
			
		||||
 | 
			
		||||
      // choose the option that matches the file type
 | 
			
		||||
      // for (const option of convertFromSelect.children) {
 | 
			
		||||
      //   console.log(option.value);
 | 
			
		||||
      //   if (option.value === fileType) {
 | 
			
		||||
      //     option.selected = true;
 | 
			
		||||
      //   }
 | 
			
		||||
      // }
 | 
			
		||||
 | 
			
		||||
      fetch(`${webroot}/conversions`, {
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        body: JSON.stringify({ fileType: fileType }),
 | 
			
		||||
        headers: {
 | 
			
		||||
          "Content-Type": "application/json",
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
        .then((res) => res.text())
 | 
			
		||||
        .then((html) => {
 | 
			
		||||
          selectContainer.innerHTML = html;
 | 
			
		||||
          updateSearchBar();
 | 
			
		||||
        })
 | 
			
		||||
        .catch((err) => console.log(err));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Append the row to the file-list table
 | 
			
		||||
    fileList.appendChild(row);
 | 
			
		||||
 | 
			
		||||
    // Append the file to the hidden input
 | 
			
		||||
    fileNames.push(file.name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uploadFiles(files);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const setTitle = () => {
 | 
			
		||||
  const title = document.querySelector("h1");
 | 
			
		||||
  title.textContent = `Convert ${fileType ? `.${fileType}` : ""}`;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Add a onclick for the delete button
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
const deleteRow = (target) => {
 | 
			
		||||
  const filename = target.parentElement.parentElement.children[0].textContent;
 | 
			
		||||
  const row = target.parentElement.parentElement;
 | 
			
		||||
  row.remove();
 | 
			
		||||
 | 
			
		||||
  // remove from fileNames
 | 
			
		||||
  const index = fileNames.indexOf(filename);
 | 
			
		||||
  fileNames.splice(index, 1);
 | 
			
		||||
 | 
			
		||||
  // reset fileInput
 | 
			
		||||
  fileInput.value = "";
 | 
			
		||||
 | 
			
		||||
  // if fileNames is empty, reset fileType
 | 
			
		||||
  if (fileNames.length === 0) {
 | 
			
		||||
    fileType = null;
 | 
			
		||||
    fileInput.removeAttribute("accept");
 | 
			
		||||
    convertButton.disabled = true;
 | 
			
		||||
    setTitle();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fetch(`${webroot}/delete`, {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    body: JSON.stringify({ filename: filename }),
 | 
			
		||||
    headers: {
 | 
			
		||||
      "Content-Type": "application/json",
 | 
			
		||||
    },
 | 
			
		||||
  })
 | 
			
		||||
    .catch((err) => console.log(err));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uploadFiles = (files) => {
 | 
			
		||||
  convertButton.disabled = true;
 | 
			
		||||
  convertButton.textContent = "Uploading...";
 | 
			
		||||
  pendingFiles += 1;
 | 
			
		||||
 | 
			
		||||
  const formData = new FormData();
 | 
			
		||||
 | 
			
		||||
  for (const file of files) {
 | 
			
		||||
    formData.append("file", file, file.name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fetch(`${webroot}/upload`, {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    body: formData,
 | 
			
		||||
  })
 | 
			
		||||
    .then((res) => res.json())
 | 
			
		||||
    .then((data) => {
 | 
			
		||||
      pendingFiles -= 1;
 | 
			
		||||
      if (pendingFiles === 0) {
 | 
			
		||||
        if (formatSelected) {
 | 
			
		||||
          convertButton.disabled = false;
 | 
			
		||||
        }
 | 
			
		||||
        convertButton.textContent = "Convert";
 | 
			
		||||
      }
 | 
			
		||||
      console.log(data);
 | 
			
		||||
    })
 | 
			
		||||
    .catch((err) => console.log(err));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const formConvert = document.querySelector(`form[action='${webroot}/convert']`);
 | 
			
		||||
 | 
			
		||||
formConvert.addEventListener("submit", () => {
 | 
			
		||||
  const hiddenInput = document.querySelector("input[name='file_names']");
 | 
			
		||||
  hiddenInput.value = JSON.stringify(fileNames);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
updateSearchBar();
 | 
			
		||||
const webroot = document.querySelector("meta[name='webroot']").content;
 | 
			
		||||
const fileInput = document.querySelector('input[type="file"]');
 | 
			
		||||
const dropZone = document.getElementById("dropzone");
 | 
			
		||||
const convertButton = document.querySelector("input[type='submit']");
 | 
			
		||||
const fileNames = [];
 | 
			
		||||
let fileType;
 | 
			
		||||
let pendingFiles = 0;
 | 
			
		||||
let formatSelected = false;
 | 
			
		||||
 | 
			
		||||
dropZone.addEventListener("dragover", () => {
 | 
			
		||||
  dropZone.classList.add("dragover");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
dropZone.addEventListener("dragleave", () => {
 | 
			
		||||
  dropZone.classList.remove("dragover");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
dropZone.addEventListener("drop", () => {
 | 
			
		||||
  dropZone.classList.remove("dragover");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const selectContainer = document.querySelector("form .select_container");
 | 
			
		||||
 | 
			
		||||
const updateSearchBar = () => {
 | 
			
		||||
  const convertToInput = document.querySelector(
 | 
			
		||||
    "input[name='convert_to_search']",
 | 
			
		||||
  );
 | 
			
		||||
  const convertToPopup = document.querySelector(".convert_to_popup");
 | 
			
		||||
  const convertToGroupElements = document.querySelectorAll(".convert_to_group");
 | 
			
		||||
  const convertToGroups = {};
 | 
			
		||||
  const convertToElement = document.querySelector("select[name='convert_to']");
 | 
			
		||||
 | 
			
		||||
  const showMatching = (search) => {
 | 
			
		||||
    for (const [targets, groupElement] of Object.values(convertToGroups)) {
 | 
			
		||||
      let matchingTargetsFound = 0;
 | 
			
		||||
      for (const target of targets) {
 | 
			
		||||
        if (target.dataset.target.includes(search)) {
 | 
			
		||||
          matchingTargetsFound++;
 | 
			
		||||
          target.classList.remove("hidden");
 | 
			
		||||
          target.classList.add("flex");
 | 
			
		||||
        } else {
 | 
			
		||||
          target.classList.add("hidden");
 | 
			
		||||
          target.classList.remove("flex");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (matchingTargetsFound === 0) {
 | 
			
		||||
        groupElement.classList.add("hidden");
 | 
			
		||||
        groupElement.classList.remove("flex");
 | 
			
		||||
      } else {
 | 
			
		||||
        groupElement.classList.remove("hidden");
 | 
			
		||||
        groupElement.classList.add("flex");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  for (const groupElement of convertToGroupElements) {
 | 
			
		||||
    const groupName = groupElement.dataset.converter;
 | 
			
		||||
 | 
			
		||||
    const targetElements = groupElement.querySelectorAll(".target");
 | 
			
		||||
    const targets = Array.from(targetElements);
 | 
			
		||||
 | 
			
		||||
    for (const target of targets) {
 | 
			
		||||
      target.onmousedown = () => {
 | 
			
		||||
        convertToElement.value = target.dataset.value;
 | 
			
		||||
        convertToInput.value = `${target.dataset.target} using ${target.dataset.converter}`;
 | 
			
		||||
        formatSelected = true;
 | 
			
		||||
        if (pendingFiles === 0 && fileNames.length > 0) {
 | 
			
		||||
          convertButton.disabled = false;
 | 
			
		||||
        }
 | 
			
		||||
        showMatching("");
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertToGroups[groupName] = [targets, groupElement];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("input", (e) => {
 | 
			
		||||
    showMatching(e.target.value.toLowerCase());
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("search", () => {
 | 
			
		||||
    // when the user clears the search bar using the 'x' button
 | 
			
		||||
    convertButton.disabled = true;
 | 
			
		||||
    formatSelected = false;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("blur", (e) => {
 | 
			
		||||
    // Keep the popup open even when clicking on a target button
 | 
			
		||||
    // for a split second to allow the click to go through
 | 
			
		||||
    if (e?.relatedTarget?.classList?.contains("target")) {
 | 
			
		||||
      convertToPopup.classList.add("hidden");
 | 
			
		||||
      convertToPopup.classList.remove("flex");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertToPopup.classList.add("hidden");
 | 
			
		||||
    convertToPopup.classList.remove("flex");
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  convertToInput.addEventListener("focus", () => {
 | 
			
		||||
    convertToPopup.classList.remove("hidden");
 | 
			
		||||
    convertToPopup.classList.add("flex");
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Add a 'change' event listener to the file input element
 | 
			
		||||
fileInput.addEventListener("change", (e) => {
 | 
			
		||||
  // Get the selected files from the event target
 | 
			
		||||
  const files = e.target.files;
 | 
			
		||||
 | 
			
		||||
  // Select the file-list table
 | 
			
		||||
  const fileList = document.querySelector("#file-list");
 | 
			
		||||
 | 
			
		||||
  // Loop through the selected files
 | 
			
		||||
  for (const file of files) {
 | 
			
		||||
    // Create a new table row for each file
 | 
			
		||||
    const row = document.createElement("tr");
 | 
			
		||||
    row.innerHTML = `
 | 
			
		||||
      <td>${file.name}</td>
 | 
			
		||||
      <td><progress max="100"></progress></td>
 | 
			
		||||
      <td>${(file.size / 1024).toFixed(2)} kB</td>
 | 
			
		||||
      <td><a onclick="deleteRow(this)">Remove</a></td>
 | 
			
		||||
    `;
 | 
			
		||||
 | 
			
		||||
    if (!fileType) {
 | 
			
		||||
      fileType = file.name.split(".").pop();
 | 
			
		||||
      fileInput.setAttribute("accept", `.${fileType}`);
 | 
			
		||||
      setTitle();
 | 
			
		||||
 | 
			
		||||
      // choose the option that matches the file type
 | 
			
		||||
      // for (const option of convertFromSelect.children) {
 | 
			
		||||
      //   console.log(option.value);
 | 
			
		||||
      //   if (option.value === fileType) {
 | 
			
		||||
      //     option.selected = true;
 | 
			
		||||
      //   }
 | 
			
		||||
      // }
 | 
			
		||||
 | 
			
		||||
      fetch(`${webroot}/conversions`, {
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        body: JSON.stringify({ fileType: fileType }),
 | 
			
		||||
        headers: {
 | 
			
		||||
          "Content-Type": "application/json",
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
        .then((res) => res.text())
 | 
			
		||||
        .then((html) => {
 | 
			
		||||
          selectContainer.innerHTML = html;
 | 
			
		||||
          updateSearchBar();
 | 
			
		||||
        })
 | 
			
		||||
        .catch((err) => console.log(err));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Append the row to the file-list table
 | 
			
		||||
    fileList.appendChild(row);
 | 
			
		||||
 | 
			
		||||
    //Imbed row into the file to reference later
 | 
			
		||||
    file.htmlRow = row;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Append the file to the hidden input
 | 
			
		||||
    fileNames.push(file.name);
 | 
			
		||||
 | 
			
		||||
    uploadFile(file);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const setTitle = () => {
 | 
			
		||||
  const title = document.querySelector("h1");
 | 
			
		||||
  title.textContent = `Convert ${fileType ? `.${fileType}` : ""}`;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Add a onclick for the delete button
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
const deleteRow = (target) => {
 | 
			
		||||
  const filename = target.parentElement.parentElement.children[0].textContent;
 | 
			
		||||
  const row = target.parentElement.parentElement;
 | 
			
		||||
  row.remove();
 | 
			
		||||
 | 
			
		||||
  // remove from fileNames
 | 
			
		||||
  const index = fileNames.indexOf(filename);
 | 
			
		||||
  fileNames.splice(index, 1);
 | 
			
		||||
 | 
			
		||||
  // reset fileInput
 | 
			
		||||
  fileInput.value = "";
 | 
			
		||||
 | 
			
		||||
  // if fileNames is empty, reset fileType
 | 
			
		||||
  if (fileNames.length === 0) {
 | 
			
		||||
    fileType = null;
 | 
			
		||||
    fileInput.removeAttribute("accept");
 | 
			
		||||
    convertButton.disabled = true;
 | 
			
		||||
    setTitle();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fetch(`${webroot}/delete`, {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    body: JSON.stringify({ filename: filename }),
 | 
			
		||||
    headers: {
 | 
			
		||||
      "Content-Type": "application/json",
 | 
			
		||||
    },
 | 
			
		||||
  })
 | 
			
		||||
    .catch((err) => console.log(err));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uploadFile = (file) => {
 | 
			
		||||
  convertButton.disabled = true;
 | 
			
		||||
  convertButton.textContent = "Uploading...";
 | 
			
		||||
  pendingFiles += 1;
 | 
			
		||||
 | 
			
		||||
  const formData = new FormData();
 | 
			
		||||
  formData.append("file", file, file.name);
 | 
			
		||||
 | 
			
		||||
  let xhr = new XMLHttpRequest(); 
 | 
			
		||||
 | 
			
		||||
  xhr.open("POST", `${webroot}/upload`, true);
 | 
			
		||||
 | 
			
		||||
  xhr.onload = () => {
 | 
			
		||||
    let data = JSON.parse(xhr.responseText);
 | 
			
		||||
 | 
			
		||||
    pendingFiles -= 1;
 | 
			
		||||
    if (pendingFiles === 0) {
 | 
			
		||||
      if (formatSelected) {
 | 
			
		||||
        convertButton.disabled = false;
 | 
			
		||||
      }
 | 
			
		||||
      convertButton.textContent = "Convert";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Remove the progress bar when upload is done
 | 
			
		||||
    let progressbar = file.htmlRow.getElementsByTagName("progress");
 | 
			
		||||
    progressbar[0].parentElement.remove();
 | 
			
		||||
    console.log(data);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  xhr.upload.onprogress = (e) => {
 | 
			
		||||
    let sent = e.loaded;
 | 
			
		||||
    let total = e.total;
 | 
			
		||||
    console.log(`upload progress (${file.name}):`, (100 * sent) / total);
 | 
			
		||||
 | 
			
		||||
    let progressbar = file.htmlRow.getElementsByTagName("progress");
 | 
			
		||||
    progressbar[0].value = ((100 * sent) / total);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  xhr.onerror = (e) => {
 | 
			
		||||
    console.log(e);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  xhr.send(formData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const formConvert = document.querySelector(`form[action='${webroot}/convert']`);
 | 
			
		||||
 | 
			
		||||
formConvert.addEventListener("submit", () => {
 | 
			
		||||
  const hiddenInput = document.querySelector("input[name='file_names']");
 | 
			
		||||
  hiddenInput.value = JSON.stringify(fileNames);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
updateSearchBar();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,40 +1,40 @@
 | 
			
		||||
import { Html } from "@elysiajs/html";
 | 
			
		||||
 | 
			
		||||
export const BaseHtml = ({
 | 
			
		||||
  children,
 | 
			
		||||
  title = "ConvertX",
 | 
			
		||||
  webroot = "",
 | 
			
		||||
}: {
 | 
			
		||||
  children: JSX.Element;
 | 
			
		||||
  title?: string;
 | 
			
		||||
  webroot?: string;
 | 
			
		||||
}) => (
 | 
			
		||||
  <html lang="en">
 | 
			
		||||
    <head>
 | 
			
		||||
      <meta charset="UTF-8" />
 | 
			
		||||
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
      <meta name="webroot" content={webroot} />
 | 
			
		||||
      <title safe>{title}</title>
 | 
			
		||||
      <link rel="stylesheet" href={`${webroot}/generated.css`} />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="apple-touch-icon"
 | 
			
		||||
        sizes="180x180"
 | 
			
		||||
        href={`${webroot}/apple-touch-icon.png`}
 | 
			
		||||
      />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="icon"
 | 
			
		||||
        type="image/png"
 | 
			
		||||
        sizes="32x32"
 | 
			
		||||
        href={`${webroot}/favicon-32x32.png`}
 | 
			
		||||
      />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="icon"
 | 
			
		||||
        type="image/png"
 | 
			
		||||
        sizes="16x16"
 | 
			
		||||
        href={`${webroot}/favicon-16x16.png`}
 | 
			
		||||
      />
 | 
			
		||||
      <link rel="manifest" href={`${webroot}/site.webmanifest`} />
 | 
			
		||||
    </head>
 | 
			
		||||
    <body class="w-full bg-neutral-900 text-neutral-200">{children}</body>
 | 
			
		||||
  </html>
 | 
			
		||||
);
 | 
			
		||||
import { Html } from "@elysiajs/html";
 | 
			
		||||
 | 
			
		||||
export const BaseHtml = ({
 | 
			
		||||
  children,
 | 
			
		||||
  title = "ConvertX",
 | 
			
		||||
  webroot = "",
 | 
			
		||||
}: {
 | 
			
		||||
  children: JSX.Element;
 | 
			
		||||
  title?: string;
 | 
			
		||||
  webroot?: string;
 | 
			
		||||
}) => (
 | 
			
		||||
  <html lang="en">
 | 
			
		||||
    <head>
 | 
			
		||||
      <meta charset="UTF-8" />
 | 
			
		||||
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
      <meta name="webroot" content={webroot} />
 | 
			
		||||
      <title safe>{title}</title>
 | 
			
		||||
      <link rel="stylesheet" href={`${webroot}/generated.css`} />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="apple-touch-icon"
 | 
			
		||||
        sizes="180x180"
 | 
			
		||||
        href={`${webroot}/apple-touch-icon.png`}
 | 
			
		||||
      />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="icon"
 | 
			
		||||
        type="image/png"
 | 
			
		||||
        sizes="32x32"
 | 
			
		||||
        href={`${webroot}/favicon-32x32.png`}
 | 
			
		||||
      />
 | 
			
		||||
      <link
 | 
			
		||||
        rel="icon"
 | 
			
		||||
        type="image/png"
 | 
			
		||||
        sizes="16x16"
 | 
			
		||||
        href={`${webroot}/favicon-16x16.png`}
 | 
			
		||||
      />
 | 
			
		||||
      <link rel="manifest" href={`${webroot}/site.webmanifest`} />
 | 
			
		||||
    </head>
 | 
			
		||||
    <body class="w-full bg-neutral-900 text-neutral-200">{children}</body>
 | 
			
		||||
  </html>
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ export const Header = ({
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <header class="w-full p-4">
 | 
			
		||||
      <nav class="mx-auto flex max-w-4xl justify-between rounded bg-neutral-900 p-4">
 | 
			
		||||
      <nav class="mx-auto flex max-w-4xl justify-between rounded-sm bg-neutral-900 p-4">
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>
 | 
			
		||||
            <strong>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
@@ -119,10 +119,8 @@ export async function convert(
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  const command = `assimp export "${filePath}" "${targetPath}"`;
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(command, (error, stdout, stderr) => {
 | 
			
		||||
    execFile("assimp", ["export", filePath, targetPath], (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
@@ -64,10 +64,8 @@ export async function convert(
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  const command = `ebook-convert "${filePath}" "${targetPath}"`;
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(command, (error, stdout, stderr) => {
 | 
			
		||||
    execFile("ebook-convert", [filePath, targetPath], (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
// This could be done dynamically by running `ffmpeg -formats` and parsing the output
 | 
			
		||||
export const properties = {
 | 
			
		||||
@@ -691,19 +691,28 @@ export async function convert(
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  let extra = "";
 | 
			
		||||
  let extraArgs: string[] = [];
 | 
			
		||||
  let message = "Done";
 | 
			
		||||
 | 
			
		||||
  if (convertTo === "ico") {
 | 
			
		||||
    // make sure image is 256x256 or smaller
 | 
			
		||||
    extra = `-filter:v "scale='min(256,iw)':min'(256,ih)':force_original_aspect_ratio=decrease"`;
 | 
			
		||||
    extraArgs = ['-filter:v', "scale='min(256,iw)':min'(256,ih)':force_original_aspect_ratio=decrease"];
 | 
			
		||||
    message = "Done: resized to 256x256";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const command = `ffmpeg ${process.env.FFMPEG_ARGS} -i "${filePath}" ${extra} "${targetPath}"`;
 | 
			
		||||
  // Parse FFMPEG_ARGS environment variable into array
 | 
			
		||||
  const ffmpegArgs = process.env.FFMPEG_ARGS ? process.env.FFMPEG_ARGS.split(/\s+/) : [];
 | 
			
		||||
  
 | 
			
		||||
  // Build arguments array
 | 
			
		||||
  const args = [
 | 
			
		||||
    ...ffmpegArgs,
 | 
			
		||||
    "-i", filePath,
 | 
			
		||||
    ...extraArgs,
 | 
			
		||||
    targetPath
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(command, (error, stdout, stderr) => {
 | 
			
		||||
    execFile("ffmpeg", args, (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,339 +1,340 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    image: [
 | 
			
		||||
      "3fr",
 | 
			
		||||
      "8bim",
 | 
			
		||||
      "8bimtext",
 | 
			
		||||
      "8bimwtext",
 | 
			
		||||
      "app1",
 | 
			
		||||
      "app1jpeg",
 | 
			
		||||
      "art",
 | 
			
		||||
      "arw",
 | 
			
		||||
      "avs",
 | 
			
		||||
      "b",
 | 
			
		||||
      "bie",
 | 
			
		||||
      "bigtiff",
 | 
			
		||||
      "bmp",
 | 
			
		||||
      "c",
 | 
			
		||||
      "cals",
 | 
			
		||||
      "caption",
 | 
			
		||||
      "cin",
 | 
			
		||||
      "cmyk",
 | 
			
		||||
      "cmyka",
 | 
			
		||||
      "cr2",
 | 
			
		||||
      "crw",
 | 
			
		||||
      "cur",
 | 
			
		||||
      "cut",
 | 
			
		||||
      "dcm",
 | 
			
		||||
      "dcr",
 | 
			
		||||
      "dcx",
 | 
			
		||||
      "dng",
 | 
			
		||||
      "dpx",
 | 
			
		||||
      "epdf",
 | 
			
		||||
      "epi",
 | 
			
		||||
      "eps",
 | 
			
		||||
      "epsf",
 | 
			
		||||
      "epsi",
 | 
			
		||||
      "ept",
 | 
			
		||||
      "ept2",
 | 
			
		||||
      "ept3",
 | 
			
		||||
      "erf",
 | 
			
		||||
      "exif",
 | 
			
		||||
      "fax",
 | 
			
		||||
      "file",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "fractal",
 | 
			
		||||
      "ftp",
 | 
			
		||||
      "g",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "gif87",
 | 
			
		||||
      "gradient",
 | 
			
		||||
      "gray",
 | 
			
		||||
      "graya",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "hrz",
 | 
			
		||||
      "http",
 | 
			
		||||
      "icb",
 | 
			
		||||
      "icc",
 | 
			
		||||
      "icm",
 | 
			
		||||
      "ico",
 | 
			
		||||
      "icon",
 | 
			
		||||
      "identity",
 | 
			
		||||
      "image",
 | 
			
		||||
      "iptc",
 | 
			
		||||
      "iptctext",
 | 
			
		||||
      "iptcwtext",
 | 
			
		||||
      "jbg",
 | 
			
		||||
      "jbig",
 | 
			
		||||
      "jng",
 | 
			
		||||
      "jnx",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "jpg",
 | 
			
		||||
      "k",
 | 
			
		||||
      "k25",
 | 
			
		||||
      "kdc",
 | 
			
		||||
      "label",
 | 
			
		||||
      "m",
 | 
			
		||||
      "mac",
 | 
			
		||||
      "map",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "mef",
 | 
			
		||||
      "miff",
 | 
			
		||||
      "mng",
 | 
			
		||||
      "mono",
 | 
			
		||||
      "mpc",
 | 
			
		||||
      "mrw",
 | 
			
		||||
      "msl",
 | 
			
		||||
      "mtv",
 | 
			
		||||
      "mvg",
 | 
			
		||||
      "nef",
 | 
			
		||||
      "null",
 | 
			
		||||
      "o",
 | 
			
		||||
      "orf",
 | 
			
		||||
      "otb",
 | 
			
		||||
      "p7",
 | 
			
		||||
      "pal",
 | 
			
		||||
      "palm",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pbm",
 | 
			
		||||
      "pcd",
 | 
			
		||||
      "pcds",
 | 
			
		||||
      "pct",
 | 
			
		||||
      "pcx",
 | 
			
		||||
      "pdb",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "pef",
 | 
			
		||||
      "pfa",
 | 
			
		||||
      "pfb",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "picon",
 | 
			
		||||
      "pict",
 | 
			
		||||
      "pix",
 | 
			
		||||
      "plasma",
 | 
			
		||||
      "png",
 | 
			
		||||
      "png00",
 | 
			
		||||
      "png24",
 | 
			
		||||
      "png32",
 | 
			
		||||
      "png48",
 | 
			
		||||
      "png64",
 | 
			
		||||
      "png8",
 | 
			
		||||
      "pnm",
 | 
			
		||||
      "ppm",
 | 
			
		||||
      "ps",
 | 
			
		||||
      "ptif",
 | 
			
		||||
      "pwp",
 | 
			
		||||
      "r",
 | 
			
		||||
      "raf",
 | 
			
		||||
      "ras",
 | 
			
		||||
      "rgb",
 | 
			
		||||
      "rgba",
 | 
			
		||||
      "rla",
 | 
			
		||||
      "rle",
 | 
			
		||||
      "sct",
 | 
			
		||||
      "sfw",
 | 
			
		||||
      "sgi",
 | 
			
		||||
      "sr2",
 | 
			
		||||
      "srf",
 | 
			
		||||
      "stegano",
 | 
			
		||||
      "sun",
 | 
			
		||||
      "svg",
 | 
			
		||||
      "svgz",
 | 
			
		||||
      "text",
 | 
			
		||||
      "tga",
 | 
			
		||||
      "tif",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "tile",
 | 
			
		||||
      "tim",
 | 
			
		||||
      "topol",
 | 
			
		||||
      "ttf",
 | 
			
		||||
      "txt",
 | 
			
		||||
      "uyvy",
 | 
			
		||||
      "vda",
 | 
			
		||||
      "vicar",
 | 
			
		||||
      "vid",
 | 
			
		||||
      "viff",
 | 
			
		||||
      "vst",
 | 
			
		||||
      "wbmp",
 | 
			
		||||
      "webp",
 | 
			
		||||
      "wmf",
 | 
			
		||||
      "wpg",
 | 
			
		||||
      "x3f",
 | 
			
		||||
      "xbm",
 | 
			
		||||
      "xc",
 | 
			
		||||
      "xcf",
 | 
			
		||||
      "xmp",
 | 
			
		||||
      "xpm",
 | 
			
		||||
      "xv",
 | 
			
		||||
      "xwd",
 | 
			
		||||
      "y",
 | 
			
		||||
      "yuv",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    image: [
 | 
			
		||||
      "8bim",
 | 
			
		||||
      "8bimtext",
 | 
			
		||||
      "8bimwtext",
 | 
			
		||||
      "app1",
 | 
			
		||||
      "app1jpeg",
 | 
			
		||||
      "art",
 | 
			
		||||
      "avs",
 | 
			
		||||
      "b",
 | 
			
		||||
      "bie",
 | 
			
		||||
      "bigtiff",
 | 
			
		||||
      "bmp",
 | 
			
		||||
      "bmp2",
 | 
			
		||||
      "bmp3",
 | 
			
		||||
      "brf",
 | 
			
		||||
      "c",
 | 
			
		||||
      "cals",
 | 
			
		||||
      "cin",
 | 
			
		||||
      "cmyk",
 | 
			
		||||
      "cmyka",
 | 
			
		||||
      "dcx",
 | 
			
		||||
      "dpx",
 | 
			
		||||
      "epdf",
 | 
			
		||||
      "epi",
 | 
			
		||||
      "eps",
 | 
			
		||||
      "eps2",
 | 
			
		||||
      "eps3",
 | 
			
		||||
      "epsf",
 | 
			
		||||
      "epsi",
 | 
			
		||||
      "ept",
 | 
			
		||||
      "ept2",
 | 
			
		||||
      "ept3",
 | 
			
		||||
      "exif",
 | 
			
		||||
      "fax",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "g",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "gif87",
 | 
			
		||||
      "gray",
 | 
			
		||||
      "graya",
 | 
			
		||||
      "histogram",
 | 
			
		||||
      "html",
 | 
			
		||||
      "icb",
 | 
			
		||||
      "icc",
 | 
			
		||||
      "icm",
 | 
			
		||||
      "info",
 | 
			
		||||
      "iptc",
 | 
			
		||||
      "iptctext",
 | 
			
		||||
      "iptcwtext",
 | 
			
		||||
      "isobrl",
 | 
			
		||||
      "isobrl6",
 | 
			
		||||
      "jbg",
 | 
			
		||||
      "jbig",
 | 
			
		||||
      "jng",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "k",
 | 
			
		||||
      "m",
 | 
			
		||||
      "m2v",
 | 
			
		||||
      "map",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "matte",
 | 
			
		||||
      "miff",
 | 
			
		||||
      "mng",
 | 
			
		||||
      "mono",
 | 
			
		||||
      "mpc",
 | 
			
		||||
      "mpeg",
 | 
			
		||||
      "mpg",
 | 
			
		||||
      "msl",
 | 
			
		||||
      "mtv",
 | 
			
		||||
      "mvg",
 | 
			
		||||
      "null",
 | 
			
		||||
      "o",
 | 
			
		||||
      "otb",
 | 
			
		||||
      "p7",
 | 
			
		||||
      "pal",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pbm",
 | 
			
		||||
      "pcd",
 | 
			
		||||
      "pcds",
 | 
			
		||||
      "pcl",
 | 
			
		||||
      "pct",
 | 
			
		||||
      "pcx",
 | 
			
		||||
      "pdb",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "picon",
 | 
			
		||||
      "pict",
 | 
			
		||||
      "png",
 | 
			
		||||
      "png00",
 | 
			
		||||
      "png24",
 | 
			
		||||
      "png32",
 | 
			
		||||
      "png48",
 | 
			
		||||
      "png64",
 | 
			
		||||
      "png8",
 | 
			
		||||
      "pnm",
 | 
			
		||||
      "ppm",
 | 
			
		||||
      "preview",
 | 
			
		||||
      "ps",
 | 
			
		||||
      "ps2",
 | 
			
		||||
      "ps3",
 | 
			
		||||
      "ptif",
 | 
			
		||||
      "r",
 | 
			
		||||
      "ras",
 | 
			
		||||
      "rgb",
 | 
			
		||||
      "rgba",
 | 
			
		||||
      "sgi",
 | 
			
		||||
      "shtml",
 | 
			
		||||
      "sun",
 | 
			
		||||
      "text",
 | 
			
		||||
      "tga",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "txt",
 | 
			
		||||
      "ubrl",
 | 
			
		||||
      "ubrl6",
 | 
			
		||||
      "uil",
 | 
			
		||||
      "uyvy",
 | 
			
		||||
      "vda",
 | 
			
		||||
      "vicar",
 | 
			
		||||
      "vid",
 | 
			
		||||
      "viff",
 | 
			
		||||
      "vst",
 | 
			
		||||
      "wbmp",
 | 
			
		||||
      "webp",
 | 
			
		||||
      "x",
 | 
			
		||||
      "xbm",
 | 
			
		||||
      "xmp",
 | 
			
		||||
      "xpm",
 | 
			
		||||
      "xv",
 | 
			
		||||
      "xwd",
 | 
			
		||||
      "y",
 | 
			
		||||
      "yuv",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(
 | 
			
		||||
      `gm convert "${filePath}" "${targetPath}"`,
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    image: [
 | 
			
		||||
      "3fr",
 | 
			
		||||
      "8bim",
 | 
			
		||||
      "8bimtext",
 | 
			
		||||
      "8bimwtext",
 | 
			
		||||
      "app1",
 | 
			
		||||
      "app1jpeg",
 | 
			
		||||
      "art",
 | 
			
		||||
      "arw",
 | 
			
		||||
      "avs",
 | 
			
		||||
      "b",
 | 
			
		||||
      "bie",
 | 
			
		||||
      "bigtiff",
 | 
			
		||||
      "bmp",
 | 
			
		||||
      "c",
 | 
			
		||||
      "cals",
 | 
			
		||||
      "caption",
 | 
			
		||||
      "cin",
 | 
			
		||||
      "cmyk",
 | 
			
		||||
      "cmyka",
 | 
			
		||||
      "cr2",
 | 
			
		||||
      "crw",
 | 
			
		||||
      "cur",
 | 
			
		||||
      "cut",
 | 
			
		||||
      "dcm",
 | 
			
		||||
      "dcr",
 | 
			
		||||
      "dcx",
 | 
			
		||||
      "dng",
 | 
			
		||||
      "dpx",
 | 
			
		||||
      "epdf",
 | 
			
		||||
      "epi",
 | 
			
		||||
      "eps",
 | 
			
		||||
      "epsf",
 | 
			
		||||
      "epsi",
 | 
			
		||||
      "ept",
 | 
			
		||||
      "ept2",
 | 
			
		||||
      "ept3",
 | 
			
		||||
      "erf",
 | 
			
		||||
      "exif",
 | 
			
		||||
      "fax",
 | 
			
		||||
      "file",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "fractal",
 | 
			
		||||
      "ftp",
 | 
			
		||||
      "g",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "gif87",
 | 
			
		||||
      "gradient",
 | 
			
		||||
      "gray",
 | 
			
		||||
      "graya",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "hrz",
 | 
			
		||||
      "http",
 | 
			
		||||
      "icb",
 | 
			
		||||
      "icc",
 | 
			
		||||
      "icm",
 | 
			
		||||
      "ico",
 | 
			
		||||
      "icon",
 | 
			
		||||
      "identity",
 | 
			
		||||
      "image",
 | 
			
		||||
      "iptc",
 | 
			
		||||
      "iptctext",
 | 
			
		||||
      "iptcwtext",
 | 
			
		||||
      "jbg",
 | 
			
		||||
      "jbig",
 | 
			
		||||
      "jng",
 | 
			
		||||
      "jnx",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "jpg",
 | 
			
		||||
      "k",
 | 
			
		||||
      "k25",
 | 
			
		||||
      "kdc",
 | 
			
		||||
      "label",
 | 
			
		||||
      "m",
 | 
			
		||||
      "mac",
 | 
			
		||||
      "map",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "mef",
 | 
			
		||||
      "miff",
 | 
			
		||||
      "mng",
 | 
			
		||||
      "mono",
 | 
			
		||||
      "mpc",
 | 
			
		||||
      "mrw",
 | 
			
		||||
      "msl",
 | 
			
		||||
      "mtv",
 | 
			
		||||
      "mvg",
 | 
			
		||||
      "nef",
 | 
			
		||||
      "null",
 | 
			
		||||
      "o",
 | 
			
		||||
      "orf",
 | 
			
		||||
      "otb",
 | 
			
		||||
      "p7",
 | 
			
		||||
      "pal",
 | 
			
		||||
      "palm",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pbm",
 | 
			
		||||
      "pcd",
 | 
			
		||||
      "pcds",
 | 
			
		||||
      "pct",
 | 
			
		||||
      "pcx",
 | 
			
		||||
      "pdb",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "pef",
 | 
			
		||||
      "pfa",
 | 
			
		||||
      "pfb",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "picon",
 | 
			
		||||
      "pict",
 | 
			
		||||
      "pix",
 | 
			
		||||
      "plasma",
 | 
			
		||||
      "png",
 | 
			
		||||
      "png00",
 | 
			
		||||
      "png24",
 | 
			
		||||
      "png32",
 | 
			
		||||
      "png48",
 | 
			
		||||
      "png64",
 | 
			
		||||
      "png8",
 | 
			
		||||
      "pnm",
 | 
			
		||||
      "ppm",
 | 
			
		||||
      "ps",
 | 
			
		||||
      "ptif",
 | 
			
		||||
      "pwp",
 | 
			
		||||
      "r",
 | 
			
		||||
      "raf",
 | 
			
		||||
      "ras",
 | 
			
		||||
      "rgb",
 | 
			
		||||
      "rgba",
 | 
			
		||||
      "rla",
 | 
			
		||||
      "rle",
 | 
			
		||||
      "sct",
 | 
			
		||||
      "sfw",
 | 
			
		||||
      "sgi",
 | 
			
		||||
      "sr2",
 | 
			
		||||
      "srf",
 | 
			
		||||
      "stegano",
 | 
			
		||||
      "sun",
 | 
			
		||||
      "svg",
 | 
			
		||||
      "svgz",
 | 
			
		||||
      "text",
 | 
			
		||||
      "tga",
 | 
			
		||||
      "tif",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "tile",
 | 
			
		||||
      "tim",
 | 
			
		||||
      "topol",
 | 
			
		||||
      "ttf",
 | 
			
		||||
      "txt",
 | 
			
		||||
      "uyvy",
 | 
			
		||||
      "vda",
 | 
			
		||||
      "vicar",
 | 
			
		||||
      "vid",
 | 
			
		||||
      "viff",
 | 
			
		||||
      "vst",
 | 
			
		||||
      "wbmp",
 | 
			
		||||
      "webp",
 | 
			
		||||
      "wmf",
 | 
			
		||||
      "wpg",
 | 
			
		||||
      "x3f",
 | 
			
		||||
      "xbm",
 | 
			
		||||
      "xc",
 | 
			
		||||
      "xcf",
 | 
			
		||||
      "xmp",
 | 
			
		||||
      "xpm",
 | 
			
		||||
      "xv",
 | 
			
		||||
      "xwd",
 | 
			
		||||
      "y",
 | 
			
		||||
      "yuv",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    image: [
 | 
			
		||||
      "8bim",
 | 
			
		||||
      "8bimtext",
 | 
			
		||||
      "8bimwtext",
 | 
			
		||||
      "app1",
 | 
			
		||||
      "app1jpeg",
 | 
			
		||||
      "art",
 | 
			
		||||
      "avs",
 | 
			
		||||
      "b",
 | 
			
		||||
      "bie",
 | 
			
		||||
      "bigtiff",
 | 
			
		||||
      "bmp",
 | 
			
		||||
      "bmp2",
 | 
			
		||||
      "bmp3",
 | 
			
		||||
      "brf",
 | 
			
		||||
      "c",
 | 
			
		||||
      "cals",
 | 
			
		||||
      "cin",
 | 
			
		||||
      "cmyk",
 | 
			
		||||
      "cmyka",
 | 
			
		||||
      "dcx",
 | 
			
		||||
      "dpx",
 | 
			
		||||
      "epdf",
 | 
			
		||||
      "epi",
 | 
			
		||||
      "eps",
 | 
			
		||||
      "eps2",
 | 
			
		||||
      "eps3",
 | 
			
		||||
      "epsf",
 | 
			
		||||
      "epsi",
 | 
			
		||||
      "ept",
 | 
			
		||||
      "ept2",
 | 
			
		||||
      "ept3",
 | 
			
		||||
      "exif",
 | 
			
		||||
      "fax",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "g",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "gif87",
 | 
			
		||||
      "gray",
 | 
			
		||||
      "graya",
 | 
			
		||||
      "histogram",
 | 
			
		||||
      "html",
 | 
			
		||||
      "icb",
 | 
			
		||||
      "icc",
 | 
			
		||||
      "icm",
 | 
			
		||||
      "info",
 | 
			
		||||
      "iptc",
 | 
			
		||||
      "iptctext",
 | 
			
		||||
      "iptcwtext",
 | 
			
		||||
      "isobrl",
 | 
			
		||||
      "isobrl6",
 | 
			
		||||
      "jbg",
 | 
			
		||||
      "jbig",
 | 
			
		||||
      "jng",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "k",
 | 
			
		||||
      "m",
 | 
			
		||||
      "m2v",
 | 
			
		||||
      "map",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "matte",
 | 
			
		||||
      "miff",
 | 
			
		||||
      "mng",
 | 
			
		||||
      "mono",
 | 
			
		||||
      "mpc",
 | 
			
		||||
      "mpeg",
 | 
			
		||||
      "mpg",
 | 
			
		||||
      "msl",
 | 
			
		||||
      "mtv",
 | 
			
		||||
      "mvg",
 | 
			
		||||
      "null",
 | 
			
		||||
      "o",
 | 
			
		||||
      "otb",
 | 
			
		||||
      "p7",
 | 
			
		||||
      "pal",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pbm",
 | 
			
		||||
      "pcd",
 | 
			
		||||
      "pcds",
 | 
			
		||||
      "pcl",
 | 
			
		||||
      "pct",
 | 
			
		||||
      "pcx",
 | 
			
		||||
      "pdb",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "picon",
 | 
			
		||||
      "pict",
 | 
			
		||||
      "png",
 | 
			
		||||
      "png00",
 | 
			
		||||
      "png24",
 | 
			
		||||
      "png32",
 | 
			
		||||
      "png48",
 | 
			
		||||
      "png64",
 | 
			
		||||
      "png8",
 | 
			
		||||
      "pnm",
 | 
			
		||||
      "ppm",
 | 
			
		||||
      "preview",
 | 
			
		||||
      "ps",
 | 
			
		||||
      "ps2",
 | 
			
		||||
      "ps3",
 | 
			
		||||
      "ptif",
 | 
			
		||||
      "r",
 | 
			
		||||
      "ras",
 | 
			
		||||
      "rgb",
 | 
			
		||||
      "rgba",
 | 
			
		||||
      "sgi",
 | 
			
		||||
      "shtml",
 | 
			
		||||
      "sun",
 | 
			
		||||
      "text",
 | 
			
		||||
      "tga",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "txt",
 | 
			
		||||
      "ubrl",
 | 
			
		||||
      "ubrl6",
 | 
			
		||||
      "uil",
 | 
			
		||||
      "uyvy",
 | 
			
		||||
      "vda",
 | 
			
		||||
      "vicar",
 | 
			
		||||
      "vid",
 | 
			
		||||
      "viff",
 | 
			
		||||
      "vst",
 | 
			
		||||
      "wbmp",
 | 
			
		||||
      "webp",
 | 
			
		||||
      "x",
 | 
			
		||||
      "xbm",
 | 
			
		||||
      "xmp",
 | 
			
		||||
      "xpm",
 | 
			
		||||
      "xv",
 | 
			
		||||
      "xwd",
 | 
			
		||||
      "y",
 | 
			
		||||
      "yuv",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile(
 | 
			
		||||
      "gm",
 | 
			
		||||
      ["convert", filePath, targetPath],
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,64 +1,59 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
    from: {
 | 
			
		||||
      images: [
 | 
			
		||||
        "svg",
 | 
			
		||||
        "pdf",
 | 
			
		||||
        "eps",
 | 
			
		||||
        "ps",
 | 
			
		||||
        "wmf",
 | 
			
		||||
        "emf",
 | 
			
		||||
        "png"
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    to: {
 | 
			
		||||
      images: [
 | 
			
		||||
        "dxf",
 | 
			
		||||
        "emf",
 | 
			
		||||
        "eps",
 | 
			
		||||
        "fxg",
 | 
			
		||||
        "gpl",
 | 
			
		||||
        "hpgl",
 | 
			
		||||
        "html",
 | 
			
		||||
        "odg",
 | 
			
		||||
        "pdf",
 | 
			
		||||
        "png",
 | 
			
		||||
        "pov",
 | 
			
		||||
        "ps",
 | 
			
		||||
        "sif",
 | 
			
		||||
        "svg",
 | 
			
		||||
        "svgz",
 | 
			
		||||
        "tex",
 | 
			
		||||
        "wmf",
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  from: {
 | 
			
		||||
    images: ["svg", "pdf", "eps", "ps", "wmf", "emf", "png"],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    images: [
 | 
			
		||||
      "dxf",
 | 
			
		||||
      "emf",
 | 
			
		||||
      "eps",
 | 
			
		||||
      "fxg",
 | 
			
		||||
      "gpl",
 | 
			
		||||
      "hpgl",
 | 
			
		||||
      "html",
 | 
			
		||||
      "odg",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "png",
 | 
			
		||||
      "pov",
 | 
			
		||||
      "ps",
 | 
			
		||||
      "sif",
 | 
			
		||||
      "svg",
 | 
			
		||||
      "svgz",
 | 
			
		||||
      "tex",
 | 
			
		||||
      "wmf",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  export function convert(
 | 
			
		||||
    filePath: string,
 | 
			
		||||
    fileType: string,
 | 
			
		||||
    convertTo: string,
 | 
			
		||||
    targetPath: string,
 | 
			
		||||
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
    options?: unknown,
 | 
			
		||||
  ): Promise<string> {
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
      exec(`inkscape "${filePath}" -o "${targetPath}"`, (error, stdout, stderr) => {
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile(
 | 
			
		||||
      "inkscape",
 | 
			
		||||
      [filePath, "-o", targetPath],
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								src/converters/libheif.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/converters/libheif.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
import { execFile } from "child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    images: [
 | 
			
		||||
      "avci",
 | 
			
		||||
      "avcs",
 | 
			
		||||
      "avif",
 | 
			
		||||
      "h264",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heics",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "heifs",
 | 
			
		||||
      "mkv",
 | 
			
		||||
      "mp4",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    images: ["jpeg", "png", "y4m"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile(
 | 
			
		||||
      "heif-convert",
 | 
			
		||||
      [filePath, targetPath],
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
@@ -1,71 +1,71 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
// declare possible conversions
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    jxl: ["jxl"],
 | 
			
		||||
    images: [
 | 
			
		||||
      "apng",
 | 
			
		||||
      "exr",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pfm",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "pgx",
 | 
			
		||||
      "png",
 | 
			
		||||
      "ppm",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    jxl: [
 | 
			
		||||
      "apng",
 | 
			
		||||
      "exr",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pfm",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "pgx",
 | 
			
		||||
      "png",
 | 
			
		||||
      "ppm",
 | 
			
		||||
    ],
 | 
			
		||||
    images: ["jxl"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  let tool = "";
 | 
			
		||||
  if (fileType === "jxl") {
 | 
			
		||||
    tool = "djxl";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (convertTo === "jxl") {
 | 
			
		||||
    tool = "cjxl";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(`${tool} "${filePath}" "${targetPath}"`, (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stdout) {
 | 
			
		||||
        console.log(`stdout: ${stdout}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stderr) {
 | 
			
		||||
        console.error(`stderr: ${stderr}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      resolve("Done");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
// declare possible conversions
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    jxl: ["jxl"],
 | 
			
		||||
    images: [
 | 
			
		||||
      "apng",
 | 
			
		||||
      "exr",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pfm",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "pgx",
 | 
			
		||||
      "png",
 | 
			
		||||
      "ppm",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    jxl: [
 | 
			
		||||
      "apng",
 | 
			
		||||
      "exr",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "pam",
 | 
			
		||||
      "pfm",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "pgx",
 | 
			
		||||
      "png",
 | 
			
		||||
      "ppm",
 | 
			
		||||
    ],
 | 
			
		||||
    images: ["jxl"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  let tool = "";
 | 
			
		||||
  if (fileType === "jxl") {
 | 
			
		||||
    tool = "djxl";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (convertTo === "jxl") {
 | 
			
		||||
    tool = "cjxl";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile(tool, [filePath, targetPath], (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stdout) {
 | 
			
		||||
        console.log(`stdout: ${stdout}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stderr) {
 | 
			
		||||
        console.error(`stderr: ${stderr}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      resolve("Done");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import { convert as convertresvg, properties as propertiesresvg } from "./resvg"
 | 
			
		||||
import { convert as convertImage, properties as propertiesImage } from "./vips";
 | 
			
		||||
import { convert as convertxelatex, properties as propertiesxelatex } from "./xelatex";
 | 
			
		||||
import { convert as convertCalibre, properties as propertiesCalibre } from "./calibre";
 | 
			
		||||
import { convert as convertLibheif, properties as propertiesLibheif } from "./libheif";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular
 | 
			
		||||
@@ -53,6 +54,10 @@ const properties: Record<
 | 
			
		||||
    properties: propertiesImage,
 | 
			
		||||
    converter: convertImage,
 | 
			
		||||
  },
 | 
			
		||||
  libheif: {
 | 
			
		||||
    properties: propertiesLibheif,
 | 
			
		||||
    converter: convertLibheif,
 | 
			
		||||
  },
 | 
			
		||||
  xelatex: {
 | 
			
		||||
    properties: propertiesxelatex,
 | 
			
		||||
    converter: convertxelatex,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,156 +1,162 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    text: [
 | 
			
		||||
      "textile",
 | 
			
		||||
      "tikiwiki",
 | 
			
		||||
      "tsv",
 | 
			
		||||
      "twiki",
 | 
			
		||||
      "typst",
 | 
			
		||||
      "vimwiki",
 | 
			
		||||
      "biblatex",
 | 
			
		||||
      "bibtex",
 | 
			
		||||
      "bits",
 | 
			
		||||
      "commonmark",
 | 
			
		||||
      "commonmark_x",
 | 
			
		||||
      "creole",
 | 
			
		||||
      "csljson",
 | 
			
		||||
      "csv",
 | 
			
		||||
      "djot",
 | 
			
		||||
      "docbook",
 | 
			
		||||
      "docx",
 | 
			
		||||
      "dokuwiki",
 | 
			
		||||
      "endnotexml",
 | 
			
		||||
      "epub",
 | 
			
		||||
      "fb2",
 | 
			
		||||
      "gfm",
 | 
			
		||||
      "haddock",
 | 
			
		||||
      "html",
 | 
			
		||||
      "ipynb",
 | 
			
		||||
      "jats",
 | 
			
		||||
      "jira",
 | 
			
		||||
      "json",
 | 
			
		||||
      "latex",
 | 
			
		||||
      "man",
 | 
			
		||||
      "markdown",
 | 
			
		||||
      "markdown_mmd",
 | 
			
		||||
      "markdown_phpextra",
 | 
			
		||||
      "markdown_strict",
 | 
			
		||||
      "mediawiki",
 | 
			
		||||
      "muse",
 | 
			
		||||
      "pandoc native",
 | 
			
		||||
      "opml",
 | 
			
		||||
      "org",
 | 
			
		||||
      "ris",
 | 
			
		||||
      "rst",
 | 
			
		||||
      "rtf",
 | 
			
		||||
      "t2t",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    text: [
 | 
			
		||||
      "tei",
 | 
			
		||||
      "texinfo",
 | 
			
		||||
      "textile",
 | 
			
		||||
      "typst",
 | 
			
		||||
      "xwiki",
 | 
			
		||||
      "zimwiki",
 | 
			
		||||
      "asciidoc",
 | 
			
		||||
      "asciidoc_legacy",
 | 
			
		||||
      "asciidoctor",
 | 
			
		||||
      "beamer",
 | 
			
		||||
      "biblatex",
 | 
			
		||||
      "bibtex",
 | 
			
		||||
      "chunkedhtml",
 | 
			
		||||
      "commonmark",
 | 
			
		||||
      "commonmark_x",
 | 
			
		||||
      "context",
 | 
			
		||||
      "csljson",
 | 
			
		||||
      "djot",
 | 
			
		||||
      "docbook",
 | 
			
		||||
      "docbook4",
 | 
			
		||||
      "docbook5",
 | 
			
		||||
      "docx",
 | 
			
		||||
      "dokuwiki",
 | 
			
		||||
      "dzslides",
 | 
			
		||||
      "epub",
 | 
			
		||||
      "epub2",
 | 
			
		||||
      "epub3",
 | 
			
		||||
      "fb2",
 | 
			
		||||
      "gfm",
 | 
			
		||||
      "haddock",
 | 
			
		||||
      "html",
 | 
			
		||||
      "html4",
 | 
			
		||||
      "html5",
 | 
			
		||||
      "icml",
 | 
			
		||||
      "ipynb",
 | 
			
		||||
      "jats",
 | 
			
		||||
      "jats_archiving",
 | 
			
		||||
      "jats_articleauthoring",
 | 
			
		||||
      "jats_publishing",
 | 
			
		||||
      "jira",
 | 
			
		||||
      "json",
 | 
			
		||||
      "latex",
 | 
			
		||||
      "man",
 | 
			
		||||
      "markdown",
 | 
			
		||||
      "markdown_mmd",
 | 
			
		||||
      "markdown_phpextra",
 | 
			
		||||
      "markdown_strict",
 | 
			
		||||
      "markua",
 | 
			
		||||
      "mediawiki",
 | 
			
		||||
      "ms",
 | 
			
		||||
      "muse",
 | 
			
		||||
      "pandoc native",
 | 
			
		||||
      "odt",
 | 
			
		||||
      "opendocument",
 | 
			
		||||
      "opml",
 | 
			
		||||
      "org",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "plain",
 | 
			
		||||
      "pptx",
 | 
			
		||||
      "revealjs",
 | 
			
		||||
      "rst",
 | 
			
		||||
      "rtf",
 | 
			
		||||
      "s5",
 | 
			
		||||
      "slideous",
 | 
			
		||||
      "slidy",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  // set xelatex here
 | 
			
		||||
  const xelatex = ["pdf", "latex"];
 | 
			
		||||
  let option = "";
 | 
			
		||||
  if (xelatex.includes(convertTo)) {
 | 
			
		||||
    option = "--pdf-engine=xelatex";
 | 
			
		||||
  }
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(
 | 
			
		||||
      `pandoc ${option} "${filePath}" -f ${fileType} -t ${convertTo} -o "${targetPath}"`,
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    text: [
 | 
			
		||||
      "textile",
 | 
			
		||||
      "tikiwiki",
 | 
			
		||||
      "tsv",
 | 
			
		||||
      "twiki",
 | 
			
		||||
      "typst",
 | 
			
		||||
      "vimwiki",
 | 
			
		||||
      "biblatex",
 | 
			
		||||
      "bibtex",
 | 
			
		||||
      "bits",
 | 
			
		||||
      "commonmark",
 | 
			
		||||
      "commonmark_x",
 | 
			
		||||
      "creole",
 | 
			
		||||
      "csljson",
 | 
			
		||||
      "csv",
 | 
			
		||||
      "djot",
 | 
			
		||||
      "docbook",
 | 
			
		||||
      "docx",
 | 
			
		||||
      "dokuwiki",
 | 
			
		||||
      "endnotexml",
 | 
			
		||||
      "epub",
 | 
			
		||||
      "fb2",
 | 
			
		||||
      "gfm",
 | 
			
		||||
      "haddock",
 | 
			
		||||
      "html",
 | 
			
		||||
      "ipynb",
 | 
			
		||||
      "jats",
 | 
			
		||||
      "jira",
 | 
			
		||||
      "json",
 | 
			
		||||
      "latex",
 | 
			
		||||
      "man",
 | 
			
		||||
      "markdown",
 | 
			
		||||
      "markdown_mmd",
 | 
			
		||||
      "markdown_phpextra",
 | 
			
		||||
      "markdown_strict",
 | 
			
		||||
      "mediawiki",
 | 
			
		||||
      "muse",
 | 
			
		||||
      "pandoc native",
 | 
			
		||||
      "opml",
 | 
			
		||||
      "org",
 | 
			
		||||
      "ris",
 | 
			
		||||
      "rst",
 | 
			
		||||
      "rtf",
 | 
			
		||||
      "t2t",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    text: [
 | 
			
		||||
      "tei",
 | 
			
		||||
      "texinfo",
 | 
			
		||||
      "textile",
 | 
			
		||||
      "typst",
 | 
			
		||||
      "xwiki",
 | 
			
		||||
      "zimwiki",
 | 
			
		||||
      "asciidoc",
 | 
			
		||||
      "asciidoc_legacy",
 | 
			
		||||
      "asciidoctor",
 | 
			
		||||
      "beamer",
 | 
			
		||||
      "biblatex",
 | 
			
		||||
      "bibtex",
 | 
			
		||||
      "chunkedhtml",
 | 
			
		||||
      "commonmark",
 | 
			
		||||
      "commonmark_x",
 | 
			
		||||
      "context",
 | 
			
		||||
      "csljson",
 | 
			
		||||
      "djot",
 | 
			
		||||
      "docbook",
 | 
			
		||||
      "docbook4",
 | 
			
		||||
      "docbook5",
 | 
			
		||||
      "docx",
 | 
			
		||||
      "dokuwiki",
 | 
			
		||||
      "dzslides",
 | 
			
		||||
      "epub",
 | 
			
		||||
      "epub2",
 | 
			
		||||
      "epub3",
 | 
			
		||||
      "fb2",
 | 
			
		||||
      "gfm",
 | 
			
		||||
      "haddock",
 | 
			
		||||
      "html",
 | 
			
		||||
      "html4",
 | 
			
		||||
      "html5",
 | 
			
		||||
      "icml",
 | 
			
		||||
      "ipynb",
 | 
			
		||||
      "jats",
 | 
			
		||||
      "jats_archiving",
 | 
			
		||||
      "jats_articleauthoring",
 | 
			
		||||
      "jats_publishing",
 | 
			
		||||
      "jira",
 | 
			
		||||
      "json",
 | 
			
		||||
      "latex",
 | 
			
		||||
      "man",
 | 
			
		||||
      "markdown",
 | 
			
		||||
      "markdown_mmd",
 | 
			
		||||
      "markdown_phpextra",
 | 
			
		||||
      "markdown_strict",
 | 
			
		||||
      "markua",
 | 
			
		||||
      "mediawiki",
 | 
			
		||||
      "ms",
 | 
			
		||||
      "muse",
 | 
			
		||||
      "pandoc native",
 | 
			
		||||
      "odt",
 | 
			
		||||
      "opendocument",
 | 
			
		||||
      "opml",
 | 
			
		||||
      "org",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "plain",
 | 
			
		||||
      "pptx",
 | 
			
		||||
      "revealjs",
 | 
			
		||||
      "rst",
 | 
			
		||||
      "rtf",
 | 
			
		||||
      "s5",
 | 
			
		||||
      "slideous",
 | 
			
		||||
      "slidy",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  // set xelatex here
 | 
			
		||||
  const xelatex = ["pdf", "latex"];
 | 
			
		||||
 | 
			
		||||
  // Build arguments array
 | 
			
		||||
  const args: string[] = [];
 | 
			
		||||
 | 
			
		||||
  if (xelatex.includes(convertTo)) {
 | 
			
		||||
    args.push("--pdf-engine=xelatex");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  args.push(filePath);
 | 
			
		||||
  args.push("-f", fileType);
 | 
			
		||||
  args.push("-t", convertTo);
 | 
			
		||||
  args.push("-o", targetPath);
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile("pandoc", args, (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stdout) {
 | 
			
		||||
        console.log(`stdout: ${stdout}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stderr) {
 | 
			
		||||
        console.error(`stderr: ${stderr}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      resolve("Done");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,37 +1,37 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    images: ["svg"],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    images: ["png"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(`resvg "${filePath}" "${targetPath}"`, (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stdout) {
 | 
			
		||||
        console.log(`stdout: ${stdout}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stderr) {
 | 
			
		||||
        console.error(`stderr: ${stderr}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      resolve("Done");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    images: ["svg"],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    images: ["png"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile("resvg", [filePath, targetPath], (error, stdout, stderr) => {
 | 
			
		||||
      if (error) {
 | 
			
		||||
        reject(`error: ${error}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stdout) {
 | 
			
		||||
        console.log(`stdout: ${stdout}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (stderr) {
 | 
			
		||||
        console.error(`stderr: ${stderr}`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      resolve("Done");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,142 +1,142 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// declare possible conversions
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    images: [
 | 
			
		||||
      "avif",
 | 
			
		||||
      "bif",
 | 
			
		||||
      "csv",
 | 
			
		||||
      "exr",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "hdr.gz",
 | 
			
		||||
      "hdr",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "img.gz",
 | 
			
		||||
      "img",
 | 
			
		||||
      "j2c",
 | 
			
		||||
      "j2k",
 | 
			
		||||
      "jp2",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "jpx",
 | 
			
		||||
      "jxl",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "mrxs",
 | 
			
		||||
      "ndpi",
 | 
			
		||||
      "nia.gz",
 | 
			
		||||
      "nia",
 | 
			
		||||
      "nii.gz",
 | 
			
		||||
      "nii",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "pfm",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "pic",
 | 
			
		||||
      "png",
 | 
			
		||||
      "ppm",
 | 
			
		||||
      "raw",
 | 
			
		||||
      "scn",
 | 
			
		||||
      "svg",
 | 
			
		||||
      "svs",
 | 
			
		||||
      "svslide",
 | 
			
		||||
      "szi",
 | 
			
		||||
      "tif",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "v",
 | 
			
		||||
      "vips",
 | 
			
		||||
      "vms",
 | 
			
		||||
      "vmu",
 | 
			
		||||
      "webp",
 | 
			
		||||
      "zip",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    images: [
 | 
			
		||||
      "avif",
 | 
			
		||||
      "dzi",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "hdr.gz",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "img.gz",
 | 
			
		||||
      "j2c",
 | 
			
		||||
      "j2k",
 | 
			
		||||
      "jp2",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "jpx",
 | 
			
		||||
      "jxl",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "nia.gz",
 | 
			
		||||
      "nia",
 | 
			
		||||
      "nii.gz",
 | 
			
		||||
      "nii",
 | 
			
		||||
      "png",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "vips",
 | 
			
		||||
      "webp",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  options: {
 | 
			
		||||
    svg: {
 | 
			
		||||
      scale: {
 | 
			
		||||
        description: "Scale the image up or down",
 | 
			
		||||
        type: "number",
 | 
			
		||||
        default: 1,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  // if (fileType === "svg") {
 | 
			
		||||
  //   const scale = options.scale || 1;
 | 
			
		||||
  //   const metadata = await sharp(filePath).metadata();
 | 
			
		||||
 | 
			
		||||
  //   if (!metadata || !metadata.width || !metadata.height) {
 | 
			
		||||
  //     throw new Error("Could not get metadata from image");
 | 
			
		||||
  //   }
 | 
			
		||||
 | 
			
		||||
  //   const newWidth = Math.round(metadata.width * scale);
 | 
			
		||||
  //   const newHeight = Math.round(metadata.height * scale);
 | 
			
		||||
 | 
			
		||||
  //   return await sharp(filePath)
 | 
			
		||||
  //     .resize(newWidth, newHeight)
 | 
			
		||||
  //     .toFormat(convertTo)
 | 
			
		||||
  //     .toFile(targetPath);
 | 
			
		||||
  // }
 | 
			
		||||
  let action = "copy";
 | 
			
		||||
  if (fileType === "pdf") {
 | 
			
		||||
    action = "pdfload";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    exec(
 | 
			
		||||
      `vips ${action} "${filePath}" "${targetPath}"`,
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
// declare possible conversions
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    images: [
 | 
			
		||||
      "avif",
 | 
			
		||||
      "bif",
 | 
			
		||||
      "csv",
 | 
			
		||||
      "exr",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "hdr.gz",
 | 
			
		||||
      "hdr",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "img.gz",
 | 
			
		||||
      "img",
 | 
			
		||||
      "j2c",
 | 
			
		||||
      "j2k",
 | 
			
		||||
      "jp2",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "jpx",
 | 
			
		||||
      "jxl",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "mrxs",
 | 
			
		||||
      "ndpi",
 | 
			
		||||
      "nia.gz",
 | 
			
		||||
      "nia",
 | 
			
		||||
      "nii.gz",
 | 
			
		||||
      "nii",
 | 
			
		||||
      "pdf",
 | 
			
		||||
      "pfm",
 | 
			
		||||
      "pgm",
 | 
			
		||||
      "pic",
 | 
			
		||||
      "png",
 | 
			
		||||
      "ppm",
 | 
			
		||||
      "raw",
 | 
			
		||||
      "scn",
 | 
			
		||||
      "svg",
 | 
			
		||||
      "svs",
 | 
			
		||||
      "svslide",
 | 
			
		||||
      "szi",
 | 
			
		||||
      "tif",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "v",
 | 
			
		||||
      "vips",
 | 
			
		||||
      "vms",
 | 
			
		||||
      "vmu",
 | 
			
		||||
      "webp",
 | 
			
		||||
      "zip",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    images: [
 | 
			
		||||
      "avif",
 | 
			
		||||
      "dzi",
 | 
			
		||||
      "fits",
 | 
			
		||||
      "gif",
 | 
			
		||||
      "hdr.gz",
 | 
			
		||||
      "heic",
 | 
			
		||||
      "heif",
 | 
			
		||||
      "img.gz",
 | 
			
		||||
      "j2c",
 | 
			
		||||
      "j2k",
 | 
			
		||||
      "jp2",
 | 
			
		||||
      "jpeg",
 | 
			
		||||
      "jpx",
 | 
			
		||||
      "jxl",
 | 
			
		||||
      "mat",
 | 
			
		||||
      "nia.gz",
 | 
			
		||||
      "nia",
 | 
			
		||||
      "nii.gz",
 | 
			
		||||
      "nii",
 | 
			
		||||
      "png",
 | 
			
		||||
      "tiff",
 | 
			
		||||
      "vips",
 | 
			
		||||
      "webp",
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  options: {
 | 
			
		||||
    svg: {
 | 
			
		||||
      scale: {
 | 
			
		||||
        description: "Scale the image up or down",
 | 
			
		||||
        type: "number",
 | 
			
		||||
        default: 1,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  // if (fileType === "svg") {
 | 
			
		||||
  //   const scale = options.scale || 1;
 | 
			
		||||
  //   const metadata = await sharp(filePath).metadata();
 | 
			
		||||
 | 
			
		||||
  //   if (!metadata || !metadata.width || !metadata.height) {
 | 
			
		||||
  //     throw new Error("Could not get metadata from image");
 | 
			
		||||
  //   }
 | 
			
		||||
 | 
			
		||||
  //   const newWidth = Math.round(metadata.width * scale);
 | 
			
		||||
  //   const newHeight = Math.round(metadata.height * scale);
 | 
			
		||||
 | 
			
		||||
  //   return await sharp(filePath)
 | 
			
		||||
  //     .resize(newWidth, newHeight)
 | 
			
		||||
  //     .toFormat(convertTo)
 | 
			
		||||
  //     .toFile(targetPath);
 | 
			
		||||
  // }
 | 
			
		||||
  let action = "copy";
 | 
			
		||||
  if (fileType === "pdf") {
 | 
			
		||||
    action = "pdfload";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    execFile(
 | 
			
		||||
      "vips",
 | 
			
		||||
      [action, filePath, targetPath],
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,46 +1,53 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    text: ["tex", "latex"],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    text: ["pdf"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    // const fileName: string = (targetPath.split("/").pop() as string).replace(".pdf", "")
 | 
			
		||||
    const outputPath = targetPath
 | 
			
		||||
      .split("/")
 | 
			
		||||
      .slice(0, -1)
 | 
			
		||||
      .join("/")
 | 
			
		||||
      .replace("./", "");
 | 
			
		||||
    exec(
 | 
			
		||||
      `latexmk -xelatex -interaction=nonstopmode -output-directory="${outputPath}" "${filePath}"`,
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import { execFile } from "node:child_process";
 | 
			
		||||
 | 
			
		||||
export const properties = {
 | 
			
		||||
  from: {
 | 
			
		||||
    text: ["tex", "latex"],
 | 
			
		||||
  },
 | 
			
		||||
  to: {
 | 
			
		||||
    text: ["pdf"],
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function convert(
 | 
			
		||||
  filePath: string,
 | 
			
		||||
  fileType: string,
 | 
			
		||||
  convertTo: string,
 | 
			
		||||
  targetPath: string,
 | 
			
		||||
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
			
		||||
  options?: unknown,
 | 
			
		||||
): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    // const fileName: string = (targetPath.split("/").pop() as string).replace(".pdf", "")
 | 
			
		||||
    const outputPath = targetPath
 | 
			
		||||
      .split("/")
 | 
			
		||||
      .slice(0, -1)
 | 
			
		||||
      .join("/")
 | 
			
		||||
      .replace("./", "");
 | 
			
		||||
 | 
			
		||||
    execFile(
 | 
			
		||||
      "latexmk",
 | 
			
		||||
      [
 | 
			
		||||
        "-xelatex",
 | 
			
		||||
        "-interaction=nonstopmode",
 | 
			
		||||
        `-output-directory=${outputPath}`,
 | 
			
		||||
        filePath,
 | 
			
		||||
      ],
 | 
			
		||||
      (error, stdout, stderr) => {
 | 
			
		||||
        if (error) {
 | 
			
		||||
          reject(`error: ${error}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stdout) {
 | 
			
		||||
          console.log(`stdout: ${stdout}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (stderr) {
 | 
			
		||||
          console.error(`stderr: ${stderr}`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        resolve("Done");
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { exec } from "node:child_process";
 | 
			
		||||
import { version } from "../../package.json";
 | 
			
		||||
 | 
			
		||||
console.log(`ConvertX v${version}`);
 | 
			
		||||
 | 
			
		||||
if (process.env.NODE_ENV === "production") {
 | 
			
		||||
@@ -99,7 +100,7 @@ if (process.env.NODE_ENV === "production") {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (stdout) {
 | 
			
		||||
      console.log(`assimp v${stdout.split("\n")[5]}`);
 | 
			
		||||
      console.log(`assimp ${stdout.split("\n")[5]}`);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -113,6 +114,16 @@ if (process.env.NODE_ENV === "production") {
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  exec("heif-info -v", (error, stdout) => {
 | 
			
		||||
    if (error) {
 | 
			
		||||
      console.error("libheif is not installed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (stdout) {
 | 
			
		||||
      console.log(`libheif v${stdout.split("\n")[0]}`);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  exec("bun -v", (error, stdout) => {
 | 
			
		||||
    if (error) {
 | 
			
		||||
      console.error("Bun is not installed. wait what");
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,11 @@
 | 
			
		||||
import tw from "tailwindcss";
 | 
			
		||||
import tailwind from "@tailwindcss/postcss";
 | 
			
		||||
import postcss from "postcss";
 | 
			
		||||
 | 
			
		||||
export const generateTailwind = async () => {
 | 
			
		||||
  const result = await Bun.file("./src/main.css")
 | 
			
		||||
    .text()
 | 
			
		||||
    .then((sourceText) => {
 | 
			
		||||
      const config = "./tailwind.config.js";
 | 
			
		||||
 | 
			
		||||
      return postcss([tw(config)]).process(sourceText, {
 | 
			
		||||
      return postcss([tailwind]).process(sourceText, {
 | 
			
		||||
        from: "./src/main.css",
 | 
			
		||||
        to: "./public/generated.css",
 | 
			
		||||
      });
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										242
									
								
								src/index.tsx
									
									
									
									
									
								
							
							
						
						
									
										242
									
								
								src/index.tsx
									
									
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
			
		||||
import { randomInt, randomUUID } from "node:crypto";
 | 
			
		||||
import { rmSync } from "node:fs";
 | 
			
		||||
import { mkdir, unlink } from "node:fs/promises";
 | 
			
		||||
import cookie from "@elysiajs/cookie";
 | 
			
		||||
import { html, Html } from "@elysiajs/html";
 | 
			
		||||
import { jwt, type JWTPayloadSpec } from "@elysiajs/jwt";
 | 
			
		||||
import { staticPlugin } from "@elysiajs/static";
 | 
			
		||||
import { Database } from "bun:sqlite";
 | 
			
		||||
import { Elysia, t } from "elysia";
 | 
			
		||||
import sanitize from "sanitize-filename";
 | 
			
		||||
import { BaseHtml } from "./components/base";
 | 
			
		||||
import { Header } from "./components/header";
 | 
			
		||||
import {
 | 
			
		||||
@@ -116,7 +116,6 @@ const app = new Elysia({
 | 
			
		||||
  },
 | 
			
		||||
  prefix: WEBROOT,
 | 
			
		||||
})
 | 
			
		||||
  .use(cookie())
 | 
			
		||||
  .use(html())
 | 
			
		||||
  .use(
 | 
			
		||||
    jwt({
 | 
			
		||||
@@ -153,7 +152,12 @@ const app = new Elysia({
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <BaseHtml title="ConvertX | Setup" webroot={WEBROOT}>
 | 
			
		||||
        <main class="mx-auto w-full max-w-4xl px-4">
 | 
			
		||||
        <main
 | 
			
		||||
          class={`
 | 
			
		||||
            mx-auto w-full max-w-4xl px-2
 | 
			
		||||
            sm:px-4
 | 
			
		||||
          `}
 | 
			
		||||
        >
 | 
			
		||||
          <h1 class="my-8 text-3xl">Welcome to ConvertX!</h1>
 | 
			
		||||
          <article class="article p-0">
 | 
			
		||||
            <header class="w-full bg-neutral-800 p-4">
 | 
			
		||||
@@ -166,7 +170,7 @@ const app = new Elysia({
 | 
			
		||||
                  <input
 | 
			
		||||
                    type="email"
 | 
			
		||||
                    name="email"
 | 
			
		||||
                    class="rounded bg-neutral-800 p-3"
 | 
			
		||||
                    class="rounded-sm bg-neutral-800 p-3"
 | 
			
		||||
                    placeholder="Email"
 | 
			
		||||
                    autocomplete="email"
 | 
			
		||||
                    required
 | 
			
		||||
@@ -177,7 +181,7 @@ const app = new Elysia({
 | 
			
		||||
                  <input
 | 
			
		||||
                    type="password"
 | 
			
		||||
                    name="password"
 | 
			
		||||
                    class="rounded bg-neutral-800 p-3"
 | 
			
		||||
                    class="rounded-sm bg-neutral-800 p-3"
 | 
			
		||||
                    placeholder="Password"
 | 
			
		||||
                    autocomplete="current-password"
 | 
			
		||||
                    required
 | 
			
		||||
@@ -217,7 +221,12 @@ const app = new Elysia({
 | 
			
		||||
            accountRegistration={ACCOUNT_REGISTRATION}
 | 
			
		||||
            allowUnauthenticated={ALLOW_UNAUTHENTICATED}
 | 
			
		||||
          />
 | 
			
		||||
          <main class="w-full px-4">
 | 
			
		||||
          <main
 | 
			
		||||
            class={`
 | 
			
		||||
              w-full px-2
 | 
			
		||||
              sm:px-4
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
            <article class="article">
 | 
			
		||||
              <form method="post" class="flex flex-col gap-4">
 | 
			
		||||
                <fieldset class="mb-4 flex flex-col gap-4">
 | 
			
		||||
@@ -226,7 +235,7 @@ const app = new Elysia({
 | 
			
		||||
                    <input
 | 
			
		||||
                      type="email"
 | 
			
		||||
                      name="email"
 | 
			
		||||
                      class="rounded bg-neutral-800 p-3"
 | 
			
		||||
                      class="rounded-sm bg-neutral-800 p-3"
 | 
			
		||||
                      placeholder="Email"
 | 
			
		||||
                      autocomplete="email"
 | 
			
		||||
                      required
 | 
			
		||||
@@ -237,7 +246,7 @@ const app = new Elysia({
 | 
			
		||||
                    <input
 | 
			
		||||
                      type="password"
 | 
			
		||||
                      name="password"
 | 
			
		||||
                      class="rounded bg-neutral-800 p-3"
 | 
			
		||||
                      class="rounded-sm bg-neutral-800 p-3"
 | 
			
		||||
                      placeholder="Password"
 | 
			
		||||
                      autocomplete="current-password"
 | 
			
		||||
                      required
 | 
			
		||||
@@ -343,7 +352,12 @@ const app = new Elysia({
 | 
			
		||||
            accountRegistration={ACCOUNT_REGISTRATION}
 | 
			
		||||
            allowUnauthenticated={ALLOW_UNAUTHENTICATED}
 | 
			
		||||
          />
 | 
			
		||||
          <main class="w-full px-4">
 | 
			
		||||
          <main
 | 
			
		||||
            class={`
 | 
			
		||||
              w-full px-2
 | 
			
		||||
              sm:px-4
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
            <article class="article">
 | 
			
		||||
              <form method="post" class="flex flex-col gap-4">
 | 
			
		||||
                <fieldset class="mb-4 flex flex-col gap-4">
 | 
			
		||||
@@ -352,7 +366,7 @@ const app = new Elysia({
 | 
			
		||||
                    <input
 | 
			
		||||
                      type="email"
 | 
			
		||||
                      name="email"
 | 
			
		||||
                      class="rounded bg-neutral-800 p-3"
 | 
			
		||||
                      class="rounded-sm bg-neutral-800 p-3"
 | 
			
		||||
                      placeholder="Email"
 | 
			
		||||
                      autocomplete="email"
 | 
			
		||||
                      required
 | 
			
		||||
@@ -363,7 +377,7 @@ const app = new Elysia({
 | 
			
		||||
                    <input
 | 
			
		||||
                      type="password"
 | 
			
		||||
                      name="password"
 | 
			
		||||
                      class="rounded bg-neutral-800 p-3"
 | 
			
		||||
                      class="rounded-sm bg-neutral-800 p-3"
 | 
			
		||||
                      placeholder="Password"
 | 
			
		||||
                      autocomplete="current-password"
 | 
			
		||||
                      required
 | 
			
		||||
@@ -556,7 +570,12 @@ const app = new Elysia({
 | 
			
		||||
            allowUnauthenticated={ALLOW_UNAUTHENTICATED}
 | 
			
		||||
            loggedIn
 | 
			
		||||
          />
 | 
			
		||||
          <main class="w-full px-4">
 | 
			
		||||
          <main
 | 
			
		||||
            class={`
 | 
			
		||||
              w-full px-2
 | 
			
		||||
              sm:px-4
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
            <article class="article">
 | 
			
		||||
              <h1 class="mb-4 text-xl">Convert</h1>
 | 
			
		||||
              <div class="mb-4 max-h-[50vh] overflow-y-auto scrollbar-thin">
 | 
			
		||||
@@ -564,8 +583,8 @@ const app = new Elysia({
 | 
			
		||||
                  id="file-list"
 | 
			
		||||
                  class={`
 | 
			
		||||
                    w-full table-auto rounded bg-neutral-900
 | 
			
		||||
                    [&_td]:p-4
 | 
			
		||||
                    [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                    [&_td]:p-4 [&_td]:first:max-w-[30vw] [&_td]:first:truncate
 | 
			
		||||
                    [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                  `}
 | 
			
		||||
                />
 | 
			
		||||
              </div>
 | 
			
		||||
@@ -601,13 +620,13 @@ const app = new Elysia({
 | 
			
		||||
                  name="convert_to_search"
 | 
			
		||||
                  placeholder="Search for conversions"
 | 
			
		||||
                  autocomplete="off"
 | 
			
		||||
                  class="w-full rounded bg-neutral-800 p-4"
 | 
			
		||||
                  class="w-full rounded-sm bg-neutral-800 p-4"
 | 
			
		||||
                />
 | 
			
		||||
                <div class="select_container relative">
 | 
			
		||||
                  <article
 | 
			
		||||
                    class={`
 | 
			
		||||
                      convert_to_popup absolute z-[2] m-0 hidden h-[30vh] max-h-[50vh] w-full
 | 
			
		||||
                      flex-col overflow-y-auto overflow-x-hidden rounded bg-neutral-800
 | 
			
		||||
                      convert_to_popup absolute z-2 m-0 hidden h-[30vh] max-h-[50vh] w-full flex-col
 | 
			
		||||
                      overflow-x-hidden overflow-y-auto rounded bg-neutral-800
 | 
			
		||||
                      sm:h-[30vh]
 | 
			
		||||
                    `}
 | 
			
		||||
                  >
 | 
			
		||||
@@ -672,7 +691,7 @@ const app = new Elysia({
 | 
			
		||||
              </article>
 | 
			
		||||
              <input
 | 
			
		||||
                class={`
 | 
			
		||||
                  btn-primary w-full
 | 
			
		||||
                  btn-primary w-full opacity-100
 | 
			
		||||
                  disabled:cursor-not-allowed disabled:opacity-50
 | 
			
		||||
                `}
 | 
			
		||||
                type="submit"
 | 
			
		||||
@@ -693,8 +712,8 @@ const app = new Elysia({
 | 
			
		||||
        <>
 | 
			
		||||
          <article
 | 
			
		||||
            class={`
 | 
			
		||||
              convert_to_popup absolute z-[2] m-0 hidden h-[50vh] max-h-[50vh] w-full flex-col
 | 
			
		||||
              overflow-y-auto overflow-x-hidden rounded bg-neutral-800
 | 
			
		||||
              convert_to_popup absolute z-2 m-0 hidden h-[50vh] max-h-[50vh] w-full flex-col
 | 
			
		||||
              overflow-x-hidden overflow-y-auto rounded bg-neutral-800
 | 
			
		||||
              sm:h-[30vh]
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
@@ -866,6 +885,10 @@ const app = new Elysia({
 | 
			
		||||
      const converterName = body.convert_to.split(",")[1];
 | 
			
		||||
      const fileNames = JSON.parse(body.file_names) as string[];
 | 
			
		||||
 | 
			
		||||
      for (let i = 0; i < fileNames.length; i++) {
 | 
			
		||||
        fileNames[i] = sanitize(fileNames[i] || "");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!Array.isArray(fileNames) || fileNames.length === 0) {
 | 
			
		||||
        return redirect(`${WEBROOT}/`, 302);
 | 
			
		||||
      }
 | 
			
		||||
@@ -942,7 +965,8 @@ const app = new Elysia({
 | 
			
		||||
    let userJobs = db
 | 
			
		||||
      .query("SELECT * FROM jobs WHERE user_id = ?")
 | 
			
		||||
      .as(Jobs)
 | 
			
		||||
      .all(user.id);
 | 
			
		||||
      .all(user.id)
 | 
			
		||||
      .reverse();
 | 
			
		||||
 | 
			
		||||
    for (const job of userJobs) {
 | 
			
		||||
      const files = db
 | 
			
		||||
@@ -964,31 +988,75 @@ const app = new Elysia({
 | 
			
		||||
            allowUnauthenticated={ALLOW_UNAUTHENTICATED}
 | 
			
		||||
            loggedIn
 | 
			
		||||
          />
 | 
			
		||||
          <main class="w-full px-4">
 | 
			
		||||
          <main
 | 
			
		||||
            class={`
 | 
			
		||||
              w-full px-2
 | 
			
		||||
              sm:px-4
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
            <article class="article">
 | 
			
		||||
              <h1 class="mb-4 text-xl">Results</h1>
 | 
			
		||||
              <table
 | 
			
		||||
                class={`
 | 
			
		||||
                  w-full table-auto rounded bg-neutral-900 text-left
 | 
			
		||||
                  w-full table-auto overflow-y-auto rounded bg-neutral-900 text-left
 | 
			
		||||
                  [&_td]:p-4
 | 
			
		||||
                  [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                  [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                `}
 | 
			
		||||
              >
 | 
			
		||||
                <thead>
 | 
			
		||||
                  <tr>
 | 
			
		||||
                    <th class="px-4 py-2">Time</th>
 | 
			
		||||
                    <th class="px-4 py-2">Files</th>
 | 
			
		||||
                    <th class="px-4 py-2">Files Done</th>
 | 
			
		||||
                    <th class="px-4 py-2">Status</th>
 | 
			
		||||
                    <th class="px-4 py-2">View</th>
 | 
			
		||||
                    <th
 | 
			
		||||
                      class={`
 | 
			
		||||
                        px-2 py-2
 | 
			
		||||
                        sm:px-4
 | 
			
		||||
                      `}
 | 
			
		||||
                    >
 | 
			
		||||
                      Time
 | 
			
		||||
                    </th>
 | 
			
		||||
                    <th
 | 
			
		||||
                      class={`
 | 
			
		||||
                        px-2 py-2
 | 
			
		||||
                        sm:px-4
 | 
			
		||||
                      `}
 | 
			
		||||
                    >
 | 
			
		||||
                      Files
 | 
			
		||||
                    </th>
 | 
			
		||||
                    <th
 | 
			
		||||
                      class={`
 | 
			
		||||
                        px-2 py-2
 | 
			
		||||
                        max-sm:hidden
 | 
			
		||||
                        sm:px-4
 | 
			
		||||
                      `}
 | 
			
		||||
                    >
 | 
			
		||||
                      Files Done
 | 
			
		||||
                    </th>
 | 
			
		||||
                    <th
 | 
			
		||||
                      class={`
 | 
			
		||||
                        px-2 py-2
 | 
			
		||||
                        sm:px-4
 | 
			
		||||
                      `}
 | 
			
		||||
                    >
 | 
			
		||||
                      Status
 | 
			
		||||
                    </th>
 | 
			
		||||
                    <th
 | 
			
		||||
                      class={`
 | 
			
		||||
                        px-2 py-2
 | 
			
		||||
                        sm:px-4
 | 
			
		||||
                      `}
 | 
			
		||||
                    >
 | 
			
		||||
                      View
 | 
			
		||||
                    </th>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody>
 | 
			
		||||
                  {userJobs.map((job) => (
 | 
			
		||||
                    <tr>
 | 
			
		||||
                      <td safe>{job.date_created}</td>
 | 
			
		||||
                      <td safe>
 | 
			
		||||
                        {job.date_created.split("T")[1]?.split(".")[0] ??
 | 
			
		||||
                          job.date_created}
 | 
			
		||||
                      </td>
 | 
			
		||||
                      <td>{job.num_files}</td>
 | 
			
		||||
                      <td>{job.finished_files}</td>
 | 
			
		||||
                      <td class="max-sm:hidden">{job.finished_files}</td>
 | 
			
		||||
                      <td safe>{job.status}</td>
 | 
			
		||||
                      <td>
 | 
			
		||||
                        <a
 | 
			
		||||
@@ -1055,7 +1123,12 @@ const app = new Elysia({
 | 
			
		||||
              allowUnauthenticated={ALLOW_UNAUTHENTICATED}
 | 
			
		||||
              loggedIn
 | 
			
		||||
            />
 | 
			
		||||
            <main class="w-full px-4">
 | 
			
		||||
            <main
 | 
			
		||||
              class={`
 | 
			
		||||
                w-full px-2
 | 
			
		||||
                sm:px-4
 | 
			
		||||
              `}
 | 
			
		||||
            >
 | 
			
		||||
              <article class="article">
 | 
			
		||||
                <div class="mb-4 flex items-center justify-between">
 | 
			
		||||
                  <h1 class="text-xl">Results</h1>
 | 
			
		||||
@@ -1090,21 +1163,51 @@ const app = new Elysia({
 | 
			
		||||
                  class={`
 | 
			
		||||
                    w-full table-auto rounded bg-neutral-900 text-left
 | 
			
		||||
                    [&_td]:p-4
 | 
			
		||||
                    [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                    [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                  `}
 | 
			
		||||
                >
 | 
			
		||||
                  <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                      <th class="px-4 py-2">Converted File Name</th>
 | 
			
		||||
                      <th class="px-4 py-2">Status</th>
 | 
			
		||||
                      <th class="px-4 py-2">View</th>
 | 
			
		||||
                      <th class="px-4 py-2">Download</th>
 | 
			
		||||
                      <th
 | 
			
		||||
                        class={`
 | 
			
		||||
                          px-2 py-2
 | 
			
		||||
                          sm:px-4
 | 
			
		||||
                        `}
 | 
			
		||||
                      >
 | 
			
		||||
                        Converted File Name
 | 
			
		||||
                      </th>
 | 
			
		||||
                      <th
 | 
			
		||||
                        class={`
 | 
			
		||||
                          px-2 py-2
 | 
			
		||||
                          sm:px-4
 | 
			
		||||
                        `}
 | 
			
		||||
                      >
 | 
			
		||||
                        Status
 | 
			
		||||
                      </th>
 | 
			
		||||
                      <th
 | 
			
		||||
                        class={`
 | 
			
		||||
                          px-2 py-2
 | 
			
		||||
                          sm:px-4
 | 
			
		||||
                        `}
 | 
			
		||||
                      >
 | 
			
		||||
                        View
 | 
			
		||||
                      </th>
 | 
			
		||||
                      <th
 | 
			
		||||
                        class={`
 | 
			
		||||
                          px-2 py-2
 | 
			
		||||
                          sm:px-4
 | 
			
		||||
                        `}
 | 
			
		||||
                      >
 | 
			
		||||
                        Download
 | 
			
		||||
                      </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                  </thead>
 | 
			
		||||
                  <tbody>
 | 
			
		||||
                    {files.map((file) => (
 | 
			
		||||
                      <tr>
 | 
			
		||||
                        <td safe>{file.output_file_name}</td>
 | 
			
		||||
                        <td safe class="max-w-[20vw] truncate">
 | 
			
		||||
                          {file.output_file_name}
 | 
			
		||||
                        </td>
 | 
			
		||||
                        <td safe>{file.status}</td>
 | 
			
		||||
                        <td>
 | 
			
		||||
                          <a
 | 
			
		||||
@@ -1212,21 +1315,51 @@ const app = new Elysia({
 | 
			
		||||
            class={`
 | 
			
		||||
              w-full table-auto rounded bg-neutral-900 text-left
 | 
			
		||||
              [&_td]:p-4
 | 
			
		||||
              [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
              [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
            <thead>
 | 
			
		||||
              <tr>
 | 
			
		||||
                <th class="px-4 py-2">Converted File Name</th>
 | 
			
		||||
                <th class="px-4 py-2">Status</th>
 | 
			
		||||
                <th class="px-4 py-2">View</th>
 | 
			
		||||
                <th class="px-4 py-2">Download</th>
 | 
			
		||||
                <th
 | 
			
		||||
                  class={`
 | 
			
		||||
                    px-2 py-2
 | 
			
		||||
                    sm:px-4
 | 
			
		||||
                  `}
 | 
			
		||||
                >
 | 
			
		||||
                  Converted File Name
 | 
			
		||||
                </th>
 | 
			
		||||
                <th
 | 
			
		||||
                  class={`
 | 
			
		||||
                    px-2 py-2
 | 
			
		||||
                    sm:px-4
 | 
			
		||||
                  `}
 | 
			
		||||
                >
 | 
			
		||||
                  Status
 | 
			
		||||
                </th>
 | 
			
		||||
                <th
 | 
			
		||||
                  class={`
 | 
			
		||||
                    px-2 py-2
 | 
			
		||||
                    sm:px-4
 | 
			
		||||
                  `}
 | 
			
		||||
                >
 | 
			
		||||
                  View
 | 
			
		||||
                </th>
 | 
			
		||||
                <th
 | 
			
		||||
                  class={`
 | 
			
		||||
                    px-2 py-2
 | 
			
		||||
                    sm:px-4
 | 
			
		||||
                  `}
 | 
			
		||||
                >
 | 
			
		||||
                  Download
 | 
			
		||||
                </th>
 | 
			
		||||
              </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
              {files.map((file) => (
 | 
			
		||||
                <tr>
 | 
			
		||||
                  <td safe>{file.output_file_name}</td>
 | 
			
		||||
                  <td safe class="max-w-[20vw] truncate">
 | 
			
		||||
                    {file.output_file_name}
 | 
			
		||||
                  </td>
 | 
			
		||||
                  <td safe>{file.status}</td>
 | 
			
		||||
                  <td>
 | 
			
		||||
                    <a
 | 
			
		||||
@@ -1281,7 +1414,7 @@ const app = new Elysia({
 | 
			
		||||
      // parse from url encoded string
 | 
			
		||||
      const userId = decodeURIComponent(params.userId);
 | 
			
		||||
      const jobId = decodeURIComponent(params.jobId);
 | 
			
		||||
      const fileName = decodeURIComponent(params.fileName);
 | 
			
		||||
      const fileName = sanitize(decodeURIComponent(params.fileName));
 | 
			
		||||
 | 
			
		||||
      const filePath = `${outputDir}${userId}/${jobId}/${fileName}`;
 | 
			
		||||
      return Bun.file(filePath);
 | 
			
		||||
@@ -1305,14 +1438,19 @@ const app = new Elysia({
 | 
			
		||||
            allowUnauthenticated={ALLOW_UNAUTHENTICATED}
 | 
			
		||||
            loggedIn
 | 
			
		||||
          />
 | 
			
		||||
          <main class="w-full px-4">
 | 
			
		||||
          <main
 | 
			
		||||
            class={`
 | 
			
		||||
              w-full px-2
 | 
			
		||||
              sm:px-4
 | 
			
		||||
            `}
 | 
			
		||||
          >
 | 
			
		||||
            <article class="article">
 | 
			
		||||
              <h1 class="mb-4 text-xl">Converters</h1>
 | 
			
		||||
              <table
 | 
			
		||||
                class={`
 | 
			
		||||
                  w-full table-auto rounded bg-neutral-900 text-left
 | 
			
		||||
                  [&_td]:p-4
 | 
			
		||||
                  [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                  [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
 | 
			
		||||
                  [&_ul]:list-inside [&_ul]:list-disc
 | 
			
		||||
                `}
 | 
			
		||||
              >
 | 
			
		||||
@@ -1420,8 +1558,14 @@ const clearJobs = () => {
 | 
			
		||||
 | 
			
		||||
  for (const job of jobs) {
 | 
			
		||||
    // delete the directories
 | 
			
		||||
    rmSync(`${outputDir}${job.user_id}/${job.id}`, { recursive: true });
 | 
			
		||||
    rmSync(`${uploadsDir}${job.user_id}/${job.id}`, { recursive: true });
 | 
			
		||||
    rmSync(`${outputDir}${job.user_id}/${job.id}`, {
 | 
			
		||||
      recursive: true,
 | 
			
		||||
      force: true,
 | 
			
		||||
    });
 | 
			
		||||
    rmSync(`${uploadsDir}${job.user_id}/${job.id}`, {
 | 
			
		||||
      recursive: true,
 | 
			
		||||
      force: true,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // delete the job
 | 
			
		||||
    db.query("DELETE FROM jobs WHERE id = ?").run(job.id);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								src/main.css
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								src/main.css
									
									
									
									
									
								
							@@ -1,31 +1,64 @@
 | 
			
		||||
@tailwind base;
 | 
			
		||||
@tailwind components;
 | 
			
		||||
@tailwind utilities;
 | 
			
		||||
@import "tailwindcss";
 | 
			
		||||
 | 
			
		||||
@layer components {
 | 
			
		||||
  .article {
 | 
			
		||||
    @apply p-4 mb-4 bg-neutral-800/40 w-full mx-auto max-w-4xl rounded;
 | 
			
		||||
  }
 | 
			
		||||
  .btn-primary {
 | 
			
		||||
    @apply bg-accent-500 text-contrast rounded p-4 hover:bg-accent-400 cursor-pointer transition-colors;
 | 
			
		||||
@plugin 'tailwind-scrollbar';
 | 
			
		||||
 | 
			
		||||
@theme {
 | 
			
		||||
  --color-contrast: rgba(var(--contrast));
 | 
			
		||||
  --color-neutral-900: rgba(var(--neutral-900));
 | 
			
		||||
  --color-neutral-800: rgba(var(--neutral-800));
 | 
			
		||||
  --color-neutral-700: rgba(var(--neutral-700));
 | 
			
		||||
  --color-neutral-600: rgba(var(--neutral-600));
 | 
			
		||||
  --color-neutral-500: rgba(var(--neutral-500));
 | 
			
		||||
  --color-neutral-400: rgba(var(--neutral-400));
 | 
			
		||||
  --color-neutral-300: rgba(var(--neutral-300));
 | 
			
		||||
  --color-neutral-200: rgba(var(--neutral-200));
 | 
			
		||||
  --color-neutral-100: rgba(var(--neutral-100));
 | 
			
		||||
  --color-accent-600: rgba(var(--accent-600));
 | 
			
		||||
  --color-accent-500: rgba(var(--accent-500));
 | 
			
		||||
  --color-accent-400: rgba(var(--accent-400));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  The default border color has changed to `currentColor` in Tailwind CSS v4,
 | 
			
		||||
  so we've added these compatibility styles to make sure everything still
 | 
			
		||||
  looks the same as it did with Tailwind CSS v3.
 | 
			
		||||
 | 
			
		||||
  If we ever want to remove these styles, we need to add an explicit border
 | 
			
		||||
  color utility to any element that depends on these defaults.
 | 
			
		||||
*/
 | 
			
		||||
@layer base {
 | 
			
		||||
  *,
 | 
			
		||||
  ::after,
 | 
			
		||||
  ::before,
 | 
			
		||||
  ::backdrop,
 | 
			
		||||
  ::file-selector-button {
 | 
			
		||||
    border-color: var(--color-gray-200, currentColor);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@utility article {
 | 
			
		||||
  @apply px-2 sm:px-4 py-4 mb-4 bg-neutral-800/40 w-full mx-auto max-w-4xl rounded-sm;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@utility btn-primary {
 | 
			
		||||
  @apply bg-accent-500 text-contrast rounded-sm p-2 sm:p-4 hover:bg-accent-400 cursor-pointer transition-colors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
    --contrast: 255, 255, 255;
 | 
			
		||||
    --neutral-900: 243, 244, 246;
 | 
			
		||||
    --neutral-800: 229, 231, 235;
 | 
			
		||||
    --neutral-700: 209, 213, 219;
 | 
			
		||||
    --neutral-600: 156, 163, 175;
 | 
			
		||||
    --neutral-500: 180, 180, 180;
 | 
			
		||||
    --neutral-400: 75, 85, 99;
 | 
			
		||||
    --neutral-300: 55, 65, 81;
 | 
			
		||||
    --neutral-200: 31, 41, 55;
 | 
			
		||||
    --neutral-100: 17, 24, 39;
 | 
			
		||||
    --accent-400: 132, 204, 22;
 | 
			
		||||
    --accent-500: 101, 163, 13;
 | 
			
		||||
    --accent-600: 77, 124, 15;
 | 
			
		||||
  }
 | 
			
		||||
  --contrast: 255, 255, 255;
 | 
			
		||||
  --neutral-900: 243, 244, 246;
 | 
			
		||||
  --neutral-800: 229, 231, 235;
 | 
			
		||||
  --neutral-700: 209, 213, 219;
 | 
			
		||||
  --neutral-600: 156, 163, 175;
 | 
			
		||||
  --neutral-500: 180, 180, 180;
 | 
			
		||||
  --neutral-400: 75, 85, 99;
 | 
			
		||||
  --neutral-300: 55, 65, 81;
 | 
			
		||||
  --neutral-200: 31, 41, 55;
 | 
			
		||||
  --neutral-100: 17, 24, 39;
 | 
			
		||||
  --accent-400: 132, 204, 22;
 | 
			
		||||
  --accent-500: 101, 163, 13;
 | 
			
		||||
  --accent-600: 77, 124, 15;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (prefers-color-scheme: dark) {
 | 
			
		||||
  :root {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
/** @type {import('tailwindcss').Config} */
 | 
			
		||||
 | 
			
		||||
import tailwindScrollbar from "tailwind-scrollbar";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  content: ["./src/**/*.{html,js,tsx,jsx,cjs,mjs}"],
 | 
			
		||||
  theme: {
 | 
			
		||||
    extend: {
 | 
			
		||||
      colors: {
 | 
			
		||||
        contrast: "rgba(var(--contrast))",
 | 
			
		||||
        "neutral-900": "rgba(var(--neutral-900))",
 | 
			
		||||
        "neutral-800": "rgba(var(--neutral-800))",
 | 
			
		||||
        "neutral-700": "rgba(var(--neutral-700))",
 | 
			
		||||
        "neutral-600": "rgba(var(--neutral-600))",
 | 
			
		||||
        "neutral-500": "rgba(var(--neutral-500))",
 | 
			
		||||
        "neutral-400": "rgba(var(--neutral-400))",
 | 
			
		||||
        "neutral-300": "rgba(var(--neutral-300))",
 | 
			
		||||
        "neutral-200": "rgba(var(--neutral-200))",
 | 
			
		||||
        "neutral-100": "rgba(var(--neutral-100))",
 | 
			
		||||
        "accent-600": "rgba(var(--accent-600))",
 | 
			
		||||
        "accent-500": "rgba(var(--accent-500))",
 | 
			
		||||
        "accent-400": "rgba(var(--accent-400))",
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  plugins: [tailwindScrollbar],
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user