diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fa0f7dee --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +vendor/ +node_modules/ +.parcel-cache/ +*.css.map +*.js.map diff --git a/apiki-favorites.php b/apiki-favorites.php new file mode 100644 index 00000000..00572555 --- /dev/null +++ b/apiki-favorites.php @@ -0,0 +1,18 @@ + + * License: MIT + * Text Domain: apiki-favorites + */ + +declare(strict_types=1); + +defined('ABSPATH') || exit; + +require_once __DIR__ . '/vendor/autoload.php'; + +ApikiFavorites\Plugin::instance()->boot(); diff --git a/assets/scss/index.scss b/assets/scss/index.scss new file mode 100644 index 00000000..72c0863a --- /dev/null +++ b/assets/scss/index.scss @@ -0,0 +1,71 @@ +.apiki-favorite-btn { + display: inline-flex; + align-items: center; + justify-content: center; + background: none; + border: none; + padding: 8px; + cursor: pointer; + transition: transform 0.2s ease, opacity 0.2s ease; + opacity: 0.5; + + &:hover { + opacity: 0.8; + transform: scale(1.2); + } + + &--active { + opacity: 1; + + svg { + fill: #e53935; + } + } + + &--loading { + opacity: 0.4; + pointer-events: none; + animation: pulse 0.8s infinite alternate; + } + + svg { + fill: none; + stroke: #e53935; + stroke-width: 2; + transition: fill 0.2s ease; + } +} + +@keyframes pulse { + from { transform: scale(1); } + to { transform: scale(1.15); } +} + +.apiki-toast { + position: fixed; + bottom: 24px; + right: 24px; + padding: 12px 20px; + border-radius: 6px; + color: #fff; + font-size: 14px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + z-index: 99999; + opacity: 0; + transform: translateY(16px); + transition: opacity 0.3s ease, transform 0.3s ease; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + + &--visible { + opacity: 1; + transform: translateY(0); + } + + &--success { + background: #43a047; + } + + &--error { + background: #e53935; + } +} diff --git a/assets/ts/api.ts b/assets/ts/api.ts new file mode 100644 index 00000000..be358433 --- /dev/null +++ b/assets/ts/api.ts @@ -0,0 +1,43 @@ +declare const apikiFavorites: { + restUrl: string; + nonce: string; + isLoggedIn: boolean; +}; + +interface FavoriteResponse { + id: number; + post_id: number; + created_at: string; +} + +async function request(method: string, body?: Record): Promise { + const options: RequestInit = { + method, + headers: { + "Content-Type": "application/json", + "X-WP-Nonce": apikiFavorites.nonce, + }, + credentials: "same-origin", + }; + + if (body) { + options.body = JSON.stringify(body); + } + + const response = await fetch(apikiFavorites.restUrl, options); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || "Request failed"); + } + + return response.json(); +} + +export function addFavorite(postId: number): Promise { + return request("POST", { post_id: postId }); +} + +export function removeFavorite(postId: number): Promise<{ deleted: boolean }> { + return request<{ deleted: boolean }>("DELETE", { post_id: postId }); +} diff --git a/assets/ts/index.ts b/assets/ts/index.ts new file mode 100644 index 00000000..5e4f7e5b --- /dev/null +++ b/assets/ts/index.ts @@ -0,0 +1,45 @@ +import { addFavorite, removeFavorite } from "./api"; +import { showToast } from "./toast"; +import "../scss/index.scss"; + +function init(): void { + document.querySelectorAll(".apiki-favorite-btn").forEach((button) => { + button.addEventListener("click", handleClick); + }); +} + +async function handleClick(event: Event): Promise { + const button = event.currentTarget as HTMLButtonElement; + const postId = Number(button.dataset.postId); + + if (!postId || button.disabled) return; + + button.disabled = true; + button.classList.add("apiki-favorite-btn--loading"); + + const isActive = button.classList.contains("apiki-favorite-btn--active"); + + try { + if (isActive) { + await removeFavorite(postId); + button.classList.remove("apiki-favorite-btn--active"); + button.setAttribute("aria-label", "Add to favorites"); + button.setAttribute("title", "Add to favorites"); + showToast("Removed from favorites", "success"); + } else { + await addFavorite(postId); + button.classList.add("apiki-favorite-btn--active"); + button.setAttribute("aria-label", "Remove from favorites"); + button.setAttribute("title", "Remove from favorites"); + showToast("Added to favorites!", "success"); + } + } catch (error) { + const message = error instanceof Error ? error.message : "Something went wrong"; + showToast(message, "error"); + } finally { + button.disabled = false; + button.classList.remove("apiki-favorite-btn--loading"); + } +} + +document.addEventListener("DOMContentLoaded", init); diff --git a/assets/ts/toast.ts b/assets/ts/toast.ts new file mode 100644 index 00000000..d9099e2e --- /dev/null +++ b/assets/ts/toast.ts @@ -0,0 +1,15 @@ +export function showToast(message: string, type: "success" | "error"): void { + const toast = document.createElement("div"); + toast.className = `apiki-toast apiki-toast--${type}`; + toast.textContent = message; + document.body.appendChild(toast); + + requestAnimationFrame(() => { + toast.classList.add("apiki-toast--visible"); + }); + + setTimeout(() => { + toast.classList.remove("apiki-toast--visible"); + toast.addEventListener("transitionend", () => toast.remove()); + }, 3000); +} diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..b220e64f --- /dev/null +++ b/composer.json @@ -0,0 +1,19 @@ +{ + "name": "apiki/favorites", + "description": "WordPress plugin for favoriting posts via REST API.", + "type": "wordpress-plugin", + "require": { + "php": ">= 8.1" + }, + "license": "MIT", + "autoload": { + "psr-4": { + "ApikiFavorites\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "ApikiFavorites\\Tests\\": "tests/" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..bbc2f4b2 --- /dev/null +++ b/composer.lock @@ -0,0 +1,20 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "d05bd1213bac7f3ed4a76f3dc64d0af5", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">= 8.1" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/dist/index.css b/dist/index.css new file mode 100644 index 00000000..2c87289f --- /dev/null +++ b/dist/index.css @@ -0,0 +1 @@ +.apiki-favorite-btn{cursor:pointer;opacity:.5;background:0 0;border:none;justify-content:center;align-items:center;padding:8px;transition:transform .2s,opacity .2s;display:inline-flex}.apiki-favorite-btn:hover{opacity:.8;transform:scale(1.2)}.apiki-favorite-btn--active{opacity:1}.apiki-favorite-btn--active svg{fill:#e53935}.apiki-favorite-btn--loading{opacity:.4;pointer-events:none;animation:.8s infinite alternate pulse}.apiki-favorite-btn svg{fill:none;stroke:#e53935;stroke-width:2px;transition:fill .2s}@keyframes pulse{0%{transform:scale(1)}to{transform:scale(1.15)}}.apiki-toast{color:#fff;z-index:99999;opacity:0;border-radius:6px;padding:12px 20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;transition:opacity .3s,transform .3s;position:fixed;bottom:24px;right:24px;transform:translateY(16px);box-shadow:0 4px 12px #00000026}.apiki-toast--visible{opacity:1;transform:translateY(0)}.apiki-toast--success{background:#43a047}.apiki-toast--error{background:#e53935} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..df7cb189 --- /dev/null +++ b/dist/index.js @@ -0,0 +1 @@ +(()=>{async function t(t,e){let i={method:t,headers:{"Content-Type":"application/json","X-WP-Nonce":apikiFavorites.nonce},credentials:"same-origin"};e&&(i.body=JSON.stringify(e));let a=await fetch(apikiFavorites.restUrl,i);if(!a.ok)throw Error((await a.json()).message||"Request failed");return a.json()}function e(t,e){let i=document.createElement("div");i.className=`apiki-toast apiki-toast--${e}`,i.textContent=t,document.body.appendChild(i),requestAnimationFrame(()=>{i.classList.add("apiki-toast--visible")}),setTimeout(()=>{i.classList.remove("apiki-toast--visible"),i.addEventListener("transitionend",()=>i.remove())},3e3)}async function i(i){let a=i.currentTarget,s=Number(a.dataset.postId);if(!s||a.disabled)return;a.disabled=!0,a.classList.add("apiki-favorite-btn--loading");let o=a.classList.contains("apiki-favorite-btn--active");try{o?(await t("DELETE",{post_id:s}),a.classList.remove("apiki-favorite-btn--active"),a.setAttribute("aria-label","Add to favorites"),a.setAttribute("title","Add to favorites"),e("Removed from favorites","success")):(await t("POST",{post_id:s}),a.classList.add("apiki-favorite-btn--active"),a.setAttribute("aria-label","Remove from favorites"),a.setAttribute("title","Remove from favorites"),e("Added to favorites!","success"))}catch(t){e(t instanceof Error?t.message:"Something went wrong","error")}finally{a.disabled=!1,a.classList.remove("apiki-favorite-btn--loading")}}document.addEventListener("DOMContentLoaded",function(){document.querySelectorAll(".apiki-favorite-btn").forEach(t=>{t.addEventListener("click",i)})})})(); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..12c558b0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +services: + wordpress: + image: wordpress:php8.3-apache + ports: + - "8888:80" + environment: + WORDPRESS_DB_HOST: db + WORDPRESS_DB_USER: wordpress + WORDPRESS_DB_PASSWORD: wordpress + WORDPRESS_DB_NAME: wordpress + volumes: + - wp_data:/var/www/html + - ./:/var/www/html/wp-content/plugins/apiki-favorites + depends_on: + db: + condition: service_healthy + + db: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + volumes: + - db_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 5s + timeout: 3s + retries: 10 + +volumes: + wp_data: + db_data: diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..633438f6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3191 @@ +{ + "name": "apiki-favorites", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "apiki-favorites", + "version": "1.0.0", + "devDependencies": { + "@parcel/transformer-sass": "^2.16.0", + "parcel": "^2.16.0", + "typescript": "^5.7.0" + } + }, + "node_modules/@lezer/common": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.1.tgz", + "integrity": "sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lezer/lr": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.8.tgz", + "integrity": "sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.8.5.tgz", + "integrity": "sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.8.5.tgz", + "integrity": "sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.8.5.tgz", + "integrity": "sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.8.5.tgz", + "integrity": "sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.8.5.tgz", + "integrity": "sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.8.5.tgz", + "integrity": "sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@mischnic/json-sourcemap": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz", + "integrity": "sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/lr": "^1.0.0", + "json5": "^2.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@parcel/bundler-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.16.4.tgz", + "integrity": "sha512-Nb8peNvhfm1+660CLwssWh4weY+Mv6vEGS6GPKqzJmTMw50udi0eS1YuWFzvmhSiu1KsYcUD37mqQ1LuIDtWoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/graph": "3.6.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/cache": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.16.4.tgz", + "integrity": "sha512-+uCyeElSga2MBbmbXpIj/WVKH7TByCrKaxtHbelfKKIJpYMgEHVjO4cuc7GUfTrUAmRUS8ZGvnX7Etgq6/jQhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/utils": "2.16.4", + "lmdb": "2.8.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/codeframe": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.16.4.tgz", + "integrity": "sha512-s64aMfOJoPrXhKH+Y98ahX0O8aXWvTR+uNlOaX4yFkpr4FFDnviLcGngDe/Yo4Qq2FJZ0P6dNswbJTUH9EGxkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/compressor-raw": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.16.4.tgz", + "integrity": "sha512-IK8IpNhw61B2HKgA1JhGhO9y+ZJFRZNTEmvhN1NdLdPqvgEXm2EunT+m6D9z7xeoeT6XnUKqM0eRckEdD0OXbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/config-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.16.4.tgz", + "integrity": "sha512-kBxuTY/5trEVnvXk92l7LVkYjNuz3SaqWymFhPjEnc8GY4ZVdcWrWdXWTB9hUhpmRYJctFCyGvM0nN05JTiM2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/bundler-default": "2.16.4", + "@parcel/compressor-raw": "2.16.4", + "@parcel/namer-default": "2.16.4", + "@parcel/optimizer-css": "2.16.4", + "@parcel/optimizer-html": "2.16.4", + "@parcel/optimizer-image": "2.16.4", + "@parcel/optimizer-svg": "2.16.4", + "@parcel/optimizer-swc": "2.16.4", + "@parcel/packager-css": "2.16.4", + "@parcel/packager-html": "2.16.4", + "@parcel/packager-js": "2.16.4", + "@parcel/packager-raw": "2.16.4", + "@parcel/packager-svg": "2.16.4", + "@parcel/packager-wasm": "2.16.4", + "@parcel/reporter-dev-server": "2.16.4", + "@parcel/resolver-default": "2.16.4", + "@parcel/runtime-browser-hmr": "2.16.4", + "@parcel/runtime-js": "2.16.4", + "@parcel/runtime-rsc": "2.16.4", + "@parcel/runtime-service-worker": "2.16.4", + "@parcel/transformer-babel": "2.16.4", + "@parcel/transformer-css": "2.16.4", + "@parcel/transformer-html": "2.16.4", + "@parcel/transformer-image": "2.16.4", + "@parcel/transformer-js": "2.16.4", + "@parcel/transformer-json": "2.16.4", + "@parcel/transformer-node": "2.16.4", + "@parcel/transformer-postcss": "2.16.4", + "@parcel/transformer-posthtml": "2.16.4", + "@parcel/transformer-raw": "2.16.4", + "@parcel/transformer-react-refresh-wrap": "2.16.4", + "@parcel/transformer-svg": "2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/core": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.16.4.tgz", + "integrity": "sha512-a0CgrW5A5kwuSu5J1RFRoMQaMs9yagvfH2jJMYVw56+/7NRI4KOtu612SG9Y1ERWfY55ZwzyFxtLWvD6LO+Anw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/cache": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/graph": "3.6.4", + "@parcel/logger": "2.16.4", + "@parcel/package-manager": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/profiler": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "base-x": "^3.0.11", + "browserslist": "^4.24.5", + "clone": "^2.1.2", + "dotenv": "^16.5.0", + "dotenv-expand": "^11.0.7", + "json5": "^2.2.3", + "msgpackr": "^1.11.2", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/diagnostic": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.16.4.tgz", + "integrity": "sha512-YN5CfX7lFd6yRLxyZT4Sj3sR6t7nnve4TdXSIqapXzQwL7Bw+sj79D95wTq2rCm3mzk5SofGxFAXul2/nG6gcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/error-overlay": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/error-overlay/-/error-overlay-2.16.4.tgz", + "integrity": "sha512-e8KYKnMsfmQnqIhsUWBUZAXlDK30wkxsAGle1tZ0gOdoplaIdVq/WjGPatHLf6igLM76c3tRn2vw8jZFput0jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/events": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.16.4.tgz", + "integrity": "sha512-slWQkBRAA7o0cN0BLEd+yCckPmlVRVhBZn5Pn6ktm4EzEtrqoMzMeJOxxH8TXaRzrQDYnTcnYIHFgXWd4kkUfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/feature-flags": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/feature-flags/-/feature-flags-2.16.4.tgz", + "integrity": "sha512-nYdx53siKPLYikHHxfzgjzzgxdrjquK6DMnuSgOTyIdRG4VHdEN0+NqKijRLuVgiUFo/dtxc2h+amwqFENMw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/fs": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.16.4.tgz", + "integrity": "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/watcher": "^2.0.7", + "@parcel/workers": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/graph": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-3.6.4.tgz", + "integrity": "sha512-Cj9yV+/k88kFhE+D+gz0YuNRpvNOCVDskO9pFqkcQhGbsGq6kg2XpZ9V7HlYraih31xf8Vb589bZOwjKIiHixQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/logger": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.16.4.tgz", + "integrity": "sha512-QR8QLlKo7xAy9JBpPDAh0RvluaixqPCeyY7Fvo2K7hrU3r85vBNNi06pHiPbWoDmB4x1+QoFwMaGnJOHR+/fMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/markdown-ansi": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.16.4.tgz", + "integrity": "sha512-0+oQApAVF3wMcQ6d1ZfZ0JsRzaMUYj9e4U+naj6YEsFsFGOPp+pQYKXBf1bobQeeB7cPKPT3SUHxFqced722Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/namer-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.16.4.tgz", + "integrity": "sha512-CE+0lFg881sJq575EXxj2lKUn81tsS5itpNUUErHxit195m3PExyAhoXM6ed/SXxwi+uv+T5FS/jjDLBNuUFDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/node-resolver-core": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.7.4.tgz", + "integrity": "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.16.4.tgz", + "integrity": "sha512-aqdXCtmvpcXYgJFGk2DtXF34wuM2TD1fZorKMrJdKB9sSkWVRs1tq6RAXQrbi0ZPDH9wfE/9An3YdkTex7RHuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-html/-/optimizer-html-2.16.4.tgz", + "integrity": "sha512-vg/R2uuSni+NYYUUV8m+5bz8p5zBv8wc/nNleoBnGuCDwn7uaUwTZ8Gt9CjZO8jjG0xCLILoc/TW+e2FF3pfgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-image": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.16.4.tgz", + "integrity": "sha512-2RV54WnvMYr18lxSx7Zlx/DXpJwMzOiPxDnoFyvaUoYutvgHO6chtcgFgh1Bvw/PoI95vYzlTkZ8QfUOk5A0JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/optimizer-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-svg/-/optimizer-svg-2.16.4.tgz", + "integrity": "sha512-22+BqIffCrVErg8y2XwhasbTaFNn75OKXZ3KTDBIfOSAZKLUKs1iHfDXETzTRN7cVcS+Q36/6EHd7N/RA8i1fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-swc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-swc/-/optimizer-swc-2.16.4.tgz", + "integrity": "sha512-+URqwnB6u1gqaLbG1O1DDApH+UVj4WCbK9No1fdxLBxQ9a84jyli25o1kK1hYB9Nb/JMyYNnEBfvYUW6RphOxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "@swc/core": "^1.11.24", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/package-manager": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.16.4.tgz", + "integrity": "sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/node-resolver-core": "3.7.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "@swc/core": "^1.11.24", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/packager-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.16.4.tgz", + "integrity": "sha512-rWRtfiX+VVIOZvq64jpeNUKkvWAbnokfHQsk/js1s5jD4ViNQgPcNLiRaiIANjymqL6+dQqWvGUSW2a5FAZYfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.16.4.tgz", + "integrity": "sha512-AWo5f6SSqBsg2uWOsX0gPX8hCx2iE6GYLg2Z4/cDy2mPlwDICN8/bxItEztSZFmObi+ti26eetBKRDxAUivyIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-js": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.16.4.tgz", + "integrity": "sha512-L2o39f/fhta+hxto7w8OTUKdstY+te5BmHZREckbQm0KTBg93BG7jB0bfoxLSZF0d8uuAYIVXjzeHNqha+du1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "globals": "^13.24.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-raw": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.16.4.tgz", + "integrity": "sha512-A9j60G9OmbTkEeE4WRMXCiErEprHLs9NkUlC4HXCxmSrPMOVaMaMva2LdejE3A9kujZqYtYfuc8+a+jN+Nro4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.16.4.tgz", + "integrity": "sha512-LT9l7eInFrAZJ6w3mYzAUgDq3SIzYbbQyW46Dz26M9lJQbf6uCaATUTac3BEHegW0ikDuw4OOGHK41BVqeeusg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-wasm": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-wasm/-/packager-wasm-2.16.4.tgz", + "integrity": "sha512-AY96Aqu/RpmaSZK2RGkIrZWjAperDw8DAlxLAiaP1D/RPVnikZtl5BmcUt/Wz3PrzG7/q9ZVqqKkWsLmhkjXZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">=16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/plugin": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.16.4.tgz", + "integrity": "sha512-aN2VQoRGC1eB41ZCDbPR/Sp0yKOxe31oemzPx1nJzOuebK2Q6FxSrJ9Bjj9j/YCaLzDtPwelsuLOazzVpXJ6qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/types": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/profiler": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/profiler/-/profiler-2.16.4.tgz", + "integrity": "sha512-R3JhfcnoReTv2sVFHPR2xKZvs3d3IRrBl9sWmAftbIJFwT4rU70/W7IdwfaJVkD/6PzHq9mcgOh1WKL4KAxPdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/types-internal": "2.16.4", + "chrome-trace-event": "^1.0.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-cli": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.16.4.tgz", + "integrity": "sha512-DQx9TwcTZrDv828+tcwEi//xyW7OHTGzGX1+UEVxPp0mSzuOmDn0zfER8qNIqGr1i4D/FXhb5UJQDhGHV8mOpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "chalk": "^4.1.2", + "term-size": "^2.2.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-dev-server": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.16.4.tgz", + "integrity": "sha512-YWvay25htQDifpDRJ0+yFh6xUxKnbfeJxYkPYyuXdxpEUhq4T0UWW0PbPCN/wFX7StgeUTXq5Poeo/+eys9m3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/codeframe": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-tracer": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-tracer/-/reporter-tracer-2.16.4.tgz", + "integrity": "sha512-JKnlXpPepak0/ZybmZn9JtyjJiDBWYrt7ZUlXQhQb0xzNcd/k+RqfwVkTKIwyFHsWtym0cwibkvsi2bWFzS7tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "chrome-trace-event": "^1.0.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/resolver-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.16.4.tgz", + "integrity": "sha512-wJe9XQS0hn/t32pntQpJbls3ZL8mGVVhK9L7s7BTmZT9ufnvP2nif1psJz/nbgnP9LF6mLSk43OdMJKpoStsjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/node-resolver-core": "3.7.4", + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-browser-hmr": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.16.4.tgz", + "integrity": "sha512-asx7p3NjUSfibI3bC7+8+jUIGHWVk2Zuq9SjJGCGDt+auT9A4uSGljnsk1BWWPqqZ0WILubq4czSAqm0+wt4cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-js": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.16.4.tgz", + "integrity": "sha512-gUKmsjg+PULQBu2QbX0QKll9tXSqHPO8NrfxHwWb2lz5xDKDos1oV0I7BoMWbHhUHkoToXZrm654oGViujtVUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-rsc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-rsc/-/runtime-rsc-2.16.4.tgz", + "integrity": "sha512-CHkotYE/cNiUjJmrc5FD9YhlFp1UF5wMNNJmoWaL40eBzsqcaV0sSn5V3bNapwewn3wrMYgdPgvOTHfaZaG73A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 12.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-service-worker": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.16.4.tgz", + "integrity": "sha512-FT0Q58bf5Re+dq5cL2XHbxqHHFZco6qtRijeVpT3TSPMRPlniMArypSytTeZzVNL7h/hxjWsNu7fRuC0yLB5hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust/-/rust-2.16.4.tgz", + "integrity": "sha512-RBMKt9rCdv6jr4vXG6LmHtxzO5TuhQvXo1kSoSIF7fURRZ81D1jzBtLxwLmfxCPsofJNqWwdhy5vIvisX+TLlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/rust-darwin-arm64": "2.16.4", + "@parcel/rust-darwin-x64": "2.16.4", + "@parcel/rust-linux-arm-gnueabihf": "2.16.4", + "@parcel/rust-linux-arm64-gnu": "2.16.4", + "@parcel/rust-linux-arm64-musl": "2.16.4", + "@parcel/rust-linux-x64-gnu": "2.16.4", + "@parcel/rust-linux-x64-musl": "2.16.4", + "@parcel/rust-win32-x64-msvc": "2.16.4" + }, + "peerDependencies": { + "napi-wasm": "^1.1.2" + }, + "peerDependenciesMeta": { + "napi-wasm": { + "optional": true + } + } + }, + "node_modules/@parcel/rust-darwin-arm64": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-arm64/-/rust-darwin-arm64-2.16.4.tgz", + "integrity": "sha512-P3Se36H9EO1fOlwXqQNQ+RsVKTGn5ztRSUGbLcT8ba6oOMmU1w7J4R810GgsCbwCuF10TJNUMkuD3Q2Sz15Q3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-darwin-x64": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-x64/-/rust-darwin-x64-2.16.4.tgz", + "integrity": "sha512-8aNKNyPIx3EthYpmVJevIdHmFsOApXAEYGi3HU69jTxLgSIfyEHDdGE9lEsMvhSrd/SSo4/euAtiV+pqK04wnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm-gnueabihf": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm-gnueabihf/-/rust-linux-arm-gnueabihf-2.16.4.tgz", + "integrity": "sha512-QrvqiSHaWRLc0JBHgUHVvDthfWSkA6AFN+ikV1UGENv4j2r/QgvuwJiG0VHrsL6pH5dRqj0vvngHzEgguke9DA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm64-gnu": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-gnu/-/rust-linux-arm64-gnu-2.16.4.tgz", + "integrity": "sha512-f3gBWQHLHRUajNZi3SMmDQiEx54RoRbXtZYQNuBQy7+NolfFcgb1ik3QhkT7xovuTF/LBmaqP3UFy0PxvR/iwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm64-musl": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-musl/-/rust-linux-arm64-musl-2.16.4.tgz", + "integrity": "sha512-cwml18RNKsBwHyZnrZg4jpecXkWjaY/mCArocWUxkFXjjB97L56QWQM9W86f2/Y3HcFcnIGJwx1SDDKJrV6OIA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-x64-gnu": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-gnu/-/rust-linux-x64-gnu-2.16.4.tgz", + "integrity": "sha512-0xIjQaN8hiG0F9R8coPYidHslDIrbfOS/qFy5GJNbGA3S49h61wZRBMQqa7JFW4+2T8R0J9j0SKHhLXpbLXrIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-x64-musl": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-musl/-/rust-linux-x64-musl-2.16.4.tgz", + "integrity": "sha512-fYn21GIecHK9RoZPKwT9NOwxwl3Gy3RYPR6zvsUi0+hpFo19Ph9EzFXN3lT8Pi5KiwQMCU4rsLb5HoWOBM1FeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-win32-x64-msvc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-win32-x64-msvc/-/rust-win32-x64-msvc-2.16.4.tgz", + "integrity": "sha512-TcpWC3I1mJpfP2++018lgvM7UX0P8IrzNxceBTHUKEIDMwmAYrUKAQFiaU0j1Ldqk6yP8SPZD3cvphumsYpJOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/source-map": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", + "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": "^12.18.3 || >=14" + } + }, + "node_modules/@parcel/transformer-babel": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.16.4.tgz", + "integrity": "sha512-CMDUOQYX7+cmeyHxHSFnoPcwvXNL7rRFE+Q06uVFzsYYiVhbwGF/1J5Bx4cW3Froumqla4YTytTsEteJEybkdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "json5": "^2.2.3", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.16.4.tgz", + "integrity": "sha512-VG/+DbDci2HKe20GFRDs65ZQf5GUFfnmZAa1BhVl/MO+ijT3XC3eoVUy5cExRkq4VLcPY4ytL0g/1T2D6x7lBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.16.4.tgz", + "integrity": "sha512-w6JErYTeNS+KAzUAER18NHFIFFvxiLGd4Fht1UYcb/FDjJdLAMB/FljyEs0Rto/WAhZ2D0MuSL25HQh837R62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-image": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.16.4.tgz", + "integrity": "sha512-ZzIn3KvvRqMfcect4Dy+57C9XoQXZhpVJKBdQWMp9wM1qJEgsVgGDcaSBYCs/UYSKMRMP6Wm20pKCt408RkQzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/transformer-js": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.16.4.tgz", + "integrity": "sha512-FD2fdO6URwAGBPidb3x1dDgLBt972mko0LelcSU05aC/pcKaV9mbCtINbPul1MlStzkxDelhuImcCYIyerheVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "@swc/helpers": "^0.5.0", + "browserslist": "^4.24.5", + "nullthrows": "^1.1.1", + "regenerator-runtime": "^0.14.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/transformer-json": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.16.4.tgz", + "integrity": "sha512-pB3ZNqgokdkBCJ+4G0BrPYcIkyM9K1HVk0GvjzcLEFDKsoAp8BGEM68FzagFM/nVq9anYTshIaoh349GK0M/bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "json5": "^2.2.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-node": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-node/-/transformer-node-2.16.4.tgz", + "integrity": "sha512-7t43CPGfMJk1LqFokwxHSsRi+kKC2QvDXaMtqiMShmk50LCwn81WgzuFvNhMwf6lSiBihWupGwF3Fqksg+aisg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-postcss": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.16.4.tgz", + "integrity": "sha512-jfmh9ho03H+qwz9S1b/a/oaOmgfMovtHKYDweIGMjKULKIee3AFRqo8RZIOuUMjDuqHWK8SqQmjery4syFV3Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "clone": "^2.1.2", + "nullthrows": "^1.1.1", + "postcss-value-parser": "^4.2.0", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-posthtml": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.16.4.tgz", + "integrity": "sha512-+GXsmGx1L25KQGQnwclgEuQe1t4QU+IoDkgN+Ikj+EnQCOWG4/ts2VpMBeqP5F18ZT4cCSRafj6317o/2lSGJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-raw": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.16.4.tgz", + "integrity": "sha512-7WDUPq+bW11G9jKxaQIVL+NPGolV99oq/GXhpjYip0SaGaLzRCW7gEk60cftuk0O7MsDaX5jcAJm3G/AX+LJKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-react-refresh-wrap": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.16.4.tgz", + "integrity": "sha512-MiLNZrsGQJTANKKa4lzZyUbGj/en0Hms474mMdQkCBFg6GmjfmXwaMMgtTfPA3ZwSp2+3LeObCyca/f9B2gBZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/error-overlay": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "react-refresh": "^0.16.0" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-sass": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-sass/-/transformer-sass-2.16.4.tgz", + "integrity": "sha512-TvYZf7dwgtIVHcxkmOlIz0e28Ec7T6z0Jhzu+WcnFSonnhyrvKuqAxy7QV5EGc6O4qvDWwAQV1lvaLU0te+mQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "sass": "^1.88.0" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.16.4.tgz", + "integrity": "sha512-0dm4cQr/WpfQP6N0xjFtwdLTxcONDfoLgTOMk4eNUWydHipSgmLtvUk/nOc/FWkwztRScfAObtZXOiPOd3Oy9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/types": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.16.4.tgz", + "integrity": "sha512-ctx4mBskZHXeDVHg4OjMwx18jfYH9BzI/7yqbDQVGvd5lyA+/oVVzYdpele2J2i2sSaJ87cA8nb57GDQ8kHAqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/types-internal": "2.16.4", + "@parcel/workers": "2.16.4" + } + }, + "node_modules/@parcel/types-internal": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/types-internal/-/types-internal-2.16.4.tgz", + "integrity": "sha512-PE6Qmt5cjzBxX+6MPLiF7r+twoC+V9Skt3zyuBQ+H1c0i9o07Bbz2NKX10nvlPukfmW6Fu/1RvTLkzBZR1bU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/source-map": "^2.1.1", + "utility-types": "^3.11.0" + } + }, + "node_modules/@parcel/utils": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.16.4.tgz", + "integrity": "sha512-lkmxQHcHyOWZLbV8t+h2CGZIkPiBurLm/TS5wNT7+tq0qt9KbVwL7FP2K93TbXhLMGTmpI79Bf3qKniPM167Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/codeframe": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/markdown-ansi": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "chalk": "^4.1.2", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/@parcel/workers": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.16.4.tgz", + "integrity": "sha512-dkBEWqnHXDZnRbTZouNt4uEGIslJT+V0c8OH1MPOfjISp1ucD6/u9ET8k9d/PxS9h1hL53og0SpBuuSEPLDl6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/profiler": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@swc/core": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.24.tgz", + "integrity": "sha512-5Hj8aNasue7yusUt8LGCUe/AjM7RMAce8ZoyDyiFwx7Al+GbYKL+yE7g4sJk8vEr1dKIkTRARkNIJENc4CjkBQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.26" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.24", + "@swc/core-darwin-x64": "1.15.24", + "@swc/core-linux-arm-gnueabihf": "1.15.24", + "@swc/core-linux-arm64-gnu": "1.15.24", + "@swc/core-linux-arm64-musl": "1.15.24", + "@swc/core-linux-ppc64-gnu": "1.15.24", + "@swc/core-linux-s390x-gnu": "1.15.24", + "@swc/core-linux-x64-gnu": "1.15.24", + "@swc/core-linux-x64-musl": "1.15.24", + "@swc/core-win32-arm64-msvc": "1.15.24", + "@swc/core-win32-ia32-msvc": "1.15.24", + "@swc/core-win32-x64-msvc": "1.15.24" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.24.tgz", + "integrity": "sha512-uM5ZGfFXjtvtJ+fe448PVBEbn/CSxS3UAyLj3O9xOqKIWy3S6hPTXSPbszxkSsGDYKi+YFhzAsR4r/eXLxEQ0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.24.tgz", + "integrity": "sha512-fMIb/Zfn929pw25VMBhV7Ji2Dl+lCWtUPNdYJQYOke+00E5fcQ9ynxtP8+qhUo/HZc+mYQb1gJxwHM9vty+lXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.24.tgz", + "integrity": "sha512-vOkjsyjjxnoYx3hMEWcGxQrMgnNrRm6WAegBXrN8foHtDAR+zpdhpGF5a4lj1bNPgXAvmysjui8cM1ov/Clkaw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.24.tgz", + "integrity": "sha512-h/oNu+upkXJ6Cicnq7YGVj9PkdfarLCdQa8l/FlHYvfv8CEiMaeeTnpLU7gSBH/rGxosM6Qkfa/J9mThGF9CLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.24.tgz", + "integrity": "sha512-ZpF/pRe1guk6sKzQI9D1jAORtjTdNlyeXn9GDz8ophof/w2WhojRblvSDJaGe7rJjcPN8AaOkhwdRUh7q8oYIg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.24.tgz", + "integrity": "sha512-QZEsZfisHTSJlmyChgDFNmKPb3W6Lhbfo/O76HhIngfEdnQNmukS38/VSe1feho+xkV5A5hETyCbx3sALBZKAQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.24.tgz", + "integrity": "sha512-DLdJKVsJgglqQrJBuoUYNmzm3leI7kUZhLbZGHv42onfKsGf6JDS3+bzCUQfte/XOqDjh/tmmn1DR/CF/tCJFw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.24.tgz", + "integrity": "sha512-IpLYfposPA/XLxYOKpRfeccl1p5dDa3+okZDHHTchBkXEaVCnq5MADPmIWwIYj1tudt7hORsEHccG5no6IUQRw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.24.tgz", + "integrity": "sha512-JHy3fMSc0t/EPWgo74+OK5TGr51aElnzqfUPaiRf2qJ/BfX5CUCfMiWVBuhI7qmVMBnk1jTRnL/xZnOSHDPLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.24.tgz", + "integrity": "sha512-Txj+qUH1z2bUd1P3JvwByfjKFti3cptlAxhWgmunBUUxy/IW3CXLZ6l6Gk4liANadKkU71nIU1X30Z5vpMT3BA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.24.tgz", + "integrity": "sha512-15D/nl3XwrhFpMv+MADFOiVwv3FvH9j8c6Rf8EXBT3Q5LoMh8YnDnSgPYqw1JzPnksvsBX6QPXLiPqmcR/Z4qQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.24.tgz", + "integrity": "sha512-PR0PlTlPra2JbaDphrOAzm6s0v9rA0F17YzB+XbWD95B4g2cWcZY9LAeTa4xll70VLw9Jr7xBrlohqlQmelMFQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", + "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@swc/types": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", + "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.14.tgz", + "integrity": "sha512-fOVLPAsFTsQfuCkvahZkzq6nf8KvGWanlYoTh0SVA0A/PIUxQGU2AOZAoD95n2gFLVDW/jP6sbGLny95nmEuHA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001785", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001785.tgz", + "integrity": "sha512-blhOL/WNR+Km1RI/LCVAvA73xplXA7ZbjzI4YkMK9pa6T/P3F2GxjNpEkyw5repTw9IvkyrjyHpwjnhZ5FOvYQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.331", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.331.tgz", + "integrity": "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-port": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", + "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/immutable": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/lmdb": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz", + "integrity": "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "msgpackr": "^1.9.5", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.1.1", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "2.8.5", + "@lmdb/lmdb-darwin-x64": "2.8.5", + "@lmdb/lmdb-linux-arm": "2.8.5", + "@lmdb/lmdb-linux-arm64": "2.8.5", + "@lmdb/lmdb-linux-x64": "2.8.5", + "@lmdb/lmdb-win32-x64": "2.8.5" + } + }, + "node_modules/lmdb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.9.tgz", + "integrity": "sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/msgpackr-extract/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.37", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", + "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "dev": true, + "license": "MIT" + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parcel": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.16.4.tgz", + "integrity": "sha512-RQlrqs4ujYNJpTQi+dITqPKNhRWEqpjPd1YBcGp50Wy3FcJHpwu0/iRm7XWz2dKU/Bwp2qCcVYPIeEDYi2uOUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/config-default": "2.16.4", + "@parcel/core": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/package-manager": "2.16.4", + "@parcel/reporter-cli": "2.16.4", + "@parcel/reporter-dev-server": "2.16.4", + "@parcel/reporter-tracer": "2.16.4", + "@parcel/utils": "2.16.4", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "get-port": "^4.2.0" + }, + "bin": { + "parcel": "lib/bin.js" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.16.0.tgz", + "integrity": "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.99.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", + "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..9647c0cb --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "apiki-favorites", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "parcel watch assets/ts/index.ts --dist-dir dist", + "build": "parcel build assets/ts/index.ts --dist-dir dist --no-source-maps" + }, + "devDependencies": { + "@parcel/transformer-sass": "^2.16.0", + "parcel": "^2.16.0", + "typescript": "^5.7.0" + } +} diff --git a/src/Assets.php b/src/Assets.php new file mode 100644 index 00000000..725da929 --- /dev/null +++ b/src/Assets.php @@ -0,0 +1,79 @@ + rest_url('apiki-favorites/v1/favorites'), + 'nonce' => wp_create_nonce('wp_rest'), + 'isLoggedIn' => is_user_logged_in(), + ]); + } + + public static function appendButton(string $content): string + { + if (!is_singular('post') || !in_the_loop() || !is_main_query()) { + return $content; + } + + if (!is_user_logged_in()) { + return $content; + } + + $postId = get_the_ID(); + + if ($postId === false) { + return $content; + } + + $isFavorite = Database::isFavorite(get_current_user_id(), $postId); + $activeClass = $isFavorite ? ' apiki-favorite-btn--active' : ''; + $label = $isFavorite + ? esc_attr__('Remove from favorites', 'apiki-favorites') + : esc_attr__('Add to favorites', 'apiki-favorites'); + + $button = sprintf( + '', + esc_attr($activeClass), + $postId, + $label, + $label + ); + + return $content . $button; + } +} diff --git a/src/Database.php b/src/Database.php new file mode 100644 index 00000000..50a4ce1e --- /dev/null +++ b/src/Database.php @@ -0,0 +1,109 @@ +prefix . 'favorite_posts'; + } + + public static function createTable(): void + { + global $wpdb; + + $table = self::tableName(); + $charset = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE IF NOT EXISTS {$table} ( + id bigint(20) unsigned NOT NULL AUTO_INCREMENT, + user_id bigint(20) unsigned NOT NULL, + post_id bigint(20) unsigned NOT NULL, + created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY user_post (user_id, post_id) + ) {$charset};"; + + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + dbDelta($sql); + } + + public static function addFavorite(int $userId, int $postId): int|false + { + global $wpdb; + + if (self::isFavorite($userId, $postId)) { + return false; + } + + $result = $wpdb->insert( + self::tableName(), + [ + 'user_id' => $userId, + 'post_id' => $postId, + ], + ['%d', '%d'] + ); + + return $result !== false ? (int) $wpdb->insert_id : false; + } + + public static function removeFavorite(int $userId, int $postId): bool + { + global $wpdb; + + $deleted = $wpdb->delete( + self::tableName(), + [ + 'user_id' => $userId, + 'post_id' => $postId, + ], + ['%d', '%d'] + ); + + return $deleted > 0; + } + + /** + * @return array + */ + public static function getFavorites(int $userId): array + { + global $wpdb; + + $table = self::tableName(); + $posts = $wpdb->posts; + + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT f.id, f.post_id, p.post_title, f.created_at + FROM {$table} f + JOIN {$posts} p ON f.post_id = p.ID + WHERE f.user_id = %d + ORDER BY f.created_at DESC", + $userId + ) + ); + + return $results ?: []; + } + + public static function isFavorite(int $userId, int $postId): bool + { + global $wpdb; + + $count = (int) $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM " . self::tableName() . " WHERE user_id = %d AND post_id = %d", + $userId, + $postId + ) + ); + + return $count > 0; + } +} diff --git a/src/Plugin.php b/src/Plugin.php new file mode 100644 index 00000000..0d5be340 --- /dev/null +++ b/src/Plugin.php @@ -0,0 +1,35 @@ + 'GET', + 'callback' => [self::class, 'getFavorites'], + 'permission_callback' => [self::class, 'checkPermission'], + ], + [ + 'methods' => 'POST', + 'callback' => [self::class, 'addFavorite'], + 'permission_callback' => [self::class, 'checkPermission'], + 'args' => self::postIdArgs(), + ], + [ + 'methods' => 'DELETE', + 'callback' => [self::class, 'removeFavorite'], + 'permission_callback' => [self::class, 'checkPermission'], + 'args' => self::postIdArgs(), + ], + ]); + } + + public static function checkPermission(): bool|WP_Error + { + if (!is_user_logged_in()) { + return new WP_Error( + 'rest_unauthorized', + __('You must be logged in.', 'apiki-favorites'), + ['status' => 401] + ); + } + + return true; + } + + public static function getFavorites(WP_REST_Request $request): WP_REST_Response + { + $favorites = Database::getFavorites(get_current_user_id()); + + return new WP_REST_Response($favorites, 200); + } + + public static function addFavorite(WP_REST_Request $request): WP_REST_Response|WP_Error + { + $postId = absint($request->get_param('post_id')); + $userId = get_current_user_id(); + + if (get_post($postId) === null) { + return new WP_Error( + 'rest_not_found', + __('Post not found.', 'apiki-favorites'), + ['status' => 404] + ); + } + + $insertId = Database::addFavorite($userId, $postId); + + if ($insertId === false) { + return new WP_Error( + 'rest_conflict', + __('Post already favorited.', 'apiki-favorites'), + ['status' => 409] + ); + } + + return new WP_REST_Response([ + 'id' => $insertId, + 'post_id' => $postId, + 'created_at' => current_time('mysql'), + ], 201); + } + + public static function removeFavorite(WP_REST_Request $request): WP_REST_Response|WP_Error + { + $postId = absint($request->get_param('post_id')); + $userId = get_current_user_id(); + + $deleted = Database::removeFavorite($userId, $postId); + + if (!$deleted) { + return new WP_Error( + 'rest_not_found', + __('Favorite not found.', 'apiki-favorites'), + ['status' => 404] + ); + } + + return new WP_REST_Response(['deleted' => true], 200); + } + + /** + * @return array> + */ + private static function postIdArgs(): array + { + return [ + 'post_id' => [ + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => static function (mixed $value): bool { + return is_numeric($value) && (int) $value > 0; + }, + ], + ]; + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..b9a0dd67 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "outDir": "dist", + "rootDir": "assets/ts" + }, + "include": ["assets/ts"] +}