diff --git a/.config/eslint.config.js b/.config/eslint.config.js
index 3200a6807..fd788f886 100644
--- a/.config/eslint.config.js
+++ b/.config/eslint.config.js
@@ -10,6 +10,6 @@ export default [
},
},
{
- ignores: ['dist/', 'node_modules/', '.astro/', '.netlify/', '.vercel/'],
+ ignores: ['**/dist/', '**/node_modules/', '.astro/', '.netlify/', '.vercel/'],
},
];
diff --git a/.env.sample b/.env.sample
index 2781bbaf0..56c2c1919 100644
--- a/.env.sample
+++ b/.env.sample
@@ -23,8 +23,9 @@ WHO_API_KEY=''
# PUBLIC_API_TIMEOUT_LIMIT='25000'# Timeout for API requests, in milliseconds
# API_CORS_ORIGIN='*' # Enable CORS, by setting your allowed hostname(s) here
# API_ENABLE_RATE_LIMIT='true' # Enable rate limiting for the API
-# REACT_APP_API_ENDPOINT='/api' # The endpoint for the API (can be local or remote)
+# PUBLIC_API_ENDPOINT='/api' # The endpoint for the API (can be local or remote)
+# APP_STATIC_DIR='' # Override location of the built React app (defaults to ../app/dist)
+# BOSS_SERVER='true' # Set on the official public instance only, builds the Astro marketing pages
# ENABLE_ANALYTICS='false' # Enable Plausible hit counter for the frontend
-# BOSS_SERVER='false' # Marketing homepage (only used by official instance)
# TRUST_PROXY='1' # Set if running behind a reverse proxy (Traefik, nginx, etc).
# Use a number of hops (e.g. '1'), 'true', or a CIDR list.
diff --git a/.github/README.md b/.github/README.md
index aa3696cb3..92204b633 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -900,9 +900,9 @@ Install the prerequisites listed in the [Developing](#developing) section, then
```bash
git clone https://github.com/Lissy93/web-check.git # Download the code from GitHub
cd web-check # Navigate into the project dir
-yarn install # Install the NPM dependencies
-yarn build # Build the app for production
-yarn serve # Start the app (API and GUI)
+yarn install # Install workspace dependencies
+yarn build # Build the api wrappers, app and site
+yarn start # Run the Express server (api and GUI)
```
---
@@ -947,7 +947,8 @@ But there are some optional environmental variables that you can set to give you
| `API_CORS_ORIGIN` | Enable CORS, by setting your allowed hostname(s) here (e.g. `example.com`) |
| `CHROME_PATH` | The path the Chromium executable (e.g. `/usr/bin/chromium`) |
| `DISABLE_GUI` | Disable the GUI, and only serve the API (e.g. `false`) |
-| `REACT_APP_API_ENDPOINT` | The endpoint for the API, either local or remote (e.g. `/api`) |
+| `PUBLIC_API_ENDPOINT` | The endpoint for the API, either local or remote (e.g. `/api`) |
+| `APP_STATIC_DIR` | Override path to the built React app (defaults to `packages/app/dist`) |
All values are optional.
@@ -964,7 +965,7 @@ Note that keys that are prefixed with `REACT_APP_` are used client-side, and as
3. Install dependencies: `yarn`
4. Start the dev server, with `yarn dev`
-You'll need [Node.js](https://nodejs.org/en) (V 18.16.1 or later) installed, plus [yarn](https://yarnpkg.com/getting-started/install) as well as [git](https://git-scm.com/).
+You'll need [Node.js](https://nodejs.org/en) (V 22 or later) installed, plus [yarn](https://yarnpkg.com/getting-started/install) as well as [git](https://git-scm.com/).
Some checks also require `chromium`, `traceroute` and `dns` to be installed within your environment. These jobs will just be skipped if those packages aren't present.
---
diff --git a/.github/workflows/bump-and-tag.yml b/.github/workflows/bump-and-tag.yml
index bb2c7287d..2f5d078a1 100644
--- a/.github/workflows/bump-and-tag.yml
+++ b/.github/workflows/bump-and-tag.yml
@@ -68,7 +68,7 @@ jobs:
github.rest.pulls.listFiles, { owner, repo, pull_number }
);
const codePatterns = [
- /^src\//, /^api\//, /^public\//, /^Dockerfile$/, /^[^/]+\.(js|mjs)$/,
+ /^packages\//, /^scripts\//, /^Dockerfile$/, /^[^/]+\.(js|mjs)$/,
];
const codeChanged = files.some(f =>
codePatterns.some(p => p.test(f.filename))
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a2257b4f6..19d0dc2ed 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -105,12 +105,20 @@ jobs:
- name: ✅ Verify Build Output
run: |
- if [ ! -d "dist/client" ]; then
- echo "❌ Build failed: dist/client directory not created"
+ if [ ! -f "packages/site/dist/index.html" ]; then
+ echo "❌ Build failed: site index not found"
exit 1
fi
- if [ ! -f "dist/server/entry.mjs" ]; then
- echo "❌ Build failed: SSR entry not found"
+ if [ ! -f "packages/site/dist/check/index.html" ]; then
+ echo "❌ Build failed: check SPA shell not found"
+ exit 1
+ fi
+ if [ ! -f "packages/app/dist/index.html" ]; then
+ echo "❌ Build failed: app standalone build not found"
+ exit 1
+ fi
+ if [ "$(ls -1 api/*.js 2>/dev/null | wc -l)" -lt 30 ]; then
+ echo "❌ Build failed: vercel api wrappers not generated"
exit 1
fi
echo "✅ Build successful"
diff --git a/.github/workflows/deploy-aws.yml b/.github/workflows/deploy-aws.yml
deleted file mode 100644
index 426035ef4..000000000
--- a/.github/workflows/deploy-aws.yml
+++ /dev/null
@@ -1,127 +0,0 @@
-name: 🚀 Deploy to AWS
-
-on:
- workflow_dispatch:
- push:
- branches:
- - master
- tags:
- - '*'
- paths:
- - api/**
- - serverless.yml
- - package.json
- - .github/workflows/deploy-aws.yml
-
-jobs:
- deploy-api:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: 16
-
- - name: Cache node_modules
- uses: actions/cache@v4
- with:
- path: node_modules
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
-
- - name: Create GitHub deployment for API
- uses: chrnorm/deployment-action@releases/v2
- id: deployment_api
- with:
- token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
- environment: AWS (Backend API)
- ref: ${{ github.ref }}
-
- - name: Install Serverless CLI and dependencies
- run: |
- npm i -g serverless
- yarn
-
- - name: Deploy to AWS
- env:
- AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
- AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
- run: serverless deploy
-
- - name: Update GitHub deployment status (API)
- if: always()
- uses: chrnorm/deployment-status@v2
- with:
- token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
- state: '${{ job.status }}'
- deployment_id: ${{ steps.deployment_api.outputs.deployment_id }}
- ref: ${{ github.ref }}
-
- deploy-frontend:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- node-version: 16
-
- - name: Cache node_modules
- uses: actions/cache@v4
- with:
- path: node_modules
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
-
- - name: Create GitHub deployment for Frontend
- uses: chrnorm/deployment-action@v2
- id: deployment_frontend
- with:
- token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
- environment: AWS (Frontend Web UI)
- ref: ${{ github.ref }}
-
- - name: Install dependencies and build
- run: |
- yarn install
- yarn build
-
- - name: Setup AWS
- uses: aws-actions/configure-aws-credentials@v4
- with:
- aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
- aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- aws-region: us-east-1
-
- - name: Upload to S3
- env:
- AWS_S3_BUCKET: 'web-check-frontend'
- run: aws s3 sync ./build/ s3://$AWS_S3_BUCKET/ --delete
-
- - name: Invalidate CloudFront cache
- uses: chetan/invalidate-cloudfront-action@v2
- env:
- DISTRIBUTION: E30XKAM2TG9FD8
- PATHS: '/*'
- AWS_REGION: 'us-east-1'
- AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
- AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
-
- - name: Update GitHub deployment status (Frontend)
- if: always()
- uses: chrnorm/deployment-status@v2
- with:
- token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}
- state: '${{ job.status }}'
- deployment_id: ${{ steps.deployment_frontend.outputs.deployment_id }}
- ref: ${{ github.ref }}
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index fa950e2ca..81583e8be 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -8,9 +8,8 @@ on:
tags:
- '*'
paths:
- - src/**
- - api/**
- - public/**
+ - packages/**
+ - scripts/**
- Dockerfile
permissions:
diff --git a/.yarnrc b/.yarnrc
index 93303a220..976983813 100644
--- a/.yarnrc
+++ b/.yarnrc
@@ -1,4 +1,2 @@
-# engines.node is pinned to 20.x so @astrojs/vercel@7.x emits a supported
-# Vercel runtime for the SSR _render function. Local devs on a different
-# Node version can still run yarn install via this flag.
+# Allow workspace install to proceed when sub-deps disagree on engine ranges
--install.ignore-engines true
diff --git a/Dockerfile b/Dockerfile
index f61566264..0e502470f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,64 +1,61 @@
-# Specify the Node.js version to use
ARG NODE_VERSION=22
-
-# Specify the Debian version to use, the default is "bullseye"
ARG DEBIAN_VERSION=bullseye
-# Use Node.js Docker image as the base image, with specific Node and Debian versions
FROM node:${NODE_VERSION}-${DEBIAN_VERSION} AS build
-# Set the container's default shell to Bash and enable some options
SHELL ["/bin/bash", "-euo", "pipefail", "-c"]
-# Install Chromium browser and Download and verify Google Chrome’s signing key
+# Install chromium plus build tooling so puppeteer and friends compile cleanly
RUN apt-get update -qq --fix-missing && \
apt-get -qqy install --allow-unauthenticated gnupg wget && \
- wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
- echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list && \
+ wget --quiet --output-document=- \
+ https://dl-ssl.google.com/linux/linux_signing_key.pub | \
+ gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
+ echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" \
+ > /etc/apt/sources.list.d/google.list && \
apt-get update -qq && \
- apt-get -qqy --no-install-recommends install chromium traceroute python make g++ && \
- rm -rf /var/lib/apt/lists/*
-
-# Run the Chromium browser's version command and redirect its output to the /etc/chromium-version file
-RUN /usr/bin/chromium --no-sandbox --version > /etc/chromium-version
+ apt-get -qqy --no-install-recommends install \
+ chromium traceroute python make g++ && \
+ rm -rf /var/lib/apt/lists/*
-# Set the working directory to /app
WORKDIR /app
-# Copy package.json and yarn.lock to the working directory
+# Copy workspace manifests first so yarn can plan and cache the dependency graph
COPY package.json yarn.lock ./
+COPY packages/api/package.json ./packages/api/package.json
+COPY packages/app/package.json ./packages/app/package.json
+COPY packages/site/package.json ./packages/site/package.json
-# Run yarn install to install dependencies and clear yarn cache
-RUN apt-get update && \
- yarn install --frozen-lockfile --network-timeout 100000 && \
+RUN yarn install --frozen-lockfile --network-timeout 100000 && \
rm -rf /app/node_modules/.cache
-# Copy all files to working directory
-COPY . .
+# Copy api and app sources plus the site's shared public assets
+# (fonts, icons) which the standalone app build pulls in. Site src is skipped.
+COPY packages/api ./packages/api
+COPY packages/app ./packages/app
+COPY packages/site/public ./packages/site/public
-# Run yarn build to build the application
-RUN yarn build --production
+RUN yarn build:docker
-# Final stage
-FROM node:${NODE_VERSION}-${DEBIAN_VERSION} AS final
+FROM node:${NODE_VERSION}-${DEBIAN_VERSION} AS final
WORKDIR /app
-COPY package.json yarn.lock ./
-COPY --from=build /app .
-
RUN apt-get update && \
apt-get install -y --no-install-recommends chromium traceroute && \
chmod 755 /usr/bin/chromium && \
- rm -rf /var/lib/apt/lists/* /app/node_modules/.cache
+ rm -rf /var/lib/apt/lists/* /tmp/*
+
+COPY --from=build /app/package.json /app/yarn.lock ./
+COPY --from=build /app/node_modules ./node_modules
+COPY --from=build /app/packages/api ./packages/api
+COPY --from=build /app/packages/app/package.json ./packages/app/package.json
+COPY --from=build /app/packages/app/dist ./packages/app/dist
-# Exposed container port, the default is 3000, which can be modified through the environment variable PORT
EXPOSE ${PORT:-3000}
-# Point Chromium-using libs at the system binary, skip puppeteer's bundled download
ENV CHROME_PATH='/usr/bin/chromium' \
PUPPETEER_EXECUTABLE_PATH='/usr/bin/chromium' \
PUPPETEER_SKIP_DOWNLOAD='true'
-# Define the command executed when the container starts and start the server.js of the Node.js application
-CMD ["yarn", "start"]
+CMD ["node", "packages/api/server.js"]
diff --git a/api/_common/aws-webpack.config.js b/api/_common/aws-webpack.config.js
deleted file mode 100644
index 7f6fe93ab..000000000
--- a/api/_common/aws-webpack.config.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const path = require('path');
-const nodeExternals = require('webpack-node-externals');
-
-module.exports = {
- target: 'node',
- mode: 'production',
- entry: {
- carbon: './api/carbon.js',
- cookies: './api/cookies.js',
- 'dns-server': './api/dns-server.js',
- dns: './api/dns.js',
- dnssec: './api/dnssec.js',
- 'get-ip': './api/get-ip.js',
- headers: './api/headers.js',
- hsts: './api/hsts.js',
- 'linked-pages': './api/linked-pages.js',
- 'mail-config': './api/mail-config.js',
- ports: './api/ports.js',
- quality: './api/quality.js',
- redirects: './api/redirects.js',
- 'robots-txt': './api/robots-txt.js',
- screenshot: './api/screenshot.js',
- 'security-txt': './api/security-txt.js',
- sitemap: './api/sitemap.js',
- 'social-tags': './api/social-tags.js',
- ssl: './api/ssl.js',
- status: './api/status.js',
- 'tech-stack': './api/tech-stack.js',
- 'trace-route': './api/trace-route.js',
- 'txt-records': './api/txt-records.js',
- whois: './api/whois.js',
- },
- externals: [nodeExternals()],
- output: {
- filename: '[name].js',
- path: path.resolve(__dirname, '.webpack'),
- libraryTarget: 'commonjs2',
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- use: {
- loader: 'babel-loader',
- },
- exclude: /node_modules/,
- },
- ],
- },
-};
diff --git a/api/archives.js b/api/archives.js
index 4818c2a2a..bba53ab44 100644
--- a/api/archives.js
+++ b/api/archives.js
@@ -1,84 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-
-const convertTimestampToDate = (timestamp) => {
- const [year, month, day, hour, minute, second] = [
- timestamp.slice(0, 4),
- timestamp.slice(4, 6) - 1,
- timestamp.slice(6, 8),
- timestamp.slice(8, 10),
- timestamp.slice(10, 12),
- timestamp.slice(12, 14),
- ].map((num) => parseInt(num, 10));
-
- return new Date(year, month, day, hour, minute, second);
-};
-
-const countPageChanges = (results) => {
- let prevDigest = null;
- return results.reduce((acc, curr) => {
- if (curr[2] !== prevDigest) {
- prevDigest = curr[2];
- return acc + 1;
- }
- return acc;
- }, -1);
-};
-
-const getAveragePageSize = (scans) => {
- const totalSize = scans.map((scan) => parseInt(scan[3], 10)).reduce((sum, size) => sum + size, 0);
- return Math.round(totalSize / scans.length);
-};
-
-const getScanFrequency = (firstScan, lastScan, totalScans, changeCount) => {
- const formatToTwoDecimal = (num) => parseFloat(num.toFixed(2));
-
- const dayFactor = (lastScan - firstScan) / (1000 * 60 * 60 * 24);
- const daysBetweenScans = formatToTwoDecimal(dayFactor / totalScans);
- const daysBetweenChanges = formatToTwoDecimal(dayFactor / changeCount);
- const scansPerDay = formatToTwoDecimal((totalScans - 1) / dayFactor);
- const changesPerDay = formatToTwoDecimal(changeCount / dayFactor);
- return {
- daysBetweenScans,
- daysBetweenChanges,
- scansPerDay,
- changesPerDay,
- };
-};
-
-const wayBackHandler = async (url) => {
- const cdxUrl = `https://web.archive.org/cdx/search/cdx?url=${url}&output=json&fl=timestamp,statuscode,digest,length,offset`;
-
- try {
- const { data } = await httpGet(cdxUrl);
-
- // Check there's data
- if (!data || !Array.isArray(data) || data.length <= 1) {
- return { skipped: 'Site has never before been archived via the Wayback Machine' };
- }
-
- // Remove the header row
- data.shift();
-
- // Process and return the results
- const firstScan = convertTimestampToDate(data[0][0]);
- const lastScan = convertTimestampToDate(data[data.length - 1][0]);
- const totalScans = data.length;
- const changeCount = countPageChanges(data);
- return {
- firstScan,
- lastScan,
- totalScans,
- changeCount,
- averagePageSize: getAveragePageSize(data),
- scanFrequency: getScanFrequency(firstScan, lastScan, totalScans, changeCount),
- scans: data,
- scanUrl: url,
- };
- } catch (err) {
- return { error: `Error fetching Wayback data: ${err.message}` };
- }
-};
-
-export const handler = middleware(wayBackHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/archives.js';
diff --git a/api/block-lists.js b/api/block-lists.js
index f34c0250b..663b5381b 100644
--- a/api/block-lists.js
+++ b/api/block-lists.js
@@ -1,62 +1,3 @@
-import dns from 'dns';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-const DNS_SERVERS = [
- { name: 'AdGuard', ip: '176.103.130.130' },
- { name: 'AdGuard Family', ip: '176.103.130.132' },
- { name: 'CleanBrowsing Adult', ip: '185.228.168.10' },
- { name: 'CleanBrowsing Family', ip: '185.228.168.168' },
- { name: 'CleanBrowsing Security', ip: '185.228.168.9' },
- { name: 'CloudFlare', ip: '1.1.1.1' },
- { name: 'CloudFlare Family', ip: '1.1.1.3' },
- { name: 'Comodo Secure', ip: '8.26.56.26' },
- { name: 'Google DNS', ip: '8.8.8.8' },
- { name: 'OpenDNS', ip: '208.67.222.222' },
- { name: 'OpenDNS Family', ip: '208.67.222.123' },
- { name: 'Quad9', ip: '9.9.9.9' },
-];
-
-// Sink IPs used by blocking DNS servers
-const SINK_IPS = new Set(['0.0.0.0', '127.0.0.1', '::1', '::', '0:0:0:0:0:0:0:0']);
-
-// Resolve a domain via a specific DNS server
-const queryServer = (domain, serverIp) =>
- new Promise((resolve) => {
- const resolver = new dns.Resolver({ timeout: 3000, tries: 1 });
- resolver.setServers([serverIp]);
- resolver.resolve4(domain, (err, addrs) => {
- if (err) return resolve({ err: err.code });
- resolve({ addrs });
- });
- });
-
-// A domain is blocked if the resolver returns a sink IP or refuses
-// to resolve a domain that a neutral resolver can resolve
-const isBlocked = (result, refResolved) => {
- if (!refResolved) return false;
- if (result.err === 'NXDOMAIN' || result.err === 'SERVFAIL') return true;
- if (!result.addrs) return false;
- return result.addrs.every((ip) => SINK_IPS.has(ip));
-};
-
-const blockListHandler = async (url) => {
- const { hostname: domain } = parseTarget(url);
- const ref = await queryServer(domain, '8.8.8.8');
- const refResolved = !!ref.addrs?.length;
-
- const results = await Promise.all(
- DNS_SERVERS.map(async ({ name, ip }) => {
- const result = await queryServer(domain, ip);
- return {
- server: name,
- serverIp: ip,
- isBlocked: isBlocked(result, refResolved),
- };
- }),
- );
- return { blocklists: results };
-};
-
-export const handler = middleware(blockListHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/block-lists.js';
diff --git a/api/carbon.js b/api/carbon.js
index 1e8e01665..834d48204 100644
--- a/api/carbon.js
+++ b/api/carbon.js
@@ -1,79 +1,3 @@
-import middleware from './_common/middleware.js';
-import { createLogger } from './_common/logger.js';
-
-const log = createLogger('carbon');
-
-const TIMEOUT = 8000;
-const MAX_BYTES = 10 * 1024 * 1024;
-const USER_AGENT = 'Mozilla/5.0 (compatible; WebCheck/2.0; +https://web-check.xyz)';
-
-// Sustainable Web Design model v3 constants, matches websitecarbon.com formula
-const KWH_PER_GB = 0.81;
-const FIRST_VISIT = 0.25;
-const RETURN_VISIT = 0.75;
-const RETURN_DATA_PCT = 0.02;
-const GRID_INTENSITY = 442;
-const RENEWABLE_INTENSITY = 50;
-const LITRES_PER_GRAM = 0.5562;
-
-// Stream the response, cap at MAX_BYTES so huge pages can't blow memory or time
-const fetchByteCount = async (url) => {
- const r = await fetch(url, {
- signal: AbortSignal.timeout(TIMEOUT),
- redirect: 'follow',
- headers: { 'user-agent': USER_AGENT, accept: 'text/html,*/*;q=0.1' },
- });
- if (!r.ok) throw new Error(`status ${r.status}`);
- if (!r.body) return 0;
- const reader = r.body.getReader();
- let total = 0;
- while (total < MAX_BYTES) {
- const { value, done } = await reader.read();
- if (done) break;
- total += value.length;
- }
- reader.cancel().catch(() => {});
- return total;
-};
-
-// SWD-based stats matching websitecarbon /data response shape
-const computeCarbon = (bytes) => {
- const adjustedBytes = bytes * (FIRST_VISIT + RETURN_VISIT * RETURN_DATA_PCT);
- const energy = (adjustedBytes / 1073741824) * KWH_PER_GB;
- const gridGrams = energy * GRID_INTENSITY;
- const renewableGrams = energy * RENEWABLE_INTENSITY;
- return {
- adjustedBytes,
- energy,
- co2: {
- grid: { grams: gridGrams, litres: gridGrams * LITRES_PER_GRAM },
- renewable: {
- grams: renewableGrams,
- litres: renewableGrams * LITRES_PER_GRAM,
- },
- },
- };
-};
-
-// Fetch site, count bytes, compute SWD carbon stats locally, no third-party API
-const carbonHandler = async (url) => {
- let bytes;
- try {
- bytes = await fetchByteCount(url);
- } catch (error) {
- log.warn(`fetch failed for ${url}`, error.message);
- return { error: `Failed to fetch site: ${error.message}` };
- }
- if (!bytes) return { skipped: 'Site returned no content, cannot calculate carbon' };
- log.debug(`measured ${bytes} bytes for ${url}`);
- return {
- url,
- bytes,
- green: false,
- statistics: computeCarbon(bytes),
- scanUrl: url,
- };
-};
-
-export const handler = middleware(carbonHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/carbon.js';
diff --git a/api/cookies.js b/api/cookies.js
index bc6093211..785487708 100644
--- a/api/cookies.js
+++ b/api/cookies.js
@@ -1,51 +1,3 @@
-import puppeteer from 'puppeteer';
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-
-const getPuppeteerCookies = async (url) => {
- const browser = await puppeteer.launch({
- headless: true,
- args: ['--no-sandbox', '--disable-setuid-sandbox'],
- });
-
- try {
- const page = await browser.newPage();
- const navigationPromise = page.goto(url, { waitUntil: 'networkidle2' });
- const timeoutPromise = new Promise((_, reject) =>
- setTimeout(() => reject(new Error('Puppeteer took too long!')), 3000),
- );
- await Promise.race([navigationPromise, timeoutPromise]);
- return await browser.cookies();
- } finally {
- await browser.close();
- }
-};
-
-const cookieHandler = async (url) => {
- let headerCookies = null;
- let clientCookies = null;
-
- try {
- const response = await httpGet(url);
- headerCookies = response.headers['set-cookie'];
- } catch (error) {
- if (error.response) {
- return { error: `Request failed with status ${error.response.status}: ${error.message}` };
- }
- return { error: `No response received: ${error.message}` };
- }
-
- try {
- clientCookies = await getPuppeteerCookies(url);
- } catch (_) {
- clientCookies = null;
- }
-
- return {
- headerCookies: headerCookies || [],
- clientCookies: clientCookies || [],
- };
-};
-
-export const handler = middleware(cookieHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/cookies.js';
diff --git a/api/dns-server.js b/api/dns-server.js
index b4b6b5077..a021b9a51 100644
--- a/api/dns-server.js
+++ b/api/dns-server.js
@@ -1,33 +1,3 @@
-import { promises as dnsPromises } from 'dns';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-import { upstreamError } from './_common/upstream.js';
-
-// Resolve a nameserver hostname to its IP addresses
-const resolveNs = async (ns) => {
- try {
- return (await dnsPromises.resolve4(ns))[0];
- } catch {
- return null;
- }
-};
-
-const dnsHandler = async (url) => {
- const { hostname: domain } = parseTarget(url);
- let nameservers;
- try {
- nameservers = await dnsPromises.resolveNs(domain);
- } catch (error) {
- return upstreamError(error, 'DNS server lookup');
- }
- const results = await Promise.all(
- nameservers.map(async (ns) => {
- const ip = await resolveNs(ns);
- return { address: ip, hostname: ns };
- }),
- );
- return { domain, dns: results };
-};
-
-export const handler = middleware(dnsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/dns-server.js';
diff --git a/api/dns.js b/api/dns.js
index 307853eea..e8893447c 100644
--- a/api/dns.js
+++ b/api/dns.js
@@ -1,23 +1,3 @@
-import dns from 'dns/promises';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-const dnsHandler = async (url) => {
- const { hostname } = parseTarget(url);
- const safe = (fn) => fn.catch(() => []);
- const [a, aaaa, mx, txt, ns, cname, soa, srv, ptr] = await Promise.all([
- safe(dns.resolve4(hostname)),
- safe(dns.resolve6(hostname)),
- safe(dns.resolveMx(hostname)),
- safe(dns.resolveTxt(hostname)),
- safe(dns.resolveNs(hostname)),
- safe(dns.resolveCname(hostname)),
- dns.resolveSoa(hostname).catch(() => null),
- safe(dns.resolveSrv(hostname)),
- safe(dns.resolvePtr(hostname)),
- ]);
- return { A: a, AAAA: aaaa, MX: mx, TXT: txt, NS: ns, CNAME: cname, SOA: soa, SRV: srv, PTR: ptr };
-};
-
-export const handler = middleware(dnsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/dns.js';
diff --git a/api/dnssec.js b/api/dnssec.js
index 6ef983b9c..f52d82fd1 100644
--- a/api/dnssec.js
+++ b/api/dnssec.js
@@ -1,38 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-
-// Query Google's public DNS JSON API for a given record type
-const queryDns = async (domain, type) => {
- const res = await httpGet('https://dns.google/resolve', {
- params: { name: domain, type },
- headers: { Accept: 'application/dns-json' },
- timeout: 5000,
- });
- return res.data;
-};
-
-const dnsSecHandler = async (url) => {
- const { hostname } = parseTarget(url);
- const [dnskey, ds, aRecord] = await Promise.all([
- queryDns(hostname, 'DNSKEY'),
- queryDns(hostname, 'DS'),
- queryDns(hostname, 'A'),
- ]);
- return {
- DNSKEY: dnskey.Answer
- ? { isFound: true, answer: dnskey.Answer, response: dnskey.Answer }
- : { isFound: false, answer: null, response: dnskey },
- DS: ds.Answer
- ? { isFound: true, answer: ds.Answer, response: ds.Answer }
- : { isFound: false, answer: null, response: ds },
- RRSIG: {
- isFound: !!aRecord.AD,
- answer: null,
- response: aRecord,
- },
- };
-};
-
-export const handler = middleware(dnsSecHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/dnssec.js';
diff --git a/api/firewall.js b/api/firewall.js
index 497c595b4..236583a2c 100644
--- a/api/firewall.js
+++ b/api/firewall.js
@@ -1,112 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-import { upstreamError } from './_common/upstream.js';
-
-const hasWaf = (waf) => ({ hasWaf: true, waf });
-
-const firewallHandler = async (url) => {
- const { href } = parseTarget(url);
- try {
- const response = await httpGet(href, {
- validateStatus: () => true,
- });
- const headers = response.headers;
-
- if (headers['server'] && headers['server'].includes('cloudflare')) {
- return hasWaf('Cloudflare');
- }
-
- if (headers['x-powered-by'] && headers['x-powered-by'].includes('AWS Lambda')) {
- return hasWaf('AWS WAF');
- }
-
- if (headers['server'] && headers['server'].includes('AkamaiGHost')) {
- return hasWaf('Akamai');
- }
-
- if (headers['server'] && headers['server'].includes('Sucuri')) {
- return hasWaf('Sucuri');
- }
-
- if (headers['server'] && headers['server'].includes('BarracudaWAF')) {
- return hasWaf('Barracuda WAF');
- }
-
- if (
- headers['server'] &&
- (headers['server'].includes('F5 BIG-IP') || headers['server'].includes('BIG-IP'))
- ) {
- return hasWaf('F5 BIG-IP');
- }
-
- if (headers['x-sucuri-id'] || headers['x-sucuri-cache']) {
- return hasWaf('Sucuri CloudProxy WAF');
- }
-
- if (headers['server'] && headers['server'].includes('FortiWeb')) {
- return hasWaf('Fortinet FortiWeb WAF');
- }
-
- if (headers['server'] && headers['server'].includes('Imperva')) {
- return hasWaf('Imperva SecureSphere WAF');
- }
-
- if (headers['x-protected-by'] && headers['x-protected-by'].includes('Sqreen')) {
- return hasWaf('Sqreen');
- }
-
- if (headers['x-waf-event-info']) {
- return hasWaf('Reblaze WAF');
- }
-
- if (headers['set-cookie'] && headers['set-cookie'].includes('_citrix_ns_id')) {
- return hasWaf('Citrix NetScaler');
- }
-
- if (headers['x-denied-reason'] || headers['x-wzws-requested-method']) {
- return hasWaf('WangZhanBao WAF');
- }
-
- if (headers['x-webcoment']) {
- return hasWaf('Webcoment Firewall');
- }
-
- if (headers['server'] && headers['server'].includes('Yundun')) {
- return hasWaf('Yundun WAF');
- }
-
- if (headers['x-yd-waf-info'] || headers['x-yd-info']) {
- return hasWaf('Yundun WAF');
- }
-
- if (headers['server'] && headers['server'].includes('Safe3WAF')) {
- return hasWaf('Safe3 Web Application Firewall');
- }
-
- if (headers['server'] && headers['server'].includes('NAXSI')) {
- return hasWaf('NAXSI WAF');
- }
-
- if (headers['x-datapower-transactionid']) {
- return hasWaf('IBM WebSphere DataPower');
- }
-
- if (headers['server'] && headers['server'].includes('QRATOR')) {
- return hasWaf('QRATOR WAF');
- }
-
- if (headers['server'] && headers['server'].includes('ddos-guard')) {
- return hasWaf('DDoS-Guard WAF');
- }
-
- return {
- hasWaf: false,
- };
- } catch (error) {
- return upstreamError(error, 'Firewall check');
- }
-};
-
-export const handler = middleware(firewallHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/firewall.js';
diff --git a/api/get-ip.js b/api/get-ip.js
index 87c13ce73..9b0dd499f 100644
--- a/api/get-ip.js
+++ b/api/get-ip.js
@@ -1,19 +1,3 @@
-import dns from 'dns';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-const lookupAsync = (address) =>
- new Promise((resolve, reject) => {
- dns.lookup(address, (err, ip, family) => {
- if (err) reject(err);
- else resolve({ ip, family });
- });
- });
-
-const ipHandler = async (url) => {
- const { hostname } = parseTarget(url);
- return await lookupAsync(hostname);
-};
-
-export const handler = middleware(ipHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/get-ip.js';
diff --git a/api/headers.js b/api/headers.js
index c84be1970..f2c357f75 100644
--- a/api/headers.js
+++ b/api/headers.js
@@ -1,17 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { upstreamError } from './_common/upstream.js';
-
-const headersHandler = async (url) => {
- try {
- const response = await httpGet(url, {
- validateStatus: (status) => status >= 200 && status < 600,
- });
- return response.headers;
- } catch (error) {
- return upstreamError(error, 'Headers fetch');
- }
-};
-
-export const handler = middleware(headersHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/headers.js';
diff --git a/api/hsts.js b/api/hsts.js
index 63c6f074f..338781553 100644
--- a/api/hsts.js
+++ b/api/hsts.js
@@ -1,42 +1,3 @@
-import https from 'https';
-import middleware from './_common/middleware.js';
-
-const MIN_MAX_AGE = 10886400;
-
-const verdict = (message, compatible = false, hstsHeader = null) => ({
- message,
- compatible,
- hstsHeader,
-});
-
-const evaluate = (header) => {
- if (!header) return verdict('Site does not serve any HSTS headers.');
- const lower = header.toLowerCase();
- const maxAge = parseInt(lower.match(/max-age=(\d+)/)?.[1] || '0', 10);
- if (maxAge < MIN_MAX_AGE)
- return verdict(`HSTS max-age is ${maxAge}, below the ${MIN_MAX_AGE} minimum.`, false, header);
- if (!lower.includes('includesubdomains'))
- return verdict('HSTS header does not include all subdomains.', false, header);
- if (!lower.includes('preload'))
- return verdict('HSTS header does not contain the preload directive.', false, header);
- return verdict('Site is compatible with the HSTS preload list!', true, header);
-};
-
-const REQUEST_TIMEOUT = 5000;
-
-const hstsHandler = async (url) =>
- new Promise((resolve) => {
- const req = https.request(url, (res) => {
- resolve(evaluate(res.headers['strict-transport-security']));
- res.resume();
- });
- req.setTimeout(REQUEST_TIMEOUT, () => {
- req.destroy();
- resolve({ error: 'HSTS check timed out' });
- });
- req.on('error', (e) => resolve({ error: `HSTS check failed: ${e.message}` }));
- req.end();
- });
-
-export const handler = middleware(hstsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/hsts.js';
diff --git a/api/http-security.js b/api/http-security.js
index d86686055..08cd030f1 100644
--- a/api/http-security.js
+++ b/api/http-security.js
@@ -1,30 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-
-// Security headers to check, mapped to response field names
-const HEADERS = {
- 'content-security-policy': 'contentSecurityPolicy',
- 'strict-transport-security': 'strictTransportPolicy',
- 'x-content-type-options': 'xContentTypeOptions',
- 'x-frame-options': 'xFrameOptions',
- 'x-xss-protection': 'xXSSProtection',
- 'referrer-policy': 'referrerPolicy',
- 'permissions-policy': 'permissionsPolicy',
- 'cross-origin-opener-policy': 'crossOriginOpenerPolicy',
- 'cross-origin-resource-policy': 'crossOriginResourcePolicy',
- 'cross-origin-embedder-policy': 'crossOriginEmbedderPolicy',
-};
-
-const httpsSecHandler = async (url) => {
- try {
- const { headers } = await httpGet(url, {
- validateStatus: () => true,
- });
- return Object.fromEntries(Object.entries(HEADERS).map(([h, key]) => [key, !!headers[h]]));
- } catch (error) {
- return { error: `Unable to fetch headers: ${error.message}` };
- }
-};
-
-export const handler = middleware(httpsSecHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/http-security.js';
diff --git a/api/linked-pages.js b/api/linked-pages.js
index dafa883c0..129fdc974 100644
--- a/api/linked-pages.js
+++ b/api/linked-pages.js
@@ -1,53 +1,3 @@
-import * as cheerio from 'cheerio';
-import urlLib from 'url';
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { upstreamError } from './_common/upstream.js';
-
-const linkedPagesHandler = async (url) => {
- let response;
- try {
- response = await httpGet(url);
- } catch (error) {
- return upstreamError(error, 'Linked pages fetch');
- }
- const html = response.data;
- const $ = cheerio.load(html);
- const internalLinksMap = new Map();
- const externalLinksMap = new Map();
-
- // Get all links on the page
- $('a[href]').each((i, link) => {
- const href = $(link).attr('href');
- const absoluteUrl = urlLib.resolve(url, href);
-
- // Check if absolute / relative, append to appropriate map or increment occurrence count
- if (absoluteUrl.startsWith(url)) {
- const count = internalLinksMap.get(absoluteUrl) || 0;
- internalLinksMap.set(absoluteUrl, count + 1);
- } else if (href.startsWith('http://') || href.startsWith('https://')) {
- const count = externalLinksMap.get(absoluteUrl) || 0;
- externalLinksMap.set(absoluteUrl, count + 1);
- }
- });
-
- // Sort by most occurrences, remove supplicates, and convert to array
- const internalLinks = [...internalLinksMap.entries()]
- .sort((a, b) => b[1] - a[1])
- .map((entry) => entry[0]);
- const externalLinks = [...externalLinksMap.entries()]
- .sort((a, b) => b[1] - a[1])
- .map((entry) => entry[0]);
-
- if (!internalLinks.length && !externalLinks.length) {
- return {
- skipped:
- 'No internal or external links found in the page HTML. ' +
- 'This often happens with single-page apps that render content client-side.',
- };
- }
- return { internal: internalLinks, external: externalLinks };
-};
-
-export const handler = middleware(linkedPagesHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/linked-pages.js';
diff --git a/api/location.js b/api/location.js
index de4f58561..c9f282d3f 100644
--- a/api/location.js
+++ b/api/location.js
@@ -1,184 +1,3 @@
-import { promises as dns } from 'dns';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-import { createLogger } from './_common/logger.js';
-
-const log = createLogger('location');
-const TIMEOUT = 4000;
-
-// Server-side fetch, no-cors so providers don't reject Sec-Fetch-Mode: cors
-const getJson = async (url, signal) => {
- const r = await fetch(url, { mode: 'no-cors', signal });
- if (!r.ok) throw new Error(`status ${r.status}`);
- return r.json();
-};
-
-// Geo providers, each parser normalises to a shared field shape
-const providers = [
- {
- name: 'ipwho.is',
- url: (ip) => `https://ipwho.is/${ip}`,
- parse: (d) =>
- d?.success === false
- ? null
- : {
- ip: d.ip,
- city: d.city,
- region: d.region,
- country_name: d.country,
- country_code: d.country_code,
- region_code: d.region_code,
- postal: d.postal,
- latitude: d.latitude,
- longitude: d.longitude,
- org: d.connection?.isp || d.connection?.org,
- timezone: d.timezone?.id,
- },
- },
- {
- name: 'ip-api.com',
- url: (ip) => `http://ip-api.com/json/${ip}`,
- parse: (d) =>
- d?.status === 'success'
- ? {
- ip: d.query,
- city: d.city,
- region: d.regionName,
- country_name: d.country,
- country_code: d.countryCode,
- region_code: d.region,
- postal: d.zip,
- latitude: d.lat,
- longitude: d.lon,
- org: d.isp || d.org,
- timezone: d.timezone,
- }
- : null,
- },
- {
- name: 'geojs.io',
- url: (ip) => `https://get.geojs.io/v1/ip/geo/${ip}.json`,
- parse: (d) =>
- d?.country_code
- ? {
- ip: d.ip,
- city: d.city,
- region: d.region,
- country_name: d.country,
- country_code: d.country_code,
- latitude: d.latitude !== 'nil' ? parseFloat(d.latitude) : undefined,
- longitude: d.longitude !== 'nil' ? parseFloat(d.longitude) : undefined,
- org: d.organization_name,
- timezone: d.timezone,
- }
- : null,
- },
- {
- name: 'reallyfreegeoip.org',
- url: (ip) => `https://reallyfreegeoip.org/json/${ip}`,
- parse: (d) =>
- d?.country_code
- ? {
- ip: d.ip,
- city: d.city,
- region: d.region_name,
- country_name: d.country_name,
- country_code: d.country_code,
- region_code: d.region_code,
- postal: d.zip_code,
- latitude: d.latitude,
- longitude: d.longitude,
- timezone: d.time_zone,
- }
- : null,
- },
-];
-
-// Query a single provider, throw unless it yields a usable result
-const tryProvider = async (p, ip, signal) => {
- const parsed = p.parse(await getJson(p.url(ip), signal));
- if (!parsed?.country_code) throw new Error('no usable data');
- log.debug(`${p.name} resolved ${ip} to ${parsed.country_code}`);
- return parsed;
-};
-
-// Race all providers, first successful result wins, abort the rest
-const lookupGeo = async (ip) => {
- const ac = new AbortController();
- const signal = AbortSignal.any([ac.signal, AbortSignal.timeout(TIMEOUT)]);
- const tasks = providers.map((p) =>
- tryProvider(p, ip, signal).catch((e) => {
- if (e.name !== 'AbortError') log.warn(`${p.name} failed for ${ip}`, e.message);
- throw e;
- }),
- );
- try {
- const result = await Promise.any(tasks);
- ac.abort();
- return result;
- } catch {
- return null;
- }
-};
-
-// Fetch country-level metadata to fill fields not provided by every geo source
-const enrichCountry = async (code) => {
- if (!code) return {};
- try {
- const data = await getJson(
- `https://restcountries.com/v3.1/alpha/${code}` +
- '?fields=tld,languages,currencies,area,population',
- );
- const c = Array.isArray(data) ? data[0] : data;
- if (!c) {
- log.debug(`restcountries returned no entry for ${code}`);
- return {};
- }
- const languages = c.languages ? Object.values(c.languages).join(', ') : undefined;
- const currCode = c.currencies ? Object.keys(c.currencies)[0] : undefined;
- const curr = currCode ? c.currencies[currCode] : null;
- return {
- country_tld: c.tld?.[0],
- languages,
- currency: currCode,
- currency_name: curr?.name,
- country_area: c.area,
- country_population: c.population,
- };
- } catch (error) {
- log.debug(`restcountries enrichment failed for ${code}`, error.message);
- return {};
- }
-};
-
-// Strip empty values so they don't shadow enrichment defaults during merge
-const compact = (o) =>
- Object.fromEntries(
- Object.entries(o).filter(([, v]) => v !== undefined && v !== null && v !== ''),
- );
-
-// Resolve hostname to IP so providers requiring a numeric address still work
-const resolveHost = async (hostname) => {
- try {
- return (await dns.lookup(hostname)).address;
- } catch (error) {
- log.warn(`DNS lookup failed for ${hostname}, falling through with raw host`, error.message);
- return hostname;
- }
-};
-
-// Resolve geographic info for a host via a chain of providers with country enrichment
-const locationHandler = async (url) => {
- const { hostname } = parseTarget(url);
- const ip = await resolveHost(hostname);
- const geo = await lookupGeo(ip);
- if (!geo) {
- log.error(`all geo providers failed for ${ip}`);
- return { error: 'IP location lookup unavailable across all providers, please try again later' };
- }
- const enrichment = await enrichCountry(geo.country_code);
- return { ...enrichment, ...compact(geo) };
-};
-
-export const handler = middleware(locationHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/location.js';
diff --git a/api/mail-config.js b/api/mail-config.js
index 71ac95ee7..715f68966 100644
--- a/api/mail-config.js
+++ b/api/mail-config.js
@@ -1,99 +1,3 @@
-import dns from 'dns/promises';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-// Safely query TXT, returning [] on ENODATA/ENOTFOUND
-const safeTxt = (name) => dns.resolveTxt(name).catch(() => []);
-
-// Try common DKIM selectors to detect if DKIM is configured
-const DKIM_SELECTORS = [
- 'default',
- 'google',
- 'selector1',
- 'selector2',
- 'k1',
- 'k2',
- 'k3',
- 's1',
- 's2',
- 'dkim',
- 'mail',
-];
-const findDkim = async (domain) => {
- const checks = DKIM_SELECTORS.map((s) =>
- safeTxt(`${s}._domainkey.${domain}`).then((r) => {
- if (!r.length) return null;
- const txt = r[0].join('');
- // Skip revoked keys (empty p= value)
- if (/p=\s*(;|$)/.test(txt)) return null;
- return { selector: s, record: r[0] };
- }),
- );
- const results = await Promise.all(checks);
- return results.filter(Boolean);
-};
-
-// Detect mail provider from MX exchange hostnames
-const MX_PROVIDERS = [
- [/google(mail)?\.com$/i, 'Google Workspace'],
- [/outlook\.com$|microsoft\.com$/i, 'Microsoft 365'],
- [/protonmail\.ch$|protonme\.ch$/i, 'ProtonMail'],
- [/zoho\.(com|eu|in)$/i, 'Zoho Mail'],
- [/yahoodns\.net$/i, 'Yahoo Mail'],
- [/mimecast\.com$/i, 'Mimecast'],
- [/pphosted\.com$/i, 'Proofpoint'],
- [/messagelabs\.com$/i, 'Broadcom Email Security'],
- [/iphmx\.com$/i, 'Cisco Email Security'],
- [/mailgun\.org$/i, 'Mailgun'],
- [/sendgrid\.net$/i, 'SendGrid'],
- [/fireeyecloud\.com$/i, 'Trellix Email Security'],
- [/barracudanetworks\.com$/i, 'Barracuda'],
-];
-
-const detectProviders = (mxRecords) => {
- const seen = new Set();
- return mxRecords.reduce((out, { exchange }) => {
- const match = MX_PROVIDERS.find(([re]) => re.test(exchange));
- if (match && !seen.has(match[1])) {
- seen.add(match[1]);
- out.push({ provider: match[1], value: exchange });
- }
- return out;
- }, []);
-};
-
-const mailConfigHandler = async (url) => {
- const { hostname: domain } = parseTarget(url);
- try {
- const [mxRecords, rootTxt, dmarcTxt, bimiTxt, dkimResults] = await Promise.all([
- dns.resolveMx(domain),
- safeTxt(domain),
- safeTxt(`_dmarc.${domain}`),
- safeTxt(`default._bimi.${domain}`),
- findDkim(domain),
- ]);
-
- // Collect email-relevant TXT records
- const emailTxt = rootTxt.filter((r) => {
- const s = r.join('').toLowerCase();
- return s.startsWith('v=spf1');
- });
- dmarcTxt.forEach((r) => emailTxt.push(r));
- bimiTxt.forEach((r) => emailTxt.push(r));
- dkimResults.forEach(({ record }) => emailTxt.push(record));
-
- return {
- mxRecords,
- txtRecords: emailTxt,
- mailServices: detectProviders(mxRecords),
- };
- } catch (error) {
- if (error.code === 'ENOTFOUND' || error.code === 'ENODATA') {
- return { skipped: 'No mail server in use on this domain' };
- }
- return { error: `Mail config lookup failed: ${error.message}` };
- }
-};
-
-export const handler = middleware(mailConfigHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/mail-config.js';
diff --git a/api/ports.js b/api/ports.js
index 6345ccb4c..3fa40511d 100644
--- a/api/ports.js
+++ b/api/ports.js
@@ -1,99 +1,3 @@
-import net from 'net';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-// A list of commonly used ports.
-const DEFAULT_PORTS_TO_CHECK = [
- 20, 21, 22, 23, 25, 53, 80, 67, 68, 69, 110, 119, 123, 143, 156, 161, 162, 179, 194, 389, 443,
- 587, 993, 995, 3000, 3306, 3389, 5060, 5900, 8000, 8080, 8888,
-];
-/*
- * Checks if the env PORTS_TO_CHECK is set, if so the string is split via "," to get an array of ports to check.
- * If the env is not set, return the default commonly used ports.
- */
-const PORTS = process.env.PORTS_TO_CHECK
- ? process.env.PORTS_TO_CHECK.split(',')
- : DEFAULT_PORTS_TO_CHECK;
-
-async function checkPort(port, domain) {
- return new Promise((resolve, reject) => {
- const socket = new net.Socket();
-
- socket.setTimeout(1500);
-
- socket.once('connect', () => {
- socket.destroy();
- resolve(port);
- });
-
- socket.once('timeout', () => {
- socket.destroy();
- reject(new Error(`Timeout at port: ${port}`));
- });
-
- socket.once('error', (e) => {
- socket.destroy();
- reject(e);
- });
-
- socket.connect(port, domain);
- });
-}
-
-const portsHandler = async (url, event, context) => {
- const { hostname: domain } = parseTarget(url);
-
- const delay = (ms) => new Promise((res) => setTimeout(res, ms));
- const timeout = delay(9000);
-
- const openPorts = [];
- const failedPorts = [];
-
- const promises = PORTS.map((port) =>
- checkPort(port, domain)
- .then(() => {
- openPorts.push(port);
- return { status: 'fulfilled', port };
- })
- .catch(() => {
- failedPorts.push(port);
- return { status: 'rejected', port };
- }),
- );
-
- let timeoutReached = false;
-
- for (const promise of promises) {
- const result = await Promise.race([
- promise,
- timeout.then(() => ({ status: 'timeout', timeout: true })),
- ]);
- if (result.status === 'timeout') {
- timeoutReached = true;
- if (result.timeout) {
- // Add the ports not checked yet to the failedPorts array
- const checkedPorts = [...openPorts, ...failedPorts];
- const portsNotChecked = PORTS.filter((port) => !checkedPorts.includes(port));
- failedPorts.push(...portsNotChecked);
- }
- break;
- }
- }
-
- if (timeoutReached) {
- return errorResponse('The function timed out before completing.');
- }
-
- // Sort openPorts and failedPorts before returning
- openPorts.sort((a, b) => a - b);
- failedPorts.sort((a, b) => a - b);
-
- return { openPorts, failedPorts };
-};
-
-const errorResponse = (message, statusCode = 444) => {
- return { error: message };
-};
-
-export const handler = middleware(portsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/ports.js';
diff --git a/api/quality.js b/api/quality.js
index f0347f8de..ccbd13106 100644
--- a/api/quality.js
+++ b/api/quality.js
@@ -1,28 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { requireEnv, upstreamError } from './_common/upstream.js';
-
-const qualityHandler = async (url) => {
- const auth = requireEnv('GOOGLE_CLOUD_API_KEY', 'Quality check');
- if (auth.skipped) return auth;
- const endpoint =
- `https://www.googleapis.com/pagespeedonline/v5/runPagespeed?` +
- `url=${encodeURIComponent(url)}&category=PERFORMANCE&category=ACCESSIBILITY` +
- `&category=BEST_PRACTICES&category=SEO&category=PWA&strategy=mobile` +
- `&key=${auth.value}`;
-
- let data;
- try {
- data = (await httpGet(endpoint)).data;
- } catch (error) {
- return upstreamError(error, 'Quality check');
- }
- const result = data.lighthouseResult || data;
- if (!result?.categories || !Object.keys(result.categories).length) {
- return { skipped: 'No quality report available for this URL' };
- }
- return result;
-};
-
-export const handler = middleware(qualityHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/quality.js';
diff --git a/api/rank.js b/api/rank.js
index b5d45d5be..395690522 100644
--- a/api/rank.js
+++ b/api/rank.js
@@ -1,29 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-import { upstreamError } from './_common/upstream.js';
-
-const rankHandler = async (url) => {
- const { hostname: domain } = parseTarget(url);
- const { TRANCO_USERNAME, TRANCO_API_KEY } = process.env;
- const auth = TRANCO_API_KEY
- ? { auth: { username: TRANCO_USERNAME, password: TRANCO_API_KEY } }
- : {};
- try {
- const response = await httpGet(`https://tranco-list.eu/api/ranks/domain/${domain}`, {
- timeout: 5000,
- ...auth,
- });
- if (!response.data?.ranks?.length) {
- return {
- skipped: `${domain} isn't ranked in the top 1 million sites yet`,
- };
- }
- return response.data;
- } catch (error) {
- return upstreamError(error, 'Tranco rank lookup');
- }
-};
-
-export const handler = middleware(rankHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/rank.js';
diff --git a/api/redirects.js b/api/redirects.js
index f6df1ef43..bb3319a3f 100644
--- a/api/redirects.js
+++ b/api/redirects.js
@@ -1,43 +1,3 @@
-import middleware from './_common/middleware.js';
-import { upstreamError } from './_common/upstream.js';
-
-const MAX_REDIRECTS = 12;
-const TIMEOUT_MS = 10000;
-const USER_AGENT = 'Mozilla/5.0 (compatible; WebCheck/2.0; +https://web-check.xyz)';
-
-// Walks the redirect chain manually, recording each Location header as got did
-const redirectsHandler = async (url) => {
- const redirects = [url];
- let current = url;
- try {
- for (let i = 0; i < MAX_REDIRECTS; i++) {
- const response = await fetch(current, {
- redirect: 'manual',
- signal: AbortSignal.timeout(TIMEOUT_MS),
- headers: { 'user-agent': USER_AGENT },
- });
- if (response.status < 300 || response.status >= 400) {
- if (response.status >= 400) {
- const err = new Error(`HTTP ${response.status}`);
- err.response = { status: response.status };
- throw err;
- }
- break;
- }
- const location = response.headers.get('location');
- if (!location) break;
- redirects.push(location);
- current = new URL(location, current).href;
- }
- return { redirects };
- } catch (error) {
- if (error.cause?.code) error.code = error.cause.code;
- if (error.name === 'TimeoutError' || error.name === 'AbortError') {
- error.code = 'ECONNABORTED';
- }
- return upstreamError(error, 'Redirect lookup');
- }
-};
-
-export const handler = middleware(redirectsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/redirects.js';
diff --git a/api/robots-txt.js b/api/robots-txt.js
index 57d776197..8f5405e00 100644
--- a/api/robots-txt.js
+++ b/api/robots-txt.js
@@ -1,33 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-import { upstreamError } from './_common/upstream.js';
-
-// Extract User-agent / Allow / Disallow rules from a robots.txt body
-const parseRobotsTxt = (content) => {
- const rules = [];
- for (let line of content.split('\n')) {
- line = line.trim();
- const ruleMatch = line.match(/^(Allow|Disallow|User-agent):\s*(\S*)$/i);
- if (ruleMatch) rules.push({ lbl: ruleMatch[1], val: ruleMatch[2] });
- }
- return { robots: rules };
-};
-
-const robotsHandler = async (url) => {
- const { protocol, hostname } = parseTarget(url);
- const host = hostname.includes(':') ? `[${hostname}]` : hostname;
- try {
- const res = await httpGet(`${protocol}//${host}/robots.txt`);
- const parsed = parseRobotsTxt(res.data || '');
- return parsed.robots.length ? parsed : { skipped: 'No robots.txt rules found for this host' };
- } catch (error) {
- if (error.response?.status === 404) {
- return { skipped: 'No robots.txt file present on this host' };
- }
- return upstreamError(error, 'robots.txt fetch');
- }
-};
-
-export const handler = middleware(robotsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/robots-txt.js';
diff --git a/api/screenshot.js b/api/screenshot.js
index 725841b35..37b22a74d 100644
--- a/api/screenshot.js
+++ b/api/screenshot.js
@@ -1,96 +1,3 @@
-import puppeteer from 'puppeteer-core';
-import chromium from '@sparticuz/chromium';
-import { randomUUID } from 'crypto';
-import { execFile } from 'child_process';
-import { promises as fs } from 'fs';
-import path from 'path';
-import middleware from './_common/middleware.js';
-import { createLogger } from './_common/logger.js';
-
-const log = createLogger('screenshot');
-
-// Screenshot via the system Chromium binary
-const directChromiumScreenshot = async (url) => {
- const tmpDir = '/tmp';
- const screenshotPath = path.join(tmpDir, `screenshot-${randomUUID()}.png`);
- log.debug(`direct method, saving to ${screenshotPath}`);
-
- return new Promise((resolve, reject) => {
- const chromePath = process.env.CHROME_PATH || '/usr/bin/chromium';
- const args = [
- '--headless',
- '--disable-gpu',
- '--no-sandbox',
- `--screenshot=${screenshotPath}`,
- url,
- ];
- execFile(chromePath, args, async (error) => {
- if (error) return reject(error);
- try {
- const buf = await fs.readFile(screenshotPath);
- await fs
- .unlink(screenshotPath)
- .catch((err) => log.warn(`temp cleanup failed: ${err.message}`));
- resolve(buf.toString('base64'));
- } catch (readError) {
- reject(readError);
- }
- });
- });
-};
-
-// Fallback to puppeteer when the direct Chromium binary call fails
-const puppeteerScreenshot = async (targetUrl) => {
- let browser = null;
- try {
- browser = await puppeteer.launch({
- args: [...chromium.args, '--no-sandbox'],
- defaultViewport: { width: 800, height: 600 },
- executablePath: process.env.CHROME_PATH || (await chromium.executablePath()),
- headless: true,
- acceptInsecureCerts: true,
- ignoreDefaultArgs: ['--disable-extensions'],
- });
- const page = await browser.newPage();
- await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]);
- page.setDefaultNavigationTimeout(8000);
- await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
- await page.evaluate(() => {
- if (!document.querySelector('body')) {
- throw new Error('No body element found on the page');
- }
- });
- const buffer = await page.screenshot();
- return buffer.toString('base64');
- } finally {
- if (browser) await browser.close().catch(() => {});
- }
-};
-
-const screenshotHandler = async (targetUrl) => {
- if (!targetUrl) throw new Error('URL is missing from queryStringParameters');
- try {
- new URL(targetUrl);
- } catch {
- throw new Error('URL provided is invalid');
- }
-
- log.debug(`request received: ${targetUrl}`);
- try {
- return { image: await directChromiumScreenshot(targetUrl) };
- } catch (directError) {
- log.warn(`direct chromium failed, falling back to puppeteer: ${directError.message}`);
- }
- try {
- return { image: await puppeteerScreenshot(targetUrl) };
- } catch (error) {
- if (/ENOENT|Browser was not found|Could not find Chromium/i.test(error.message)) {
- return { skipped: error.message };
- }
- log.error(`puppeteer screenshot failed: ${error.message}`);
- throw error;
- }
-};
-
-export const handler = middleware(screenshotHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/screenshot.js';
diff --git a/api/security-txt.js b/api/security-txt.js
index f773d6a3a..3c0e88bb1 100644
--- a/api/security-txt.js
+++ b/api/security-txt.js
@@ -1,80 +1,3 @@
-import { URL } from 'url';
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-
-// RFC 9116 recommends .well-known first, legacy /security.txt as fallback
-const SECURITY_TXT_PATHS = ['/.well-known/security.txt', '/security.txt'];
-
-const parseResult = (result) => {
- let output = {};
- let counts = {};
- const lines = result.split('\n');
- const regex = /^([^:]+):\s*(.+)$/;
-
- for (const line of lines) {
- if (!line.startsWith('#') && !line.startsWith('-----') && line.trim() !== '') {
- const match = line.match(regex);
- if (match && match.length > 2) {
- let key = match[1].trim();
- const value = match[2].trim();
- if (output.hasOwnProperty(key)) {
- counts[key] = counts[key] ? counts[key] + 1 : 1;
- key += counts[key];
- }
- output[key] = value;
- }
- }
- }
-
- return output;
-};
-
-const isPgpSigned = (result) => {
- if (result.includes('-----BEGIN PGP SIGNED MESSAGE-----')) {
- return true;
- }
- return false;
-};
-
-const securityTxtHandler = async (urlParam) => {
- let url;
- try {
- url = new URL(urlParam.includes('://') ? urlParam : 'https://' + urlParam);
- } catch (error) {
- throw new Error('Invalid URL format');
- }
- url.pathname = '';
-
- for (let path of SECURITY_TXT_PATHS) {
- try {
- const result = await fetchSecurityTxt(url, path);
- if (result && result.toLowerCase().includes(' {
- const url = new URL(path, baseURL);
- const res = await httpGet(url.toString(), {
- headers: { 'User-Agent': 'curl/8.0.0' },
- validateStatus: () => true,
- });
- return res.status === 200 ? res.data : null;
-};
-
-export const handler = middleware(securityTxtHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/security-txt.js';
diff --git a/api/shodan.js b/api/shodan.js
index 06156814f..d87837f28 100644
--- a/api/shodan.js
+++ b/api/shodan.js
@@ -1,22 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-import { requireEnv, upstreamError } from './_common/upstream.js';
-
-// Server-side Shodan lookup so the API key never touches the client
-const shodanHandler = async (url) => {
- const auth = requireEnv('SHODAN_API_KEY', 'Shodan');
- if (auth.skipped) return auth;
- const { hostname } = parseTarget(url);
- try {
- const res = await httpGet(`https://api.shodan.io/shodan/host/${hostname}?key=${auth.value}`, {
- timeout: 8000,
- });
- return res.data;
- } catch (error) {
- return upstreamError(error, 'Shodan lookup');
- }
-};
-
-export const handler = middleware(shodanHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/shodan.js';
diff --git a/api/sitemap.js b/api/sitemap.js
index ef7859ee5..3739692b9 100644
--- a/api/sitemap.js
+++ b/api/sitemap.js
@@ -1,129 +1,3 @@
-import xml2js from 'xml2js';
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { upstreamError } from './_common/upstream.js';
-import { createLogger } from './_common/logger.js';
-
-const log = createLogger('sitemap');
-const TIMEOUT = 6000;
-const MAX_DEPTH = 3;
-const MAX_CHILD_SITEMAPS = 25;
-const MAX_URLS = 5000;
-
-// Browser-ish headers so picky CDNs do not return 406/403 to the default Node UA
-const HEADERS = {
- 'user-agent': 'Mozilla/5.0 (compatible; web-check-bot/1.0; +https://web-check.xyz)',
- accept: 'application/xml, text/xml, application/rss+xml, */*;q=0.1',
-};
-
-// Reduce a target URL to its origin so child paths resolve cleanly
-const toOrigin = (url) => {
- try {
- return new URL(url).origin;
- } catch {
- return url.replace(/\/+$/, '');
- }
-};
-
-// Fetch and parse XML in lenient mode so minor well-formedness errors do not abort
-const fetchSitemap = async (sitemapUrl) => {
- const res = await httpGet(sitemapUrl, { timeout: TIMEOUT, headers: HEADERS });
- return new xml2js.Parser({ strict: false, normalizeTags: true }).parseStringPromise(res.data);
-};
-
-// Pull the first Sitemap: directive out of robots.txt, if any
-const findSitemapInRobots = async (origin) => {
- try {
- const robots = await httpGet(`${origin}/robots.txt`, { timeout: TIMEOUT, headers: HEADERS });
- for (const line of String(robots.data).split('\n')) {
- if (line.toLowerCase().startsWith('sitemap:')) {
- return line.split(/\s+/)[1]?.trim() || null;
- }
- }
- } catch (error) {
- log.debug(`robots.txt fetch failed for ${origin}`, error.message);
- }
- return null;
-};
-
-// Recursively flatten a sitemap-index into its child url sets
-const expandSitemap = async (parsed, depth) => {
- if (!parsed?.sitemapindex?.sitemap || depth >= MAX_DEPTH) return parsed;
- const children = parsed.sitemapindex.sitemap
- .map((s) => s?.loc?.[0])
- .filter(Boolean)
- .slice(0, MAX_CHILD_SITEMAPS);
- const fetched = await Promise.all(
- children.map((loc) =>
- fetchSitemap(loc).catch((error) => {
- log.debug(`child sitemap failed for ${loc}`, error.message);
- return null;
- }),
- ),
- );
- const expanded = await Promise.all(
- fetched.map((child) => (child ? expandSitemap(child, depth + 1) : null)),
- );
- const urls = expanded.flatMap((child) => child?.urlset?.url || []);
- return {
- sitemapindex: parsed.sitemapindex,
- urlset: urls.length ? { url: urls } : undefined,
- sources: children,
- };
-};
-
-// Whether the parsed XML matched one of the canonical sitemap shapes
-const isValidSitemap = (p) => !!(p?.urlset?.url?.length || p?.sitemapindex?.sitemap?.length);
-
-// Keep only the four fields the frontend renders, dropping locale alternates and image/video extras
-const slimUrl = (u) => {
- const out = { loc: u.loc };
- if (u.lastmod) out.lastmod = u.lastmod;
- if (u.changefreq) out.changefreq = u.changefreq;
- if (u.priority) out.priority = u.priority;
- return out;
-};
-
-// Drop bulky XML extensions and cap total entries so the JSON payload stays sane
-const slimResult = (r) => {
- if (!r) return r;
- const out = {};
- if (r.urlset?.url) out.urlset = { url: r.urlset.url.slice(0, MAX_URLS).map(slimUrl) };
- if (r.sitemapindex?.sitemap) {
- out.sitemapindex = {
- sitemap: r.sitemapindex.sitemap.map((s) => ({ loc: s.loc })),
- };
- }
- if (r.sources) out.sources = r.sources;
- return out;
-};
-
-// Try a candidate URL, return parsed result only when it looks like a real sitemap
-const tryFetch = async (target, label) => {
- try {
- const parsed = await fetchSitemap(target);
- if (isValidSitemap(parsed)) return parsed;
- log.debug(`${label} parsed but lacked urlset/sitemapindex (${target})`);
- } catch (error) {
- log.debug(`${label} fetch failed (${target})`, error.message);
- }
- return null;
-};
-
-const sitemapHandler = async (url) => {
- const origin = toOrigin(url);
- let parsed = await tryFetch(`${origin}/sitemap.xml`, 'sitemap.xml');
- if (!parsed) {
- const fromRobots = await findSitemapInRobots(origin);
- if (fromRobots) parsed = await tryFetch(fromRobots, 'robots-listed sitemap');
- }
- if (!parsed) return { skipped: 'No sitemap found for this site' };
- try {
- return slimResult(await expandSitemap(parsed, 0));
- } catch (error) {
- return upstreamError(error, 'Sitemap fetch');
- }
-};
-
-export const handler = middleware(sitemapHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/sitemap.js';
diff --git a/api/social-tags.js b/api/social-tags.js
index 7902f60cf..78506452b 100644
--- a/api/social-tags.js
+++ b/api/social-tags.js
@@ -1,76 +1,3 @@
-import * as cheerio from 'cheerio';
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { upstreamError } from './_common/upstream.js';
-
-const socialTagsHandler = async (url) => {
- let response;
- try {
- response = await httpGet(url);
- } catch (error) {
- return upstreamError(error, 'Social tags fetch');
- }
- try {
- const $ = cheerio.load(response.data);
-
- const metadata = {
- // Basic meta tags
- title: $('head title').text(),
- description: $('meta[name="description"]').attr('content'),
- keywords: $('meta[name="keywords"]').attr('content'),
- canonicalUrl: $('link[rel="canonical"]').attr('href'),
-
- // OpenGraph Protocol
- ogTitle: $('meta[property="og:title"]').attr('content'),
- ogType: $('meta[property="og:type"]').attr('content'),
- ogImage: $('meta[property="og:image"]').attr('content'),
- ogUrl: $('meta[property="og:url"]').attr('content'),
- ogDescription: $('meta[property="og:description"]').attr('content'),
- ogSiteName: $('meta[property="og:site_name"]').attr('content'),
-
- // Twitter Cards
- twitterCard: $('meta[name="twitter:card"]').attr('content'),
- twitterSite: $('meta[name="twitter:site"]').attr('content'),
- twitterCreator: $('meta[name="twitter:creator"]').attr('content'),
- twitterTitle: $('meta[name="twitter:title"]').attr('content'),
- twitterDescription: $('meta[name="twitter:description"]').attr('content'),
- twitterImage: $('meta[name="twitter:image"]').attr('content'),
-
- // Misc
- themeColor: $('meta[name="theme-color"]').attr('content'),
- robots: $('meta[name="robots"]').attr('content'),
- googlebot: $('meta[name="googlebot"]').attr('content'),
- generator: $('meta[name="generator"]').attr('content'),
- viewport: $('meta[name="viewport"]').attr('content'),
- author: $('meta[name="author"]').attr('content'),
- publisher: $('link[rel="publisher"]').attr('href'),
- favicon: $('link[rel="icon"]').attr('href'),
- };
-
- const SOCIAL_FIELDS = [
- 'title',
- 'description',
- 'keywords',
- 'canonicalUrl',
- 'ogTitle',
- 'ogImage',
- 'ogDescription',
- 'ogSiteName',
- 'twitterTitle',
- 'twitterDescription',
- 'twitterImage',
- 'author',
- 'publisher',
- 'themeColor',
- ];
- if (!SOCIAL_FIELDS.some((f) => metadata[f])) {
- return { skipped: 'No social tags found on this page' };
- }
- return metadata;
- } catch (error) {
- return { error: `Failed parsing social tags: ${error.message}` };
- }
-};
-
-export const handler = middleware(socialTagsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/social-tags.js';
diff --git a/api/ssl.js b/api/ssl.js
index fe166d5c1..996c6f0c4 100644
--- a/api/ssl.js
+++ b/api/ssl.js
@@ -1,36 +1,3 @@
-import tls from 'tls';
-import middleware from './_common/middleware.js';
-
-const sslHandler = async (urlString) => {
- const parsedUrl = new URL(urlString);
- const options = {
- host: parsedUrl.hostname,
- port: parsedUrl.port || 443,
- servername: parsedUrl.hostname,
- rejectUnauthorized: false,
- };
-
- return new Promise((resolve, reject) => {
- const socket = tls.connect(options, () => {
- const cert = socket.getPeerCertificate();
- if (!cert || Object.keys(cert).length === 0) {
- reject(new Error('No certificate presented by the server'));
- socket.end();
- return;
- }
- const { raw, issuerCertificate, ...certData } = cert;
- resolve({
- ...certData,
- isValid: socket.authorized,
- authError: socket.authorizationError || null,
- });
- socket.end();
- });
- socket.on('error', (e) => {
- reject(new Error(`SSL connection failed: ${e.message}`));
- });
- });
-};
-
-export const handler = middleware(sslHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/ssl.js';
diff --git a/api/status.js b/api/status.js
index d3e37c9ca..b17a64665 100644
--- a/api/status.js
+++ b/api/status.js
@@ -1,58 +1,3 @@
-import https from 'https';
-import { performance, PerformanceObserver } from 'perf_hooks';
-import middleware from './_common/middleware.js';
-
-const statusHandler = async (url) => {
- if (!url) {
- throw new Error('You must provide a URL query parameter!');
- }
-
- let dnsLookupTime;
- let responseCode;
- let startTime;
-
- const obs = new PerformanceObserver((items) => {
- dnsLookupTime = items.getEntries()[0].duration;
- performance.clearMarks();
- });
-
- obs.observe({ entryTypes: ['measure'] });
-
- performance.mark('A');
-
- try {
- startTime = performance.now();
- const response = await new Promise((resolve, reject) => {
- const req = https.get(url, (res) => {
- let data = '';
- responseCode = res.statusCode;
- res.on('data', (chunk) => {
- data += chunk;
- });
- res.on('end', () => {
- resolve(res);
- });
- });
-
- req.on('error', reject);
- req.end();
- });
-
- if (responseCode < 200 || responseCode >= 400) {
- throw new Error(`Received non-success response code: ${responseCode}`);
- }
-
- performance.mark('B');
- performance.measure('A to B', 'A', 'B');
- let responseTime = performance.now() - startTime;
- obs.disconnect();
-
- return { isUp: true, dnsLookupTime, responseTime, responseCode };
- } catch (error) {
- obs.disconnect();
- throw error;
- }
-};
-
-export const handler = middleware(statusHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/status.js';
diff --git a/api/tech-stack.js b/api/tech-stack.js
index 2d62eff3b..bf04066b3 100644
--- a/api/tech-stack.js
+++ b/api/tech-stack.js
@@ -1,47 +1,3 @@
-import chromium from '@sparticuz/chromium';
-import middleware from './_common/middleware.js';
-
-// Wappalyzer reads CHROMIUM_BIN at module load, so we must resolve
-// the path before importing it (hence the dynamic import in the handler)
-const ensureChromiumBin = async () => {
- if (process.env.CHROMIUM_BIN) return;
- const envPath = process.env.CHROME_PATH || process.env.PUPPETEER_EXECUTABLE_PATH;
- if (envPath) {
- process.env.CHROMIUM_BIN = envPath;
- return;
- }
- // On serverless, puppeteer has no cached binary, use @sparticuz/chromium
- if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.NETLIFY) {
- process.env.CHROMIUM_BIN = await chromium.executablePath();
- // Avoid conflict with @sparticuz/chromium's extraction path at /tmp/chromium
- if (!process.env.CHROMIUM_DATA_DIR) {
- process.env.CHROMIUM_DATA_DIR = '/tmp/chromium-data';
- }
- }
-};
-
-const techStackHandler = async (url) => {
- await ensureChromiumBin();
- const { default: Wappalyzer } = await import('wappalyzer');
- const wappalyzer = new Wappalyzer({});
-
- try {
- await wappalyzer.init();
- const site = await wappalyzer.open(url, {}, { local: {}, session: {} });
- const results = await site.analyze();
- if (!results.technologies || results.technologies.length === 0) {
- throw new Error('Unable to find any technologies for site');
- }
- return results;
- } catch (error) {
- if (/ENOENT|Browser was not found|Could not find Chromium/i.test(error.message)) {
- return { skipped: error.message };
- }
- throw new Error(error.message);
- } finally {
- await wappalyzer.destroy();
- }
-};
-
-export const handler = middleware(techStackHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/tech-stack.js';
diff --git a/api/threats.js b/api/threats.js
index 1f8d72655..fb7d2cfca 100644
--- a/api/threats.js
+++ b/api/threats.js
@@ -1,96 +1,3 @@
-import xml2js from 'xml2js';
-import middleware from './_common/middleware.js';
-import { httpPost } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-import { requireEnv, upstreamError } from './_common/upstream.js';
-
-const safeBrowsing = async (url) => {
- const auth = requireEnv('GOOGLE_CLOUD_API_KEY', 'Google Safe Browsing');
- if (auth.skipped) return auth;
- try {
- const res = await httpPost(
- `https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${auth.value}`,
- {
- threatInfo: {
- threatTypes: [
- 'MALWARE',
- 'SOCIAL_ENGINEERING',
- 'UNWANTED_SOFTWARE',
- 'POTENTIALLY_HARMFUL_APPLICATION',
- 'API_ABUSE',
- ],
- platformTypes: ['ANY_PLATFORM'],
- threatEntryTypes: ['URL'],
- threatEntries: [{ url }],
- },
- },
- );
- return res.data?.matches ? { unsafe: true, details: res.data.matches } : { unsafe: false };
- } catch (error) {
- return upstreamError(error, 'Google Safe Browsing');
- }
-};
-
-const urlHaus = async (url) => {
- const { hostname } = parseTarget(url);
- try {
- const res = await httpPost('https://urlhaus-api.abuse.ch/v1/host/', `host=${hostname}`, {
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
- });
- return res.data;
- } catch (error) {
- return upstreamError(error, 'URLhaus');
- }
-};
-
-const phishTank = async (url) => {
- try {
- const encoded = Buffer.from(url).toString('base64');
- const res = await httpPost(`https://checkurl.phishtank.com/checkurl/?url=${encoded}`, null, {
- headers: { 'User-Agent': 'phishtank/web-check' },
- timeout: 3000,
- });
- const parsed = await xml2js.parseStringPromise(res.data, { explicitArray: false });
- return parsed.response.results;
- } catch (error) {
- return upstreamError(error, 'PhishTank');
- }
-};
-
-const cloudmersive = async (url) => {
- const auth = requireEnv('CLOUDMERSIVE_API_KEY', 'Cloudmersive');
- if (auth.skipped) return auth;
- try {
- const res = await httpPost(
- 'https://api.cloudmersive.com/virus/scan/website',
- `Url=${encodeURIComponent(url)}`,
- {
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- Apikey: auth.value,
- },
- },
- );
- return res.data;
- } catch (error) {
- return upstreamError(error, 'Cloudmersive');
- }
-};
-
-// Aggregate four threat-feed lookups; skip the card if every source failed
-const threatsHandler = async (url) => {
- const sources = await Promise.all([
- safeBrowsing(url),
- urlHaus(url),
- phishTank(url),
- cloudmersive(url),
- ]);
- const [safe, haus, phish, cloud] = sources;
- if (sources.every((s) => s?.error || s?.skipped)) {
- return { skipped: 'No threat sources returned data for this host' };
- }
- return { safeBrowsing: safe, urlHaus: haus, phishTank: phish, cloudmersive: cloud };
-};
-
-export const handler = middleware(threatsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/threats.js';
diff --git a/api/tls-connection.js b/api/tls-connection.js
index 329b09c62..748ff8be2 100644
--- a/api/tls-connection.js
+++ b/api/tls-connection.js
@@ -1,84 +1,3 @@
-import tls from 'tls';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-const HANDSHAKE_TIMEOUT = 4000;
-
-const isIp = (h) => /^[\d.]+$/.test(h) || h.includes(':');
-
-// Open one TLS handshake to the host and capture what was negotiated
-const handshake = ({ hostname, port }) =>
- new Promise((resolve, reject) => {
- let ocspStapled = false;
- const socket = tls.connect({
- host: hostname,
- port: port ? Number(port) : 443,
- ...(isIp(hostname) ? {} : { servername: hostname }),
- ALPNProtocols: ['h2', 'http/1.1'],
- rejectUnauthorized: false,
- requestOCSP: true,
- });
- socket.on('OCSPResponse', (res) => {
- ocspStapled = res?.length > 0;
- });
-
- let settled = false;
- const finish = (fn) => (arg) => {
- if (settled) return;
- settled = true;
- fn(arg);
- };
- socket.setTimeout(HANDSHAKE_TIMEOUT);
- socket.once(
- 'secureConnect',
- finish(() => {
- const cipher = socket.getCipher();
- const protocol = socket.getProtocol();
- const ephemeral =
- typeof socket.getEphemeralKeyInfo === 'function' ? socket.getEphemeralKeyInfo() : null;
- const result = {
- protocol,
- cipher: cipher && {
- name: cipher.name,
- standardName: cipher.standardName,
- version: cipher.version,
- },
- alpnProtocol: socket.alpnProtocol || null,
- sessionResumption: !!socket.getSession(),
- forwardSecrecy: protocol === 'TLSv1.3' || (!!cipher && /^(ECDHE|DHE)/.test(cipher.name)),
- authorized: socket.authorized,
- authError: socket.authorizationError ? String(socket.authorizationError) : null,
- ephemeralKey: ephemeral && {
- type: ephemeral.type || null,
- name: ephemeral.name || null,
- size: ephemeral.size || null,
- },
- ocspStapled,
- };
- socket.end();
- resolve(result);
- }),
- );
- socket.once(
- 'timeout',
- finish(() => {
- socket.destroy();
- reject(new Error('TLS handshake timed-out'));
- }),
- );
- socket.once(
- 'error',
- finish((err) => {
- socket.destroy();
- reject(err);
- }),
- );
- });
-
-const tlsConnectionHandler = async (url) => {
- const { hostname, port } = parseTarget(url);
- return handshake({ hostname, port });
-};
-
-export const handler = middleware(tlsConnectionHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/tls-connection.js';
diff --git a/api/tls-labs.js b/api/tls-labs.js
index 900a3a7d7..c4596e17f 100644
--- a/api/tls-labs.js
+++ b/api/tls-labs.js
@@ -1,32 +1,3 @@
-import middleware from './_common/middleware.js';
-import { httpGet } from './_common/http.js';
-import { parseTarget } from './_common/parse-target.js';
-import { upstreamError } from './_common/upstream.js';
-
-const SSL_LABS = 'https://api.ssllabs.com/api/v3/analyze';
-
-// Pull a cached SSL Labs report; skip if no fresh cache available
-const tlsLabsHandler = async (url) => {
- const { hostname } = parseTarget(url);
- try {
- const res = await httpGet(SSL_LABS, {
- params: { host: hostname, fromCache: 'on', maxAge: 24, all: 'done' },
- timeout: 8000,
- headers: { 'User-Agent': 'web-check (https://web-check.xyz)' },
- });
- const data = res.data;
- if (!data || data.status !== 'READY' || !data.endpoints?.length) {
- return {
- skipped:
- 'No cached SSL Labs report for this host. ' +
- 'Run a fresh scan at https://www.ssllabs.com/ssltest/',
- };
- }
- return data;
- } catch (error) {
- return upstreamError(error, 'SSL Labs lookup');
- }
-};
-
-export const handler = middleware(tlsLabsHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/tls-labs.js';
diff --git a/api/trace-route.js b/api/trace-route.js
index c181bdb91..557f36ff4 100644
--- a/api/trace-route.js
+++ b/api/trace-route.js
@@ -1,58 +1,3 @@
-import { execFile } from 'child_process';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-const LOCAL_TIMEOUT = 8000;
-
-// Parse traceroute -n output into [{ip, time}] entries, skipping unanswered hops
-const parseHops = (stdout) => {
- const hops = [];
- for (const line of stdout.split('\n')) {
- const m = line.match(/^\s*\d+\s+([\d.]+|\S*::\S*)\s+([\d.]+)\s*ms/);
- if (m) hops.push({ ip: m[1], time: Number(m[2]) });
- }
- return hops;
-};
-
-// Run the system traceroute binary via execFile (no shell, no injection)
-const runTraceroute = (host) =>
- new Promise((resolve, reject) => {
- execFile(
- 'traceroute',
- ['-q', '1', '-n', '-w', '2', host],
- { timeout: LOCAL_TIMEOUT },
- (err, stdout) => (err ? reject(err) : resolve(parseHops(stdout))),
- );
- });
-
-const isMissingBinary = (err) =>
- err?.code === 'ENOENT' || /command not found|not installed/i.test(err?.message || '');
-
-const traceRouteHandler = async (url) => {
- const start = Date.now();
- const { hostname } = parseTarget(url);
- let hops;
- try {
- hops = await runTraceroute(hostname);
- } catch (err) {
- if (isMissingBinary(err)) {
- return {
- skipped:
- 'Traceroute is not installed in this environment. ' +
- 'Install via your package manager, or run web-check via Docker.',
- };
- }
- return { error: `Traceroute failed: ${err.message}` };
- }
- if (!hops.length) {
- return { skipped: 'Traceroute returned no answered hops for this host' };
- }
- return {
- message: 'Traceroute completed!',
- result: hops.map(({ ip, time }) => ({ [ip]: [time] })),
- timeTaken: Date.now() - start,
- };
-};
-
-export const handler = middleware(traceRouteHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/trace-route.js';
diff --git a/api/txt-records.js b/api/txt-records.js
index 76303605a..564a51d86 100644
--- a/api/txt-records.js
+++ b/api/txt-records.js
@@ -1,22 +1,3 @@
-import dns from 'dns/promises';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-
-const txtRecordHandler = async (url) => {
- const { hostname } = parseTarget(url);
- const txtRecords = await dns.resolveTxt(hostname);
- // Join chunks (DNS splits long records at 255 bytes), then key=value
- const result = {};
- for (const chunks of txtRecords) {
- const full = chunks.join('');
- const eq = full.indexOf('=');
- let key = eq > 0 ? full.slice(0, eq) : full;
- const val = eq > 0 ? full.slice(eq + 1) : '';
- while (key in result) key += '_';
- result[key] = val;
- }
- return result;
-};
-
-export const handler = middleware(txtRecordHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/txt-records.js';
diff --git a/api/whois.js b/api/whois.js
index 9a3e0ec13..977476f81 100644
--- a/api/whois.js
+++ b/api/whois.js
@@ -1,135 +1,3 @@
-import net from 'net';
-import psl from 'psl';
-import { whoisDomain } from 'whoiser';
-import middleware from './_common/middleware.js';
-import { parseTarget } from './_common/parse-target.js';
-import { createLogger } from './_common/logger.js';
-
-const log = createLogger('whois');
-const TIMEOUT = 8000;
-
-// Walk every WHOIS/RDAP source, return the first non-empty value across the given keys
-const pick = (results, ...keys) => {
- for (const src of Object.values(results)) {
- for (const key of keys) {
- const v = src?.[key];
- if (v === undefined || v === null) continue;
- if (typeof v === 'string' && !v.trim()) continue;
- if (Array.isArray(v) && !v.length) continue;
- return v;
- }
- }
- return undefined;
-};
-
-// Lower-case + dedupe nameservers, drop empty entries
-const cleanNs = (ns) => {
- if (!Array.isArray(ns)) return undefined;
- const out = [...new Set(ns.map((n) => String(n).trim().toLowerCase()).filter(Boolean))];
- return out.length ? out : undefined;
-};
-
-// Convert a date string to ISO 8601 when parseable, otherwise return the raw value
-const toIso = (raw) => {
- if (!raw || typeof raw !== 'string') return raw;
- const trimmed = raw.trim().replace(/\s*#.*$/, '');
- const t = Date.parse(trimmed);
- if (!Number.isNaN(t)) return new Date(t).toISOString();
- const m = trimmed.match(/^(\d{4})(\d{2})(\d{2})$/);
- if (m) return new Date(`${m[1]}-${m[2]}-${m[3]}T00:00:00Z`).toISOString();
- return raw;
-};
-
-// Reduce a hostname to its registrable domain so registry WHOIS lookups succeed
-const baseDomain = (host) => psl.parse(host)?.domain || host;
-
-// Pull the formatted-name value out of an RDAP entity vCard
-const vcardFn = (vcard) => {
- if (!Array.isArray(vcard?.[1])) return undefined;
- const fn = vcard[1].find((f) => Array.isArray(f) && f[0] === 'fn');
- return fn?.[3] || undefined;
-};
-
-// Map an RDAP response into the same field names whoiser exposes, so pick() works uniformly
-const rdapToWhoiserShape = (data) => {
- if (!data || data.errorCode || data.objectClassName === 'error') return null;
- const events = data.events || [];
- const evt = (a) => events.find((e) => e.eventAction === a)?.eventDate;
- const registrar = (data.entities || []).find((e) => (e.roles || []).includes('registrar'));
- const ianaId = registrar?.publicIds?.find((p) => /iana/i.test(p.type))?.identifier;
- const registrarUrlEntry = registrar?.links?.find((l) => l.rel === 'about' || l.rel === 'related');
- return {
- 'Domain Name': data.ldhName,
- 'Created Date': evt('registration'),
- 'Updated Date': evt('last changed') || evt('last update of RDAP database'),
- 'Expiry Date': evt('expiration'),
- 'Registry Domain ID': data.handle,
- Registrar: vcardFn(registrar?.vcardArray),
- 'Registrar IANA ID': ianaId,
- 'Registrar URL': registrarUrlEntry?.href,
- 'Domain Status': data.status,
- 'Name Server': (data.nameservers || []).map((n) => n.ldhName).filter(Boolean),
- DNSSEC: data.secureDNS?.delegationSigned ? 'signed' : 'unsigned',
- };
-};
-
-// Last-resort lookup via rdap.org (a meta-resolver that bootstraps the right RDAP server)
-const fetchRdapFallback = async (domain) => {
- try {
- const res = await fetch(`https://rdap.org/domain/${encodeURIComponent(domain)}`, {
- signal: AbortSignal.timeout(TIMEOUT),
- });
- if (!res.ok) return null;
- return rdapToWhoiserShape(await res.json());
- } catch {
- return null;
- }
-};
-
-// Whether a parsed result set has anything worth returning to the frontend
-const hasUsefulData = (r) =>
- r &&
- (pick(r, 'Created Date', 'Creation Date') ||
- pick(r, 'Updated Date') ||
- pick(r, 'Expiry Date', 'Registry Expiry Date') ||
- pick(r, 'Registrar') ||
- cleanNs(pick(r, 'Name Server')));
-
-// Resolve domain registration data via whoiser, with rdap.org as a fallback for TLD gaps
-const whoisHandler = async (url) => {
- const { hostname } = parseTarget(url);
- if (net.isIP(hostname)) {
- return { skipped: 'WHOIS lookups apply to domains, not IP addresses' };
- }
- const target = baseDomain(hostname);
- let results = {};
- try {
- results = await whoisDomain(target, { follow: 2, timeout: TIMEOUT });
- } catch (error) {
- log.debug(`whoisDomain failed for ${target}: ${error.message}`);
- }
- if (!hasUsefulData(results)) {
- const rdap = await fetchRdapFallback(target);
- if (rdap) results = { ...results, 'rdap.org': rdap };
- }
- if (!hasUsefulData(results)) {
- return { skipped: 'No WHOIS data available for this domain' };
- }
- return {
- domain: pick(results, 'Domain Name') || target,
- registrar: pick(results, 'Registrar'),
- registrarUrl: pick(results, 'Registrar URL'),
- registrarIanaId: pick(results, 'Registrar IANA ID'),
- registrarWhoisServer: pick(results, 'Registrar WHOIS Server'),
- registryDomainId: pick(results, 'Registry Domain ID'),
- created: toIso(pick(results, 'Created Date', 'Creation Date')),
- updated: toIso(pick(results, 'Updated Date')),
- expires: toIso(pick(results, 'Expiry Date', 'Registry Expiry Date', 'Expiration Date')),
- nameservers: cleanNs(pick(results, 'Name Server')),
- status: pick(results, 'Domain Status'),
- dnssec: pick(results, 'DNSSEC'),
- };
-};
-
-export const handler = middleware(whoisHandler);
-export default handler;
+// Generated by scripts/sync-vercel-api.js, do not edit by hand
+// Source of truth lives in packages/api/handlers
+export { default, handler } from '../packages/api/handlers/whois.js';
diff --git a/astro.config.mjs b/astro.config.mjs
deleted file mode 100644
index a5d02e47c..000000000
--- a/astro.config.mjs
+++ /dev/null
@@ -1,78 +0,0 @@
-import { defineConfig } from 'astro/config';
-
-// Integrations
-import svelte from '@astrojs/svelte';
-import react from '@astrojs/react';
-import partytown from '@astrojs/partytown';
-import sitemap from '@astrojs/sitemap';
-
-// Adapters
-import vercelAdapter from '@astrojs/vercel';
-import netlifyAdapter from '@astrojs/netlify';
-import nodeAdapter from '@astrojs/node';
-import cloudflareAdapter from '@astrojs/cloudflare';
-
-// Helper function to unwrap both Vite and Node environment variables
-const unwrapEnvVar = (varName, fallbackValue) => {
- const classicEnvVar = process?.env && process.env[varName];
- const viteEnvVar = import.meta.env[varName];
- return classicEnvVar || viteEnvVar || fallbackValue;
-};
-
-// Determine the deploy target (vercel, netlify, cloudflare, node)
-const deployTarget = unwrapEnvVar('PLATFORM', 'node').toLowerCase();
-
-// Determine the output mode (static or server). Mixed prerender supported in static mode
-const output = unwrapEnvVar('OUTPUT', 'static');
-
-// The FQDN of where the site is hosted (used for sitemaps & canonical URLs)
-const site = unwrapEnvVar('SITE_URL', 'https://web-check.xyz');
-
-// The base URL of the site (if serving from a subdirectory)
-const base = unwrapEnvVar('BASE_URL', '/');
-
-// Should run the app in boss-mode (requires extra configuration)
-const isBossServer = unwrapEnvVar('BOSS_SERVER', false);
-
-// Initialize Astro integrations
-const integrations = [svelte(), react(), partytown(), sitemap()];
-
-// Set the appropriate adapter, based on the deploy target
-function getAdapter(target) {
- switch (target) {
- case 'vercel':
- return vercelAdapter();
- case 'netlify':
- return netlifyAdapter();
- case 'cloudflare':
- return cloudflareAdapter();
- case 'node':
- return nodeAdapter({ mode: 'middleware' });
- default:
- throw new Error(`Unsupported deploy target: ${target}`);
- }
-}
-const adapter = getAdapter(deployTarget);
-
-// Print build information to console
-console.log(
- `\n\x1b[1m\x1b[35m Preparing to start build of Web Check.... \x1b[0m\n`,
- `\x1b[35m\x1b[2mCompiling for "${deployTarget}" using "${output}" mode, ` +
- `to deploy to "${site}" at "${base}"\x1b[0m\n`,
- `\x1b[2m\x1b[36m🛟 For documentation and support, visit the GitHub repo: ` +
- `https://github.com/lissy93/web-check \n`,
- `💖 Found Web-Check useful? Consider sponsoring us on GitHub ` +
- `to help fund maintenance & development.\x1b[0m\n`,
-);
-
-const redirects = {
- '/about': '/check/about',
-};
-
-// Skip the marketing homepage for self-hosted users
-if (!isBossServer && isBossServer !== true) {
- redirects['/'] = '/check';
-}
-
-// Export Astro configuration
-export default defineConfig({ output, base, integrations, site, adapter, redirects });
diff --git a/netlify.toml b/netlify.toml
index 136485ec2..0c9717d29 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,41 +1,27 @@
-# Build settings and site core config
[build]
base = "/"
command = "yarn build"
- publish = "dist"
- functions = "api"
+ publish = "packages/site/dist"
+ functions = "packages/api/handlers"
-# Environmental variables and optional secrets
[build.environment]
PLATFORM = "netlify"
- PUBLIC_API_ENDPOINT = "/.netlify/functions"
- # Build configuration env vars (uncomment if you want to conigure these)
- # CI="false" # Set CI to false, to prevent warnings from exiting the build
- # CHROME_PATH='/usr/bin/chromium' # Path to Chromium binary
- # NODE_VERSION = "16.16.0" # Set the version of Node.js to use
- # Optional secrets and API keys (uncomment if you want to add these)
- # GOOGLE_CLOUD_API_KEY='' # Google Cloud API key, for running Lighthouse scans
- # BUILT_WITH_API_KEY='' # BuiltWith API key, for detecting site features
- # REACT_APP_SHODAN_API_KEY='' # Shodan API key, for using Shodan scan API
- # REACT_APP_WHO_API_KEY='' # WhoAPI key, for iniiating client-side whois lookup
-
-# Redirect the /api/* path to the lambda functions
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
- status = 301
- force = true
+ status = 200
+
+[[redirects]]
+ from = "/check/*"
+ to = "/check/index.html"
+ status = 200
-# Plugins
[[plugins]]
-package = "netlify-plugin-chromium"
+ package = "netlify-plugin-chromium"
[plugins.inputs]
- packageManager = "yarn"
+ packageManager = "yarn"
-# Set any security headers here
[[headers]]
for = "/*"
[headers.values]
- # Uncomment to enable Netlify user control. Requires premium plan.
- # Basic-Auth = "someuser:somepassword anotheruser:anotherpassword"
diff --git a/package.json b/package.json
index 541838a44..037e93fcc 100644
--- a/package.json
+++ b/package.json
@@ -2,60 +2,38 @@
"name": "web-check",
"type": "module",
"version": "2.1.0",
+ "private": true,
"homepage": "https://web-check.xyz",
"engines": {
"node": ">=22"
},
+ "workspaces": [
+ "packages/*"
+ ],
"scripts": {
- "start": "node server",
- "build": "astro check && astro build",
+ "start": "yarn workspace @web-check/api start",
+ "prebuild": "node scripts/sync-vercel-api.js",
+ "build": "yarn workspace @web-check/app build && yarn workspace @web-check/site build",
+ "build:app": "yarn workspace @web-check/app build",
+ "build:site": "yarn workspace @web-check/site build",
+ "build:docker": "yarn build:app",
+ "dev:api": "yarn workspace @web-check/api dev",
+ "dev:site": "yarn workspace @web-check/site dev",
"dev:vercel": "PLATFORM='vercel' npx vercel dev",
"dev:netlify": "PLATFORM='netlify' npx netlify dev",
- "dev:api": "DISABLE_GUI='true' PORT='3001' nodemon server",
- "dev:astro": "PUBLIC_API_ENDPOINT=http://localhost:3001/api astro dev",
- "dev": "concurrently -c magenta,cyan -n backend,frontend 'yarn dev:api' 'yarn dev:astro'",
- "typecheck": "astro check",
+ "dev": "concurrently -c magenta,cyan -n backend,frontend 'yarn dev:api' 'yarn dev:site'",
+ "typecheck": "yarn workspace @web-check/site typecheck",
"lint": "eslint --config .config/eslint.config.js .",
"format:check": "prettier --check --ignore-unknown '!yarn.lock' '!**/*.md' .",
"format:fix": "prettier --write --ignore-unknown '!yarn.lock' '!**/*.md' ."
},
- "dependencies": {
- "@astrojs/check": "^0.9.9",
- "@astrojs/react": "^5.0.4",
- "@emotion/react": "^11.14.0",
- "@emotion/styled": "^11.14.1",
- "@fortawesome/fontawesome-svg-core": "^7.2.0",
- "@fortawesome/free-brands-svg-icons": "^7.2.0",
- "@fortawesome/free-regular-svg-icons": "^7.2.0",
- "@fortawesome/free-solid-svg-icons": "^7.2.0",
- "@fortawesome/svelte-fontawesome": "^0.2.4",
- "@sparticuz/chromium": "^148.0.0",
- "@types/react": "^19.2.14",
- "@types/react-dom": "^19.2.3",
- "astro": "^6.2.2",
- "cheerio": "^1.2.0",
- "chromium": "^3.0.3",
- "cors": "^2.8.6",
- "dotenv": "^17.4.2",
- "express": "^5.2.1",
- "express-rate-limit": "^8.5.0",
- "framer-motion": "^12.38.0",
- "prop-types": "^15.8.1",
- "psl": "^1.15.0",
- "puppeteer": "^24.42.0",
- "puppeteer-core": "^24.42.0",
- "react": "^19.2.5",
- "react-dom": "^19.2.5",
- "react-masonry-css": "^1.0.16",
- "react-router-dom": "^7.14.2",
- "react-simple-maps": "^3.0.0",
- "react-toastify": "^11.1.0",
- "recharts": "^3.8.1",
- "svelte": "^5.55.5",
- "typescript": "^6.0.3",
- "wappalyzer": "^6.10.66",
- "whoiser": "^2.0.0-beta.10",
- "xml2js": "^0.6.2"
+ "devDependencies": {
+ "@typescript-eslint/parser": "^8.59.2",
+ "concurrently": "^9.2.1",
+ "eslint": "^10.3.0",
+ "eslint-plugin-astro": "^1.7.0",
+ "prettier": "^3.8.3",
+ "prettier-plugin-astro": "^0.14.1"
},
"resolutions": {
"tar-fs": "^2.1.4",
@@ -69,24 +47,6 @@
"uuid": "^14.0.0",
"yaml": "^2.8.3"
},
- "devDependencies": {
- "@astrojs/cloudflare": "^13.3.1",
- "@astrojs/netlify": "^7.0.8",
- "@astrojs/node": "^10.0.6",
- "@astrojs/partytown": "^2.1.7",
- "@astrojs/sitemap": "^3.7.2",
- "@astrojs/svelte": "^8.1.0",
- "@astrojs/ts-plugin": "^1.10.7",
- "@astrojs/vercel": "^10.0.6",
- "@typescript-eslint/parser": "^8.59.2",
- "concurrently": "^9.2.1",
- "eslint": "^10.3.0",
- "eslint-plugin-astro": "^1.7.0",
- "nodemon": "^3.1.14",
- "prettier": "^3.8.3",
- "prettier-plugin-astro": "^0.14.1",
- "sass": "^1.99.0"
- },
"prettier": {
"printWidth": 100,
"semi": true,
diff --git a/api/_common/http.js b/packages/api/handlers/_common/http.js
similarity index 100%
rename from api/_common/http.js
rename to packages/api/handlers/_common/http.js
diff --git a/api/_common/logger.js b/packages/api/handlers/_common/logger.js
similarity index 100%
rename from api/_common/logger.js
rename to packages/api/handlers/_common/logger.js
diff --git a/api/_common/middleware.js b/packages/api/handlers/_common/middleware.js
similarity index 96%
rename from api/_common/middleware.js
rename to packages/api/handlers/_common/middleware.js
index e96cb30d5..44dd42da6 100644
--- a/api/_common/middleware.js
+++ b/packages/api/handlers/_common/middleware.js
@@ -116,6 +116,8 @@ const commonMiddleware = (handler) => {
return nativeMode ? vercelHandler : netlifyHandler;
};
+// Netlify bundles handlers as CJS, esbuild's interop loses the default export
+// unless module.exports is the function itself. Do not remove the CJS branch
if (PLATFORM === 'NETLIFY') {
module.exports = commonMiddleware;
}
diff --git a/api/_common/parse-target.js b/packages/api/handlers/_common/parse-target.js
similarity index 100%
rename from api/_common/parse-target.js
rename to packages/api/handlers/_common/parse-target.js
diff --git a/api/_common/upstream.js b/packages/api/handlers/_common/upstream.js
similarity index 100%
rename from api/_common/upstream.js
rename to packages/api/handlers/_common/upstream.js
diff --git a/packages/api/handlers/archives.js b/packages/api/handlers/archives.js
new file mode 100644
index 000000000..4818c2a2a
--- /dev/null
+++ b/packages/api/handlers/archives.js
@@ -0,0 +1,84 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+
+const convertTimestampToDate = (timestamp) => {
+ const [year, month, day, hour, minute, second] = [
+ timestamp.slice(0, 4),
+ timestamp.slice(4, 6) - 1,
+ timestamp.slice(6, 8),
+ timestamp.slice(8, 10),
+ timestamp.slice(10, 12),
+ timestamp.slice(12, 14),
+ ].map((num) => parseInt(num, 10));
+
+ return new Date(year, month, day, hour, minute, second);
+};
+
+const countPageChanges = (results) => {
+ let prevDigest = null;
+ return results.reduce((acc, curr) => {
+ if (curr[2] !== prevDigest) {
+ prevDigest = curr[2];
+ return acc + 1;
+ }
+ return acc;
+ }, -1);
+};
+
+const getAveragePageSize = (scans) => {
+ const totalSize = scans.map((scan) => parseInt(scan[3], 10)).reduce((sum, size) => sum + size, 0);
+ return Math.round(totalSize / scans.length);
+};
+
+const getScanFrequency = (firstScan, lastScan, totalScans, changeCount) => {
+ const formatToTwoDecimal = (num) => parseFloat(num.toFixed(2));
+
+ const dayFactor = (lastScan - firstScan) / (1000 * 60 * 60 * 24);
+ const daysBetweenScans = formatToTwoDecimal(dayFactor / totalScans);
+ const daysBetweenChanges = formatToTwoDecimal(dayFactor / changeCount);
+ const scansPerDay = formatToTwoDecimal((totalScans - 1) / dayFactor);
+ const changesPerDay = formatToTwoDecimal(changeCount / dayFactor);
+ return {
+ daysBetweenScans,
+ daysBetweenChanges,
+ scansPerDay,
+ changesPerDay,
+ };
+};
+
+const wayBackHandler = async (url) => {
+ const cdxUrl = `https://web.archive.org/cdx/search/cdx?url=${url}&output=json&fl=timestamp,statuscode,digest,length,offset`;
+
+ try {
+ const { data } = await httpGet(cdxUrl);
+
+ // Check there's data
+ if (!data || !Array.isArray(data) || data.length <= 1) {
+ return { skipped: 'Site has never before been archived via the Wayback Machine' };
+ }
+
+ // Remove the header row
+ data.shift();
+
+ // Process and return the results
+ const firstScan = convertTimestampToDate(data[0][0]);
+ const lastScan = convertTimestampToDate(data[data.length - 1][0]);
+ const totalScans = data.length;
+ const changeCount = countPageChanges(data);
+ return {
+ firstScan,
+ lastScan,
+ totalScans,
+ changeCount,
+ averagePageSize: getAveragePageSize(data),
+ scanFrequency: getScanFrequency(firstScan, lastScan, totalScans, changeCount),
+ scans: data,
+ scanUrl: url,
+ };
+ } catch (err) {
+ return { error: `Error fetching Wayback data: ${err.message}` };
+ }
+};
+
+export const handler = middleware(wayBackHandler);
+export default handler;
diff --git a/packages/api/handlers/block-lists.js b/packages/api/handlers/block-lists.js
new file mode 100644
index 000000000..f34c0250b
--- /dev/null
+++ b/packages/api/handlers/block-lists.js
@@ -0,0 +1,62 @@
+import dns from 'dns';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+const DNS_SERVERS = [
+ { name: 'AdGuard', ip: '176.103.130.130' },
+ { name: 'AdGuard Family', ip: '176.103.130.132' },
+ { name: 'CleanBrowsing Adult', ip: '185.228.168.10' },
+ { name: 'CleanBrowsing Family', ip: '185.228.168.168' },
+ { name: 'CleanBrowsing Security', ip: '185.228.168.9' },
+ { name: 'CloudFlare', ip: '1.1.1.1' },
+ { name: 'CloudFlare Family', ip: '1.1.1.3' },
+ { name: 'Comodo Secure', ip: '8.26.56.26' },
+ { name: 'Google DNS', ip: '8.8.8.8' },
+ { name: 'OpenDNS', ip: '208.67.222.222' },
+ { name: 'OpenDNS Family', ip: '208.67.222.123' },
+ { name: 'Quad9', ip: '9.9.9.9' },
+];
+
+// Sink IPs used by blocking DNS servers
+const SINK_IPS = new Set(['0.0.0.0', '127.0.0.1', '::1', '::', '0:0:0:0:0:0:0:0']);
+
+// Resolve a domain via a specific DNS server
+const queryServer = (domain, serverIp) =>
+ new Promise((resolve) => {
+ const resolver = new dns.Resolver({ timeout: 3000, tries: 1 });
+ resolver.setServers([serverIp]);
+ resolver.resolve4(domain, (err, addrs) => {
+ if (err) return resolve({ err: err.code });
+ resolve({ addrs });
+ });
+ });
+
+// A domain is blocked if the resolver returns a sink IP or refuses
+// to resolve a domain that a neutral resolver can resolve
+const isBlocked = (result, refResolved) => {
+ if (!refResolved) return false;
+ if (result.err === 'NXDOMAIN' || result.err === 'SERVFAIL') return true;
+ if (!result.addrs) return false;
+ return result.addrs.every((ip) => SINK_IPS.has(ip));
+};
+
+const blockListHandler = async (url) => {
+ const { hostname: domain } = parseTarget(url);
+ const ref = await queryServer(domain, '8.8.8.8');
+ const refResolved = !!ref.addrs?.length;
+
+ const results = await Promise.all(
+ DNS_SERVERS.map(async ({ name, ip }) => {
+ const result = await queryServer(domain, ip);
+ return {
+ server: name,
+ serverIp: ip,
+ isBlocked: isBlocked(result, refResolved),
+ };
+ }),
+ );
+ return { blocklists: results };
+};
+
+export const handler = middleware(blockListHandler);
+export default handler;
diff --git a/packages/api/handlers/carbon.js b/packages/api/handlers/carbon.js
new file mode 100644
index 000000000..1e8e01665
--- /dev/null
+++ b/packages/api/handlers/carbon.js
@@ -0,0 +1,79 @@
+import middleware from './_common/middleware.js';
+import { createLogger } from './_common/logger.js';
+
+const log = createLogger('carbon');
+
+const TIMEOUT = 8000;
+const MAX_BYTES = 10 * 1024 * 1024;
+const USER_AGENT = 'Mozilla/5.0 (compatible; WebCheck/2.0; +https://web-check.xyz)';
+
+// Sustainable Web Design model v3 constants, matches websitecarbon.com formula
+const KWH_PER_GB = 0.81;
+const FIRST_VISIT = 0.25;
+const RETURN_VISIT = 0.75;
+const RETURN_DATA_PCT = 0.02;
+const GRID_INTENSITY = 442;
+const RENEWABLE_INTENSITY = 50;
+const LITRES_PER_GRAM = 0.5562;
+
+// Stream the response, cap at MAX_BYTES so huge pages can't blow memory or time
+const fetchByteCount = async (url) => {
+ const r = await fetch(url, {
+ signal: AbortSignal.timeout(TIMEOUT),
+ redirect: 'follow',
+ headers: { 'user-agent': USER_AGENT, accept: 'text/html,*/*;q=0.1' },
+ });
+ if (!r.ok) throw new Error(`status ${r.status}`);
+ if (!r.body) return 0;
+ const reader = r.body.getReader();
+ let total = 0;
+ while (total < MAX_BYTES) {
+ const { value, done } = await reader.read();
+ if (done) break;
+ total += value.length;
+ }
+ reader.cancel().catch(() => {});
+ return total;
+};
+
+// SWD-based stats matching websitecarbon /data response shape
+const computeCarbon = (bytes) => {
+ const adjustedBytes = bytes * (FIRST_VISIT + RETURN_VISIT * RETURN_DATA_PCT);
+ const energy = (adjustedBytes / 1073741824) * KWH_PER_GB;
+ const gridGrams = energy * GRID_INTENSITY;
+ const renewableGrams = energy * RENEWABLE_INTENSITY;
+ return {
+ adjustedBytes,
+ energy,
+ co2: {
+ grid: { grams: gridGrams, litres: gridGrams * LITRES_PER_GRAM },
+ renewable: {
+ grams: renewableGrams,
+ litres: renewableGrams * LITRES_PER_GRAM,
+ },
+ },
+ };
+};
+
+// Fetch site, count bytes, compute SWD carbon stats locally, no third-party API
+const carbonHandler = async (url) => {
+ let bytes;
+ try {
+ bytes = await fetchByteCount(url);
+ } catch (error) {
+ log.warn(`fetch failed for ${url}`, error.message);
+ return { error: `Failed to fetch site: ${error.message}` };
+ }
+ if (!bytes) return { skipped: 'Site returned no content, cannot calculate carbon' };
+ log.debug(`measured ${bytes} bytes for ${url}`);
+ return {
+ url,
+ bytes,
+ green: false,
+ statistics: computeCarbon(bytes),
+ scanUrl: url,
+ };
+};
+
+export const handler = middleware(carbonHandler);
+export default handler;
diff --git a/packages/api/handlers/cookies.js b/packages/api/handlers/cookies.js
new file mode 100644
index 000000000..bc6093211
--- /dev/null
+++ b/packages/api/handlers/cookies.js
@@ -0,0 +1,51 @@
+import puppeteer from 'puppeteer';
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+
+const getPuppeteerCookies = async (url) => {
+ const browser = await puppeteer.launch({
+ headless: true,
+ args: ['--no-sandbox', '--disable-setuid-sandbox'],
+ });
+
+ try {
+ const page = await browser.newPage();
+ const navigationPromise = page.goto(url, { waitUntil: 'networkidle2' });
+ const timeoutPromise = new Promise((_, reject) =>
+ setTimeout(() => reject(new Error('Puppeteer took too long!')), 3000),
+ );
+ await Promise.race([navigationPromise, timeoutPromise]);
+ return await browser.cookies();
+ } finally {
+ await browser.close();
+ }
+};
+
+const cookieHandler = async (url) => {
+ let headerCookies = null;
+ let clientCookies = null;
+
+ try {
+ const response = await httpGet(url);
+ headerCookies = response.headers['set-cookie'];
+ } catch (error) {
+ if (error.response) {
+ return { error: `Request failed with status ${error.response.status}: ${error.message}` };
+ }
+ return { error: `No response received: ${error.message}` };
+ }
+
+ try {
+ clientCookies = await getPuppeteerCookies(url);
+ } catch (_) {
+ clientCookies = null;
+ }
+
+ return {
+ headerCookies: headerCookies || [],
+ clientCookies: clientCookies || [],
+ };
+};
+
+export const handler = middleware(cookieHandler);
+export default handler;
diff --git a/packages/api/handlers/dns-server.js b/packages/api/handlers/dns-server.js
new file mode 100644
index 000000000..b4b6b5077
--- /dev/null
+++ b/packages/api/handlers/dns-server.js
@@ -0,0 +1,33 @@
+import { promises as dnsPromises } from 'dns';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+import { upstreamError } from './_common/upstream.js';
+
+// Resolve a nameserver hostname to its IP addresses
+const resolveNs = async (ns) => {
+ try {
+ return (await dnsPromises.resolve4(ns))[0];
+ } catch {
+ return null;
+ }
+};
+
+const dnsHandler = async (url) => {
+ const { hostname: domain } = parseTarget(url);
+ let nameservers;
+ try {
+ nameservers = await dnsPromises.resolveNs(domain);
+ } catch (error) {
+ return upstreamError(error, 'DNS server lookup');
+ }
+ const results = await Promise.all(
+ nameservers.map(async (ns) => {
+ const ip = await resolveNs(ns);
+ return { address: ip, hostname: ns };
+ }),
+ );
+ return { domain, dns: results };
+};
+
+export const handler = middleware(dnsHandler);
+export default handler;
diff --git a/packages/api/handlers/dns.js b/packages/api/handlers/dns.js
new file mode 100644
index 000000000..307853eea
--- /dev/null
+++ b/packages/api/handlers/dns.js
@@ -0,0 +1,23 @@
+import dns from 'dns/promises';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+const dnsHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ const safe = (fn) => fn.catch(() => []);
+ const [a, aaaa, mx, txt, ns, cname, soa, srv, ptr] = await Promise.all([
+ safe(dns.resolve4(hostname)),
+ safe(dns.resolve6(hostname)),
+ safe(dns.resolveMx(hostname)),
+ safe(dns.resolveTxt(hostname)),
+ safe(dns.resolveNs(hostname)),
+ safe(dns.resolveCname(hostname)),
+ dns.resolveSoa(hostname).catch(() => null),
+ safe(dns.resolveSrv(hostname)),
+ safe(dns.resolvePtr(hostname)),
+ ]);
+ return { A: a, AAAA: aaaa, MX: mx, TXT: txt, NS: ns, CNAME: cname, SOA: soa, SRV: srv, PTR: ptr };
+};
+
+export const handler = middleware(dnsHandler);
+export default handler;
diff --git a/packages/api/handlers/dnssec.js b/packages/api/handlers/dnssec.js
new file mode 100644
index 000000000..6ef983b9c
--- /dev/null
+++ b/packages/api/handlers/dnssec.js
@@ -0,0 +1,38 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+
+// Query Google's public DNS JSON API for a given record type
+const queryDns = async (domain, type) => {
+ const res = await httpGet('https://dns.google/resolve', {
+ params: { name: domain, type },
+ headers: { Accept: 'application/dns-json' },
+ timeout: 5000,
+ });
+ return res.data;
+};
+
+const dnsSecHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ const [dnskey, ds, aRecord] = await Promise.all([
+ queryDns(hostname, 'DNSKEY'),
+ queryDns(hostname, 'DS'),
+ queryDns(hostname, 'A'),
+ ]);
+ return {
+ DNSKEY: dnskey.Answer
+ ? { isFound: true, answer: dnskey.Answer, response: dnskey.Answer }
+ : { isFound: false, answer: null, response: dnskey },
+ DS: ds.Answer
+ ? { isFound: true, answer: ds.Answer, response: ds.Answer }
+ : { isFound: false, answer: null, response: ds },
+ RRSIG: {
+ isFound: !!aRecord.AD,
+ answer: null,
+ response: aRecord,
+ },
+ };
+};
+
+export const handler = middleware(dnsSecHandler);
+export default handler;
diff --git a/packages/api/handlers/firewall.js b/packages/api/handlers/firewall.js
new file mode 100644
index 000000000..497c595b4
--- /dev/null
+++ b/packages/api/handlers/firewall.js
@@ -0,0 +1,112 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+import { upstreamError } from './_common/upstream.js';
+
+const hasWaf = (waf) => ({ hasWaf: true, waf });
+
+const firewallHandler = async (url) => {
+ const { href } = parseTarget(url);
+ try {
+ const response = await httpGet(href, {
+ validateStatus: () => true,
+ });
+ const headers = response.headers;
+
+ if (headers['server'] && headers['server'].includes('cloudflare')) {
+ return hasWaf('Cloudflare');
+ }
+
+ if (headers['x-powered-by'] && headers['x-powered-by'].includes('AWS Lambda')) {
+ return hasWaf('AWS WAF');
+ }
+
+ if (headers['server'] && headers['server'].includes('AkamaiGHost')) {
+ return hasWaf('Akamai');
+ }
+
+ if (headers['server'] && headers['server'].includes('Sucuri')) {
+ return hasWaf('Sucuri');
+ }
+
+ if (headers['server'] && headers['server'].includes('BarracudaWAF')) {
+ return hasWaf('Barracuda WAF');
+ }
+
+ if (
+ headers['server'] &&
+ (headers['server'].includes('F5 BIG-IP') || headers['server'].includes('BIG-IP'))
+ ) {
+ return hasWaf('F5 BIG-IP');
+ }
+
+ if (headers['x-sucuri-id'] || headers['x-sucuri-cache']) {
+ return hasWaf('Sucuri CloudProxy WAF');
+ }
+
+ if (headers['server'] && headers['server'].includes('FortiWeb')) {
+ return hasWaf('Fortinet FortiWeb WAF');
+ }
+
+ if (headers['server'] && headers['server'].includes('Imperva')) {
+ return hasWaf('Imperva SecureSphere WAF');
+ }
+
+ if (headers['x-protected-by'] && headers['x-protected-by'].includes('Sqreen')) {
+ return hasWaf('Sqreen');
+ }
+
+ if (headers['x-waf-event-info']) {
+ return hasWaf('Reblaze WAF');
+ }
+
+ if (headers['set-cookie'] && headers['set-cookie'].includes('_citrix_ns_id')) {
+ return hasWaf('Citrix NetScaler');
+ }
+
+ if (headers['x-denied-reason'] || headers['x-wzws-requested-method']) {
+ return hasWaf('WangZhanBao WAF');
+ }
+
+ if (headers['x-webcoment']) {
+ return hasWaf('Webcoment Firewall');
+ }
+
+ if (headers['server'] && headers['server'].includes('Yundun')) {
+ return hasWaf('Yundun WAF');
+ }
+
+ if (headers['x-yd-waf-info'] || headers['x-yd-info']) {
+ return hasWaf('Yundun WAF');
+ }
+
+ if (headers['server'] && headers['server'].includes('Safe3WAF')) {
+ return hasWaf('Safe3 Web Application Firewall');
+ }
+
+ if (headers['server'] && headers['server'].includes('NAXSI')) {
+ return hasWaf('NAXSI WAF');
+ }
+
+ if (headers['x-datapower-transactionid']) {
+ return hasWaf('IBM WebSphere DataPower');
+ }
+
+ if (headers['server'] && headers['server'].includes('QRATOR')) {
+ return hasWaf('QRATOR WAF');
+ }
+
+ if (headers['server'] && headers['server'].includes('ddos-guard')) {
+ return hasWaf('DDoS-Guard WAF');
+ }
+
+ return {
+ hasWaf: false,
+ };
+ } catch (error) {
+ return upstreamError(error, 'Firewall check');
+ }
+};
+
+export const handler = middleware(firewallHandler);
+export default handler;
diff --git a/packages/api/handlers/get-ip.js b/packages/api/handlers/get-ip.js
new file mode 100644
index 000000000..87c13ce73
--- /dev/null
+++ b/packages/api/handlers/get-ip.js
@@ -0,0 +1,19 @@
+import dns from 'dns';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+const lookupAsync = (address) =>
+ new Promise((resolve, reject) => {
+ dns.lookup(address, (err, ip, family) => {
+ if (err) reject(err);
+ else resolve({ ip, family });
+ });
+ });
+
+const ipHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ return await lookupAsync(hostname);
+};
+
+export const handler = middleware(ipHandler);
+export default handler;
diff --git a/packages/api/handlers/headers.js b/packages/api/handlers/headers.js
new file mode 100644
index 000000000..c84be1970
--- /dev/null
+++ b/packages/api/handlers/headers.js
@@ -0,0 +1,17 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { upstreamError } from './_common/upstream.js';
+
+const headersHandler = async (url) => {
+ try {
+ const response = await httpGet(url, {
+ validateStatus: (status) => status >= 200 && status < 600,
+ });
+ return response.headers;
+ } catch (error) {
+ return upstreamError(error, 'Headers fetch');
+ }
+};
+
+export const handler = middleware(headersHandler);
+export default handler;
diff --git a/packages/api/handlers/hsts.js b/packages/api/handlers/hsts.js
new file mode 100644
index 000000000..63c6f074f
--- /dev/null
+++ b/packages/api/handlers/hsts.js
@@ -0,0 +1,42 @@
+import https from 'https';
+import middleware from './_common/middleware.js';
+
+const MIN_MAX_AGE = 10886400;
+
+const verdict = (message, compatible = false, hstsHeader = null) => ({
+ message,
+ compatible,
+ hstsHeader,
+});
+
+const evaluate = (header) => {
+ if (!header) return verdict('Site does not serve any HSTS headers.');
+ const lower = header.toLowerCase();
+ const maxAge = parseInt(lower.match(/max-age=(\d+)/)?.[1] || '0', 10);
+ if (maxAge < MIN_MAX_AGE)
+ return verdict(`HSTS max-age is ${maxAge}, below the ${MIN_MAX_AGE} minimum.`, false, header);
+ if (!lower.includes('includesubdomains'))
+ return verdict('HSTS header does not include all subdomains.', false, header);
+ if (!lower.includes('preload'))
+ return verdict('HSTS header does not contain the preload directive.', false, header);
+ return verdict('Site is compatible with the HSTS preload list!', true, header);
+};
+
+const REQUEST_TIMEOUT = 5000;
+
+const hstsHandler = async (url) =>
+ new Promise((resolve) => {
+ const req = https.request(url, (res) => {
+ resolve(evaluate(res.headers['strict-transport-security']));
+ res.resume();
+ });
+ req.setTimeout(REQUEST_TIMEOUT, () => {
+ req.destroy();
+ resolve({ error: 'HSTS check timed out' });
+ });
+ req.on('error', (e) => resolve({ error: `HSTS check failed: ${e.message}` }));
+ req.end();
+ });
+
+export const handler = middleware(hstsHandler);
+export default handler;
diff --git a/packages/api/handlers/http-security.js b/packages/api/handlers/http-security.js
new file mode 100644
index 000000000..d86686055
--- /dev/null
+++ b/packages/api/handlers/http-security.js
@@ -0,0 +1,30 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+
+// Security headers to check, mapped to response field names
+const HEADERS = {
+ 'content-security-policy': 'contentSecurityPolicy',
+ 'strict-transport-security': 'strictTransportPolicy',
+ 'x-content-type-options': 'xContentTypeOptions',
+ 'x-frame-options': 'xFrameOptions',
+ 'x-xss-protection': 'xXSSProtection',
+ 'referrer-policy': 'referrerPolicy',
+ 'permissions-policy': 'permissionsPolicy',
+ 'cross-origin-opener-policy': 'crossOriginOpenerPolicy',
+ 'cross-origin-resource-policy': 'crossOriginResourcePolicy',
+ 'cross-origin-embedder-policy': 'crossOriginEmbedderPolicy',
+};
+
+const httpsSecHandler = async (url) => {
+ try {
+ const { headers } = await httpGet(url, {
+ validateStatus: () => true,
+ });
+ return Object.fromEntries(Object.entries(HEADERS).map(([h, key]) => [key, !!headers[h]]));
+ } catch (error) {
+ return { error: `Unable to fetch headers: ${error.message}` };
+ }
+};
+
+export const handler = middleware(httpsSecHandler);
+export default handler;
diff --git a/packages/api/handlers/linked-pages.js b/packages/api/handlers/linked-pages.js
new file mode 100644
index 000000000..dafa883c0
--- /dev/null
+++ b/packages/api/handlers/linked-pages.js
@@ -0,0 +1,53 @@
+import * as cheerio from 'cheerio';
+import urlLib from 'url';
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { upstreamError } from './_common/upstream.js';
+
+const linkedPagesHandler = async (url) => {
+ let response;
+ try {
+ response = await httpGet(url);
+ } catch (error) {
+ return upstreamError(error, 'Linked pages fetch');
+ }
+ const html = response.data;
+ const $ = cheerio.load(html);
+ const internalLinksMap = new Map();
+ const externalLinksMap = new Map();
+
+ // Get all links on the page
+ $('a[href]').each((i, link) => {
+ const href = $(link).attr('href');
+ const absoluteUrl = urlLib.resolve(url, href);
+
+ // Check if absolute / relative, append to appropriate map or increment occurrence count
+ if (absoluteUrl.startsWith(url)) {
+ const count = internalLinksMap.get(absoluteUrl) || 0;
+ internalLinksMap.set(absoluteUrl, count + 1);
+ } else if (href.startsWith('http://') || href.startsWith('https://')) {
+ const count = externalLinksMap.get(absoluteUrl) || 0;
+ externalLinksMap.set(absoluteUrl, count + 1);
+ }
+ });
+
+ // Sort by most occurrences, remove supplicates, and convert to array
+ const internalLinks = [...internalLinksMap.entries()]
+ .sort((a, b) => b[1] - a[1])
+ .map((entry) => entry[0]);
+ const externalLinks = [...externalLinksMap.entries()]
+ .sort((a, b) => b[1] - a[1])
+ .map((entry) => entry[0]);
+
+ if (!internalLinks.length && !externalLinks.length) {
+ return {
+ skipped:
+ 'No internal or external links found in the page HTML. ' +
+ 'This often happens with single-page apps that render content client-side.',
+ };
+ }
+ return { internal: internalLinks, external: externalLinks };
+};
+
+export const handler = middleware(linkedPagesHandler);
+export default handler;
diff --git a/packages/api/handlers/location.js b/packages/api/handlers/location.js
new file mode 100644
index 000000000..de4f58561
--- /dev/null
+++ b/packages/api/handlers/location.js
@@ -0,0 +1,184 @@
+import { promises as dns } from 'dns';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+import { createLogger } from './_common/logger.js';
+
+const log = createLogger('location');
+const TIMEOUT = 4000;
+
+// Server-side fetch, no-cors so providers don't reject Sec-Fetch-Mode: cors
+const getJson = async (url, signal) => {
+ const r = await fetch(url, { mode: 'no-cors', signal });
+ if (!r.ok) throw new Error(`status ${r.status}`);
+ return r.json();
+};
+
+// Geo providers, each parser normalises to a shared field shape
+const providers = [
+ {
+ name: 'ipwho.is',
+ url: (ip) => `https://ipwho.is/${ip}`,
+ parse: (d) =>
+ d?.success === false
+ ? null
+ : {
+ ip: d.ip,
+ city: d.city,
+ region: d.region,
+ country_name: d.country,
+ country_code: d.country_code,
+ region_code: d.region_code,
+ postal: d.postal,
+ latitude: d.latitude,
+ longitude: d.longitude,
+ org: d.connection?.isp || d.connection?.org,
+ timezone: d.timezone?.id,
+ },
+ },
+ {
+ name: 'ip-api.com',
+ url: (ip) => `http://ip-api.com/json/${ip}`,
+ parse: (d) =>
+ d?.status === 'success'
+ ? {
+ ip: d.query,
+ city: d.city,
+ region: d.regionName,
+ country_name: d.country,
+ country_code: d.countryCode,
+ region_code: d.region,
+ postal: d.zip,
+ latitude: d.lat,
+ longitude: d.lon,
+ org: d.isp || d.org,
+ timezone: d.timezone,
+ }
+ : null,
+ },
+ {
+ name: 'geojs.io',
+ url: (ip) => `https://get.geojs.io/v1/ip/geo/${ip}.json`,
+ parse: (d) =>
+ d?.country_code
+ ? {
+ ip: d.ip,
+ city: d.city,
+ region: d.region,
+ country_name: d.country,
+ country_code: d.country_code,
+ latitude: d.latitude !== 'nil' ? parseFloat(d.latitude) : undefined,
+ longitude: d.longitude !== 'nil' ? parseFloat(d.longitude) : undefined,
+ org: d.organization_name,
+ timezone: d.timezone,
+ }
+ : null,
+ },
+ {
+ name: 'reallyfreegeoip.org',
+ url: (ip) => `https://reallyfreegeoip.org/json/${ip}`,
+ parse: (d) =>
+ d?.country_code
+ ? {
+ ip: d.ip,
+ city: d.city,
+ region: d.region_name,
+ country_name: d.country_name,
+ country_code: d.country_code,
+ region_code: d.region_code,
+ postal: d.zip_code,
+ latitude: d.latitude,
+ longitude: d.longitude,
+ timezone: d.time_zone,
+ }
+ : null,
+ },
+];
+
+// Query a single provider, throw unless it yields a usable result
+const tryProvider = async (p, ip, signal) => {
+ const parsed = p.parse(await getJson(p.url(ip), signal));
+ if (!parsed?.country_code) throw new Error('no usable data');
+ log.debug(`${p.name} resolved ${ip} to ${parsed.country_code}`);
+ return parsed;
+};
+
+// Race all providers, first successful result wins, abort the rest
+const lookupGeo = async (ip) => {
+ const ac = new AbortController();
+ const signal = AbortSignal.any([ac.signal, AbortSignal.timeout(TIMEOUT)]);
+ const tasks = providers.map((p) =>
+ tryProvider(p, ip, signal).catch((e) => {
+ if (e.name !== 'AbortError') log.warn(`${p.name} failed for ${ip}`, e.message);
+ throw e;
+ }),
+ );
+ try {
+ const result = await Promise.any(tasks);
+ ac.abort();
+ return result;
+ } catch {
+ return null;
+ }
+};
+
+// Fetch country-level metadata to fill fields not provided by every geo source
+const enrichCountry = async (code) => {
+ if (!code) return {};
+ try {
+ const data = await getJson(
+ `https://restcountries.com/v3.1/alpha/${code}` +
+ '?fields=tld,languages,currencies,area,population',
+ );
+ const c = Array.isArray(data) ? data[0] : data;
+ if (!c) {
+ log.debug(`restcountries returned no entry for ${code}`);
+ return {};
+ }
+ const languages = c.languages ? Object.values(c.languages).join(', ') : undefined;
+ const currCode = c.currencies ? Object.keys(c.currencies)[0] : undefined;
+ const curr = currCode ? c.currencies[currCode] : null;
+ return {
+ country_tld: c.tld?.[0],
+ languages,
+ currency: currCode,
+ currency_name: curr?.name,
+ country_area: c.area,
+ country_population: c.population,
+ };
+ } catch (error) {
+ log.debug(`restcountries enrichment failed for ${code}`, error.message);
+ return {};
+ }
+};
+
+// Strip empty values so they don't shadow enrichment defaults during merge
+const compact = (o) =>
+ Object.fromEntries(
+ Object.entries(o).filter(([, v]) => v !== undefined && v !== null && v !== ''),
+ );
+
+// Resolve hostname to IP so providers requiring a numeric address still work
+const resolveHost = async (hostname) => {
+ try {
+ return (await dns.lookup(hostname)).address;
+ } catch (error) {
+ log.warn(`DNS lookup failed for ${hostname}, falling through with raw host`, error.message);
+ return hostname;
+ }
+};
+
+// Resolve geographic info for a host via a chain of providers with country enrichment
+const locationHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ const ip = await resolveHost(hostname);
+ const geo = await lookupGeo(ip);
+ if (!geo) {
+ log.error(`all geo providers failed for ${ip}`);
+ return { error: 'IP location lookup unavailable across all providers, please try again later' };
+ }
+ const enrichment = await enrichCountry(geo.country_code);
+ return { ...enrichment, ...compact(geo) };
+};
+
+export const handler = middleware(locationHandler);
+export default handler;
diff --git a/packages/api/handlers/mail-config.js b/packages/api/handlers/mail-config.js
new file mode 100644
index 000000000..71ac95ee7
--- /dev/null
+++ b/packages/api/handlers/mail-config.js
@@ -0,0 +1,99 @@
+import dns from 'dns/promises';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+// Safely query TXT, returning [] on ENODATA/ENOTFOUND
+const safeTxt = (name) => dns.resolveTxt(name).catch(() => []);
+
+// Try common DKIM selectors to detect if DKIM is configured
+const DKIM_SELECTORS = [
+ 'default',
+ 'google',
+ 'selector1',
+ 'selector2',
+ 'k1',
+ 'k2',
+ 'k3',
+ 's1',
+ 's2',
+ 'dkim',
+ 'mail',
+];
+const findDkim = async (domain) => {
+ const checks = DKIM_SELECTORS.map((s) =>
+ safeTxt(`${s}._domainkey.${domain}`).then((r) => {
+ if (!r.length) return null;
+ const txt = r[0].join('');
+ // Skip revoked keys (empty p= value)
+ if (/p=\s*(;|$)/.test(txt)) return null;
+ return { selector: s, record: r[0] };
+ }),
+ );
+ const results = await Promise.all(checks);
+ return results.filter(Boolean);
+};
+
+// Detect mail provider from MX exchange hostnames
+const MX_PROVIDERS = [
+ [/google(mail)?\.com$/i, 'Google Workspace'],
+ [/outlook\.com$|microsoft\.com$/i, 'Microsoft 365'],
+ [/protonmail\.ch$|protonme\.ch$/i, 'ProtonMail'],
+ [/zoho\.(com|eu|in)$/i, 'Zoho Mail'],
+ [/yahoodns\.net$/i, 'Yahoo Mail'],
+ [/mimecast\.com$/i, 'Mimecast'],
+ [/pphosted\.com$/i, 'Proofpoint'],
+ [/messagelabs\.com$/i, 'Broadcom Email Security'],
+ [/iphmx\.com$/i, 'Cisco Email Security'],
+ [/mailgun\.org$/i, 'Mailgun'],
+ [/sendgrid\.net$/i, 'SendGrid'],
+ [/fireeyecloud\.com$/i, 'Trellix Email Security'],
+ [/barracudanetworks\.com$/i, 'Barracuda'],
+];
+
+const detectProviders = (mxRecords) => {
+ const seen = new Set();
+ return mxRecords.reduce((out, { exchange }) => {
+ const match = MX_PROVIDERS.find(([re]) => re.test(exchange));
+ if (match && !seen.has(match[1])) {
+ seen.add(match[1]);
+ out.push({ provider: match[1], value: exchange });
+ }
+ return out;
+ }, []);
+};
+
+const mailConfigHandler = async (url) => {
+ const { hostname: domain } = parseTarget(url);
+ try {
+ const [mxRecords, rootTxt, dmarcTxt, bimiTxt, dkimResults] = await Promise.all([
+ dns.resolveMx(domain),
+ safeTxt(domain),
+ safeTxt(`_dmarc.${domain}`),
+ safeTxt(`default._bimi.${domain}`),
+ findDkim(domain),
+ ]);
+
+ // Collect email-relevant TXT records
+ const emailTxt = rootTxt.filter((r) => {
+ const s = r.join('').toLowerCase();
+ return s.startsWith('v=spf1');
+ });
+ dmarcTxt.forEach((r) => emailTxt.push(r));
+ bimiTxt.forEach((r) => emailTxt.push(r));
+ dkimResults.forEach(({ record }) => emailTxt.push(record));
+
+ return {
+ mxRecords,
+ txtRecords: emailTxt,
+ mailServices: detectProviders(mxRecords),
+ };
+ } catch (error) {
+ if (error.code === 'ENOTFOUND' || error.code === 'ENODATA') {
+ return { skipped: 'No mail server in use on this domain' };
+ }
+ return { error: `Mail config lookup failed: ${error.message}` };
+ }
+};
+
+export const handler = middleware(mailConfigHandler);
+export default handler;
diff --git a/packages/api/handlers/ports.js b/packages/api/handlers/ports.js
new file mode 100644
index 000000000..6345ccb4c
--- /dev/null
+++ b/packages/api/handlers/ports.js
@@ -0,0 +1,99 @@
+import net from 'net';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+// A list of commonly used ports.
+const DEFAULT_PORTS_TO_CHECK = [
+ 20, 21, 22, 23, 25, 53, 80, 67, 68, 69, 110, 119, 123, 143, 156, 161, 162, 179, 194, 389, 443,
+ 587, 993, 995, 3000, 3306, 3389, 5060, 5900, 8000, 8080, 8888,
+];
+/*
+ * Checks if the env PORTS_TO_CHECK is set, if so the string is split via "," to get an array of ports to check.
+ * If the env is not set, return the default commonly used ports.
+ */
+const PORTS = process.env.PORTS_TO_CHECK
+ ? process.env.PORTS_TO_CHECK.split(',')
+ : DEFAULT_PORTS_TO_CHECK;
+
+async function checkPort(port, domain) {
+ return new Promise((resolve, reject) => {
+ const socket = new net.Socket();
+
+ socket.setTimeout(1500);
+
+ socket.once('connect', () => {
+ socket.destroy();
+ resolve(port);
+ });
+
+ socket.once('timeout', () => {
+ socket.destroy();
+ reject(new Error(`Timeout at port: ${port}`));
+ });
+
+ socket.once('error', (e) => {
+ socket.destroy();
+ reject(e);
+ });
+
+ socket.connect(port, domain);
+ });
+}
+
+const portsHandler = async (url, event, context) => {
+ const { hostname: domain } = parseTarget(url);
+
+ const delay = (ms) => new Promise((res) => setTimeout(res, ms));
+ const timeout = delay(9000);
+
+ const openPorts = [];
+ const failedPorts = [];
+
+ const promises = PORTS.map((port) =>
+ checkPort(port, domain)
+ .then(() => {
+ openPorts.push(port);
+ return { status: 'fulfilled', port };
+ })
+ .catch(() => {
+ failedPorts.push(port);
+ return { status: 'rejected', port };
+ }),
+ );
+
+ let timeoutReached = false;
+
+ for (const promise of promises) {
+ const result = await Promise.race([
+ promise,
+ timeout.then(() => ({ status: 'timeout', timeout: true })),
+ ]);
+ if (result.status === 'timeout') {
+ timeoutReached = true;
+ if (result.timeout) {
+ // Add the ports not checked yet to the failedPorts array
+ const checkedPorts = [...openPorts, ...failedPorts];
+ const portsNotChecked = PORTS.filter((port) => !checkedPorts.includes(port));
+ failedPorts.push(...portsNotChecked);
+ }
+ break;
+ }
+ }
+
+ if (timeoutReached) {
+ return errorResponse('The function timed out before completing.');
+ }
+
+ // Sort openPorts and failedPorts before returning
+ openPorts.sort((a, b) => a - b);
+ failedPorts.sort((a, b) => a - b);
+
+ return { openPorts, failedPorts };
+};
+
+const errorResponse = (message, statusCode = 444) => {
+ return { error: message };
+};
+
+export const handler = middleware(portsHandler);
+export default handler;
diff --git a/packages/api/handlers/quality.js b/packages/api/handlers/quality.js
new file mode 100644
index 000000000..f0347f8de
--- /dev/null
+++ b/packages/api/handlers/quality.js
@@ -0,0 +1,28 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { requireEnv, upstreamError } from './_common/upstream.js';
+
+const qualityHandler = async (url) => {
+ const auth = requireEnv('GOOGLE_CLOUD_API_KEY', 'Quality check');
+ if (auth.skipped) return auth;
+ const endpoint =
+ `https://www.googleapis.com/pagespeedonline/v5/runPagespeed?` +
+ `url=${encodeURIComponent(url)}&category=PERFORMANCE&category=ACCESSIBILITY` +
+ `&category=BEST_PRACTICES&category=SEO&category=PWA&strategy=mobile` +
+ `&key=${auth.value}`;
+
+ let data;
+ try {
+ data = (await httpGet(endpoint)).data;
+ } catch (error) {
+ return upstreamError(error, 'Quality check');
+ }
+ const result = data.lighthouseResult || data;
+ if (!result?.categories || !Object.keys(result.categories).length) {
+ return { skipped: 'No quality report available for this URL' };
+ }
+ return result;
+};
+
+export const handler = middleware(qualityHandler);
+export default handler;
diff --git a/packages/api/handlers/rank.js b/packages/api/handlers/rank.js
new file mode 100644
index 000000000..b5d45d5be
--- /dev/null
+++ b/packages/api/handlers/rank.js
@@ -0,0 +1,29 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+import { upstreamError } from './_common/upstream.js';
+
+const rankHandler = async (url) => {
+ const { hostname: domain } = parseTarget(url);
+ const { TRANCO_USERNAME, TRANCO_API_KEY } = process.env;
+ const auth = TRANCO_API_KEY
+ ? { auth: { username: TRANCO_USERNAME, password: TRANCO_API_KEY } }
+ : {};
+ try {
+ const response = await httpGet(`https://tranco-list.eu/api/ranks/domain/${domain}`, {
+ timeout: 5000,
+ ...auth,
+ });
+ if (!response.data?.ranks?.length) {
+ return {
+ skipped: `${domain} isn't ranked in the top 1 million sites yet`,
+ };
+ }
+ return response.data;
+ } catch (error) {
+ return upstreamError(error, 'Tranco rank lookup');
+ }
+};
+
+export const handler = middleware(rankHandler);
+export default handler;
diff --git a/packages/api/handlers/redirects.js b/packages/api/handlers/redirects.js
new file mode 100644
index 000000000..f6df1ef43
--- /dev/null
+++ b/packages/api/handlers/redirects.js
@@ -0,0 +1,43 @@
+import middleware from './_common/middleware.js';
+import { upstreamError } from './_common/upstream.js';
+
+const MAX_REDIRECTS = 12;
+const TIMEOUT_MS = 10000;
+const USER_AGENT = 'Mozilla/5.0 (compatible; WebCheck/2.0; +https://web-check.xyz)';
+
+// Walks the redirect chain manually, recording each Location header as got did
+const redirectsHandler = async (url) => {
+ const redirects = [url];
+ let current = url;
+ try {
+ for (let i = 0; i < MAX_REDIRECTS; i++) {
+ const response = await fetch(current, {
+ redirect: 'manual',
+ signal: AbortSignal.timeout(TIMEOUT_MS),
+ headers: { 'user-agent': USER_AGENT },
+ });
+ if (response.status < 300 || response.status >= 400) {
+ if (response.status >= 400) {
+ const err = new Error(`HTTP ${response.status}`);
+ err.response = { status: response.status };
+ throw err;
+ }
+ break;
+ }
+ const location = response.headers.get('location');
+ if (!location) break;
+ redirects.push(location);
+ current = new URL(location, current).href;
+ }
+ return { redirects };
+ } catch (error) {
+ if (error.cause?.code) error.code = error.cause.code;
+ if (error.name === 'TimeoutError' || error.name === 'AbortError') {
+ error.code = 'ECONNABORTED';
+ }
+ return upstreamError(error, 'Redirect lookup');
+ }
+};
+
+export const handler = middleware(redirectsHandler);
+export default handler;
diff --git a/packages/api/handlers/robots-txt.js b/packages/api/handlers/robots-txt.js
new file mode 100644
index 000000000..57d776197
--- /dev/null
+++ b/packages/api/handlers/robots-txt.js
@@ -0,0 +1,33 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+import { upstreamError } from './_common/upstream.js';
+
+// Extract User-agent / Allow / Disallow rules from a robots.txt body
+const parseRobotsTxt = (content) => {
+ const rules = [];
+ for (let line of content.split('\n')) {
+ line = line.trim();
+ const ruleMatch = line.match(/^(Allow|Disallow|User-agent):\s*(\S*)$/i);
+ if (ruleMatch) rules.push({ lbl: ruleMatch[1], val: ruleMatch[2] });
+ }
+ return { robots: rules };
+};
+
+const robotsHandler = async (url) => {
+ const { protocol, hostname } = parseTarget(url);
+ const host = hostname.includes(':') ? `[${hostname}]` : hostname;
+ try {
+ const res = await httpGet(`${protocol}//${host}/robots.txt`);
+ const parsed = parseRobotsTxt(res.data || '');
+ return parsed.robots.length ? parsed : { skipped: 'No robots.txt rules found for this host' };
+ } catch (error) {
+ if (error.response?.status === 404) {
+ return { skipped: 'No robots.txt file present on this host' };
+ }
+ return upstreamError(error, 'robots.txt fetch');
+ }
+};
+
+export const handler = middleware(robotsHandler);
+export default handler;
diff --git a/packages/api/handlers/screenshot.js b/packages/api/handlers/screenshot.js
new file mode 100644
index 000000000..725841b35
--- /dev/null
+++ b/packages/api/handlers/screenshot.js
@@ -0,0 +1,96 @@
+import puppeteer from 'puppeteer-core';
+import chromium from '@sparticuz/chromium';
+import { randomUUID } from 'crypto';
+import { execFile } from 'child_process';
+import { promises as fs } from 'fs';
+import path from 'path';
+import middleware from './_common/middleware.js';
+import { createLogger } from './_common/logger.js';
+
+const log = createLogger('screenshot');
+
+// Screenshot via the system Chromium binary
+const directChromiumScreenshot = async (url) => {
+ const tmpDir = '/tmp';
+ const screenshotPath = path.join(tmpDir, `screenshot-${randomUUID()}.png`);
+ log.debug(`direct method, saving to ${screenshotPath}`);
+
+ return new Promise((resolve, reject) => {
+ const chromePath = process.env.CHROME_PATH || '/usr/bin/chromium';
+ const args = [
+ '--headless',
+ '--disable-gpu',
+ '--no-sandbox',
+ `--screenshot=${screenshotPath}`,
+ url,
+ ];
+ execFile(chromePath, args, async (error) => {
+ if (error) return reject(error);
+ try {
+ const buf = await fs.readFile(screenshotPath);
+ await fs
+ .unlink(screenshotPath)
+ .catch((err) => log.warn(`temp cleanup failed: ${err.message}`));
+ resolve(buf.toString('base64'));
+ } catch (readError) {
+ reject(readError);
+ }
+ });
+ });
+};
+
+// Fallback to puppeteer when the direct Chromium binary call fails
+const puppeteerScreenshot = async (targetUrl) => {
+ let browser = null;
+ try {
+ browser = await puppeteer.launch({
+ args: [...chromium.args, '--no-sandbox'],
+ defaultViewport: { width: 800, height: 600 },
+ executablePath: process.env.CHROME_PATH || (await chromium.executablePath()),
+ headless: true,
+ acceptInsecureCerts: true,
+ ignoreDefaultArgs: ['--disable-extensions'],
+ });
+ const page = await browser.newPage();
+ await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]);
+ page.setDefaultNavigationTimeout(8000);
+ await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
+ await page.evaluate(() => {
+ if (!document.querySelector('body')) {
+ throw new Error('No body element found on the page');
+ }
+ });
+ const buffer = await page.screenshot();
+ return buffer.toString('base64');
+ } finally {
+ if (browser) await browser.close().catch(() => {});
+ }
+};
+
+const screenshotHandler = async (targetUrl) => {
+ if (!targetUrl) throw new Error('URL is missing from queryStringParameters');
+ try {
+ new URL(targetUrl);
+ } catch {
+ throw new Error('URL provided is invalid');
+ }
+
+ log.debug(`request received: ${targetUrl}`);
+ try {
+ return { image: await directChromiumScreenshot(targetUrl) };
+ } catch (directError) {
+ log.warn(`direct chromium failed, falling back to puppeteer: ${directError.message}`);
+ }
+ try {
+ return { image: await puppeteerScreenshot(targetUrl) };
+ } catch (error) {
+ if (/ENOENT|Browser was not found|Could not find Chromium/i.test(error.message)) {
+ return { skipped: error.message };
+ }
+ log.error(`puppeteer screenshot failed: ${error.message}`);
+ throw error;
+ }
+};
+
+export const handler = middleware(screenshotHandler);
+export default handler;
diff --git a/packages/api/handlers/security-txt.js b/packages/api/handlers/security-txt.js
new file mode 100644
index 000000000..f773d6a3a
--- /dev/null
+++ b/packages/api/handlers/security-txt.js
@@ -0,0 +1,80 @@
+import { URL } from 'url';
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+
+// RFC 9116 recommends .well-known first, legacy /security.txt as fallback
+const SECURITY_TXT_PATHS = ['/.well-known/security.txt', '/security.txt'];
+
+const parseResult = (result) => {
+ let output = {};
+ let counts = {};
+ const lines = result.split('\n');
+ const regex = /^([^:]+):\s*(.+)$/;
+
+ for (const line of lines) {
+ if (!line.startsWith('#') && !line.startsWith('-----') && line.trim() !== '') {
+ const match = line.match(regex);
+ if (match && match.length > 2) {
+ let key = match[1].trim();
+ const value = match[2].trim();
+ if (output.hasOwnProperty(key)) {
+ counts[key] = counts[key] ? counts[key] + 1 : 1;
+ key += counts[key];
+ }
+ output[key] = value;
+ }
+ }
+ }
+
+ return output;
+};
+
+const isPgpSigned = (result) => {
+ if (result.includes('-----BEGIN PGP SIGNED MESSAGE-----')) {
+ return true;
+ }
+ return false;
+};
+
+const securityTxtHandler = async (urlParam) => {
+ let url;
+ try {
+ url = new URL(urlParam.includes('://') ? urlParam : 'https://' + urlParam);
+ } catch (error) {
+ throw new Error('Invalid URL format');
+ }
+ url.pathname = '';
+
+ for (let path of SECURITY_TXT_PATHS) {
+ try {
+ const result = await fetchSecurityTxt(url, path);
+ if (result && result.toLowerCase().includes(' {
+ const url = new URL(path, baseURL);
+ const res = await httpGet(url.toString(), {
+ headers: { 'User-Agent': 'curl/8.0.0' },
+ validateStatus: () => true,
+ });
+ return res.status === 200 ? res.data : null;
+};
+
+export const handler = middleware(securityTxtHandler);
+export default handler;
diff --git a/packages/api/handlers/shodan.js b/packages/api/handlers/shodan.js
new file mode 100644
index 000000000..06156814f
--- /dev/null
+++ b/packages/api/handlers/shodan.js
@@ -0,0 +1,22 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+import { requireEnv, upstreamError } from './_common/upstream.js';
+
+// Server-side Shodan lookup so the API key never touches the client
+const shodanHandler = async (url) => {
+ const auth = requireEnv('SHODAN_API_KEY', 'Shodan');
+ if (auth.skipped) return auth;
+ const { hostname } = parseTarget(url);
+ try {
+ const res = await httpGet(`https://api.shodan.io/shodan/host/${hostname}?key=${auth.value}`, {
+ timeout: 8000,
+ });
+ return res.data;
+ } catch (error) {
+ return upstreamError(error, 'Shodan lookup');
+ }
+};
+
+export const handler = middleware(shodanHandler);
+export default handler;
diff --git a/packages/api/handlers/sitemap.js b/packages/api/handlers/sitemap.js
new file mode 100644
index 000000000..ef7859ee5
--- /dev/null
+++ b/packages/api/handlers/sitemap.js
@@ -0,0 +1,129 @@
+import xml2js from 'xml2js';
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { upstreamError } from './_common/upstream.js';
+import { createLogger } from './_common/logger.js';
+
+const log = createLogger('sitemap');
+const TIMEOUT = 6000;
+const MAX_DEPTH = 3;
+const MAX_CHILD_SITEMAPS = 25;
+const MAX_URLS = 5000;
+
+// Browser-ish headers so picky CDNs do not return 406/403 to the default Node UA
+const HEADERS = {
+ 'user-agent': 'Mozilla/5.0 (compatible; web-check-bot/1.0; +https://web-check.xyz)',
+ accept: 'application/xml, text/xml, application/rss+xml, */*;q=0.1',
+};
+
+// Reduce a target URL to its origin so child paths resolve cleanly
+const toOrigin = (url) => {
+ try {
+ return new URL(url).origin;
+ } catch {
+ return url.replace(/\/+$/, '');
+ }
+};
+
+// Fetch and parse XML in lenient mode so minor well-formedness errors do not abort
+const fetchSitemap = async (sitemapUrl) => {
+ const res = await httpGet(sitemapUrl, { timeout: TIMEOUT, headers: HEADERS });
+ return new xml2js.Parser({ strict: false, normalizeTags: true }).parseStringPromise(res.data);
+};
+
+// Pull the first Sitemap: directive out of robots.txt, if any
+const findSitemapInRobots = async (origin) => {
+ try {
+ const robots = await httpGet(`${origin}/robots.txt`, { timeout: TIMEOUT, headers: HEADERS });
+ for (const line of String(robots.data).split('\n')) {
+ if (line.toLowerCase().startsWith('sitemap:')) {
+ return line.split(/\s+/)[1]?.trim() || null;
+ }
+ }
+ } catch (error) {
+ log.debug(`robots.txt fetch failed for ${origin}`, error.message);
+ }
+ return null;
+};
+
+// Recursively flatten a sitemap-index into its child url sets
+const expandSitemap = async (parsed, depth) => {
+ if (!parsed?.sitemapindex?.sitemap || depth >= MAX_DEPTH) return parsed;
+ const children = parsed.sitemapindex.sitemap
+ .map((s) => s?.loc?.[0])
+ .filter(Boolean)
+ .slice(0, MAX_CHILD_SITEMAPS);
+ const fetched = await Promise.all(
+ children.map((loc) =>
+ fetchSitemap(loc).catch((error) => {
+ log.debug(`child sitemap failed for ${loc}`, error.message);
+ return null;
+ }),
+ ),
+ );
+ const expanded = await Promise.all(
+ fetched.map((child) => (child ? expandSitemap(child, depth + 1) : null)),
+ );
+ const urls = expanded.flatMap((child) => child?.urlset?.url || []);
+ return {
+ sitemapindex: parsed.sitemapindex,
+ urlset: urls.length ? { url: urls } : undefined,
+ sources: children,
+ };
+};
+
+// Whether the parsed XML matched one of the canonical sitemap shapes
+const isValidSitemap = (p) => !!(p?.urlset?.url?.length || p?.sitemapindex?.sitemap?.length);
+
+// Keep only the four fields the frontend renders, dropping locale alternates and image/video extras
+const slimUrl = (u) => {
+ const out = { loc: u.loc };
+ if (u.lastmod) out.lastmod = u.lastmod;
+ if (u.changefreq) out.changefreq = u.changefreq;
+ if (u.priority) out.priority = u.priority;
+ return out;
+};
+
+// Drop bulky XML extensions and cap total entries so the JSON payload stays sane
+const slimResult = (r) => {
+ if (!r) return r;
+ const out = {};
+ if (r.urlset?.url) out.urlset = { url: r.urlset.url.slice(0, MAX_URLS).map(slimUrl) };
+ if (r.sitemapindex?.sitemap) {
+ out.sitemapindex = {
+ sitemap: r.sitemapindex.sitemap.map((s) => ({ loc: s.loc })),
+ };
+ }
+ if (r.sources) out.sources = r.sources;
+ return out;
+};
+
+// Try a candidate URL, return parsed result only when it looks like a real sitemap
+const tryFetch = async (target, label) => {
+ try {
+ const parsed = await fetchSitemap(target);
+ if (isValidSitemap(parsed)) return parsed;
+ log.debug(`${label} parsed but lacked urlset/sitemapindex (${target})`);
+ } catch (error) {
+ log.debug(`${label} fetch failed (${target})`, error.message);
+ }
+ return null;
+};
+
+const sitemapHandler = async (url) => {
+ const origin = toOrigin(url);
+ let parsed = await tryFetch(`${origin}/sitemap.xml`, 'sitemap.xml');
+ if (!parsed) {
+ const fromRobots = await findSitemapInRobots(origin);
+ if (fromRobots) parsed = await tryFetch(fromRobots, 'robots-listed sitemap');
+ }
+ if (!parsed) return { skipped: 'No sitemap found for this site' };
+ try {
+ return slimResult(await expandSitemap(parsed, 0));
+ } catch (error) {
+ return upstreamError(error, 'Sitemap fetch');
+ }
+};
+
+export const handler = middleware(sitemapHandler);
+export default handler;
diff --git a/packages/api/handlers/social-tags.js b/packages/api/handlers/social-tags.js
new file mode 100644
index 000000000..7902f60cf
--- /dev/null
+++ b/packages/api/handlers/social-tags.js
@@ -0,0 +1,76 @@
+import * as cheerio from 'cheerio';
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { upstreamError } from './_common/upstream.js';
+
+const socialTagsHandler = async (url) => {
+ let response;
+ try {
+ response = await httpGet(url);
+ } catch (error) {
+ return upstreamError(error, 'Social tags fetch');
+ }
+ try {
+ const $ = cheerio.load(response.data);
+
+ const metadata = {
+ // Basic meta tags
+ title: $('head title').text(),
+ description: $('meta[name="description"]').attr('content'),
+ keywords: $('meta[name="keywords"]').attr('content'),
+ canonicalUrl: $('link[rel="canonical"]').attr('href'),
+
+ // OpenGraph Protocol
+ ogTitle: $('meta[property="og:title"]').attr('content'),
+ ogType: $('meta[property="og:type"]').attr('content'),
+ ogImage: $('meta[property="og:image"]').attr('content'),
+ ogUrl: $('meta[property="og:url"]').attr('content'),
+ ogDescription: $('meta[property="og:description"]').attr('content'),
+ ogSiteName: $('meta[property="og:site_name"]').attr('content'),
+
+ // Twitter Cards
+ twitterCard: $('meta[name="twitter:card"]').attr('content'),
+ twitterSite: $('meta[name="twitter:site"]').attr('content'),
+ twitterCreator: $('meta[name="twitter:creator"]').attr('content'),
+ twitterTitle: $('meta[name="twitter:title"]').attr('content'),
+ twitterDescription: $('meta[name="twitter:description"]').attr('content'),
+ twitterImage: $('meta[name="twitter:image"]').attr('content'),
+
+ // Misc
+ themeColor: $('meta[name="theme-color"]').attr('content'),
+ robots: $('meta[name="robots"]').attr('content'),
+ googlebot: $('meta[name="googlebot"]').attr('content'),
+ generator: $('meta[name="generator"]').attr('content'),
+ viewport: $('meta[name="viewport"]').attr('content'),
+ author: $('meta[name="author"]').attr('content'),
+ publisher: $('link[rel="publisher"]').attr('href'),
+ favicon: $('link[rel="icon"]').attr('href'),
+ };
+
+ const SOCIAL_FIELDS = [
+ 'title',
+ 'description',
+ 'keywords',
+ 'canonicalUrl',
+ 'ogTitle',
+ 'ogImage',
+ 'ogDescription',
+ 'ogSiteName',
+ 'twitterTitle',
+ 'twitterDescription',
+ 'twitterImage',
+ 'author',
+ 'publisher',
+ 'themeColor',
+ ];
+ if (!SOCIAL_FIELDS.some((f) => metadata[f])) {
+ return { skipped: 'No social tags found on this page' };
+ }
+ return metadata;
+ } catch (error) {
+ return { error: `Failed parsing social tags: ${error.message}` };
+ }
+};
+
+export const handler = middleware(socialTagsHandler);
+export default handler;
diff --git a/packages/api/handlers/ssl.js b/packages/api/handlers/ssl.js
new file mode 100644
index 000000000..fe166d5c1
--- /dev/null
+++ b/packages/api/handlers/ssl.js
@@ -0,0 +1,36 @@
+import tls from 'tls';
+import middleware from './_common/middleware.js';
+
+const sslHandler = async (urlString) => {
+ const parsedUrl = new URL(urlString);
+ const options = {
+ host: parsedUrl.hostname,
+ port: parsedUrl.port || 443,
+ servername: parsedUrl.hostname,
+ rejectUnauthorized: false,
+ };
+
+ return new Promise((resolve, reject) => {
+ const socket = tls.connect(options, () => {
+ const cert = socket.getPeerCertificate();
+ if (!cert || Object.keys(cert).length === 0) {
+ reject(new Error('No certificate presented by the server'));
+ socket.end();
+ return;
+ }
+ const { raw, issuerCertificate, ...certData } = cert;
+ resolve({
+ ...certData,
+ isValid: socket.authorized,
+ authError: socket.authorizationError || null,
+ });
+ socket.end();
+ });
+ socket.on('error', (e) => {
+ reject(new Error(`SSL connection failed: ${e.message}`));
+ });
+ });
+};
+
+export const handler = middleware(sslHandler);
+export default handler;
diff --git a/packages/api/handlers/status.js b/packages/api/handlers/status.js
new file mode 100644
index 000000000..d3e37c9ca
--- /dev/null
+++ b/packages/api/handlers/status.js
@@ -0,0 +1,58 @@
+import https from 'https';
+import { performance, PerformanceObserver } from 'perf_hooks';
+import middleware from './_common/middleware.js';
+
+const statusHandler = async (url) => {
+ if (!url) {
+ throw new Error('You must provide a URL query parameter!');
+ }
+
+ let dnsLookupTime;
+ let responseCode;
+ let startTime;
+
+ const obs = new PerformanceObserver((items) => {
+ dnsLookupTime = items.getEntries()[0].duration;
+ performance.clearMarks();
+ });
+
+ obs.observe({ entryTypes: ['measure'] });
+
+ performance.mark('A');
+
+ try {
+ startTime = performance.now();
+ const response = await new Promise((resolve, reject) => {
+ const req = https.get(url, (res) => {
+ let data = '';
+ responseCode = res.statusCode;
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+ res.on('end', () => {
+ resolve(res);
+ });
+ });
+
+ req.on('error', reject);
+ req.end();
+ });
+
+ if (responseCode < 200 || responseCode >= 400) {
+ throw new Error(`Received non-success response code: ${responseCode}`);
+ }
+
+ performance.mark('B');
+ performance.measure('A to B', 'A', 'B');
+ let responseTime = performance.now() - startTime;
+ obs.disconnect();
+
+ return { isUp: true, dnsLookupTime, responseTime, responseCode };
+ } catch (error) {
+ obs.disconnect();
+ throw error;
+ }
+};
+
+export const handler = middleware(statusHandler);
+export default handler;
diff --git a/packages/api/handlers/tech-stack.js b/packages/api/handlers/tech-stack.js
new file mode 100644
index 000000000..2d62eff3b
--- /dev/null
+++ b/packages/api/handlers/tech-stack.js
@@ -0,0 +1,47 @@
+import chromium from '@sparticuz/chromium';
+import middleware from './_common/middleware.js';
+
+// Wappalyzer reads CHROMIUM_BIN at module load, so we must resolve
+// the path before importing it (hence the dynamic import in the handler)
+const ensureChromiumBin = async () => {
+ if (process.env.CHROMIUM_BIN) return;
+ const envPath = process.env.CHROME_PATH || process.env.PUPPETEER_EXECUTABLE_PATH;
+ if (envPath) {
+ process.env.CHROMIUM_BIN = envPath;
+ return;
+ }
+ // On serverless, puppeteer has no cached binary, use @sparticuz/chromium
+ if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.NETLIFY) {
+ process.env.CHROMIUM_BIN = await chromium.executablePath();
+ // Avoid conflict with @sparticuz/chromium's extraction path at /tmp/chromium
+ if (!process.env.CHROMIUM_DATA_DIR) {
+ process.env.CHROMIUM_DATA_DIR = '/tmp/chromium-data';
+ }
+ }
+};
+
+const techStackHandler = async (url) => {
+ await ensureChromiumBin();
+ const { default: Wappalyzer } = await import('wappalyzer');
+ const wappalyzer = new Wappalyzer({});
+
+ try {
+ await wappalyzer.init();
+ const site = await wappalyzer.open(url, {}, { local: {}, session: {} });
+ const results = await site.analyze();
+ if (!results.technologies || results.technologies.length === 0) {
+ throw new Error('Unable to find any technologies for site');
+ }
+ return results;
+ } catch (error) {
+ if (/ENOENT|Browser was not found|Could not find Chromium/i.test(error.message)) {
+ return { skipped: error.message };
+ }
+ throw new Error(error.message);
+ } finally {
+ await wappalyzer.destroy();
+ }
+};
+
+export const handler = middleware(techStackHandler);
+export default handler;
diff --git a/packages/api/handlers/threats.js b/packages/api/handlers/threats.js
new file mode 100644
index 000000000..1f8d72655
--- /dev/null
+++ b/packages/api/handlers/threats.js
@@ -0,0 +1,96 @@
+import xml2js from 'xml2js';
+import middleware from './_common/middleware.js';
+import { httpPost } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+import { requireEnv, upstreamError } from './_common/upstream.js';
+
+const safeBrowsing = async (url) => {
+ const auth = requireEnv('GOOGLE_CLOUD_API_KEY', 'Google Safe Browsing');
+ if (auth.skipped) return auth;
+ try {
+ const res = await httpPost(
+ `https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${auth.value}`,
+ {
+ threatInfo: {
+ threatTypes: [
+ 'MALWARE',
+ 'SOCIAL_ENGINEERING',
+ 'UNWANTED_SOFTWARE',
+ 'POTENTIALLY_HARMFUL_APPLICATION',
+ 'API_ABUSE',
+ ],
+ platformTypes: ['ANY_PLATFORM'],
+ threatEntryTypes: ['URL'],
+ threatEntries: [{ url }],
+ },
+ },
+ );
+ return res.data?.matches ? { unsafe: true, details: res.data.matches } : { unsafe: false };
+ } catch (error) {
+ return upstreamError(error, 'Google Safe Browsing');
+ }
+};
+
+const urlHaus = async (url) => {
+ const { hostname } = parseTarget(url);
+ try {
+ const res = await httpPost('https://urlhaus-api.abuse.ch/v1/host/', `host=${hostname}`, {
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ });
+ return res.data;
+ } catch (error) {
+ return upstreamError(error, 'URLhaus');
+ }
+};
+
+const phishTank = async (url) => {
+ try {
+ const encoded = Buffer.from(url).toString('base64');
+ const res = await httpPost(`https://checkurl.phishtank.com/checkurl/?url=${encoded}`, null, {
+ headers: { 'User-Agent': 'phishtank/web-check' },
+ timeout: 3000,
+ });
+ const parsed = await xml2js.parseStringPromise(res.data, { explicitArray: false });
+ return parsed.response.results;
+ } catch (error) {
+ return upstreamError(error, 'PhishTank');
+ }
+};
+
+const cloudmersive = async (url) => {
+ const auth = requireEnv('CLOUDMERSIVE_API_KEY', 'Cloudmersive');
+ if (auth.skipped) return auth;
+ try {
+ const res = await httpPost(
+ 'https://api.cloudmersive.com/virus/scan/website',
+ `Url=${encodeURIComponent(url)}`,
+ {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ Apikey: auth.value,
+ },
+ },
+ );
+ return res.data;
+ } catch (error) {
+ return upstreamError(error, 'Cloudmersive');
+ }
+};
+
+// Aggregate four threat-feed lookups; skip the card if every source failed
+const threatsHandler = async (url) => {
+ const sources = await Promise.all([
+ safeBrowsing(url),
+ urlHaus(url),
+ phishTank(url),
+ cloudmersive(url),
+ ]);
+ const [safe, haus, phish, cloud] = sources;
+ if (sources.every((s) => s?.error || s?.skipped)) {
+ return { skipped: 'No threat sources returned data for this host' };
+ }
+ return { safeBrowsing: safe, urlHaus: haus, phishTank: phish, cloudmersive: cloud };
+};
+
+export const handler = middleware(threatsHandler);
+export default handler;
diff --git a/packages/api/handlers/tls-connection.js b/packages/api/handlers/tls-connection.js
new file mode 100644
index 000000000..329b09c62
--- /dev/null
+++ b/packages/api/handlers/tls-connection.js
@@ -0,0 +1,84 @@
+import tls from 'tls';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+const HANDSHAKE_TIMEOUT = 4000;
+
+const isIp = (h) => /^[\d.]+$/.test(h) || h.includes(':');
+
+// Open one TLS handshake to the host and capture what was negotiated
+const handshake = ({ hostname, port }) =>
+ new Promise((resolve, reject) => {
+ let ocspStapled = false;
+ const socket = tls.connect({
+ host: hostname,
+ port: port ? Number(port) : 443,
+ ...(isIp(hostname) ? {} : { servername: hostname }),
+ ALPNProtocols: ['h2', 'http/1.1'],
+ rejectUnauthorized: false,
+ requestOCSP: true,
+ });
+ socket.on('OCSPResponse', (res) => {
+ ocspStapled = res?.length > 0;
+ });
+
+ let settled = false;
+ const finish = (fn) => (arg) => {
+ if (settled) return;
+ settled = true;
+ fn(arg);
+ };
+ socket.setTimeout(HANDSHAKE_TIMEOUT);
+ socket.once(
+ 'secureConnect',
+ finish(() => {
+ const cipher = socket.getCipher();
+ const protocol = socket.getProtocol();
+ const ephemeral =
+ typeof socket.getEphemeralKeyInfo === 'function' ? socket.getEphemeralKeyInfo() : null;
+ const result = {
+ protocol,
+ cipher: cipher && {
+ name: cipher.name,
+ standardName: cipher.standardName,
+ version: cipher.version,
+ },
+ alpnProtocol: socket.alpnProtocol || null,
+ sessionResumption: !!socket.getSession(),
+ forwardSecrecy: protocol === 'TLSv1.3' || (!!cipher && /^(ECDHE|DHE)/.test(cipher.name)),
+ authorized: socket.authorized,
+ authError: socket.authorizationError ? String(socket.authorizationError) : null,
+ ephemeralKey: ephemeral && {
+ type: ephemeral.type || null,
+ name: ephemeral.name || null,
+ size: ephemeral.size || null,
+ },
+ ocspStapled,
+ };
+ socket.end();
+ resolve(result);
+ }),
+ );
+ socket.once(
+ 'timeout',
+ finish(() => {
+ socket.destroy();
+ reject(new Error('TLS handshake timed-out'));
+ }),
+ );
+ socket.once(
+ 'error',
+ finish((err) => {
+ socket.destroy();
+ reject(err);
+ }),
+ );
+ });
+
+const tlsConnectionHandler = async (url) => {
+ const { hostname, port } = parseTarget(url);
+ return handshake({ hostname, port });
+};
+
+export const handler = middleware(tlsConnectionHandler);
+export default handler;
diff --git a/packages/api/handlers/tls-labs.js b/packages/api/handlers/tls-labs.js
new file mode 100644
index 000000000..900a3a7d7
--- /dev/null
+++ b/packages/api/handlers/tls-labs.js
@@ -0,0 +1,32 @@
+import middleware from './_common/middleware.js';
+import { httpGet } from './_common/http.js';
+import { parseTarget } from './_common/parse-target.js';
+import { upstreamError } from './_common/upstream.js';
+
+const SSL_LABS = 'https://api.ssllabs.com/api/v3/analyze';
+
+// Pull a cached SSL Labs report; skip if no fresh cache available
+const tlsLabsHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ try {
+ const res = await httpGet(SSL_LABS, {
+ params: { host: hostname, fromCache: 'on', maxAge: 24, all: 'done' },
+ timeout: 8000,
+ headers: { 'User-Agent': 'web-check (https://web-check.xyz)' },
+ });
+ const data = res.data;
+ if (!data || data.status !== 'READY' || !data.endpoints?.length) {
+ return {
+ skipped:
+ 'No cached SSL Labs report for this host. ' +
+ 'Run a fresh scan at https://www.ssllabs.com/ssltest/',
+ };
+ }
+ return data;
+ } catch (error) {
+ return upstreamError(error, 'SSL Labs lookup');
+ }
+};
+
+export const handler = middleware(tlsLabsHandler);
+export default handler;
diff --git a/packages/api/handlers/trace-route.js b/packages/api/handlers/trace-route.js
new file mode 100644
index 000000000..c181bdb91
--- /dev/null
+++ b/packages/api/handlers/trace-route.js
@@ -0,0 +1,58 @@
+import { execFile } from 'child_process';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+const LOCAL_TIMEOUT = 8000;
+
+// Parse traceroute -n output into [{ip, time}] entries, skipping unanswered hops
+const parseHops = (stdout) => {
+ const hops = [];
+ for (const line of stdout.split('\n')) {
+ const m = line.match(/^\s*\d+\s+([\d.]+|\S*::\S*)\s+([\d.]+)\s*ms/);
+ if (m) hops.push({ ip: m[1], time: Number(m[2]) });
+ }
+ return hops;
+};
+
+// Run the system traceroute binary via execFile (no shell, no injection)
+const runTraceroute = (host) =>
+ new Promise((resolve, reject) => {
+ execFile(
+ 'traceroute',
+ ['-q', '1', '-n', '-w', '2', host],
+ { timeout: LOCAL_TIMEOUT },
+ (err, stdout) => (err ? reject(err) : resolve(parseHops(stdout))),
+ );
+ });
+
+const isMissingBinary = (err) =>
+ err?.code === 'ENOENT' || /command not found|not installed/i.test(err?.message || '');
+
+const traceRouteHandler = async (url) => {
+ const start = Date.now();
+ const { hostname } = parseTarget(url);
+ let hops;
+ try {
+ hops = await runTraceroute(hostname);
+ } catch (err) {
+ if (isMissingBinary(err)) {
+ return {
+ skipped:
+ 'Traceroute is not installed in this environment. ' +
+ 'Install via your package manager, or run web-check via Docker.',
+ };
+ }
+ return { error: `Traceroute failed: ${err.message}` };
+ }
+ if (!hops.length) {
+ return { skipped: 'Traceroute returned no answered hops for this host' };
+ }
+ return {
+ message: 'Traceroute completed!',
+ result: hops.map(({ ip, time }) => ({ [ip]: [time] })),
+ timeTaken: Date.now() - start,
+ };
+};
+
+export const handler = middleware(traceRouteHandler);
+export default handler;
diff --git a/packages/api/handlers/txt-records.js b/packages/api/handlers/txt-records.js
new file mode 100644
index 000000000..76303605a
--- /dev/null
+++ b/packages/api/handlers/txt-records.js
@@ -0,0 +1,22 @@
+import dns from 'dns/promises';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+
+const txtRecordHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ const txtRecords = await dns.resolveTxt(hostname);
+ // Join chunks (DNS splits long records at 255 bytes), then key=value
+ const result = {};
+ for (const chunks of txtRecords) {
+ const full = chunks.join('');
+ const eq = full.indexOf('=');
+ let key = eq > 0 ? full.slice(0, eq) : full;
+ const val = eq > 0 ? full.slice(eq + 1) : '';
+ while (key in result) key += '_';
+ result[key] = val;
+ }
+ return result;
+};
+
+export const handler = middleware(txtRecordHandler);
+export default handler;
diff --git a/packages/api/handlers/whois.js b/packages/api/handlers/whois.js
new file mode 100644
index 000000000..9a3e0ec13
--- /dev/null
+++ b/packages/api/handlers/whois.js
@@ -0,0 +1,135 @@
+import net from 'net';
+import psl from 'psl';
+import { whoisDomain } from 'whoiser';
+import middleware from './_common/middleware.js';
+import { parseTarget } from './_common/parse-target.js';
+import { createLogger } from './_common/logger.js';
+
+const log = createLogger('whois');
+const TIMEOUT = 8000;
+
+// Walk every WHOIS/RDAP source, return the first non-empty value across the given keys
+const pick = (results, ...keys) => {
+ for (const src of Object.values(results)) {
+ for (const key of keys) {
+ const v = src?.[key];
+ if (v === undefined || v === null) continue;
+ if (typeof v === 'string' && !v.trim()) continue;
+ if (Array.isArray(v) && !v.length) continue;
+ return v;
+ }
+ }
+ return undefined;
+};
+
+// Lower-case + dedupe nameservers, drop empty entries
+const cleanNs = (ns) => {
+ if (!Array.isArray(ns)) return undefined;
+ const out = [...new Set(ns.map((n) => String(n).trim().toLowerCase()).filter(Boolean))];
+ return out.length ? out : undefined;
+};
+
+// Convert a date string to ISO 8601 when parseable, otherwise return the raw value
+const toIso = (raw) => {
+ if (!raw || typeof raw !== 'string') return raw;
+ const trimmed = raw.trim().replace(/\s*#.*$/, '');
+ const t = Date.parse(trimmed);
+ if (!Number.isNaN(t)) return new Date(t).toISOString();
+ const m = trimmed.match(/^(\d{4})(\d{2})(\d{2})$/);
+ if (m) return new Date(`${m[1]}-${m[2]}-${m[3]}T00:00:00Z`).toISOString();
+ return raw;
+};
+
+// Reduce a hostname to its registrable domain so registry WHOIS lookups succeed
+const baseDomain = (host) => psl.parse(host)?.domain || host;
+
+// Pull the formatted-name value out of an RDAP entity vCard
+const vcardFn = (vcard) => {
+ if (!Array.isArray(vcard?.[1])) return undefined;
+ const fn = vcard[1].find((f) => Array.isArray(f) && f[0] === 'fn');
+ return fn?.[3] || undefined;
+};
+
+// Map an RDAP response into the same field names whoiser exposes, so pick() works uniformly
+const rdapToWhoiserShape = (data) => {
+ if (!data || data.errorCode || data.objectClassName === 'error') return null;
+ const events = data.events || [];
+ const evt = (a) => events.find((e) => e.eventAction === a)?.eventDate;
+ const registrar = (data.entities || []).find((e) => (e.roles || []).includes('registrar'));
+ const ianaId = registrar?.publicIds?.find((p) => /iana/i.test(p.type))?.identifier;
+ const registrarUrlEntry = registrar?.links?.find((l) => l.rel === 'about' || l.rel === 'related');
+ return {
+ 'Domain Name': data.ldhName,
+ 'Created Date': evt('registration'),
+ 'Updated Date': evt('last changed') || evt('last update of RDAP database'),
+ 'Expiry Date': evt('expiration'),
+ 'Registry Domain ID': data.handle,
+ Registrar: vcardFn(registrar?.vcardArray),
+ 'Registrar IANA ID': ianaId,
+ 'Registrar URL': registrarUrlEntry?.href,
+ 'Domain Status': data.status,
+ 'Name Server': (data.nameservers || []).map((n) => n.ldhName).filter(Boolean),
+ DNSSEC: data.secureDNS?.delegationSigned ? 'signed' : 'unsigned',
+ };
+};
+
+// Last-resort lookup via rdap.org (a meta-resolver that bootstraps the right RDAP server)
+const fetchRdapFallback = async (domain) => {
+ try {
+ const res = await fetch(`https://rdap.org/domain/${encodeURIComponent(domain)}`, {
+ signal: AbortSignal.timeout(TIMEOUT),
+ });
+ if (!res.ok) return null;
+ return rdapToWhoiserShape(await res.json());
+ } catch {
+ return null;
+ }
+};
+
+// Whether a parsed result set has anything worth returning to the frontend
+const hasUsefulData = (r) =>
+ r &&
+ (pick(r, 'Created Date', 'Creation Date') ||
+ pick(r, 'Updated Date') ||
+ pick(r, 'Expiry Date', 'Registry Expiry Date') ||
+ pick(r, 'Registrar') ||
+ cleanNs(pick(r, 'Name Server')));
+
+// Resolve domain registration data via whoiser, with rdap.org as a fallback for TLD gaps
+const whoisHandler = async (url) => {
+ const { hostname } = parseTarget(url);
+ if (net.isIP(hostname)) {
+ return { skipped: 'WHOIS lookups apply to domains, not IP addresses' };
+ }
+ const target = baseDomain(hostname);
+ let results = {};
+ try {
+ results = await whoisDomain(target, { follow: 2, timeout: TIMEOUT });
+ } catch (error) {
+ log.debug(`whoisDomain failed for ${target}: ${error.message}`);
+ }
+ if (!hasUsefulData(results)) {
+ const rdap = await fetchRdapFallback(target);
+ if (rdap) results = { ...results, 'rdap.org': rdap };
+ }
+ if (!hasUsefulData(results)) {
+ return { skipped: 'No WHOIS data available for this domain' };
+ }
+ return {
+ domain: pick(results, 'Domain Name') || target,
+ registrar: pick(results, 'Registrar'),
+ registrarUrl: pick(results, 'Registrar URL'),
+ registrarIanaId: pick(results, 'Registrar IANA ID'),
+ registrarWhoisServer: pick(results, 'Registrar WHOIS Server'),
+ registryDomainId: pick(results, 'Registry Domain ID'),
+ created: toIso(pick(results, 'Created Date', 'Creation Date')),
+ updated: toIso(pick(results, 'Updated Date')),
+ expires: toIso(pick(results, 'Expiry Date', 'Registry Expiry Date', 'Expiration Date')),
+ nameservers: cleanNs(pick(results, 'Name Server')),
+ status: pick(results, 'Domain Status'),
+ dnssec: pick(results, 'DNSSEC'),
+ };
+};
+
+export const handler = middleware(whoisHandler);
+export default handler;
diff --git a/packages/api/package.json b/packages/api/package.json
new file mode 100644
index 000000000..27a3fcd18
--- /dev/null
+++ b/packages/api/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@web-check/api",
+ "version": "2.1.0",
+ "private": true,
+ "type": "module",
+ "main": "./server.js",
+ "scripts": {
+ "start": "node server.js",
+ "dev": "DISABLE_GUI='true' PORT='3001' nodemon server.js"
+ },
+ "dependencies": {
+ "@sparticuz/chromium": "^148.0.0",
+ "cheerio": "^1.2.0",
+ "cors": "^2.8.6",
+ "dotenv": "^17.4.2",
+ "express": "^5.2.1",
+ "express-rate-limit": "^8.5.0",
+ "psl": "^1.15.0",
+ "puppeteer": "^24.42.0",
+ "puppeteer-core": "^24.42.0",
+ "wappalyzer": "^6.10.66",
+ "whoiser": "^2.0.0-beta.10",
+ "xml2js": "^0.6.2"
+ },
+ "devDependencies": {
+ "nodemon": "^3.1.14"
+ }
+}
diff --git a/packages/api/server.js b/packages/api/server.js
new file mode 100644
index 000000000..8853f452b
--- /dev/null
+++ b/packages/api/server.js
@@ -0,0 +1,203 @@
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+import cors from 'cors';
+import dotenv from 'dotenv';
+import express from 'express';
+import rateLimit from 'express-rate-limit';
+import { createLogger } from './handlers/_common/logger.js';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+// Load env from the monorepo root so all workspaces share one .env file
+dotenv.config({ path: path.resolve(__dirname, '..', '..', '.env') });
+
+const log = createLogger('server');
+
+const PORT = parseInt(process.env.PORT || '3000', 10);
+const API_DIR = '/api';
+const HANDLERS_DIR = path.join(__dirname, 'handlers');
+const STATIC_DIR = path.join(__dirname, 'static');
+const APP_DIST = process.env.APP_STATIC_DIR || path.resolve(__dirname, '..', 'app', 'dist');
+const APP_INDEX = path.join(APP_DIST, 'index.html');
+
+// Tells middleware to use the express-style handler signature
+process.env.WC_SERVER = 'true';
+
+const app = express();
+
+// Honour TRUST_PROXY when set, parsing booleans and integer hop counts
+const trustProxy = process.env.TRUST_PROXY;
+if (trustProxy) {
+ const parsed = /^\d+$/.test(trustProxy)
+ ? parseInt(trustProxy, 10)
+ : trustProxy === 'true'
+ ? true
+ : trustProxy === 'false'
+ ? false
+ : trustProxy;
+ app.set('trust proxy', parsed);
+}
+
+app.use(cors({ origin: process.env.API_CORS_ORIGIN || '*' }));
+
+const RATE_LIMITS = [
+ { window: 10 * 60, max: 100, label: '10 minutes' },
+ { window: 60 * 60, max: 250, label: '1 hour' },
+ { window: 12 * 60 * 60, max: 500, label: '12 hours' },
+];
+
+const rateLimitMessage = (label) =>
+ `You've been rate-limited, please try again in ${label}.\n` +
+ 'This keeps the service running smoothly for everyone. ' +
+ 'You can get around these limits by running your own instance of Web Check.';
+
+if (process.env.API_ENABLE_RATE_LIMIT === 'true') {
+ for (const limit of RATE_LIMITS) {
+ app.use(
+ API_DIR,
+ rateLimit({
+ windowMs: limit.window * 1000,
+ limit: limit.max,
+ standardHeaders: true,
+ legacyHeaders: false,
+ message: { error: rateLimitMessage(limit.label) },
+ }),
+ );
+ }
+}
+
+const handlers = {};
+
+// Discover and dynamically import every handler module under ./handlers
+const loadHandlers = async () => {
+ const entries = await fs.promises.readdir(HANDLERS_DIR, { withFileTypes: true });
+ const files = entries.filter((e) => e.isFile() && e.name.endsWith('.js'));
+ await Promise.all(
+ files.map(async (entry) => {
+ const route = `${API_DIR}/${entry.name.replace(/\.js$/, '')}`;
+ try {
+ const mod = await import(path.join(HANDLERS_DIR, entry.name));
+ const handler = mod.default || mod.handler;
+ if (typeof handler === 'function') handlers[route] = handler;
+ } catch (err) {
+ log.error(`failed to load handler ${entry.name}: ${err.message}`);
+ }
+ }),
+ );
+
+ for (const [route, handler] of Object.entries(handlers)) {
+ app.get(route, async (req, res) => {
+ try {
+ await handler(req, res);
+ } catch (err) {
+ res.status(500).json({ error: err.message });
+ }
+ });
+ }
+};
+
+// Render the static placeholder template with a status message
+const renderPlaceholder = async (res, msgId, logs) => {
+ const messages = {
+ notCompiled:
+ 'Looks like the GUI app has not yet been compiled.
' +
+ 'Run yarn build to continue, then restart the server.',
+ disabledGui:
+ 'Web-Check API is up and running!
Access the endpoints at ' +
+ `${API_DIR}`,
+ };
+ const tail = logs ? `
${logs}
` : '';
+ const body = (messages[msgId] || 'An unknown error occurred') + tail;
+ try {
+ const tplPath = path.join(STATIC_DIR, 'placeholder.html');
+ const tpl = await fs.promises.readFile(tplPath, 'utf-8');
+ res.status(500).send(tpl.replace('', body));
+ } catch {
+ res.status(500).send(`${body}`);
+ }
+};
+
+// Aggregate every handler in parallel for the bare /api endpoint
+app.get(API_DIR, async (req, res) => {
+ const { url } = req.query;
+ const maxMs = parseInt(process.env.PUBLIC_API_TIMEOUT_LIMIT || '60000', 10);
+
+ const runHandler = async (handler, name) => {
+ let captured;
+ const mockRes = { status: () => mockRes, json: (body) => (captured = body) };
+ let timer;
+ const timeout = new Promise((resolve) => {
+ timer = setTimeout(() => {
+ const seconds = maxMs / 1000;
+ resolve({ error: `Timed out after ${seconds} seconds, when executing ${name}` });
+ }, maxMs);
+ });
+ const work = handler({ ...req, query: { url } }, mockRes)
+ .then(() => captured)
+ .catch((err) => ({ error: err.message }));
+ const result = await Promise.race([work, timeout]);
+ clearTimeout(timer);
+ return result;
+ };
+
+ const results = {};
+ await Promise.all(
+ Object.entries(handlers).map(async ([route, handler]) => {
+ const name = route.replace(`${API_DIR}/`, '');
+ results[name] = await runHandler(handler, name);
+ }),
+ );
+ res.json(results);
+});
+
+await loadHandlers();
+
+const guiDisabled = process.env.DISABLE_GUI && process.env.DISABLE_GUI !== 'false';
+const guiAvailable = !guiDisabled && fs.existsSync(APP_INDEX);
+
+// Redirect bare root to the React app, unless the GUI has been disabled
+app.get('/', (_req, res) => {
+ if (guiDisabled) return renderPlaceholder(res, 'disabledGui');
+ if (!guiAvailable) return renderPlaceholder(res, 'notCompiled');
+ res.redirect(302, '/check');
+});
+
+if (guiAvailable) {
+ app.use(express.static(APP_DIST, { index: false }));
+ // SPA fallback: serve app shell for /check, redirect other paths to it
+ app.use((req, res, next) => {
+ if (req.method !== 'GET' || req.path.startsWith(`${API_DIR}/`)) return next();
+ if (req.path === '/check' || req.path.startsWith('/check/')) {
+ return res.sendFile(APP_INDEX);
+ }
+ res.redirect(302, '/check');
+ });
+}
+
+// Final fallback for unmatched paths
+app.use((req, res) => {
+ if (req.path.startsWith(`${API_DIR}/`)) {
+ res.status(404).json({ error: 'Not found' });
+ } else if (!guiAvailable) {
+ renderPlaceholder(res, 'notCompiled');
+ } else {
+ res.status(404).sendFile(path.join(STATIC_DIR, 'error.html'));
+ }
+});
+
+const banner = () => {
+ process.stdout.write(
+ '\x1b[36m\n' +
+ ' __ __ _ ___ _ _ \n' +
+ ' \\ \\ / /__| |__ ___ / __| |_ ___ __| |__\n' +
+ " \\ \\/\\/ / -_) '_ \\___| (__| ' \\/ -_) _| / /\n" +
+ ' \\_/\\_/\\___|_.__/ \\___|_||_\\___\\__|_\\_\\\n' +
+ '\x1b[0m\n' +
+ `\x1b[1m\x1b[32mWeb-Check is up and running at ` +
+ `http://localhost:${PORT}\x1b[0m\n` +
+ '\x1b[2m\x1b[36m https://github.com/lissy93/web-check\x1b[0m\n\n',
+ );
+};
+
+app.listen(PORT, banner);
diff --git a/public/error.html b/packages/api/static/error.html
similarity index 100%
rename from public/error.html
rename to packages/api/static/error.html
diff --git a/public/placeholder.html b/packages/api/static/placeholder.html
similarity index 100%
rename from public/placeholder.html
rename to packages/api/static/placeholder.html
diff --git a/packages/app/index.html b/packages/app/index.html
new file mode 100644
index 000000000..1d1501a46
--- /dev/null
+++ b/packages/app/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Web Check
+
+
+
+
+
+
diff --git a/packages/app/package.json b/packages/app/package.json
new file mode 100644
index 000000000..76a5d2962
--- /dev/null
+++ b/packages/app/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "@web-check/app",
+ "version": "2.1.0",
+ "private": true,
+ "type": "module",
+ "exports": {
+ "./main": "./src/main.tsx",
+ "./styles/*": "./src/styles/*",
+ "./*": "./src/*"
+ },
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@emotion/react": "^11.14.0",
+ "@emotion/styled": "^11.14.1",
+ "framer-motion": "^12.38.0",
+ "prop-types": "^15.8.1",
+ "react": "^19.2.5",
+ "react-dom": "^19.2.5",
+ "react-masonry-css": "^1.0.16",
+ "react-router-dom": "^7.14.2",
+ "react-simple-maps": "^3.0.0",
+ "react-toastify": "^11.1.0",
+ "recharts": "^3.8.1"
+ },
+ "devDependencies": {
+ "@types/react": "^19.2.14",
+ "@types/react-dom": "^19.2.3",
+ "@vitejs/plugin-react": "^5.0.4",
+ "typescript": "^6.0.3",
+ "vite": "^7.2.0"
+ }
+}
diff --git a/src/web-check-live/App.tsx b/packages/app/src/App.tsx
similarity index 100%
rename from src/web-check-live/App.tsx
rename to packages/app/src/App.tsx
diff --git a/src/web-check-live/assets/data/map-features.json b/packages/app/src/assets/data/map-features.json
similarity index 100%
rename from src/web-check-live/assets/data/map-features.json
rename to packages/app/src/assets/data/map-features.json
diff --git a/src/web-check-live/components/Form/Button.tsx b/packages/app/src/components/Form/Button.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Button.tsx
rename to packages/app/src/components/Form/Button.tsx
diff --git a/src/web-check-live/components/Form/Card.tsx b/packages/app/src/components/Form/Card.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Card.tsx
rename to packages/app/src/components/Form/Card.tsx
diff --git a/src/web-check-live/components/Form/Heading.tsx b/packages/app/src/components/Form/Heading.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Heading.tsx
rename to packages/app/src/components/Form/Heading.tsx
diff --git a/src/web-check-live/components/Form/Input.tsx b/packages/app/src/components/Form/Input.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Input.tsx
rename to packages/app/src/components/Form/Input.tsx
diff --git a/src/web-check-live/components/Form/Modal.tsx b/packages/app/src/components/Form/Modal.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Modal.tsx
rename to packages/app/src/components/Form/Modal.tsx
diff --git a/src/web-check-live/components/Form/Nav.tsx b/packages/app/src/components/Form/Nav.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Nav.tsx
rename to packages/app/src/components/Form/Nav.tsx
diff --git a/src/web-check-live/components/Form/Row.tsx b/packages/app/src/components/Form/Row.tsx
similarity index 100%
rename from src/web-check-live/components/Form/Row.tsx
rename to packages/app/src/components/Form/Row.tsx
diff --git a/src/web-check-live/components/Results/Archives.tsx b/packages/app/src/components/Results/Archives.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Archives.tsx
rename to packages/app/src/components/Results/Archives.tsx
diff --git a/src/web-check-live/components/Results/BlockLists.tsx b/packages/app/src/components/Results/BlockLists.tsx
similarity index 100%
rename from src/web-check-live/components/Results/BlockLists.tsx
rename to packages/app/src/components/Results/BlockLists.tsx
diff --git a/src/web-check-live/components/Results/BuiltWith.tsx b/packages/app/src/components/Results/BuiltWith.tsx
similarity index 100%
rename from src/web-check-live/components/Results/BuiltWith.tsx
rename to packages/app/src/components/Results/BuiltWith.tsx
diff --git a/src/web-check-live/components/Results/CarbonFootprint.tsx b/packages/app/src/components/Results/CarbonFootprint.tsx
similarity index 100%
rename from src/web-check-live/components/Results/CarbonFootprint.tsx
rename to packages/app/src/components/Results/CarbonFootprint.tsx
diff --git a/src/web-check-live/components/Results/ContentLinks.tsx b/packages/app/src/components/Results/ContentLinks.tsx
similarity index 100%
rename from src/web-check-live/components/Results/ContentLinks.tsx
rename to packages/app/src/components/Results/ContentLinks.tsx
diff --git a/src/web-check-live/components/Results/Cookies.tsx b/packages/app/src/components/Results/Cookies.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Cookies.tsx
rename to packages/app/src/components/Results/Cookies.tsx
diff --git a/src/web-check-live/components/Results/DnsRecords.tsx b/packages/app/src/components/Results/DnsRecords.tsx
similarity index 100%
rename from src/web-check-live/components/Results/DnsRecords.tsx
rename to packages/app/src/components/Results/DnsRecords.tsx
diff --git a/src/web-check-live/components/Results/DnsSec.tsx b/packages/app/src/components/Results/DnsSec.tsx
similarity index 100%
rename from src/web-check-live/components/Results/DnsSec.tsx
rename to packages/app/src/components/Results/DnsSec.tsx
diff --git a/src/web-check-live/components/Results/DnsServer.tsx b/packages/app/src/components/Results/DnsServer.tsx
similarity index 100%
rename from src/web-check-live/components/Results/DnsServer.tsx
rename to packages/app/src/components/Results/DnsServer.tsx
diff --git a/src/web-check-live/components/Results/DomainLookup.tsx b/packages/app/src/components/Results/DomainLookup.tsx
similarity index 100%
rename from src/web-check-live/components/Results/DomainLookup.tsx
rename to packages/app/src/components/Results/DomainLookup.tsx
diff --git a/src/web-check-live/components/Results/Firewall.tsx b/packages/app/src/components/Results/Firewall.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Firewall.tsx
rename to packages/app/src/components/Results/Firewall.tsx
diff --git a/src/web-check-live/components/Results/Headers.tsx b/packages/app/src/components/Results/Headers.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Headers.tsx
rename to packages/app/src/components/Results/Headers.tsx
diff --git a/src/web-check-live/components/Results/HostNames.tsx b/packages/app/src/components/Results/HostNames.tsx
similarity index 100%
rename from src/web-check-live/components/Results/HostNames.tsx
rename to packages/app/src/components/Results/HostNames.tsx
diff --git a/src/web-check-live/components/Results/Hsts.tsx b/packages/app/src/components/Results/Hsts.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Hsts.tsx
rename to packages/app/src/components/Results/Hsts.tsx
diff --git a/src/web-check-live/components/Results/HttpSecurity.tsx b/packages/app/src/components/Results/HttpSecurity.tsx
similarity index 100%
rename from src/web-check-live/components/Results/HttpSecurity.tsx
rename to packages/app/src/components/Results/HttpSecurity.tsx
diff --git a/src/web-check-live/components/Results/Lighthouse.tsx b/packages/app/src/components/Results/Lighthouse.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Lighthouse.tsx
rename to packages/app/src/components/Results/Lighthouse.tsx
diff --git a/src/web-check-live/components/Results/MailConfig.tsx b/packages/app/src/components/Results/MailConfig.tsx
similarity index 100%
rename from src/web-check-live/components/Results/MailConfig.tsx
rename to packages/app/src/components/Results/MailConfig.tsx
diff --git a/src/web-check-live/components/Results/OpenPorts.tsx b/packages/app/src/components/Results/OpenPorts.tsx
similarity index 100%
rename from src/web-check-live/components/Results/OpenPorts.tsx
rename to packages/app/src/components/Results/OpenPorts.tsx
diff --git a/src/web-check-live/components/Results/Rank.tsx b/packages/app/src/components/Results/Rank.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Rank.tsx
rename to packages/app/src/components/Results/Rank.tsx
diff --git a/src/web-check-live/components/Results/Redirects.tsx b/packages/app/src/components/Results/Redirects.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Redirects.tsx
rename to packages/app/src/components/Results/Redirects.tsx
diff --git a/src/web-check-live/components/Results/RobotsTxt.tsx b/packages/app/src/components/Results/RobotsTxt.tsx
similarity index 100%
rename from src/web-check-live/components/Results/RobotsTxt.tsx
rename to packages/app/src/components/Results/RobotsTxt.tsx
diff --git a/src/web-check-live/components/Results/Screenshot.tsx b/packages/app/src/components/Results/Screenshot.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Screenshot.tsx
rename to packages/app/src/components/Results/Screenshot.tsx
diff --git a/src/web-check-live/components/Results/SecurityTxt.tsx b/packages/app/src/components/Results/SecurityTxt.tsx
similarity index 100%
rename from src/web-check-live/components/Results/SecurityTxt.tsx
rename to packages/app/src/components/Results/SecurityTxt.tsx
diff --git a/src/web-check-live/components/Results/ServerInfo.tsx b/packages/app/src/components/Results/ServerInfo.tsx
similarity index 100%
rename from src/web-check-live/components/Results/ServerInfo.tsx
rename to packages/app/src/components/Results/ServerInfo.tsx
diff --git a/src/web-check-live/components/Results/ServerLocation.tsx b/packages/app/src/components/Results/ServerLocation.tsx
similarity index 100%
rename from src/web-check-live/components/Results/ServerLocation.tsx
rename to packages/app/src/components/Results/ServerLocation.tsx
diff --git a/src/web-check-live/components/Results/ServerStatus.tsx b/packages/app/src/components/Results/ServerStatus.tsx
similarity index 100%
rename from src/web-check-live/components/Results/ServerStatus.tsx
rename to packages/app/src/components/Results/ServerStatus.tsx
diff --git a/src/web-check-live/components/Results/Sitemap.tsx b/packages/app/src/components/Results/Sitemap.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Sitemap.tsx
rename to packages/app/src/components/Results/Sitemap.tsx
diff --git a/src/web-check-live/components/Results/SocialTags.tsx b/packages/app/src/components/Results/SocialTags.tsx
similarity index 100%
rename from src/web-check-live/components/Results/SocialTags.tsx
rename to packages/app/src/components/Results/SocialTags.tsx
diff --git a/src/web-check-live/components/Results/SslCert.tsx b/packages/app/src/components/Results/SslCert.tsx
similarity index 100%
rename from src/web-check-live/components/Results/SslCert.tsx
rename to packages/app/src/components/Results/SslCert.tsx
diff --git a/src/web-check-live/components/Results/TechStack.tsx b/packages/app/src/components/Results/TechStack.tsx
similarity index 100%
rename from src/web-check-live/components/Results/TechStack.tsx
rename to packages/app/src/components/Results/TechStack.tsx
diff --git a/src/web-check-live/components/Results/Threats.tsx b/packages/app/src/components/Results/Threats.tsx
similarity index 100%
rename from src/web-check-live/components/Results/Threats.tsx
rename to packages/app/src/components/Results/Threats.tsx
diff --git a/src/web-check-live/components/Results/TlsClientCompat.tsx b/packages/app/src/components/Results/TlsClientCompat.tsx
similarity index 100%
rename from src/web-check-live/components/Results/TlsClientCompat.tsx
rename to packages/app/src/components/Results/TlsClientCompat.tsx
diff --git a/src/web-check-live/components/Results/TlsConnection.tsx b/packages/app/src/components/Results/TlsConnection.tsx
similarity index 100%
rename from src/web-check-live/components/Results/TlsConnection.tsx
rename to packages/app/src/components/Results/TlsConnection.tsx
diff --git a/src/web-check-live/components/Results/TlsSecurityAudit.tsx b/packages/app/src/components/Results/TlsSecurityAudit.tsx
similarity index 100%
rename from src/web-check-live/components/Results/TlsSecurityAudit.tsx
rename to packages/app/src/components/Results/TlsSecurityAudit.tsx
diff --git a/src/web-check-live/components/Results/TraceRoute.tsx b/packages/app/src/components/Results/TraceRoute.tsx
similarity index 100%
rename from src/web-check-live/components/Results/TraceRoute.tsx
rename to packages/app/src/components/Results/TraceRoute.tsx
diff --git a/src/web-check-live/components/Results/TxtRecords.tsx b/packages/app/src/components/Results/TxtRecords.tsx
similarity index 100%
rename from src/web-check-live/components/Results/TxtRecords.tsx
rename to packages/app/src/components/Results/TxtRecords.tsx
diff --git a/src/web-check-live/components/Results/WhoIs.tsx b/packages/app/src/components/Results/WhoIs.tsx
similarity index 100%
rename from src/web-check-live/components/Results/WhoIs.tsx
rename to packages/app/src/components/Results/WhoIs.tsx
diff --git a/src/web-check-live/components/boundaries/PageError.tsx b/packages/app/src/components/boundaries/PageError.tsx
similarity index 100%
rename from src/web-check-live/components/boundaries/PageError.tsx
rename to packages/app/src/components/boundaries/PageError.tsx
diff --git a/src/web-check-live/components/misc/ActionButtons.tsx b/packages/app/src/components/misc/ActionButtons.tsx
similarity index 100%
rename from src/web-check-live/components/misc/ActionButtons.tsx
rename to packages/app/src/components/misc/ActionButtons.tsx
diff --git a/src/web-check-live/components/misc/AdditionalResources.tsx b/packages/app/src/components/misc/AdditionalResources.tsx
similarity index 100%
rename from src/web-check-live/components/misc/AdditionalResources.tsx
rename to packages/app/src/components/misc/AdditionalResources.tsx
diff --git a/src/web-check-live/components/misc/DocContent.tsx b/packages/app/src/components/misc/DocContent.tsx
similarity index 100%
rename from src/web-check-live/components/misc/DocContent.tsx
rename to packages/app/src/components/misc/DocContent.tsx
diff --git a/src/web-check-live/components/misc/ErrorBoundary.tsx b/packages/app/src/components/misc/ErrorBoundary.tsx
similarity index 100%
rename from src/web-check-live/components/misc/ErrorBoundary.tsx
rename to packages/app/src/components/misc/ErrorBoundary.tsx
diff --git a/src/web-check-live/components/misc/FancyBackground.tsx b/packages/app/src/components/misc/FancyBackground.tsx
similarity index 100%
rename from src/web-check-live/components/misc/FancyBackground.tsx
rename to packages/app/src/components/misc/FancyBackground.tsx
diff --git a/src/web-check-live/components/misc/Flag.tsx b/packages/app/src/components/misc/Flag.tsx
similarity index 100%
rename from src/web-check-live/components/misc/Flag.tsx
rename to packages/app/src/components/misc/Flag.tsx
diff --git a/src/web-check-live/components/misc/Footer.tsx b/packages/app/src/components/misc/Footer.tsx
similarity index 100%
rename from src/web-check-live/components/misc/Footer.tsx
rename to packages/app/src/components/misc/Footer.tsx
diff --git a/src/web-check-live/components/misc/Loader.tsx b/packages/app/src/components/misc/Loader.tsx
similarity index 100%
rename from src/web-check-live/components/misc/Loader.tsx
rename to packages/app/src/components/misc/Loader.tsx
diff --git a/src/web-check-live/components/misc/LocationMap.tsx b/packages/app/src/components/misc/LocationMap.tsx
similarity index 100%
rename from src/web-check-live/components/misc/LocationMap.tsx
rename to packages/app/src/components/misc/LocationMap.tsx
diff --git a/src/web-check-live/components/misc/ProgressBar.tsx b/packages/app/src/components/misc/ProgressBar.tsx
similarity index 100%
rename from src/web-check-live/components/misc/ProgressBar.tsx
rename to packages/app/src/components/misc/ProgressBar.tsx
diff --git a/src/web-check-live/components/misc/SelfScanMsg.tsx b/packages/app/src/components/misc/SelfScanMsg.tsx
similarity index 100%
rename from src/web-check-live/components/misc/SelfScanMsg.tsx
rename to packages/app/src/components/misc/SelfScanMsg.tsx
diff --git a/src/web-check-live/components/misc/ViewRaw.tsx b/packages/app/src/components/misc/ViewRaw.tsx
similarity index 100%
rename from src/web-check-live/components/misc/ViewRaw.tsx
rename to packages/app/src/components/misc/ViewRaw.tsx
diff --git a/packages/app/src/entry.tsx b/packages/app/src/entry.tsx
new file mode 100644
index 000000000..e606d3c57
--- /dev/null
+++ b/packages/app/src/entry.tsx
@@ -0,0 +1,7 @@
+import { createRoot } from 'react-dom/client';
+import Main from './main';
+import './styles/index.css';
+
+// Standalone mount used by vite build and the Express server
+const container = document.getElementById('root');
+if (container) createRoot(container).render();
diff --git a/src/web-check-live/hooks/useJobs.ts b/packages/app/src/hooks/useJobs.ts
similarity index 100%
rename from src/web-check-live/hooks/useJobs.ts
rename to packages/app/src/hooks/useJobs.ts
diff --git a/src/web-check-live/jobs/registry.ts b/packages/app/src/jobs/registry.ts
similarity index 100%
rename from src/web-check-live/jobs/registry.ts
rename to packages/app/src/jobs/registry.ts
diff --git a/src/web-check-live/jobs/types.ts b/packages/app/src/jobs/types.ts
similarity index 100%
rename from src/web-check-live/jobs/types.ts
rename to packages/app/src/jobs/types.ts
diff --git a/src/web-check-live/main.tsx b/packages/app/src/main.tsx
similarity index 100%
rename from src/web-check-live/main.tsx
rename to packages/app/src/main.tsx
diff --git a/src/web-check-live/styles/colors.ts b/packages/app/src/styles/colors.ts
similarity index 100%
rename from src/web-check-live/styles/colors.ts
rename to packages/app/src/styles/colors.ts
diff --git a/src/web-check-live/styles/dimensions.ts b/packages/app/src/styles/dimensions.ts
similarity index 100%
rename from src/web-check-live/styles/dimensions.ts
rename to packages/app/src/styles/dimensions.ts
diff --git a/src/web-check-live/styles/globals.tsx b/packages/app/src/styles/globals.tsx
similarity index 100%
rename from src/web-check-live/styles/globals.tsx
rename to packages/app/src/styles/globals.tsx
diff --git a/src/web-check-live/styles/index.css b/packages/app/src/styles/index.css
similarity index 100%
rename from src/web-check-live/styles/index.css
rename to packages/app/src/styles/index.css
diff --git a/src/web-check-live/styles/typography.ts b/packages/app/src/styles/typography.ts
similarity index 100%
rename from src/web-check-live/styles/typography.ts
rename to packages/app/src/styles/typography.ts
diff --git a/src/web-check-live/typings/file-types.d.ts b/packages/app/src/typings/file-types.d.ts
similarity index 100%
rename from src/web-check-live/typings/file-types.d.ts
rename to packages/app/src/typings/file-types.d.ts
diff --git a/src/web-check-live/typings/jsx.d.ts b/packages/app/src/typings/jsx.d.ts
similarity index 100%
rename from src/web-check-live/typings/jsx.d.ts
rename to packages/app/src/typings/jsx.d.ts
diff --git a/src/web-check-live/typings/react-simple-maps.d.ts b/packages/app/src/typings/react-simple-maps.d.ts
similarity index 100%
rename from src/web-check-live/typings/react-simple-maps.d.ts
rename to packages/app/src/typings/react-simple-maps.d.ts
diff --git a/src/web-check-live/utils/address-type-checker.ts b/packages/app/src/utils/address-type-checker.ts
similarity index 100%
rename from src/web-check-live/utils/address-type-checker.ts
rename to packages/app/src/utils/address-type-checker.ts
diff --git a/src/web-check-live/utils/docs.ts b/packages/app/src/utils/docs.ts
similarity index 100%
rename from src/web-check-live/utils/docs.ts
rename to packages/app/src/utils/docs.ts
diff --git a/src/web-check-live/utils/get-keys.ts b/packages/app/src/utils/get-keys.ts
similarity index 100%
rename from src/web-check-live/utils/get-keys.ts
rename to packages/app/src/utils/get-keys.ts
diff --git a/src/web-check-live/utils/logger.ts b/packages/app/src/utils/logger.ts
similarity index 100%
rename from src/web-check-live/utils/logger.ts
rename to packages/app/src/utils/logger.ts
diff --git a/src/web-check-live/utils/parse-json.ts b/packages/app/src/utils/parse-json.ts
similarity index 100%
rename from src/web-check-live/utils/parse-json.ts
rename to packages/app/src/utils/parse-json.ts
diff --git a/src/web-check-live/utils/result-processor.ts b/packages/app/src/utils/result-processor.ts
similarity index 100%
rename from src/web-check-live/utils/result-processor.ts
rename to packages/app/src/utils/result-processor.ts
diff --git a/src/web-check-live/views/About.tsx b/packages/app/src/views/About.tsx
similarity index 100%
rename from src/web-check-live/views/About.tsx
rename to packages/app/src/views/About.tsx
diff --git a/src/web-check-live/views/Home.tsx b/packages/app/src/views/Home.tsx
similarity index 74%
rename from src/web-check-live/views/Home.tsx
rename to packages/app/src/views/Home.tsx
index 0abcf1c50..e31b5b36e 100644
--- a/src/web-check-live/views/Home.tsx
+++ b/packages/app/src/views/Home.tsx
@@ -38,59 +38,6 @@ const UserInputMain = styled.form`
z-index: 2;
`;
-const SponsorCard = styled.div`
- background: ${colors.backgroundLighter};
- box-shadow: 4px 4px 0px ${colors.bgShadowColor};
- border-radius: 8px;
- padding: 1rem;
- z-index: 5;
- margin: 1rem;
- width: calc(100% - 2rem);
- max-width: 60rem;
- z-index: 2;
- .inner {
- display: flex;
- justify-content: space-between;
- flex-wrap: wrap;
- gap: 1rem;
- p {
- margin: 0.25rem 0;
- }
- }
- a {
- color: ${colors.textColor};
- }
- img {
- border-radius: 0.25rem;
- box-shadow: 2px 2px 0px ${colors.fgShadowColor};
- transition: box-shadow 0.2s;
- margin: 0 auto;
- display: block;
- width: 200px;
- &:hover {
- box-shadow: 4px 4px 0px ${colors.fgShadowColor};
- }
- &:active {
- box-shadow: -2px -2px 0px ${colors.fgShadowColor};
- }
- }
- .cta {
- font-size: 0.78rem;
- a {
- color: ${colors.primary};
- }
- }
-`;
-
-// const FindIpButton = styled.a`
-// margin: 0.5rem;
-// cursor: pointer;
-// display: block;
-// text-align: center;
-// color: ${colors.primary};
-// text-decoration: underline;
-// `;
-
const ErrorMessage = styled.p`
color: ${colors.danger};
margin: 0.5rem;
@@ -241,46 +188,6 @@ const Home = (): JSX.Element => {
Analyze!
-
-
- Sponsored by
-
-
-
diff --git a/src/web-check-live/views/NotFound.tsx b/packages/app/src/views/NotFound.tsx
similarity index 100%
rename from src/web-check-live/views/NotFound.tsx
rename to packages/app/src/views/NotFound.tsx
diff --git a/src/web-check-live/views/Results.tsx b/packages/app/src/views/Results.tsx
similarity index 100%
rename from src/web-check-live/views/Results.tsx
rename to packages/app/src/views/Results.tsx
diff --git a/packages/app/tsconfig.json b/packages/app/tsconfig.json
new file mode 100644
index 000000000..534e0deaf
--- /dev/null
+++ b/packages/app/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "ES2020",
+ "moduleResolution": "node",
+ "allowImportingTsExtensions": true,
+ "lib": ["DOM", "DOM.Iterable", "ES2020"],
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "jsxImportSource": "react",
+ "baseUrl": ".",
+ "paths": {
+ "web-check-live/*": ["src/*"]
+ }
+ },
+ "include": ["src"]
+}
diff --git a/packages/app/vite.config.js b/packages/app/vite.config.js
new file mode 100644
index 000000000..6ace65de2
--- /dev/null
+++ b/packages/app/vite.config.js
@@ -0,0 +1,22 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+import { fileURLToPath } from 'url';
+import { dirname, resolve } from 'path';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+export default defineConfig({
+ plugins: [react({ jsxImportSource: '@emotion/react' })],
+ // Shared brand assets (fonts, favicons, web-check.png) are owned by the site
+ // package, so the standalone app build copies them into dist from there
+ publicDir: resolve(__dirname, '..', 'site', 'public'),
+ resolve: {
+ alias: { 'web-check-live': resolve(__dirname, 'src') },
+ },
+ build: {
+ outDir: 'dist',
+ sourcemap: false,
+ emptyOutDir: true,
+ },
+ server: { port: 5173 },
+});
diff --git a/packages/site/astro.config.mjs b/packages/site/astro.config.mjs
new file mode 100644
index 000000000..01d32676f
--- /dev/null
+++ b/packages/site/astro.config.mjs
@@ -0,0 +1,56 @@
+import { defineConfig } from 'astro/config';
+import { fileURLToPath } from 'url';
+import dotenv from 'dotenv';
+import svelte from '@astrojs/svelte';
+import react from '@astrojs/react';
+import partytown from '@astrojs/partytown';
+import sitemap from '@astrojs/sitemap';
+
+// Load env vars at build-time from root
+dotenv.config({ path: fileURLToPath(new URL('../../.env', import.meta.url)) });
+
+const env = (key, fallback) => process?.env?.[key] || fallback;
+const site = env('SITE_URL', 'https://web-check.xyz');
+const base = env('BASE_URL', '/');
+
+// Main instance shoes marketing pages
+const isBossServer = env('BOSS_SERVER', '') === 'true';
+
+const redirects = { '/about': '/check/about' };
+if (!isBossServer) redirects['/'] = '/check';
+
+// Resolves the React app source so internal `web-check-live/*` imports resolve
+const appSrc = fileURLToPath(new URL('../app/src', import.meta.url));
+
+// Load .env from the monorepo root so all workspaces share one file
+const envDir = fileURLToPath(new URL('../..', import.meta.url));
+
+// Dev-only rewrite so deep /check/ URLs serve the SPA shell
+// In production this is handled by the platform redirect rules
+const checkSpaFallback = {
+ name: 'check-spa-fallback',
+ apply: 'serve',
+ configureServer(server) {
+ server.middlewares.use((req, _res, next) => {
+ const url = req.url || '';
+ if (url.startsWith('/check/') && url !== '/check/') {
+ const queryIdx = url.indexOf('?');
+ req.url = '/check' + (queryIdx >= 0 ? url.slice(queryIdx) : '');
+ }
+ next();
+ });
+ },
+};
+
+export default defineConfig({
+ output: 'static',
+ site,
+ base,
+ integrations: [svelte(), react(), partytown(), sitemap()],
+ redirects,
+ vite: {
+ envDir,
+ resolve: { alias: { 'web-check-live': appSrc } },
+ plugins: [checkSpaFallback],
+ },
+});
diff --git a/packages/site/package.json b/packages/site/package.json
new file mode 100644
index 000000000..f73f56374
--- /dev/null
+++ b/packages/site/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "@web-check/site",
+ "version": "2.1.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "PUBLIC_API_ENDPOINT=http://localhost:3001/api astro dev",
+ "build": "astro check && astro build",
+ "preview": "astro preview",
+ "typecheck": "astro check"
+ },
+ "dependencies": {
+ "@astrojs/partytown": "^2.1.7",
+ "@astrojs/react": "^5.0.4",
+ "@astrojs/sitemap": "^3.7.2",
+ "@astrojs/svelte": "^8.1.0",
+ "@emotion/react": "^11.14.0",
+ "@emotion/styled": "^11.14.1",
+ "@fortawesome/fontawesome-svg-core": "^7.2.0",
+ "@fortawesome/free-brands-svg-icons": "^7.2.0",
+ "@fortawesome/free-regular-svg-icons": "^7.2.0",
+ "@fortawesome/free-solid-svg-icons": "^7.2.0",
+ "@fortawesome/svelte-fontawesome": "^0.2.4",
+ "@web-check/app": "*",
+ "astro": "^6.2.2",
+ "framer-motion": "^12.38.0",
+ "react": "^19.2.5",
+ "react-dom": "^19.2.5",
+ "svelte": "^5.55.5"
+ },
+ "devDependencies": {
+ "@astrojs/check": "^0.9.9",
+ "@astrojs/ts-plugin": "^1.10.7",
+ "@types/react": "^19.2.14",
+ "@types/react-dom": "^19.2.3",
+ "dotenv": "^17.4.2",
+ "sass": "^1.99.0",
+ "typescript": "^6.0.3"
+ }
+}
diff --git a/public/android-chrome-192x192.png b/packages/site/public/android-chrome-192x192.png
similarity index 100%
rename from public/android-chrome-192x192.png
rename to packages/site/public/android-chrome-192x192.png
diff --git a/public/android-chrome-512x512.png b/packages/site/public/android-chrome-512x512.png
similarity index 100%
rename from public/android-chrome-512x512.png
rename to packages/site/public/android-chrome-512x512.png
diff --git a/public/apple-touch-icon.png b/packages/site/public/apple-touch-icon.png
similarity index 100%
rename from public/apple-touch-icon.png
rename to packages/site/public/apple-touch-icon.png
diff --git a/public/assets/badges/dockerhub.svg b/packages/site/public/assets/badges/dockerhub.svg
similarity index 100%
rename from public/assets/badges/dockerhub.svg
rename to packages/site/public/assets/badges/dockerhub.svg
diff --git a/public/assets/badges/github.svg b/packages/site/public/assets/badges/github.svg
similarity index 100%
rename from public/assets/badges/github.svg
rename to packages/site/public/assets/badges/github.svg
diff --git a/public/assets/badges/sponsor.svg b/packages/site/public/assets/badges/sponsor.svg
similarity index 100%
rename from public/assets/badges/sponsor.svg
rename to packages/site/public/assets/badges/sponsor.svg
diff --git a/public/assets/badges/webcheck.svg b/packages/site/public/assets/badges/webcheck.svg
similarity index 100%
rename from public/assets/badges/webcheck.svg
rename to packages/site/public/assets/badges/webcheck.svg
diff --git a/public/assets/images/background-dots.svg b/packages/site/public/assets/images/background-dots.svg
similarity index 100%
rename from public/assets/images/background-dots.svg
rename to packages/site/public/assets/images/background-dots.svg
diff --git a/public/assets/images/docker.svg b/packages/site/public/assets/images/docker.svg
similarity index 100%
rename from public/assets/images/docker.svg
rename to packages/site/public/assets/images/docker.svg
diff --git a/public/assets/images/fly.svg b/packages/site/public/assets/images/fly.svg
similarity index 100%
rename from public/assets/images/fly.svg
rename to packages/site/public/assets/images/fly.svg
diff --git a/public/assets/images/github.svg b/packages/site/public/assets/images/github.svg
similarity index 100%
rename from public/assets/images/github.svg
rename to packages/site/public/assets/images/github.svg
diff --git a/public/assets/images/netlify.svg b/packages/site/public/assets/images/netlify.svg
similarity index 100%
rename from public/assets/images/netlify.svg
rename to packages/site/public/assets/images/netlify.svg
diff --git a/public/assets/images/swagger.svg b/packages/site/public/assets/images/swagger.svg
similarity index 100%
rename from public/assets/images/swagger.svg
rename to packages/site/public/assets/images/swagger.svg
diff --git a/public/assets/images/vercel.svg b/packages/site/public/assets/images/vercel.svg
similarity index 100%
rename from public/assets/images/vercel.svg
rename to packages/site/public/assets/images/vercel.svg
diff --git a/public/assets/images/webauthn.svg b/packages/site/public/assets/images/webauthn.svg
similarity index 100%
rename from public/assets/images/webauthn.svg
rename to packages/site/public/assets/images/webauthn.svg
diff --git a/public/banner.png b/packages/site/public/banner.png
similarity index 100%
rename from public/banner.png
rename to packages/site/public/banner.png
diff --git a/public/favicon-16x16.png b/packages/site/public/favicon-16x16.png
similarity index 100%
rename from public/favicon-16x16.png
rename to packages/site/public/favicon-16x16.png
diff --git a/public/favicon-32x32.png b/packages/site/public/favicon-32x32.png
similarity index 100%
rename from public/favicon-32x32.png
rename to packages/site/public/favicon-32x32.png
diff --git a/public/favicon.ico b/packages/site/public/favicon.ico
similarity index 100%
rename from public/favicon.ico
rename to packages/site/public/favicon.ico
diff --git a/public/favicon.svg b/packages/site/public/favicon.svg
similarity index 100%
rename from public/favicon.svg
rename to packages/site/public/favicon.svg
diff --git a/public/fonts/Hubot-Sans/Hubot-Sans.ttf b/packages/site/public/fonts/Hubot-Sans/Hubot-Sans.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/Hubot-Sans.ttf
rename to packages/site/public/fonts/Hubot-Sans/Hubot-Sans.ttf
diff --git a/public/fonts/Hubot-Sans/Hubot-Sans.woff2 b/packages/site/public/fonts/Hubot-Sans/Hubot-Sans.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/Hubot-Sans.woff2
rename to packages/site/public/fonts/Hubot-Sans/Hubot-Sans.woff2
diff --git a/public/fonts/Hubot-Sans/LICENSE b/packages/site/public/fonts/Hubot-Sans/LICENSE
similarity index 100%
rename from public/fonts/Hubot-Sans/LICENSE
rename to packages/site/public/fonts/Hubot-Sans/LICENSE
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Black.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-BlackItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Bold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-BoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraBoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLight.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-ExtraLightItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Italic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Light.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-LightItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Medium.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-MediumItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-Regular.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSans-SemiBoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Black.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BlackItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Bold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-BoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraBoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLight.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-ExtraLightItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Italic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Light.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-LightItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Medium.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-MediumItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-Regular.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansCondensed-SemiBoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Black.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BlackItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Bold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-BoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraBoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLight.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-ExtraLightItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Italic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Light.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-LightItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Medium.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-MediumItalic.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-Regular.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBold.otf
diff --git a/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf b/packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf
similarity index 100%
rename from public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf
rename to packages/site/public/fonts/Hubot-Sans/OTF/HubotSansExpanded-SemiBoldItalic.otf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Black.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-BlackItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Bold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-BoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraBoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLight.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-ExtraLightItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Italic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Light.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-LightItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Medium.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-MediumItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-Regular.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSans-SemiBoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Black.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BlackItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Bold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-BoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraBoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLight.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-ExtraLightItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Italic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Light.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-LightItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Medium.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-MediumItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-Regular.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansCondensed-SemiBoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Black.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BlackItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Bold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-BoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraBoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLight.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-ExtraLightItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Italic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Light.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-LightItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Medium.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-MediumItalic.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-Regular.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBold.ttf
diff --git a/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf b/packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf
similarity index 100%
rename from public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf
rename to packages/site/public/fonts/Hubot-Sans/TTF/HubotSansExpanded-SemiBoldItalic.ttf
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Black.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-BlackItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Bold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-BoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraBoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLight.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-ExtraLightItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Italic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Light.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-LightItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Medium.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-MediumItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-Regular.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans-SemiBoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Black.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BlackItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Bold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-BoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraBoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLight.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-ExtraLightItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Italic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Light.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-LightItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Medium.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-MediumItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-Regular.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansCondensed-SemiBoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Black.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BlackItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Bold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-BoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraBoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLight.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-ExtraLightItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Italic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Light.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-LightItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Medium.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-MediumItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-Regular.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBold.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSansExpanded-SemiBoldItalic.woff2
diff --git a/public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2 b/packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2
similarity index 100%
rename from public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2
rename to packages/site/public/fonts/Hubot-Sans/WOFF2/HubotSans[slnt,wdth,wght].woff2
diff --git a/public/fonts/Inter-Black.ttf b/packages/site/public/fonts/Inter-Black.ttf
similarity index 100%
rename from public/fonts/Inter-Black.ttf
rename to packages/site/public/fonts/Inter-Black.ttf
diff --git a/public/fonts/Inter-Bold.ttf b/packages/site/public/fonts/Inter-Bold.ttf
similarity index 100%
rename from public/fonts/Inter-Bold.ttf
rename to packages/site/public/fonts/Inter-Bold.ttf
diff --git a/public/fonts/Inter-ExtraBold.ttf b/packages/site/public/fonts/Inter-ExtraBold.ttf
similarity index 100%
rename from public/fonts/Inter-ExtraBold.ttf
rename to packages/site/public/fonts/Inter-ExtraBold.ttf
diff --git a/public/fonts/Inter-ExtraLight.ttf b/packages/site/public/fonts/Inter-ExtraLight.ttf
similarity index 100%
rename from public/fonts/Inter-ExtraLight.ttf
rename to packages/site/public/fonts/Inter-ExtraLight.ttf
diff --git a/public/fonts/Inter-Light.ttf b/packages/site/public/fonts/Inter-Light.ttf
similarity index 100%
rename from public/fonts/Inter-Light.ttf
rename to packages/site/public/fonts/Inter-Light.ttf
diff --git a/public/fonts/Inter-Medium.ttf b/packages/site/public/fonts/Inter-Medium.ttf
similarity index 100%
rename from public/fonts/Inter-Medium.ttf
rename to packages/site/public/fonts/Inter-Medium.ttf
diff --git a/public/fonts/Inter-Regular.ttf b/packages/site/public/fonts/Inter-Regular.ttf
similarity index 100%
rename from public/fonts/Inter-Regular.ttf
rename to packages/site/public/fonts/Inter-Regular.ttf
diff --git a/public/fonts/Inter-SemiBold.ttf b/packages/site/public/fonts/Inter-SemiBold.ttf
similarity index 100%
rename from public/fonts/Inter-SemiBold.ttf
rename to packages/site/public/fonts/Inter-SemiBold.ttf
diff --git a/public/fonts/Inter-Thin.ttf b/packages/site/public/fonts/Inter-Thin.ttf
similarity index 100%
rename from public/fonts/Inter-Thin.ttf
rename to packages/site/public/fonts/Inter-Thin.ttf
diff --git a/public/fonts/Inter-VariableFont_slnt,wght.ttf b/packages/site/public/fonts/Inter-VariableFont_slnt,wght.ttf
similarity index 100%
rename from public/fonts/Inter-VariableFont_slnt,wght.ttf
rename to packages/site/public/fonts/Inter-VariableFont_slnt,wght.ttf
diff --git a/public/fonts/PTMono-Regular.ttf b/packages/site/public/fonts/PTMono-Regular.ttf
similarity index 100%
rename from public/fonts/PTMono-Regular.ttf
rename to packages/site/public/fonts/PTMono-Regular.ttf
diff --git a/public/manifest.json b/packages/site/public/manifest.json
similarity index 100%
rename from public/manifest.json
rename to packages/site/public/manifest.json
diff --git a/public/resources/openapi-spec.yml b/packages/site/public/resources/openapi-spec.yml
similarity index 100%
rename from public/resources/openapi-spec.yml
rename to packages/site/public/resources/openapi-spec.yml
diff --git a/public/robots.txt b/packages/site/public/robots.txt
similarity index 100%
rename from public/robots.txt
rename to packages/site/public/robots.txt
diff --git a/public/security.txt b/packages/site/public/security.txt
similarity index 100%
rename from public/security.txt
rename to packages/site/public/security.txt
diff --git a/public/web-check.png b/packages/site/public/web-check.png
similarity index 100%
rename from public/web-check.png
rename to packages/site/public/web-check.png
diff --git a/src/components/homepage/AboutSection.astro b/packages/site/src/components/homepage/AboutSection.astro
similarity index 100%
rename from src/components/homepage/AboutSection.astro
rename to packages/site/src/components/homepage/AboutSection.astro
diff --git a/src/components/homepage/AnimatedButton.astro b/packages/site/src/components/homepage/AnimatedButton.astro
similarity index 100%
rename from src/components/homepage/AnimatedButton.astro
rename to packages/site/src/components/homepage/AnimatedButton.astro
diff --git a/src/components/homepage/AnimatedInput.astro b/packages/site/src/components/homepage/AnimatedInput.astro
similarity index 100%
rename from src/components/homepage/AnimatedInput.astro
rename to packages/site/src/components/homepage/AnimatedInput.astro
diff --git a/src/components/homepage/ButtonGroup.astro b/packages/site/src/components/homepage/ButtonGroup.astro
similarity index 100%
rename from src/components/homepage/ButtonGroup.astro
rename to packages/site/src/components/homepage/ButtonGroup.astro
diff --git a/src/components/homepage/Features.astro b/packages/site/src/components/homepage/Features.astro
similarity index 100%
rename from src/components/homepage/Features.astro
rename to packages/site/src/components/homepage/Features.astro
diff --git a/src/components/homepage/HeroForm.astro b/packages/site/src/components/homepage/HeroForm.astro
similarity index 100%
rename from src/components/homepage/HeroForm.astro
rename to packages/site/src/components/homepage/HeroForm.astro
diff --git a/src/components/homepage/HomeBackground.tsx b/packages/site/src/components/homepage/HomeBackground.tsx
similarity index 100%
rename from src/components/homepage/HomeBackground.tsx
rename to packages/site/src/components/homepage/HomeBackground.tsx
diff --git a/src/components/homepage/Screenshots.astro b/packages/site/src/components/homepage/Screenshots.astro
similarity index 100%
rename from src/components/homepage/Screenshots.astro
rename to packages/site/src/components/homepage/Screenshots.astro
diff --git a/src/components/homepage/SponsorSegment.astro b/packages/site/src/components/homepage/SponsorSegment.astro
similarity index 100%
rename from src/components/homepage/SponsorSegment.astro
rename to packages/site/src/components/homepage/SponsorSegment.astro
diff --git a/src/components/homepage/TempDisabled.astro b/packages/site/src/components/homepage/TempDisabled.astro
similarity index 100%
rename from src/components/homepage/TempDisabled.astro
rename to packages/site/src/components/homepage/TempDisabled.astro
diff --git a/src/components/molecules/Icon.svelte b/packages/site/src/components/molecules/Icon.svelte
similarity index 100%
rename from src/components/molecules/Icon.svelte
rename to packages/site/src/components/molecules/Icon.svelte
diff --git a/src/components/scafold/Footer.astro b/packages/site/src/components/scafold/Footer.astro
similarity index 100%
rename from src/components/scafold/Footer.astro
rename to packages/site/src/components/scafold/Footer.astro
diff --git a/src/components/scafold/Nav.astro b/packages/site/src/components/scafold/Nav.astro
similarity index 100%
rename from src/components/scafold/Nav.astro
rename to packages/site/src/components/scafold/Nav.astro
diff --git a/src/env.d.ts b/packages/site/src/env.d.ts
similarity index 100%
rename from src/env.d.ts
rename to packages/site/src/env.d.ts
diff --git a/src/layouts/Base.astro b/packages/site/src/layouts/Base.astro
similarity index 100%
rename from src/layouts/Base.astro
rename to packages/site/src/layouts/Base.astro
diff --git a/src/layouts/MetaTags.astro b/packages/site/src/layouts/MetaTags.astro
similarity index 100%
rename from src/layouts/MetaTags.astro
rename to packages/site/src/layouts/MetaTags.astro
diff --git a/src/pages/account/index.astro b/packages/site/src/pages/account/index.astro
similarity index 100%
rename from src/pages/account/index.astro
rename to packages/site/src/pages/account/index.astro
diff --git a/packages/site/src/pages/check/index.astro b/packages/site/src/pages/check/index.astro
new file mode 100644
index 000000000..760297b63
--- /dev/null
+++ b/packages/site/src/pages/check/index.astro
@@ -0,0 +1,28 @@
+---
+import BaseLayout from '@layouts/Base.astro';
+import Main from '@web-check/app/main';
+import '@web-check/app/styles/index.css';
+---
+
+
+
+
+
+
diff --git a/src/pages/index.astro b/packages/site/src/pages/index.astro
similarity index 87%
rename from src/pages/index.astro
rename to packages/site/src/pages/index.astro
index f5e27d4c8..508047722 100644
--- a/src/pages/index.astro
+++ b/packages/site/src/pages/index.astro
@@ -6,15 +6,10 @@ import HomeBackground from '@/components/homepage/HomeBackground';
import AboutSection from '@/components/homepage/AboutSection.astro';
import Footer from '@components/scafold/Footer.astro';
-const isBossServer = import.meta.env.BOSS_SERVER === 'true';
-
const disableEverything = import.meta.env.VITE_DISABLE_EVERYTHING === true;
---
-
- {!isBossServer && }
-
{disableEverything && }
diff --git a/src/pages/self-hosted-setup.astro b/packages/site/src/pages/self-hosted-setup.astro
similarity index 100%
rename from src/pages/self-hosted-setup.astro
rename to packages/site/src/pages/self-hosted-setup.astro
diff --git a/src/pages/web-check-api/index.astro b/packages/site/src/pages/web-check-api/index.astro
similarity index 100%
rename from src/pages/web-check-api/index.astro
rename to packages/site/src/pages/web-check-api/index.astro
diff --git a/src/pages/web-check-api/spec.astro b/packages/site/src/pages/web-check-api/spec.astro
similarity index 100%
rename from src/pages/web-check-api/spec.astro
rename to packages/site/src/pages/web-check-api/spec.astro
diff --git a/src/styles/colors.scss b/packages/site/src/styles/colors.scss
similarity index 100%
rename from src/styles/colors.scss
rename to packages/site/src/styles/colors.scss
diff --git a/src/styles/global.scss b/packages/site/src/styles/global.scss
similarity index 100%
rename from src/styles/global.scss
rename to packages/site/src/styles/global.scss
diff --git a/src/styles/media-queries.scss b/packages/site/src/styles/media-queries.scss
similarity index 100%
rename from src/styles/media-queries.scss
rename to packages/site/src/styles/media-queries.scss
diff --git a/src/styles/typography.scss b/packages/site/src/styles/typography.scss
similarity index 100%
rename from src/styles/typography.scss
rename to packages/site/src/styles/typography.scss
diff --git a/svelte.config.js b/packages/site/svelte.config.js
similarity index 100%
rename from svelte.config.js
rename to packages/site/svelte.config.js
diff --git a/tsconfig.json b/packages/site/tsconfig.json
similarity index 81%
rename from tsconfig.json
rename to packages/site/tsconfig.json
index bd8d9d624..755de5688 100644
--- a/tsconfig.json
+++ b/packages/site/tsconfig.json
@@ -2,13 +2,9 @@
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
- "moduleResolution": "node",
+ "moduleResolution": "bundler",
"allowImportingTsExtensions": true,
- "plugins": [
- {
- "name": "@astrojs/ts-plugin"
- }
- ],
+ "plugins": [{ "name": "@astrojs/ts-plugin" }],
"lib": ["DOM", "DOM.Iterable", "ES2020"],
"allowJs": true,
"skipLibCheck": true,
@@ -29,7 +25,8 @@
"@layouts/*": ["layouts/*"],
"@pages/*": ["pages/*"],
"@styles/*": ["styles/*"],
- "@assets/*": ["assets/*"]
+ "@assets/*": ["assets/*"],
+ "web-check-live/*": ["../../app/src/*"]
}
},
"include": ["src"]
diff --git a/scripts/sync-vercel-api.js b/scripts/sync-vercel-api.js
new file mode 100644
index 000000000..bc20b1910
--- /dev/null
+++ b/scripts/sync-vercel-api.js
@@ -0,0 +1,60 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+// Vercel only discovers serverless functions in /api at the project root, so we
+// emit thin re-export wrappers from the canonical handlers in packages/api
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const HANDLERS_DIR = path.resolve(__dirname, '../packages/api/handlers');
+const OUT_DIR = path.resolve(__dirname, '../api');
+const HEADER =
+ '// Generated by scripts/sync-vercel-api.js, do not edit by hand\n' +
+ '// Source of truth lives in packages/api/handlers\n';
+
+const readIfExists = (file) => {
+ try {
+ return fs.readFileSync(file, 'utf-8');
+ } catch {
+ return null;
+ }
+};
+
+const sync = () => {
+ fs.mkdirSync(OUT_DIR, { recursive: true });
+
+ const sources = fs
+ .readdirSync(HANDLERS_DIR, { withFileTypes: true })
+ .filter((e) => e.isFile() && e.name.endsWith('.js'))
+ .map((e) => e.name);
+
+ let written = 0;
+ for (const name of sources) {
+ const out = path.join(OUT_DIR, name);
+ const target = path.join(HANDLERS_DIR, name);
+ const rel = path.relative(OUT_DIR, target).split(path.sep).join('/');
+ const body = `${HEADER}export { default, handler } from '${rel}';\n`;
+ if (readIfExists(out) !== body) {
+ fs.writeFileSync(out, body);
+ written += 1;
+ }
+ }
+
+ let removed = 0;
+ const existing = fs
+ .readdirSync(OUT_DIR, { withFileTypes: true })
+ .filter((e) => e.isFile() && e.name.endsWith('.js'))
+ .map((e) => e.name);
+
+ for (const name of existing) {
+ if (!sources.includes(name)) {
+ fs.unlinkSync(path.join(OUT_DIR, name));
+ removed += 1;
+ }
+ }
+
+ process.stdout.write(
+ `Vercel api wrappers: ${sources.length} total, ` + `${written} written, ${removed} removed\n`,
+ );
+};
+
+sync();
diff --git a/server.js b/server.js
deleted file mode 100644
index 49f33328a..000000000
--- a/server.js
+++ /dev/null
@@ -1,226 +0,0 @@
-import fs from 'fs';
-import path from 'path';
-import cors from 'cors';
-import dotenv from 'dotenv';
-import express from 'express';
-import rateLimit from 'express-rate-limit';
-
-// Load environment variables from .env file
-dotenv.config();
-
-// Create the Express app
-const app = express();
-
-const trustProxy = process.env.TRUST_PROXY;
-if (trustProxy) {
- const parsed = /^\d+$/.test(trustProxy)
- ? parseInt(trustProxy, 10)
- : trustProxy === 'true'
- ? true
- : trustProxy === 'false'
- ? false
- : trustProxy;
- app.set('trust proxy', parsed);
-}
-
-const __filename = new URL(import.meta.url).pathname;
-const __dirname = path.dirname(__filename);
-
-const port = process.env.PORT || 3000; // The port to run the server on
-const API_DIR = '/api'; // Name of the dir containing the lambda functions
-const dirPath = path.join(__dirname, API_DIR); // Path to the lambda functions dir
-const guiPath = path.join(__dirname, 'dist', 'client');
-const placeholderFilePath = path.join(__dirname, 'public', 'placeholder.html');
-const handlers = {}; // Will store list of API endpoints
-process.env.WC_SERVER = 'true'; // Tells middleware to return in non-lambda mode
-
-// Enable CORS
-app.use(
- cors({
- origin: process.env.API_CORS_ORIGIN || '*',
- }),
-);
-
-// Define max requests within each time frame
-const limits = [
- { timeFrame: 10 * 60, max: 100, messageTime: '10 minutes' },
- { timeFrame: 60 * 60, max: 250, messageTime: '1 hour' },
- { timeFrame: 12 * 60 * 60, max: 500, messageTime: '12 hours' },
-];
-
-// Construct a message to be returned if the user has been rate-limited
-const makeLimiterResponseMsg = (retryAfter) => {
- const why =
- 'This keeps the service running smoothly for everyone. ' +
- 'You can get around these limits by running your own instance of Web Check.';
- return `You've been rate-limited, please try again in ${retryAfter} seconds.\n${why}`;
-};
-
-// Create rate limiters for each time frame
-const limiters = limits.map((limit) =>
- rateLimit({
- windowMs: limit.timeFrame * 1000,
- limit: limit.max,
- standardHeaders: true,
- legacyHeaders: false,
- message: { error: makeLimiterResponseMsg(limit.messageTime) },
- }),
-);
-
-// If rate-limiting enabled, then apply the limiters to the /api endpoint
-if (process.env.API_ENABLE_RATE_LIMIT === 'true') {
- app.use(API_DIR, limiters);
-}
-
-// Read and register each API function as an Express routes
-fs.readdirSync(dirPath, { withFileTypes: true })
- .filter((dirent) => dirent.isFile() && dirent.name.endsWith('.js'))
- .forEach(async (dirent) => {
- const routeName = dirent.name.split('.')[0];
- const route = `${API_DIR}/${routeName}`;
- // const handler = require(path.join(dirPath, dirent.name));
-
- const handlerModule = await import(path.join(dirPath, dirent.name));
- const handler = handlerModule.default || handlerModule;
- handlers[route] = handler;
-
- app.get(route, async (req, res) => {
- try {
- await handler(req, res);
- } catch (err) {
- res.status(500).json({ error: err.message });
- }
- });
- });
-
-const renderPlaceholderPage = async (res, msgId, logs) => {
- const errorMessages = {
- notCompiled:
- 'Looks like the GUI app has not yet been compiled.
' +
- 'Run yarn build to continue, then restart the server.',
- notCompiledSsrHandler:
- 'Server-side rendering failed to initiate, as SSR handler not found.
' +
- 'This can be fixed by running yarn build, then restarting the server.
',
- disabledGui:
- 'Web-Check API is up and running!
Access the endpoints at ' +
- `${API_DIR}`,
- };
- const logOutput = logs ? `${logs}
` : '';
- const errorMessage = (errorMessages[msgId] || 'An mystery error occurred.') + logOutput;
- const placeholderContent = await fs.promises.readFile(placeholderFilePath, 'utf-8');
- const htmlContent = placeholderContent.replace('', errorMessage);
- res.status(500).send(htmlContent);
-};
-
-// Create a single API endpoint to execute all lambda functions
-app.get(API_DIR, async (req, res) => {
- const results = {};
- const { url } = req.query;
- const maxExecutionTime = process.env.PUBLIC_API_TIMEOUT_LIMIT || 60000;
-
- const executeHandler = async (handler, req) => {
- return new Promise(async (resolve, reject) => {
- try {
- const mockRes = {
- status: () => mockRes,
- json: (body) => resolve({ body }),
- };
- await handler({ ...req, query: { url } }, mockRes);
- } catch (err) {
- reject(err);
- }
- });
- };
-
- const timeout = (ms, jobName = null) => {
- return new Promise((_, reject) => {
- setTimeout(() => {
- reject(
- new Error(
- `Timed out after ${ms / 1000} seconds${jobName ? `, when executing ${jobName}` : ''}`,
- ),
- );
- }, ms);
- });
- };
-
- const handlerPromises = Object.entries(handlers).map(async ([route, handler]) => {
- const routeName = route.replace(`${API_DIR}/`, '');
-
- try {
- const result = await Promise.race([
- executeHandler(handler, req, res),
- timeout(maxExecutionTime, routeName),
- ]);
- results[routeName] = result.body;
- } catch (err) {
- results[routeName] = { error: err.message };
- }
- });
-
- await Promise.all(handlerPromises);
- res.json(results);
-});
-
-// Skip the marketing homepage, for self-hosted users
-app.use((req, res, next) => {
- if (req.path === '/' && process.env.BOSS_SERVER !== 'true' && !process.env.DISABLE_GUI) {
- return res.redirect(302, '/check');
- }
- next();
-});
-
-// Serve up the GUI - if build dir exists, and GUI feature enabled
-if (process.env.DISABLE_GUI && process.env.DISABLE_GUI !== 'false') {
- app.get('/', async (req, res) => {
- renderPlaceholderPage(res, 'disabledGui');
- });
-} else if (!fs.existsSync(guiPath)) {
- app.get('/', async (req, res) => {
- renderPlaceholderPage(res, 'notCompiled');
- });
-} else {
- // GUI enabled, and build files present, let's go!!
- app.use(express.static('dist/client/'));
- app.use(async (req, res, next) => {
- const ssrHandlerPath = path.join(__dirname, 'dist', 'server', 'entry.mjs');
- import(ssrHandlerPath)
- .then(({ handler: ssrHandler }) => {
- ssrHandler(req, res, next);
- })
- .catch(async (err) => {
- renderPlaceholderPage(res, 'notCompiledSsrHandler', err.message);
- });
- });
-}
-
-// Anything left unhandled (which isn't an API endpoint), return a 404
-app.use((req, res, next) => {
- if (!req.path.startsWith(`${API_DIR}/`)) {
- res.status(404).sendFile(path.join(__dirname, 'public', 'error.html'));
- } else {
- next();
- }
-});
-
-// Print nice welcome message to user
-const printMessage = () => {
- console.log(
- `\x1b[36m\n` +
- ' __ __ _ ___ _ _ \n' +
- ' \\ \\ / /__| |__ ___ / __| |_ ___ __| |__\n' +
- " \\ \\/\\/ / -_) '_ \\___| (__| ' \\/ -_) _| / /\n" +
- ' \\_/\\_/\\___|_.__/ \\___|_||_\\___\\__|_\\_\\\n' +
- `\x1b[0m\n`,
- `\x1b[1m\x1b[32m🚀 Web-Check is up and running at http://localhost:${port} \x1b[0m\n\n`,
- `\x1b[2m\x1b[36m🛟 For documentation and support, visit the GitHub repo: ` +
- `https://github.com/lissy93/web-check \n`,
- `💖 Found Web-Check useful? Consider sponsoring us on GitHub ` +
- `to help fund maintenance & development.\x1b[0m`,
- );
-};
-
-// Create server
-app.listen(port, () => {
- printMessage();
-});
diff --git a/src/pages/check/[...target].astro b/src/pages/check/[...target].astro
deleted file mode 100644
index b69e2f4b0..000000000
--- a/src/pages/check/[...target].astro
+++ /dev/null
@@ -1,40 +0,0 @@
----
-import BaseLayout from '@layouts/Base.astro';
-import Main from '../../web-check-live/main.tsx';
-import '../../web-check-live/styles/index.css';
-
-export const prerender = false;
-
-const { search } = new URL(Astro.request.url);
-
-const searchUrl = new URLSearchParams(search).get('url');
-
-if (searchUrl) {
- Astro.redirect(`/check/${encodeURIComponent(searchUrl)}`);
-}
----
-
-
-
-
-
-
diff --git a/vercel.json b/vercel.json
index 22d403e59..595989fcf 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1,15 +1,13 @@
{
"version": 2,
- "routes": [
- {
- "src": "/api/(.*)",
- "dest": "/api/$1.js"
- }
+ "buildCommand": "yarn build",
+ "outputDirectory": "packages/site/dist",
+ "rewrites": [
+ { "source": "/check", "destination": "/check/index.html" },
+ { "source": "/check/:path*", "destination": "/check/index.html" }
],
"functions": {
- "api/*.js": {
- "maxDuration": 20
- }
+ "api/*.js": { "maxDuration": 20 }
},
"env": {
"PLATFORM": "vercel",
@@ -17,8 +15,6 @@
"CHROME_PATH": "/usr/bin/chromium"
},
"build": {
- "env": {
- "PLATFORM": "vercel"
- }
+ "env": { "PLATFORM": "vercel" }
}
}
diff --git a/vite.config.js b/vite.config.js
deleted file mode 100644
index 73acc9227..000000000
--- a/vite.config.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// vite.config.js
-import { defineConfig } from 'vite';
-import react from '@vitejs/plugin-react';
-
-export default defineConfig({
- plugins: [
- react({
- jsxImportSource: '@emotion/react',
- babel: {
- plugins: ['babel-plugin-styled-components'],
- },
- }),
- ],
-});
diff --git a/yarn.lock b/yarn.lock
index 8d57936c9..c7db7dc45 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12,18 +12,6 @@
kleur "^4.1.5"
yargs "^17.7.2"
-"@astrojs/cloudflare@^13.3.1":
- version "13.3.1"
- resolved "https://registry.npmjs.org/@astrojs/cloudflare/-/cloudflare-13.3.1.tgz"
- integrity sha512-I2HcdP1KVppLMd0lXARI+/MKXbvrZdTvkLLKSBNtj5zhRhnDhugnyewjGKN0Ap5+khktD+rime7BgjfUlJ9iZw==
- dependencies:
- "@astrojs/internal-helpers" "0.9.0"
- "@astrojs/underscore-redirects" "1.0.3"
- "@cloudflare/vite-plugin" "^1.32.3"
- piccolore "^0.1.3"
- tinyglobby "^0.2.15"
- vite "^7.3.2"
-
"@astrojs/compiler@^2.0.0 || ^3.0.0", "@astrojs/compiler@^2.13.1", "@astrojs/compiler@^2.9.1":
version "2.13.1"
resolved "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz"
@@ -92,30 +80,6 @@
unist-util-visit-parents "^6.0.2"
vfile "^6.0.3"
-"@astrojs/netlify@^7.0.8":
- version "7.0.8"
- resolved "https://registry.npmjs.org/@astrojs/netlify/-/netlify-7.0.8.tgz"
- integrity sha512-wOkOMoiUePWrGGOEvaXAC8PzUUYIWB16oChOzH/Ziy9teMkgc56TifNW9SiIussylMJQNjhC+AJYoWUHkKiiuQ==
- dependencies:
- "@astrojs/internal-helpers" "0.9.0"
- "@astrojs/underscore-redirects" "1.0.3"
- "@netlify/blobs" "^10.7.0"
- "@netlify/functions" "^5.1.2"
- "@netlify/vite-plugin" "^2.10.3"
- "@vercel/nft" "^1.3.2"
- esbuild "^0.27.3"
- tinyglobby "^0.2.15"
- vite "^7.3.2"
-
-"@astrojs/node@^10.0.6":
- version "10.0.6"
- resolved "https://registry.npmjs.org/@astrojs/node/-/node-10.0.6.tgz"
- integrity sha512-e8JmaP4sGxqvdei14kmBzhAqgd5/L5MTExW3Hks5DOt9LDvGzlsFZwnXVXzWPVjW/PErl7t9uLg7xWhCqfkSrA==
- dependencies:
- "@astrojs/internal-helpers" "0.9.0"
- send "^1.2.1"
- server-destroy "^1.0.1"
-
"@astrojs/partytown@^2.1.7":
version "2.1.7"
resolved "https://registry.npmjs.org/@astrojs/partytown/-/partytown-2.1.7.tgz"
@@ -186,24 +150,6 @@
semver "^7.7.4"
vscode-languageserver-textdocument "^1.0.12"
-"@astrojs/underscore-redirects@1.0.3":
- version "1.0.3"
- resolved "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-1.0.3.tgz"
- integrity sha512-cxnGSw+sJigBLdX4TMSZKkzV6C3gMLJMucDk2W+n281Xhie68T2/9f1+1NMNDCZsc5i0FED7Qt5I10g2O9wtZg==
-
-"@astrojs/vercel@^10.0.6":
- version "10.0.6"
- resolved "https://registry.npmjs.org/@astrojs/vercel/-/vercel-10.0.6.tgz"
- integrity sha512-Ubd1M77QWqXXluFNL8/ynmfyZCfIUVuL6QRpPXGYOIQ8Dv3QBXM34e0CMig3OgmihSIWNv9sqQHzEHDyDJV9QQ==
- dependencies:
- "@astrojs/internal-helpers" "0.9.0"
- "@vercel/analytics" "^1.6.1"
- "@vercel/functions" "^3.4.3"
- "@vercel/nft" "^1.3.2"
- "@vercel/routing-utils" "^5.3.3"
- esbuild "^0.27.3"
- tinyglobby "^0.2.15"
-
"@astrojs/yaml2ts@^0.2.3":
version "0.2.3"
resolved "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.3.tgz"
@@ -211,7 +157,7 @@
dependencies:
yaml "^2.8.2"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.26.2", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0":
version "7.29.0"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz"
integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
@@ -318,7 +264,7 @@
"@babel/template" "^7.28.6"
"@babel/types" "^7.29.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0", "@babel/parser@^7.29.2":
+"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
version "7.29.3"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz"
integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==
@@ -366,7 +312,7 @@
"@babel/types" "^7.29.0"
debug "^4.3.1"
-"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0":
+"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.0":
version "7.29.0"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz"
integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
@@ -399,86 +345,6 @@
fast-wrap-ansi "^0.2.0"
sisteransi "^1.0.5"
-"@cloudflare/kv-asset-handler@0.5.0":
- version "0.5.0"
- resolved "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz"
- integrity sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==
-
-"@cloudflare/unenv-preset@2.16.1":
- version "2.16.1"
- resolved "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz"
- integrity sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==
-
-"@cloudflare/vite-plugin@^1.32.3":
- version "1.35.0"
- resolved "https://registry.npmjs.org/@cloudflare/vite-plugin/-/vite-plugin-1.35.0.tgz"
- integrity sha512-TtyBYqeIcRrbEAShwnNOyaMHA8SnwIFQ5h9OtMF3mr0xEF9XHqnICkZqMLGOFSP9INrjtJKUBIDlWbK+fjSBmA==
- dependencies:
- "@cloudflare/unenv-preset" "2.16.1"
- miniflare "4.20260430.0"
- unenv "2.0.0-rc.24"
- wrangler "4.87.0"
- ws "8.18.0"
-
-"@cloudflare/workerd-darwin-64@1.20260430.1":
- version "1.20260430.1"
- resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260430.1.tgz#1dbf994e7a02d5014254e237fb28157309401a5e"
- integrity sha512-ADohZUHf7NBvPp2PdZig2Opxx+hDkk3ve7jrTne3JRx9kDSB73zc4LzcEeEN8LKkbAcqZmvfRJfpChSlusu0lA==
-
-"@cloudflare/workerd-darwin-arm64@1.20260430.1":
- version "1.20260430.1"
- resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260430.1.tgz#6e9953dfa763eb946f65fdfb77597668a6f21077"
- integrity sha512-/DoYC/1wHs+YRZzzqSQg1/EHB4hiv1yV5U8FnmapRRIzVaPtnt+ApeOXeMrIdKidgKOI8TqQzgBU8xbIM7Cl4Q==
-
-"@cloudflare/workerd-linux-64@1.20260430.1":
- version "1.20260430.1"
- resolved "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260430.1.tgz"
- integrity sha512-koJhBWvEVZPKCVFtMLp2iMHlYr+lFCF47wGbnlKdHVlemV0zTxJEyHI8aLlrhPLhBmOmYLp46rXw09/qJkRIhQ==
-
-"@cloudflare/workerd-linux-arm64@1.20260430.1":
- version "1.20260430.1"
- resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260430.1.tgz#05940bc745d4c70eccb8341ef9bd30e72faa1d93"
- integrity sha512-hMdapNAzNQZDXGGkg4Slydc3fRJP5FUZLJVVcZCW/+imhhJro9Z1rv5n/wfR+txKoSWhTYR8eOp8Pyi2bzLzlw==
-
-"@cloudflare/workerd-windows-64@1.20260430.1":
- version "1.20260430.1"
- resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260430.1.tgz#5240fb60d9f2879d70e1a106fbcea2a3f9295efe"
- integrity sha512-jS3ffixjb5USOwz4frw4WzCz0HrjVxkgyU3WiYb06N7hBAfN6eOrveAJ4QRef0+suK4V1vQFoB1oKdRBsXe9Dw==
-
-"@colors/colors@1.6.0", "@colors/colors@^1.6.0":
- version "1.6.0"
- resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz"
- integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==
-
-"@cspotcode/source-map-support@0.8.1":
- version "0.8.1"
- resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz"
- integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
- dependencies:
- "@jridgewell/trace-mapping" "0.3.9"
-
-"@dabh/diagnostics@^2.0.8":
- version "2.0.8"
- resolved "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz"
- integrity sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==
- dependencies:
- "@so-ric/colorspace" "^1.1.6"
- enabled "2.0.x"
- kuler "^2.0.0"
-
-"@dependents/detective-less@^5.0.1":
- version "5.0.3"
- resolved "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-5.0.3.tgz"
- integrity sha512-v6oD9Ukp+N7V4n6p5I/+mM5fIohSfkrDSGlFm5w/pYmchvbk+sMIHsLxrFJ5Lnujewj1BzWL0K84d88lwZAMQA==
- dependencies:
- gonzales-pe "^4.3.0"
- node-source-walk "^7.0.1"
-
-"@electric-sql/pglite@^0.3.15":
- version "0.3.16"
- resolved "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.3.16.tgz"
- integrity sha512-mZkZfOd9OqTMHsK+1cje8OSzfAQcpD7JmILXTl5ahdempjUDdmg4euf1biDex5/LfQIDJ3gvCu6qDgdnDxfJmA==
-
"@emmetio/abbreviation@^2.3.3":
version "2.3.3"
resolved "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz"
@@ -637,269 +503,131 @@
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz"
integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==
-"@envelop/instrumentation@^1.0.0":
- version "1.0.0"
- resolved "https://registry.npmjs.org/@envelop/instrumentation/-/instrumentation-1.0.0.tgz"
- integrity sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==
- dependencies:
- "@whatwg-node/promise-helpers" "^1.2.1"
- tslib "^2.5.0"
-
-"@esbuild/aix-ppc64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz#815b39267f9bffd3407ea6c376ac32946e24f8d2"
- integrity sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==
-
"@esbuild/aix-ppc64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz#82b74f92aa78d720b714162939fb248c90addf53"
integrity sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==
-"@esbuild/android-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz#19b882408829ad8e12b10aff2840711b2da361e8"
- integrity sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==
-
"@esbuild/android-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz#f78cb8a3121fc205a53285adb24972db385d185d"
integrity sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==
-"@esbuild/android-arm@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz#90be58de27915efa27b767fcbdb37a4470627d7b"
- integrity sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==
-
"@esbuild/android-arm@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.7.tgz#593e10a1450bbfcac6cb321f61f468453bac209d"
integrity sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==
-"@esbuild/android-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz#d7dcc976f16e01a9aaa2f9b938fbec7389f895ac"
- integrity sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==
-
"@esbuild/android-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.7.tgz#453143d073326033d2d22caf9e48de4bae274b07"
integrity sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==
-"@esbuild/darwin-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz#9f6cac72b3a8532298a6a4493ed639a8988e8abd"
- integrity sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==
-
"@esbuild/darwin-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz#6f23000fb9b40b7e04b7d0606c0693bd0632f322"
integrity sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==
-"@esbuild/darwin-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz#ac61d645faa37fd650340f1866b0812e1fb14d6a"
- integrity sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==
-
"@esbuild/darwin-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz#27393dd18bb1263c663979c5f1576e00c2d024be"
integrity sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==
-"@esbuild/freebsd-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz#b8625689d73cf1830fe58c39051acdc12474ea1b"
- integrity sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==
-
"@esbuild/freebsd-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz#22e4638fa502d1c0027077324c97640e3adf3a62"
integrity sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==
-"@esbuild/freebsd-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz#07be7dd3c9d42fe0eccd2ab9f9ded780bc53bead"
- integrity sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==
-
"@esbuild/freebsd-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz#9224b8e4fea924ce2194e3efc3e9aebf822192d6"
integrity sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==
-"@esbuild/linux-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz#bf31918fe5c798586460d2b3d6c46ed2c01ca0b6"
- integrity sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==
-
"@esbuild/linux-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz#4f5d1c27527d817b35684ae21419e57c2bda0966"
integrity sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==
-"@esbuild/linux-arm@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz#28493ee46abec1dc3f500223cd9f8d2df08f9d11"
- integrity sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==
-
"@esbuild/linux-arm@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz#b9e9d070c8c1c0449cf12b20eac37d70a4595921"
integrity sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==
-"@esbuild/linux-ia32@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz#750752a8b30b43647402561eea764d0a41d0ee29"
- integrity sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==
-
"@esbuild/linux-ia32@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz#3f80fb696aa96051a94047f35c85b08b21c36f9e"
integrity sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==
-"@esbuild/linux-loong64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz#a5a92813a04e71198c50f05adfaf18fc1e95b9ed"
- integrity sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==
-
"@esbuild/linux-loong64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz#9be1f2c28210b13ebb4156221bba356fe1675205"
integrity sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==
-"@esbuild/linux-mips64el@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz#deb45d7fd2d2161eadf1fbc593637ed766d50bb1"
- integrity sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==
-
"@esbuild/linux-mips64el@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz#4ab5ee67a3dfcbcb5e8fd7883dae6e735b1163b8"
integrity sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==
-"@esbuild/linux-ppc64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz#6f39ae0b8c4d3d2d61a65b26df79f6e12a1c3d78"
- integrity sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==
-
"@esbuild/linux-ppc64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz#dac78c689f6499459c4321e5c15032c12307e7ea"
integrity sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==
-"@esbuild/linux-riscv64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz#4c5c19c3916612ec8e3915187030b9df0b955c1d"
- integrity sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==
-
"@esbuild/linux-riscv64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz#050f7d3b355c3a98308e935bc4d6325da91b0027"
integrity sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==
-"@esbuild/linux-s390x@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz#9ed17b3198fa08ad5ccaa9e74f6c0aff7ad0156d"
- integrity sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==
-
"@esbuild/linux-s390x@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz#d61f715ce61d43fe5844ad0d8f463f88cbe4fef6"
integrity sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==
-"@esbuild/linux-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz"
- integrity sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==
-
"@esbuild/linux-x64@0.27.7":
version "0.27.7"
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz"
integrity sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==
-"@esbuild/netbsd-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz#dd0cb2fa543205fcd931df44f4786bfcce6df7d7"
- integrity sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==
-
"@esbuild/netbsd-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz#1650f2c1b948deeb3ef948f2fc30614723c09690"
integrity sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==
-"@esbuild/netbsd-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz#028ad1807a8e03e155153b2d025b506c3787354b"
- integrity sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==
-
"@esbuild/netbsd-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz#65772ab342c4b3319bf0705a211050aac1b6e320"
integrity sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==
-"@esbuild/openbsd-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz#e3c16ff3490c9b59b969fffca87f350ffc0e2af5"
- integrity sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==
-
"@esbuild/openbsd-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz#37ed7cfa66549d7955852fce37d0c3de4e715ea1"
integrity sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==
-"@esbuild/openbsd-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz#c5a4693fcb03d1cbecbf8b422422468dfc0d2a8b"
- integrity sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==
-
"@esbuild/openbsd-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz#01bf3d385855ef50cb33db7c4b52f957c34cd179"
integrity sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==
-"@esbuild/openharmony-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz#082082444f12db564a0775a41e1991c0e125055e"
- integrity sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==
-
"@esbuild/openharmony-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz#6c1f94b34086599aabda4eac8f638294b9877410"
integrity sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==
-"@esbuild/sunos-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz#5ab036c53f929e8405c4e96e865a424160a1b537"
- integrity sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==
-
"@esbuild/sunos-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz#4b0dd17ae0a6941d2d0fd35a906392517071a90d"
integrity sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==
-"@esbuild/win32-arm64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz#38de700ef4b960a0045370c171794526e589862e"
- integrity sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==
-
"@esbuild/win32-arm64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz#34193ab5565d6ff68ca928ac04be75102ccb2e77"
integrity sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==
-"@esbuild/win32-ia32@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz#451b93dc03ec5d4f38619e6cd64d9f9eff06f55c"
- integrity sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==
-
"@esbuild/win32-ia32@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz#eb67f0e4482515d8c1894ede631c327a4da9fc4d"
integrity sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==
-"@esbuild/win32-x64@0.27.3":
- version "0.27.3"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz#0eaf705c941a218a43dba8e09f1df1d6cd2f1f17"
- integrity sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==
-
"@esbuild/win32-x64@0.27.7":
version "0.27.7"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz#8fe30b3088b89b4873c3a6cc87597ae3920c0a8b"
@@ -953,16 +681,6 @@
"@eslint/core" "^1.2.1"
levn "^0.4.1"
-"@fastify/accept-negotiator@^2.0.1":
- version "2.0.1"
- resolved "https://registry.npmjs.org/@fastify/accept-negotiator/-/accept-negotiator-2.0.1.tgz"
- integrity sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==
-
-"@fastify/busboy@^3.1.1":
- version "3.2.0"
- resolved "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz"
- integrity sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==
-
"@fortawesome/fontawesome-common-types@7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.2.0.tgz"
@@ -1027,21 +745,11 @@
resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
-"@humanwhocodes/momoa@^2.0.2":
- version "2.0.4"
- resolved "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz"
- integrity sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==
-
"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2":
version "0.4.3"
resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz"
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
-"@iarna/toml@^2.2.5":
- version "2.2.5"
- resolved "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz"
- integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==
-
"@img/colour@^1.0.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz"
@@ -1189,30 +897,6 @@
resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz#a81ffb00e69267cd0a1d626eaedb8a8430b2b2f8"
integrity sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==
-"@import-maps/resolve@^2.0.0":
- version "2.0.0"
- resolved "https://registry.npmjs.org/@import-maps/resolve/-/resolve-2.0.0.tgz"
- integrity sha512-RwzRTpmrrS6Q1ZhQExwuxJGK1Wqhv4stt+OF2JzS+uawewpwNyU7EJL1WpBex7aDiiGLs4FsXGkfUBdYuX7xiQ==
-
-"@isaacs/cliui@^8.0.2":
- version "8.0.2"
- resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz"
- integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
- dependencies:
- string-width "^5.1.2"
- string-width-cjs "npm:string-width@^4.2.0"
- strip-ansi "^7.0.1"
- strip-ansi-cjs "npm:strip-ansi@^6.0.1"
- wrap-ansi "^8.1.0"
- wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
-
-"@isaacs/fs-minipass@^4.0.0":
- version "4.0.1"
- resolved "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz"
- integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==
- dependencies:
- minipass "^7.0.4"
-
"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5":
version "0.3.13"
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz"
@@ -1229,24 +913,16 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
-"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0":
+"@jridgewell/resolve-uri@^3.1.0":
version "3.1.2"
resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz"
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
-"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
version "1.5.5"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz"
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
-"@jridgewell/trace-mapping@0.3.9":
- version "0.3.9"
- resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz"
- integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
- dependencies:
- "@jridgewell/resolve-uri" "^3.0.3"
- "@jridgewell/sourcemap-codec" "^1.4.10"
-
"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
version "0.3.31"
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz"
@@ -1255,358 +931,6 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
-"@mapbox/node-pre-gyp@^2.0.0":
- version "2.0.3"
- resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.3.tgz"
- integrity sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==
- dependencies:
- consola "^3.2.3"
- detect-libc "^2.0.0"
- https-proxy-agent "^7.0.5"
- node-fetch "^2.6.7"
- nopt "^8.0.0"
- semver "^7.5.3"
- tar "^7.4.0"
-
-"@netlify/ai@^0.4.1":
- version "0.4.1"
- resolved "https://registry.npmjs.org/@netlify/ai/-/ai-0.4.1.tgz"
- integrity sha512-ETLtV/9taYrcGhszwO+BLFgFJJ2MCnJp8BwxfwV6Z/+z3SsaUG4ExC8x4xzNCdB2GPWxXrXkvR2LFNsPFSLcRA==
- dependencies:
- "@netlify/api" "^14.0.18"
-
-"@netlify/api@^14.0.18":
- version "14.0.18"
- resolved "https://registry.npmjs.org/@netlify/api/-/api-14.0.18.tgz"
- integrity sha512-4STtNybPXALobjTHEIU48Huv9Si1sNxgHbtYslNBPvQu9/aTpxhRHDZuUOkE/QuhHSbaCNCWJSYFGIRxpCdXxg==
- dependencies:
- "@netlify/open-api" "^2.51.0"
- node-fetch "^3.0.0"
- p-wait-for "^5.0.0"
- picoquery "^2.5.0"
-
-"@netlify/binary-info@^1.0.0":
- version "1.0.0"
- resolved "https://registry.npmjs.org/@netlify/binary-info/-/binary-info-1.0.0.tgz"
- integrity sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==
-
-"@netlify/blobs@10.7.4", "@netlify/blobs@^10.7.0", "@netlify/blobs@^10.7.4":
- version "10.7.4"
- resolved "https://registry.npmjs.org/@netlify/blobs/-/blobs-10.7.4.tgz"
- integrity sha512-03lXstB4xxDKeYs2RTTZrUGRC0ea2nVZvkdGlw2A42AdK7KA6N0ocVmkIn9x91oqFsqK3dWJTAv2bzaLjsehXg==
- dependencies:
- "@netlify/dev-utils" "4.4.3"
- "@netlify/otel" "^5.1.5"
- "@netlify/runtime-utils" "2.3.0"
-
-"@netlify/cache@3.4.4":
- version "3.4.4"
- resolved "https://registry.npmjs.org/@netlify/cache/-/cache-3.4.4.tgz"
- integrity sha512-CL9WZjbxe9/Gkcpfkl6h1F0BkBxUg9b4HHleGjmo0rs/PDUJ2NDQVKtEospllH2+KDUdB6EsPhiJN+v9Jcdv1g==
- dependencies:
- "@netlify/runtime-utils" "2.3.0"
-
-"@netlify/config@^24.4.3":
- version "24.5.0"
- resolved "https://registry.npmjs.org/@netlify/config/-/config-24.5.0.tgz"
- integrity sha512-d9M/H9ouQUlu6OnEYa9z4Sa+RZUn7OioS6bw6kKRtalllkQiSAtbgzjXz/2umgABsJGmxYXyjSOk7P8QcKluJg==
- dependencies:
- "@iarna/toml" "^2.2.5"
- "@netlify/api" "^14.0.18"
- "@netlify/headers-parser" "^9.0.3"
- "@netlify/redirect-parser" "^15.0.4"
- chalk "^5.0.0"
- cron-parser "^4.1.0"
- deepmerge "^4.2.2"
- dot-prop "^9.0.0"
- execa "^8.0.0"
- fast-safe-stringify "^2.0.7"
- figures "^6.0.0"
- filter-obj "^6.0.0"
- find-up "^7.0.0"
- indent-string "^5.0.0"
- is-plain-obj "^4.0.0"
- map-obj "^5.0.0"
- omit.js "^2.0.2"
- p-locate "^6.0.0"
- path-type "^6.0.0"
- read-package-up "^11.0.0"
- tomlify-j0.4 "^3.0.0"
- validate-npm-package-name "^5.0.0"
- yaml "^2.8.0"
- yargs "^17.6.0"
- zod "^4.0.5"
-
-"@netlify/database-dev@0.10.1":
- version "0.10.1"
- resolved "https://registry.npmjs.org/@netlify/database-dev/-/database-dev-0.10.1.tgz"
- integrity sha512-kHLdS6r45TsDiS5aBrHUmzqPvoaWQEUZnaZeMwnIrLMwX8f2bIa6YAMOJJYJhyKm2drVo3C/T92/lJ5iGV/VBQ==
- dependencies:
- "@electric-sql/pglite" "^0.3.15"
- pg-gateway "0.3.0-beta.4"
-
-"@netlify/dev-utils@4.4.3", "@netlify/dev-utils@^4.4.3":
- version "4.4.3"
- resolved "https://registry.npmjs.org/@netlify/dev-utils/-/dev-utils-4.4.3.tgz"
- integrity sha512-VkMD8YACshR6pHgoub6nikkI+SQVdhjVvLsOK2ZSpN2wMlDHdsD8uRjESfzv/yYfq5jlsGskfx1cf1FUurWt9A==
- dependencies:
- "@whatwg-node/server" "^0.10.0"
- ansis "^4.1.0"
- chokidar "^4.0.1"
- decache "^4.6.2"
- dettle "^1.0.5"
- dot-prop "9.0.0"
- empathic "^2.0.0"
- env-paths "^3.0.0"
- image-size "^2.0.2"
- js-image-generator "^1.0.4"
- parse-gitignore "^2.0.0"
- semver "^7.7.2"
- tmp-promise "^3.0.3"
- uuid "^13.0.0"
- write-file-atomic "^5.0.1"
-
-"@netlify/dev@4.18.1":
- version "4.18.1"
- resolved "https://registry.npmjs.org/@netlify/dev/-/dev-4.18.1.tgz"
- integrity sha512-qbLvurzxBiLbBo4z2GfoXnFU5OS7QcGZTLzI1L31i3YahXPWJV7tnTn0kEAeyRV0tHmmVBF/FEzTws8cFzFSjQ==
- dependencies:
- "@netlify/ai" "^0.4.1"
- "@netlify/blobs" "10.7.4"
- "@netlify/config" "^24.4.3"
- "@netlify/database-dev" "0.10.1"
- "@netlify/dev-utils" "4.4.3"
- "@netlify/edge-functions-dev" "1.0.16"
- "@netlify/functions-dev" "1.2.6"
- "@netlify/headers" "2.1.8"
- "@netlify/images" "1.3.7"
- "@netlify/redirects" "3.1.10"
- "@netlify/runtime" "4.1.20"
- "@netlify/static" "3.1.7"
- ulid "^3.0.0"
-
-"@netlify/edge-bundler@^14.9.15":
- version "14.10.1"
- resolved "https://registry.npmjs.org/@netlify/edge-bundler/-/edge-bundler-14.10.1.tgz"
- integrity sha512-Kg/LHnLZnv18qzAQonnFMYcGbair/z5DI40le1L9PJlz+S7lR2xOVg0gBzTRccG1VylXozwp4GVYhVT4v7n2GA==
- dependencies:
- "@import-maps/resolve" "^2.0.0"
- "@sveltejs/acorn-typescript" "^1.0.9"
- acorn "^8.15.0"
- ajv "^8.11.2"
- ajv-errors "^3.0.0"
- better-ajv-errors "^1.2.0"
- common-path-prefix "^3.0.0"
- env-paths "^3.0.0"
- esbuild "0.27.3"
- execa "^8.0.0"
- find-up "^7.0.0"
- get-port "^7.0.0"
- node-stream-zip "^1.15.0"
- p-retry "^6.0.0"
- p-wait-for "^5.0.0"
- parse-imports "^2.2.1"
- path-key "^4.0.0"
- semver "^7.3.8"
- tar "^7.5.12"
- tmp-promise "^3.0.3"
- urlpattern-polyfill "8.0.2"
- uuid "^11.0.0"
-
-"@netlify/edge-functions-bootstrap@2.16.0":
- version "2.16.0"
- resolved "https://registry.npmjs.org/@netlify/edge-functions-bootstrap/-/edge-functions-bootstrap-2.16.0.tgz"
- integrity sha512-v8QQihSbBHj3JxtJsHoepXALpNumD9M7egHoc8z62FYl5it34dWczkaJoFFopEyhiBVKi4K/n0ZYpdzwfujd6g==
-
-"@netlify/edge-functions-dev@1.0.16":
- version "1.0.16"
- resolved "https://registry.npmjs.org/@netlify/edge-functions-dev/-/edge-functions-dev-1.0.16.tgz"
- integrity sha512-QQGUNPRvynKg4NJ7iiR0mYcsdA/QwIdUB/Fb4SGhhqBPicTcW4V5bEZ/JaMvEBMd2ZY8EKuWQ63Ryl4TVHI+QQ==
- dependencies:
- "@netlify/dev-utils" "4.4.3"
- "@netlify/edge-bundler" "^14.9.15"
- "@netlify/edge-functions" "3.0.6"
- "@netlify/edge-functions-bootstrap" "2.16.0"
- "@netlify/runtime-utils" "2.3.0"
- get-port "^7.1.0"
-
-"@netlify/edge-functions@3.0.6":
- version "3.0.6"
- resolved "https://registry.npmjs.org/@netlify/edge-functions/-/edge-functions-3.0.6.tgz"
- integrity sha512-xkVcTcpAuQKAY5GXKOjPTIct5Mz53NPHXOasggA+LTAxDDV4ohqSM8BIaXh1SgbcniHZyFhBqhc5hxZ+fFz5bQ==
- dependencies:
- "@netlify/types" "2.6.0"
-
-"@netlify/functions-dev@1.2.6":
- version "1.2.6"
- resolved "https://registry.npmjs.org/@netlify/functions-dev/-/functions-dev-1.2.6.tgz"
- integrity sha512-hhfgKGZ2mQAv85jb3o4hYZ7s8Ad/+99qz51AoxhE26KkU1IKuRuKwEowWZUtvih0KPmvmGcVHbd49KYVIlf0tA==
- dependencies:
- "@netlify/blobs" "10.7.4"
- "@netlify/dev-utils" "4.4.3"
- "@netlify/functions" "5.2.0"
- "@netlify/zip-it-and-ship-it" "^14.5.0"
- cron-parser "^4.9.0"
- decache "^4.6.2"
- extract-zip "^2.0.1"
- is-stream "^4.0.1"
- jwt-decode "^4.0.0"
- lambda-local "^2.2.0"
- read-package-up "^11.0.0"
- semver "^7.6.3"
- source-map-support "^0.5.21"
-
-"@netlify/functions@5.2.0", "@netlify/functions@^5.1.2":
- version "5.2.0"
- resolved "https://registry.npmjs.org/@netlify/functions/-/functions-5.2.0.tgz"
- integrity sha512-Pj93qeQd1tkQ5xm9gWJZmBf/1riLYqYHc0OzFukrJomrj82Ott53Rr/Q88H1ms5cF+P5QXRKWmA2JSxSybKfjA==
- dependencies:
- "@netlify/types" "2.6.0"
-
-"@netlify/headers-parser@^9.0.3":
- version "9.0.3"
- resolved "https://registry.npmjs.org/@netlify/headers-parser/-/headers-parser-9.0.3.tgz"
- integrity sha512-KNzC9RaKDwJVS44iTK6JxNA6LeXH0PUw0pLktWpmMVI/0FR98bvxaHcAisjHqbThAjxL9QjL1UZh0KzHCkxpNQ==
- dependencies:
- "@iarna/toml" "^2.2.5"
- escape-string-regexp "^5.0.0"
- fast-safe-stringify "^2.0.7"
- is-plain-obj "^4.0.0"
- map-obj "^5.0.0"
- path-exists "^5.0.0"
-
-"@netlify/headers@2.1.8":
- version "2.1.8"
- resolved "https://registry.npmjs.org/@netlify/headers/-/headers-2.1.8.tgz"
- integrity sha512-OhHT8nq84tSvXWaOMCLgcaGKnUccbIYg7/Ink4NyVHNwJ7L2fFGb6Mi4lPWluHhncYJE9p0eK7JMiKKj49Q0Qw==
- dependencies:
- "@netlify/headers-parser" "^9.0.3"
-
-"@netlify/images@1.3.7":
- version "1.3.7"
- resolved "https://registry.npmjs.org/@netlify/images/-/images-1.3.7.tgz"
- integrity sha512-qWKCbtYQbyHtzVjLcaAxZsxrd8qpIVnLWwvn2635E8zQSO7L0wb2oPTUhMEOOIxIurWuY3JSRGevpve6ifataQ==
- dependencies:
- ipx "^3.1.1"
-
-"@netlify/open-api@^2.51.0":
- version "2.53.0"
- resolved "https://registry.npmjs.org/@netlify/open-api/-/open-api-2.53.0.tgz"
- integrity sha512-CcIhcB+XzY77nze7vLTdxkqS/uX5DXleo3adE8H+M7TapLX6GTXp5qMIsq8bAuHy5eGw0ijRrAnSUmkOP4DM2w==
-
-"@netlify/otel@^5.1.5":
- version "5.1.5"
- resolved "https://registry.npmjs.org/@netlify/otel/-/otel-5.1.5.tgz"
- integrity sha512-RORbePN1ghdHp4pIkG3ccFMqmx5hwMfSyLGKp7bKVf1F5rSe1QjrCBp5xihEWI3xuh3fAqQroTlNYnoOud8RTQ==
- dependencies:
- "@opentelemetry/api" "1.9.0"
- "@opentelemetry/core" "1.30.1"
- "@opentelemetry/instrumentation" "^0.203.0"
- "@opentelemetry/resources" "1.30.1"
- "@opentelemetry/sdk-trace-node" "1.30.1"
-
-"@netlify/redirect-parser@^15.0.4":
- version "15.0.4"
- resolved "https://registry.npmjs.org/@netlify/redirect-parser/-/redirect-parser-15.0.4.tgz"
- integrity sha512-UYHRCO4HZI6WMpf8RheaCWnGafeJeFTsp/5yK887fyGqohDmFbc26NuFUvRl7J6sNu+di/1lLmRXP+yJ1X9TDA==
- dependencies:
- "@iarna/toml" "^2.2.5"
- fast-safe-stringify "^2.1.1"
- is-plain-obj "^4.0.0"
- path-exists "^5.0.0"
-
-"@netlify/redirects@3.1.10":
- version "3.1.10"
- resolved "https://registry.npmjs.org/@netlify/redirects/-/redirects-3.1.10.tgz"
- integrity sha512-q4PbtkeNDxKqfOemsrG5F/vkpNfLwjVQpx69+sS2Qg/PYOOneayKJOlCKhVc6QQUtDuhFV6WZ8JHielYMj1pVw==
- dependencies:
- "@netlify/dev-utils" "4.4.3"
- "@netlify/redirect-parser" "^15.0.4"
- cookie "^1.0.2"
- jsonwebtoken "9.0.3"
- netlify-redirector "^0.5.0"
-
-"@netlify/runtime-utils@2.3.0":
- version "2.3.0"
- resolved "https://registry.npmjs.org/@netlify/runtime-utils/-/runtime-utils-2.3.0.tgz"
- integrity sha512-cW8weDvsKV7zfia2m5EcBy6KILGoPD+eYZ3qWNGnIo05DGF28goPES0xKSDkNYgAF/2rRSIhie2qcBhbGVgSRg==
-
-"@netlify/runtime@4.1.20":
- version "4.1.20"
- resolved "https://registry.npmjs.org/@netlify/runtime/-/runtime-4.1.20.tgz"
- integrity sha512-maPRSTG+q9rTkeP+hj5X8PN6OkUShp1E62+GBtZrVRVrkTYLiF3mz2JGUw32lCbw2OqqvlUab85N4OMPSdP5HA==
- dependencies:
- "@netlify/blobs" "^10.7.4"
- "@netlify/cache" "3.4.4"
- "@netlify/runtime-utils" "2.3.0"
- "@netlify/types" "2.6.0"
-
-"@netlify/serverless-functions-api@2.15.0":
- version "2.15.0"
- resolved "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-2.15.0.tgz"
- integrity sha512-FDZwRBWq6zgmuYkszHGcN1qYliTOY7/ZzuWWxJy1WoB4cZt6gdzgN5Gx9zuIKfiL9KelL0iAnd/bZrrfLZZ5ig==
- dependencies:
- "@netlify/types" "^2.6.0"
-
-"@netlify/static@3.1.7":
- version "3.1.7"
- resolved "https://registry.npmjs.org/@netlify/static/-/static-3.1.7.tgz"
- integrity sha512-7gfDmUJKIFiVvqoqAoN7wkZkQx8KgVw5+ancu4v+QFU/hLt+gWqNH+ngxaCKCA0hmDE4oD1xNbClxlh9bNOetw==
- dependencies:
- mime-types "^3.0.0"
-
-"@netlify/types@2.6.0", "@netlify/types@^2.6.0":
- version "2.6.0"
- resolved "https://registry.npmjs.org/@netlify/types/-/types-2.6.0.tgz"
- integrity sha512-yD20EizHJDQxajJ66Vo8RTwLwR2jMNVxufPG8MHd2AScX8jW4z0VPnnJHArq2GYPFTFZRHmiAhDrXr5m8zof6w==
-
-"@netlify/vite-plugin@^2.10.3":
- version "2.12.1"
- resolved "https://registry.npmjs.org/@netlify/vite-plugin/-/vite-plugin-2.12.1.tgz"
- integrity sha512-P5WErLc6/E3eiNit1HQpWfEePvl528op/I84yxqJEOUa15NzxJYSbPDQ8CYUmz7ifhiZDbi1RFFmGoz0eA6aSA==
- dependencies:
- "@netlify/dev" "4.18.1"
- "@netlify/dev-utils" "^4.4.3"
- dedent "^1.7.0"
-
-"@netlify/zip-it-and-ship-it@^14.5.0":
- version "14.5.4"
- resolved "https://registry.npmjs.org/@netlify/zip-it-and-ship-it/-/zip-it-and-ship-it-14.5.4.tgz"
- integrity sha512-kaX/03YsBy/9ZOTNF/EtbBkof/Uukul5mnxs/SHD8LPY9Co6TcdMz61ZfDNyAYeIdfTMDIs4EFNBQPvzHexEMg==
- dependencies:
- "@babel/parser" "^7.22.5"
- "@babel/types" "^7.28.5"
- "@netlify/binary-info" "^1.0.0"
- "@netlify/serverless-functions-api" "2.15.0"
- "@vercel/nft" "0.29.4"
- archiver "^7.0.0"
- common-path-prefix "^3.0.0"
- copy-file "^11.0.0"
- es-module-lexer "^1.0.0"
- esbuild "0.27.3"
- execa "^8.0.0"
- fast-glob "^3.3.3"
- filter-obj "^6.0.0"
- find-up "^7.0.0"
- is-path-inside "^4.0.0"
- junk "^4.0.0"
- locate-path "^7.0.0"
- merge-options "^3.0.4"
- minimatch "^10.2.4"
- normalize-path "^3.0.0"
- p-map "^7.0.0"
- path-exists "^5.0.0"
- precinct "^12.0.0"
- require-package-name "^2.0.1"
- resolve "^2.0.0-next.1"
- semver "^7.3.8"
- tmp-promise "^3.0.2"
- toml "^3.0.0"
- unixify "^1.0.0"
- urlpattern-polyfill "8.0.2"
- yargs "^17.0.0"
- zod "^3.23.8"
-
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
@@ -1628,92 +952,6 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
-"@opentelemetry/api-logs@0.203.0":
- version "0.203.0"
- resolved "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz"
- integrity sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==
- dependencies:
- "@opentelemetry/api" "^1.3.0"
-
-"@opentelemetry/api@1.9.0":
- version "1.9.0"
- resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz"
- integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
-
-"@opentelemetry/api@^1.3.0":
- version "1.9.1"
- resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz"
- integrity sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==
-
-"@opentelemetry/context-async-hooks@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz"
- integrity sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==
-
-"@opentelemetry/core@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz"
- integrity sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==
- dependencies:
- "@opentelemetry/semantic-conventions" "1.28.0"
-
-"@opentelemetry/instrumentation@^0.203.0":
- version "0.203.0"
- resolved "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz"
- integrity sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==
- dependencies:
- "@opentelemetry/api-logs" "0.203.0"
- import-in-the-middle "^1.8.1"
- require-in-the-middle "^7.1.1"
-
-"@opentelemetry/propagator-b3@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.30.1.tgz"
- integrity sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ==
- dependencies:
- "@opentelemetry/core" "1.30.1"
-
-"@opentelemetry/propagator-jaeger@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.30.1.tgz"
- integrity sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg==
- dependencies:
- "@opentelemetry/core" "1.30.1"
-
-"@opentelemetry/resources@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz"
- integrity sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==
- dependencies:
- "@opentelemetry/core" "1.30.1"
- "@opentelemetry/semantic-conventions" "1.28.0"
-
-"@opentelemetry/sdk-trace-base@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz"
- integrity sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==
- dependencies:
- "@opentelemetry/core" "1.30.1"
- "@opentelemetry/resources" "1.30.1"
- "@opentelemetry/semantic-conventions" "1.28.0"
-
-"@opentelemetry/sdk-trace-node@1.30.1":
- version "1.30.1"
- resolved "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.30.1.tgz"
- integrity sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ==
- dependencies:
- "@opentelemetry/context-async-hooks" "1.30.1"
- "@opentelemetry/core" "1.30.1"
- "@opentelemetry/propagator-b3" "1.30.1"
- "@opentelemetry/propagator-jaeger" "1.30.1"
- "@opentelemetry/sdk-trace-base" "1.30.1"
- semver "^7.5.2"
-
-"@opentelemetry/semantic-conventions@1.28.0":
- version "1.28.0"
- resolved "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz"
- integrity sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==
-
"@oslojs/encoding@^1.1.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz"
@@ -1769,15 +1007,6 @@
resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz#02400c54b4a67efcc7e2327b249711920ac969e2"
integrity sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==
-"@parcel/watcher-wasm@^2.5.6":
- version "2.5.6"
- resolved "https://registry.npmjs.org/@parcel/watcher-wasm/-/watcher-wasm-2.5.6.tgz"
- integrity sha512-byAiBZ1t3tXQvc8dMD/eoyE7lTXYorhn+6uVW5AC+JGI1KtJC/LvDche5cfUE+qiefH+Ybq0bUCJU0aB1cSHUA==
- dependencies:
- is-glob "^4.0.3"
- napi-wasm "^1.1.0"
- picomatch "^4.0.3"
-
"@parcel/watcher-win32-arm64@2.5.6":
version "2.5.6"
resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz#caae3d3c7583ca0a7171e6bd142c34d20ea1691e"
@@ -1793,7 +1022,7 @@
resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz#73fdafba2e21c448f0e456bbe13178d8fe11739d"
integrity sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==
-"@parcel/watcher@^2.4.1", "@parcel/watcher@^2.5.6":
+"@parcel/watcher@^2.4.1":
version "2.5.6"
resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz"
integrity sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==
@@ -1817,37 +1046,11 @@
"@parcel/watcher-win32-ia32" "2.5.6"
"@parcel/watcher-win32-x64" "2.5.6"
-"@pkgjs/parseargs@^0.11.0":
- version "0.11.0"
- resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
- integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
-
"@pkgr/core@^0.2.9":
version "0.2.9"
resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz"
integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==
-"@poppinss/colors@^4.1.5":
- version "4.1.6"
- resolved "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz"
- integrity sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==
- dependencies:
- kleur "^4.1.5"
-
-"@poppinss/dumper@^0.6.4":
- version "0.6.5"
- resolved "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz"
- integrity sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==
- dependencies:
- "@poppinss/colors" "^4.1.5"
- "@sindresorhus/is" "^7.0.2"
- supports-color "^10.0.0"
-
-"@poppinss/exception@^1.2.2":
- version "1.2.3"
- resolved "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz"
- integrity sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==
-
"@puppeteer/browsers@2.13.0":
version "2.13.0"
resolved "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz"
@@ -1885,7 +1088,7 @@
resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz"
integrity sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==
-"@rollup/pluginutils@^5.1.3", "@rollup/pluginutils@^5.3.0":
+"@rollup/pluginutils@^5.3.0":
version "5.3.0"
resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz"
integrity sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==
@@ -2083,24 +1286,6 @@
resolved "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz"
integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==
-"@sindresorhus/is@^4.0.0":
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
- integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
-
-"@sindresorhus/is@^7.0.2":
- version "7.2.0"
- resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz"
- integrity sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==
-
-"@so-ric/colorspace@^1.1.6":
- version "1.1.6"
- resolved "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz"
- integrity sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==
- dependencies:
- color "^5.0.2"
- text-hex "1.0.x"
-
"@sparticuz/chromium@^148.0.0":
version "148.0.0"
resolved "https://registry.npmjs.org/@sparticuz/chromium/-/chromium-148.0.0.tgz"
@@ -2108,11 +1293,6 @@
dependencies:
tar-fs "^3.1.2"
-"@speed-highlight/core@^1.2.7":
- version "1.2.15"
- resolved "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz"
- integrity sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==
-
"@standard-schema/spec@^1.0.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz"
@@ -2123,7 +1303,7 @@
resolved "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz"
integrity sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==
-"@sveltejs/acorn-typescript@^1.0.5", "@sveltejs/acorn-typescript@^1.0.9":
+"@sveltejs/acorn-typescript@^1.0.5":
version "1.0.9"
resolved "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz"
integrity sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==
@@ -2146,13 +1326,6 @@
obug "^2.1.0"
vitefu "^1.1.1"
-"@szmarczak/http-timer@^4.0.5":
- version "4.0.6"
- resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
- integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
- dependencies:
- defer-to-connect "^2.0.0"
-
"@tootallnate/quickjs-emscripten@^0.23.0":
version "0.23.0"
resolved "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz"
@@ -2191,16 +1364,6 @@
dependencies:
"@babel/types" "^7.28.2"
-"@types/cacheable-request@^6.0.1":
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183"
- integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==
- dependencies:
- "@types/http-cache-semantics" "*"
- "@types/keyv" "^3.1.4"
- "@types/node" "*"
- "@types/responselike" "^1.0.0"
-
"@types/d3-array@^3.0.3":
version "3.2.2"
resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz"
@@ -2276,23 +1439,11 @@
dependencies:
"@types/unist" "*"
-"@types/http-cache-semantics@*":
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#f6a7788f438cbfde15f29acad46512b4c01913b3"
- integrity sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==
-
"@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
-"@types/keyv@^3.1.4":
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6"
- integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==
- dependencies:
- "@types/node" "*"
-
"@types/mdast@^4.0.0":
version "4.0.4"
resolved "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz"
@@ -2326,11 +1477,6 @@
dependencies:
undici-types "~7.16.0"
-"@types/normalize-package-data@^2.4.3":
- version "2.4.4"
- resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz"
- integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==
-
"@types/parse-json@^4.0.0":
version "4.0.2"
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz"
@@ -2348,18 +1494,6 @@
dependencies:
csstype "^3.2.2"
-"@types/responselike@^1.0.0":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50"
- integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==
- dependencies:
- "@types/node" "*"
-
-"@types/retry@0.12.2":
- version "0.12.2"
- resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz"
- integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==
-
"@types/sax@^1.2.1":
version "1.2.7"
resolved "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz"
@@ -2367,11 +1501,6 @@
dependencies:
"@types/node" "*"
-"@types/triple-beam@^1.3.2":
- version "1.3.5"
- resolved "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz"
- integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==
-
"@types/trusted-types@^2.0.7":
version "2.0.7"
resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz"
@@ -2432,7 +1561,7 @@
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz"
integrity sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==
-"@typescript-eslint/typescript-estree@8.59.2", "@typescript-eslint/typescript-estree@^8.58.2":
+"@typescript-eslint/typescript-estree@8.59.2":
version "8.59.2"
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz"
integrity sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==
@@ -2460,70 +1589,7 @@
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz"
integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==
-"@vercel/analytics@^1.6.1":
- version "1.6.1"
- resolved "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.6.1.tgz"
- integrity sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==
-
-"@vercel/functions@^3.4.3":
- version "3.5.0"
- resolved "https://registry.npmjs.org/@vercel/functions/-/functions-3.5.0.tgz"
- integrity sha512-+RokZ+4gkYyOsKBuJ29cQ8iSZG123LLJbZfPry20kkTgrN9U0277La4feP4DnWVo3sGoYa4plCEKY9XKUYoX9g==
- dependencies:
- "@vercel/oidc" "3.4.0"
-
-"@vercel/nft@0.29.4":
- version "0.29.4"
- resolved "https://registry.npmjs.org/@vercel/nft/-/nft-0.29.4.tgz"
- integrity sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==
- dependencies:
- "@mapbox/node-pre-gyp" "^2.0.0"
- "@rollup/pluginutils" "^5.1.3"
- acorn "^8.6.0"
- acorn-import-attributes "^1.9.5"
- async-sema "^3.1.1"
- bindings "^1.4.0"
- estree-walker "2.0.2"
- glob "^10.4.5"
- graceful-fs "^4.2.9"
- node-gyp-build "^4.2.2"
- picomatch "^4.0.2"
- resolve-from "^5.0.0"
-
-"@vercel/nft@^1.3.2":
- version "1.5.0"
- resolved "https://registry.npmjs.org/@vercel/nft/-/nft-1.5.0.tgz"
- integrity sha512-IWTDeIoWhQ7ZtRO/JRKH+jhmeQvZYhtGPmzw/QGDY+wDCQqfm25P9yIdoAFagu4fWsK4IwZXDFIjrmp5rRm/sA==
- dependencies:
- "@mapbox/node-pre-gyp" "^2.0.0"
- "@rollup/pluginutils" "^5.1.3"
- acorn "^8.6.0"
- acorn-import-attributes "^1.9.5"
- async-sema "^3.1.1"
- bindings "^1.4.0"
- estree-walker "2.0.2"
- glob "^13.0.0"
- graceful-fs "^4.2.9"
- node-gyp-build "^4.2.2"
- picomatch "^4.0.2"
- resolve-from "^5.0.0"
-
-"@vercel/oidc@3.4.0":
- version "3.4.0"
- resolved "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.4.0.tgz"
- integrity sha512-p0sKfHkfRmMaqqDwNL4tjnX9TgRrLMlEtUjIxfrEns8pOxz1R9ztqOVI+ehqiq93/2/HnfPe/UBZkfAZwnx0UA==
-
-"@vercel/routing-utils@^5.3.3":
- version "5.3.3"
- resolved "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-5.3.3.tgz"
- integrity sha512-KYm2sLNUD48gDScv8ob4ejc3Gww2jcJyW80hTdYlenAPz/5BQar1Gyh38xrUuZ532TUwSb5mV1uRbAuiykq0EQ==
- dependencies:
- path-to-regexp "6.1.0"
- path-to-regexp-updated "npm:path-to-regexp@6.3.0"
- optionalDependencies:
- ajv "^6.12.3"
-
-"@vitejs/plugin-react@^5.2.0":
+"@vitejs/plugin-react@^5.0.4", "@vitejs/plugin-react@^5.2.0":
version "5.2.0"
resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz"
integrity sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==
@@ -2608,109 +1674,6 @@
resolved "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz"
integrity sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==
-"@vue/compiler-core@3.5.33":
- version "3.5.33"
- resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.33.tgz"
- integrity sha512-3PZLQwFw4Za3TC8t0FvTy3wI16Kt+pmwcgNZca4Pj9iWL2E72a/gZlpBtAJvEdDMdCxdG/qq0C7PN0bsJuv0Rw==
- dependencies:
- "@babel/parser" "^7.29.2"
- "@vue/shared" "3.5.33"
- entities "^7.0.1"
- estree-walker "^2.0.2"
- source-map-js "^1.2.1"
-
-"@vue/compiler-dom@3.5.33":
- version "3.5.33"
- resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.33.tgz"
- integrity sha512-PXq0yrfCLzzL07rbXO4awtXY1Z06LG2eu6Adg3RJFa/j3Cii217XxxLXG22N330gw7GmALCY0Z8RgXEviwgpjA==
- dependencies:
- "@vue/compiler-core" "3.5.33"
- "@vue/shared" "3.5.33"
-
-"@vue/compiler-sfc@^3.5.32":
- version "3.5.33"
- resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.33.tgz"
- integrity sha512-UTUvRO9cY+rROrx/pvN9P5Z7FgA6QGfokUCfhQE4EnmUj3rVnK+CHI0LsEO1pg+I7//iRYMUfcNcCPe7tg0CoA==
- dependencies:
- "@babel/parser" "^7.29.2"
- "@vue/compiler-core" "3.5.33"
- "@vue/compiler-dom" "3.5.33"
- "@vue/compiler-ssr" "3.5.33"
- "@vue/shared" "3.5.33"
- estree-walker "^2.0.2"
- magic-string "^0.30.21"
- postcss "^8.5.10"
- source-map-js "^1.2.1"
-
-"@vue/compiler-ssr@3.5.33":
- version "3.5.33"
- resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.33.tgz"
- integrity sha512-IErjYdnj1qIupG5xxiVIYiiRvDhGWV4zuh/RCrwfYpuL+HWQzeU6lCk/nF9r7olWMnjKxCAkOctT2qFWFkzb1A==
- dependencies:
- "@vue/compiler-dom" "3.5.33"
- "@vue/shared" "3.5.33"
-
-"@vue/shared@3.5.33":
- version "3.5.33"
- resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.5.33.tgz"
- integrity sha512-5vR2QIlmaLG77Ygd4pMP6+SGQ5yox9VhtnbDWTy9DzMzdmeLxZ1QqxrywEZ9sa1AVubfIJyaCG3ytyWU81ufcQ==
-
-"@whatwg-node/disposablestack@^0.0.6":
- version "0.0.6"
- resolved "https://registry.npmjs.org/@whatwg-node/disposablestack/-/disposablestack-0.0.6.tgz"
- integrity sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==
- dependencies:
- "@whatwg-node/promise-helpers" "^1.0.0"
- tslib "^2.6.3"
-
-"@whatwg-node/fetch@^0.10.13":
- version "0.10.13"
- resolved "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.13.tgz"
- integrity sha512-b4PhJ+zYj4357zwk4TTuF2nEe0vVtOrwdsrNo5hL+u1ojXNhh1FgJ6pg1jzDlwlT4oBdzfSwaBwMCtFCsIWg8Q==
- dependencies:
- "@whatwg-node/node-fetch" "^0.8.3"
- urlpattern-polyfill "^10.0.0"
-
-"@whatwg-node/node-fetch@^0.8.3":
- version "0.8.5"
- resolved "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.8.5.tgz"
- integrity sha512-4xzCl/zphPqlp9tASLVeUhB5+WJHbuWGYpfoC2q1qh5dw0AqZBW7L27V5roxYWijPxj4sspRAAoOH3d2ztaHUQ==
- dependencies:
- "@fastify/busboy" "^3.1.1"
- "@whatwg-node/disposablestack" "^0.0.6"
- "@whatwg-node/promise-helpers" "^1.3.2"
- tslib "^2.6.3"
-
-"@whatwg-node/promise-helpers@^1.0.0", "@whatwg-node/promise-helpers@^1.2.1", "@whatwg-node/promise-helpers@^1.3.2":
- version "1.3.2"
- resolved "https://registry.npmjs.org/@whatwg-node/promise-helpers/-/promise-helpers-1.3.2.tgz"
- integrity sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==
- dependencies:
- tslib "^2.6.3"
-
-"@whatwg-node/server@^0.10.0":
- version "0.10.18"
- resolved "https://registry.npmjs.org/@whatwg-node/server/-/server-0.10.18.tgz"
- integrity sha512-kMwLlxUbduttIgaPdSkmEarFpP+mSY8FEm+QWMBRJwxOHWkri+cxd8KZHO9EMrB9vgUuz+5WEaCawaL5wGVoXg==
- dependencies:
- "@envelop/instrumentation" "^1.0.0"
- "@whatwg-node/disposablestack" "^0.0.6"
- "@whatwg-node/fetch" "^0.10.13"
- "@whatwg-node/promise-helpers" "^1.3.2"
- tslib "^2.6.3"
-
-abbrev@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz"
- integrity sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==
-
-abort-controller@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz"
- integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
- dependencies:
- event-target-shim "^5.0.0"
-
accepts@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz"
@@ -2719,17 +1682,12 @@ accepts@^2.0.0:
mime-types "^3.0.0"
negotiator "^1.0.0"
-acorn-import-attributes@^1.9.5:
- version "1.9.5"
- resolved "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz"
- integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==
-
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-acorn@^8.12.1, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.6.0:
+acorn@^8.12.1, acorn@^8.15.0, acorn@^8.16.0:
version "8.16.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz"
integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
@@ -2751,12 +1709,7 @@ ajv-draft-04@^1.0.0:
resolved "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz"
integrity sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==
-ajv-errors@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz"
- integrity sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==
-
-ajv@^6.12.3, ajv@^6.14.0:
+ajv@^6.14.0:
version "6.15.0"
resolved "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz"
integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==
@@ -2766,7 +1719,7 @@ ajv@^6.12.3, ajv@^6.14.0:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-ajv@^8.11.2, ajv@^8.17.1:
+ajv@^8.17.1:
version "8.20.0"
resolved "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz"
integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==
@@ -2781,11 +1734,6 @@ ansi-regex@^5.0.1:
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
-ansi-regex@^6.2.2:
- version "6.2.2"
- resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz"
- integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
-
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
@@ -2793,16 +1741,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
-ansi-styles@^6.1.0:
- version "6.2.3"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz"
- integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
-
-ansis@^4.1.0:
- version "4.2.0"
- resolved "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz"
- integrity sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==
-
anymatch@^3.1.3, anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
@@ -2811,32 +1749,6 @@ anymatch@^3.1.3, anymatch@~3.1.2:
normalize-path "^3.0.0"
picomatch "^2.0.4"
-archiver-utils@^5.0.0, archiver-utils@^5.0.2:
- version "5.0.2"
- resolved "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz"
- integrity sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==
- dependencies:
- glob "^10.0.0"
- graceful-fs "^4.2.0"
- is-stream "^2.0.1"
- lazystream "^1.0.0"
- lodash "^4.17.15"
- normalize-path "^3.0.0"
- readable-stream "^4.0.0"
-
-archiver@^7.0.0:
- version "7.0.1"
- resolved "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz"
- integrity sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==
- dependencies:
- archiver-utils "^5.0.2"
- async "^3.2.4"
- buffer-crc32 "^1.0.0"
- readable-stream "^4.0.0"
- readdir-glob "^1.1.2"
- tar-stream "^3.0.0"
- zip-stream "^6.0.1"
-
arg@^5.0.0:
version "5.0.2"
resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz"
@@ -2857,47 +1769,11 @@ aria-query@^5.3.2:
resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz"
integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==
-array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz"
- integrity sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==
- dependencies:
- call-bound "^1.0.3"
- is-array-buffer "^3.0.5"
-
array-iterate@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz"
integrity sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==
-array.prototype.flatmap@^1.3.3:
- version "1.3.3"
- resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz"
- integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==
- dependencies:
- call-bind "^1.0.8"
- define-properties "^1.2.1"
- es-abstract "^1.23.5"
- es-shim-unscopables "^1.0.2"
-
-arraybuffer.prototype.slice@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz"
- integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==
- dependencies:
- array-buffer-byte-length "^1.0.1"
- call-bind "^1.0.8"
- define-properties "^1.2.1"
- es-abstract "^1.23.5"
- es-errors "^1.3.0"
- get-intrinsic "^1.2.6"
- is-array-buffer "^3.0.4"
-
-ast-module-types@^6.0.1:
- version "6.0.1"
- resolved "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.1.tgz"
- integrity sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==
-
ast-types@^0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz"
@@ -2993,38 +1869,11 @@ astrojs-compiler-sync@^1.0.0:
dependencies:
synckit "^0.11.0"
-async-function@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz"
- integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==
-
-async-sema@^3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz"
- integrity sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==
-
-async@^3.2.3, async@^3.2.4:
- version "3.2.6"
- resolved "https://registry.npmjs.org/async/-/async-3.2.6.tgz"
- integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
-
-available-typed-arrays@^1.0.7:
- version "1.0.7"
- resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz"
- integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
- dependencies:
- possible-typed-array-names "^1.0.0"
-
axobject-query@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz"
integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==
-b4a@^1.6.4:
- version "1.8.1"
- resolved "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz"
- integrity sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==
-
babel-plugin-macros@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz"
@@ -3049,53 +1898,10 @@ balanced-match@^4.0.2:
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz"
integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==
-bare-events@^2.5.4, bare-events@^2.7.0:
- version "2.8.2"
- resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz"
- integrity sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==
-
-bare-fs@^4.5.5:
- version "4.7.1"
- resolved "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.1.tgz"
- integrity sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==
- dependencies:
- bare-events "^2.5.4"
- bare-path "^3.0.0"
- bare-stream "^2.6.4"
- bare-url "^2.2.2"
- fast-fifo "^1.3.2"
-
-bare-os@^3.0.1:
- version "3.9.1"
- resolved "https://registry.npmjs.org/bare-os/-/bare-os-3.9.1.tgz"
- integrity sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==
-
-bare-path@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz"
- integrity sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==
- dependencies:
- bare-os "^3.0.1"
-
-bare-stream@^2.6.4:
- version "2.13.1"
- resolved "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.1.tgz"
- integrity sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==
- dependencies:
- streamx "^2.25.0"
- teex "^1.0.1"
-
-bare-url@^2.2.2:
- version "2.4.2"
- resolved "https://registry.npmjs.org/bare-url/-/bare-url-2.4.2.tgz"
- integrity sha512-/9a2j4ac6ckpmAHvod/ob7x439OAHst/drc2Clnq+reRYd/ovddwcF4LfoxHyNk5AuGBnPg+HqFjmE/Zpq6v0A==
- dependencies:
- bare-path "^3.0.0"
-
-base64-js@^1.3.1:
- version "1.5.1"
- resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
- integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+base64-js@^1.3.1:
+ version "1.5.1"
+ resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
+ integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
baseline-browser-mapping@^2.10.12:
version "2.10.27"
@@ -3107,29 +1913,11 @@ basic-ftp@^5.0.2, basic-ftp@^5.2.0:
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.3.1.tgz#3148ee9af43c0522514a4f973fecb1d3cbb6d71e"
integrity sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==
-better-ajv-errors@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.2.0.tgz"
- integrity sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==
- dependencies:
- "@babel/code-frame" "^7.16.0"
- "@humanwhocodes/momoa" "^2.0.2"
- chalk "^4.1.2"
- jsonpointer "^5.0.0"
- leven "^3.1.0 < 4"
-
binary-extensions@^2.0.0:
version "2.3.0"
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
-bindings@^1.4.0:
- version "1.5.0"
- resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz"
- integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
- dependencies:
- file-uri-to-path "1.0.0"
-
bl@^4.0.3:
version "4.1.0"
resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz"
@@ -3139,11 +1927,6 @@ bl@^4.0.3:
inherits "^2.0.4"
readable-stream "^3.4.0"
-blake3-wasm@2.1.5:
- version "2.1.5"
- resolved "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz"
- integrity sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==
-
body-parser@^2.2.1:
version "2.2.2"
resolved "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz"
@@ -3164,15 +1947,7 @@ boolbase@^1.0.0:
resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
-brace-expansion@^1.1.7:
- version "1.1.14"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.14.tgz#d9de602370d91347cd9ddad1224d4fd701eb348b"
- integrity sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==
- dependencies:
- balanced-match "^1.0.0"
- concat-map "0.0.1"
-
-brace-expansion@^2.0.1, brace-expansion@^2.0.2:
+brace-expansion@^2.0.1:
version "2.1.0"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz"
integrity sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==
@@ -3204,26 +1979,11 @@ browserslist@^4.24.0:
node-releases "^2.0.36"
update-browserslist-db "^1.2.3"
-buffer-crc32@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz"
- integrity sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==
-
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
-buffer-equal-constant-time@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz"
- integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
-
-buffer-from@^1.0.0:
- version "1.1.2"
- resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
- integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
-
buffer@^5.2.1, buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
@@ -3232,42 +1992,11 @@ buffer@^5.2.1, buffer@^5.5.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
-buffer@^6.0.3:
- version "6.0.3"
- resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz"
- integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
- dependencies:
- base64-js "^1.3.1"
- ieee754 "^1.2.1"
-
bytes@^3.1.2, bytes@~3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
-cacheable-lookup@^5.0.3:
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
- integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
-
-cacheable-request@^7.0.2:
- version "7.0.4"
- resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817"
- integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==
- dependencies:
- clone-response "^1.0.2"
- get-stream "^5.1.0"
- http-cache-semantics "^4.0.0"
- keyv "^4.0.0"
- lowercase-keys "^2.0.0"
- normalize-url "^6.0.1"
- responselike "^2.0.0"
-
-cachedir@^2.3.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d"
- integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==
-
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
@@ -3276,17 +2005,7 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
es-errors "^1.3.0"
function-bind "^1.1.2"
-call-bind@^1.0.7, call-bind@^1.0.8, call-bind@^1.0.9:
- version "1.0.9"
- resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz"
- integrity sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==
- dependencies:
- call-bind-apply-helpers "^1.0.2"
- es-define-property "^1.0.1"
- get-intrinsic "^1.3.0"
- set-function-length "^1.2.2"
-
-call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4:
+call-bound@^1.0.2:
version "1.0.4"
resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz"
integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
@@ -3294,11 +2013,6 @@ call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4:
call-bind-apply-helpers "^1.0.2"
get-intrinsic "^1.3.0"
-callsite@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz"
- integrity sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==
-
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
@@ -3314,7 +2028,7 @@ ccount@^2.0.0:
resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz"
integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==
-chalk@4.1.2, chalk@^4.1.2:
+chalk@4.1.2:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -3322,11 +2036,6 @@ chalk@4.1.2, chalk@^4.1.2:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
-chalk@^5.0.0:
- version "5.6.2"
- resolved "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz"
- integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==
-
character-entities-html4@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz"
@@ -3386,7 +2095,7 @@ chokidar@^3.5.2:
optionalDependencies:
fsevents "~2.3.2"
-chokidar@^4.0.0, chokidar@^4.0.1, chokidar@^4.0.3:
+chokidar@^4.0.0, chokidar@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz"
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
@@ -3405,11 +2114,6 @@ chownr@^1.1.1:
resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
-chownr@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz"
- integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==
-
chromium-bidi@0.4.5:
version "0.4.5"
resolved "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.5.tgz"
@@ -3425,42 +2129,11 @@ chromium-bidi@14.0.0:
mitt "^3.0.1"
zod "^3.24.1"
-chromium@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/chromium/-/chromium-3.0.3.tgz#0f776510d6b2749d3cf5632383c6e15a97390e9c"
- integrity sha512-TfbzP/3t38Us5xrbb9x87M/y5I/j3jx0zeJhhQ72gjp6dwJuhVP6hBZnBH4wEg7512VVXk9zCfTuPFOdw7bQqg==
- dependencies:
- cachedir "^2.3.0"
- debug "^4.1.0"
- extract-zip "^1.7.0"
- got "^11.5.1"
- progress "^2.0.3"
- rimraf "^2.7.1"
- tmp "0.0.33"
- tunnel "^0.0.6"
-
ci-info@^4.4.0:
version "4.4.0"
resolved "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz"
integrity sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==
-citty@^0.1.5, citty@^0.1.6:
- version "0.1.6"
- resolved "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz"
- integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==
- dependencies:
- consola "^3.2.3"
-
-citty@^0.2.2:
- version "0.2.2"
- resolved "https://registry.npmjs.org/citty/-/citty-0.2.2.tgz"
- integrity sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==
-
-cjs-module-lexer@^1.2.2:
- version "1.4.3"
- resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz"
- integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==
-
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz"
@@ -3470,13 +2143,6 @@ cliui@^8.0.1:
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
-clone-response@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3"
- integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==
- dependencies:
- mimic-response "^1.0.0"
-
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
@@ -3489,99 +2155,31 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
-color-convert@^3.1.3:
- version "3.1.3"
- resolved "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz"
- integrity sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==
- dependencies:
- color-name "^2.0.0"
-
-color-name@^1.1.4, color-name@~1.1.4:
+color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-color-name@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz"
- integrity sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==
-
-color-string@^2.1.3:
- version "2.1.4"
- resolved "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz"
- integrity sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==
- dependencies:
- color-name "^2.0.0"
-
-color@^5.0.2:
- version "5.0.3"
- resolved "https://registry.npmjs.org/color/-/color-5.0.3.tgz"
- integrity sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==
- dependencies:
- color-convert "^3.1.3"
- color-string "^2.1.3"
-
comma-separated-tokens@^2.0.0:
version "2.0.3"
resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz"
integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==
-commander@2, commander@^2.20.3:
+commander@2:
version "2.20.3"
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-commander@^10.0.1:
- version "10.0.1"
- resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz"
- integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
-
commander@^11.1.0:
version "11.1.0"
resolved "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz"
integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==
-commander@^12.1.0:
- version "12.1.0"
- resolved "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz"
- integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==
-
common-ancestor-path@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz"
integrity sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==
-common-path-prefix@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz"
- integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==
-
-compress-commons@^6.0.2:
- version "6.0.2"
- resolved "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz"
- integrity sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==
- dependencies:
- crc-32 "^1.2.0"
- crc32-stream "^6.0.0"
- is-stream "^2.0.1"
- normalize-path "^3.0.0"
- readable-stream "^4.0.0"
-
-concat-map@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-
-concat-stream@^1.6.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
- integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
- dependencies:
- buffer-from "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^2.2.2"
- typedarray "^0.0.6"
-
concurrently@^9.2.1:
version "9.2.1"
resolved "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz"
@@ -3594,16 +2192,6 @@ concurrently@^9.2.1:
tree-kill "1.2.2"
yargs "17.7.2"
-confbox@^0.1.8:
- version "0.1.8"
- resolved "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz"
- integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
-
-consola@^3.2.3, consola@^3.4.2:
- version "3.4.2"
- resolved "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz"
- integrity sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==
-
content-disposition@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz"
@@ -3639,24 +2227,11 @@ cookie@^0.7.1:
resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz"
integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
-cookie@^1.0.1, cookie@^1.0.2, cookie@^1.1.1:
+cookie@^1.0.1, cookie@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz"
integrity sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==
-copy-file@^11.0.0:
- version "11.1.0"
- resolved "https://registry.npmjs.org/copy-file/-/copy-file-11.1.0.tgz"
- integrity sha512-X8XDzyvYaA6msMyAM575CUoygY5b44QzLcGRKsK3MFmXcOvQa518dNPLsKYwkYsn72g3EiW+LE0ytd/FlqWmyw==
- dependencies:
- graceful-fs "^4.2.11"
- p-event "^6.0.0"
-
-core-util-is@~1.0.0:
- version "1.0.3"
- resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
- integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
-
cors@^2.8.6:
version "2.8.6"
resolved "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz"
@@ -3696,26 +2271,6 @@ cosmiconfig@^9.0.0:
js-yaml "^4.1.0"
parse-json "^5.2.0"
-crc-32@^1.2.0:
- version "1.2.2"
- resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz"
- integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
-
-crc32-stream@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz"
- integrity sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==
- dependencies:
- crc-32 "^1.2.0"
- readable-stream "^4.0.0"
-
-cron-parser@^4.1.0, cron-parser@^4.9.0:
- version "4.9.0"
- resolved "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz"
- integrity sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==
- dependencies:
- luxon "^3.2.1"
-
cross-fetch@3.1.5:
version "3.1.5"
resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz"
@@ -3723,7 +2278,7 @@ cross-fetch@3.1.5:
dependencies:
node-fetch "2.6.7"
-cross-spawn@^7.0.3, cross-spawn@^7.0.6:
+cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
@@ -3732,11 +2287,6 @@ cross-spawn@^7.0.3, cross-spawn@^7.0.6:
shebang-command "^2.0.0"
which "^2.0.1"
-"crossws@>=0.2.0 <0.5.0":
- version "0.4.5"
- resolved "https://registry.npmjs.org/crossws/-/crossws-0.4.5.tgz"
- integrity sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==
-
crossws@^0.3.5:
version "0.3.5"
resolved "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz"
@@ -3781,11 +2331,6 @@ cssesc@^3.0.0:
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
-cssfilter@0.0.10:
- version "0.0.10"
- resolved "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz"
- integrity sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==
-
csso@^5.0.5:
version "5.0.5"
resolved "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz"
@@ -3940,44 +2485,12 @@ d3-zoom@^2.0.0:
d3-selection "2"
d3-transition "2"
-data-uri-to-buffer@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz"
- integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
-
data-uri-to-buffer@^6.0.2:
version "6.0.2"
resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz"
integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==
-data-view-buffer@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz"
- integrity sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==
- dependencies:
- call-bound "^1.0.3"
- es-errors "^1.3.0"
- is-data-view "^1.0.2"
-
-data-view-byte-length@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz"
- integrity sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==
- dependencies:
- call-bound "^1.0.3"
- es-errors "^1.3.0"
- is-data-view "^1.0.2"
-
-data-view-byte-offset@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz"
- integrity sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==
- dependencies:
- call-bound "^1.0.2"
- es-errors "^1.3.0"
- is-data-view "^1.0.1"
-
-debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.4.0, debug@^4.4.3:
+debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4.3:
version "4.4.3"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
@@ -3991,20 +2504,6 @@ debug@4.3.4:
dependencies:
ms "2.1.2"
-debug@^2.6.9:
- version "2.6.9"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
-decache@^4.6.2:
- version "4.6.2"
- resolved "https://registry.npmjs.org/decache/-/decache-4.6.2.tgz"
- integrity sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==
- dependencies:
- callsite "^1.0.0"
-
decimal.js-light@^2.5.1:
version "2.5.1"
resolved "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz"
@@ -4017,57 +2516,22 @@ decode-named-character-reference@^1.0.0:
dependencies:
character-entities "^2.0.0"
-decompress-response@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
- integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
- dependencies:
- mimic-response "^3.1.0"
-
dedent-js@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz"
integrity sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==
-dedent@^1.7.0:
- version "1.7.2"
- resolved "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz"
- integrity sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==
-
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
-deepmerge@^4.2.2, deepmerge@^4.3.1:
+deepmerge@^4.3.1:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
-defer-to-connect@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
- integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
-
-define-data-property@^1.0.1, define-data-property@^1.1.4:
- version "1.1.4"
- resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz"
- integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
- dependencies:
- es-define-property "^1.0.0"
- es-errors "^1.3.0"
- gopd "^1.0.1"
-
-define-properties@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz"
- integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
- dependencies:
- define-data-property "^1.0.1"
- has-property-descriptors "^1.0.0"
- object-keys "^1.1.1"
-
-defu@^6.1.4, defu@^6.1.6, defu@^6.1.7:
+defu@^6.1.6:
version "6.1.7"
resolved "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz"
integrity sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==
@@ -4096,92 +2560,11 @@ destr@^2.0.5:
resolved "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz"
integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==
-detect-libc@^2.0.0, detect-libc@^2.0.3, detect-libc@^2.1.2:
+detect-libc@^2.0.3, detect-libc@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz"
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
-detective-amd@^6.0.1:
- version "6.1.0"
- resolved "https://registry.npmjs.org/detective-amd/-/detective-amd-6.1.0.tgz"
- integrity sha512-fmI6LGMvotqd49QaA3ZYw+q0aGp2yXmMjzIuY6fH9j9YFIXY/73yDhMwhX9cPbhWd+AH06NH1Di/LKOuCH0Ubg==
- dependencies:
- ast-module-types "^6.0.1"
- escodegen "^2.1.0"
- get-amd-module-type "^6.0.2"
- node-source-walk "^7.0.1"
-
-detective-cjs@^6.1.0:
- version "6.1.1"
- resolved "https://registry.npmjs.org/detective-cjs/-/detective-cjs-6.1.1.tgz"
- integrity sha512-pSh7mkCKEtLlmANqLu3KDFS3NV8Hx41jy/JF1/gAWOgU+Uo5QTkeI1tWNP4dWGo4L0E9j18Ez9EPsTleautKqA==
- dependencies:
- ast-module-types "^6.0.1"
- node-source-walk "^7.0.1"
-
-detective-es6@^5.0.1:
- version "5.0.2"
- resolved "https://registry.npmjs.org/detective-es6/-/detective-es6-5.0.2.tgz"
- integrity sha512-+qHHGYhjupiVs4rnIpI9nZ5B130A4AmE35ZX1w33hb46vcZ7T3jfDbvmPw0FhWtMHn5BS5HHu7ZtnZ53bMcXZA==
- dependencies:
- node-source-walk "^7.0.1"
-
-detective-postcss@^7.0.1:
- version "7.0.1"
- resolved "https://registry.npmjs.org/detective-postcss/-/detective-postcss-7.0.1.tgz"
- integrity sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==
- dependencies:
- is-url "^1.2.4"
- postcss-values-parser "^6.0.2"
-
-detective-sass@^6.0.1:
- version "6.0.2"
- resolved "https://registry.npmjs.org/detective-sass/-/detective-sass-6.0.2.tgz"
- integrity sha512-i3xpXHDKS0qI2aFW4asQ7fqlPK00ndOVZELvQapFJCaF0VxYmsNWtd0AmvXbTLMk7bfO5VdIeorhY9KfmHVoVA==
- dependencies:
- gonzales-pe "^4.3.0"
- node-source-walk "^7.0.1"
-
-detective-scss@^5.0.1:
- version "5.0.2"
- resolved "https://registry.npmjs.org/detective-scss/-/detective-scss-5.0.2.tgz"
- integrity sha512-9JOEMZ8pDh3ShXmftq7hoQqqJsClaGgxo1hghfCeFlmKf5TC/Twtwb0PAaK8dXwpg9Z0uCmEYSrCxO+kel2eEg==
- dependencies:
- gonzales-pe "^4.3.0"
- node-source-walk "^7.0.1"
-
-detective-stylus@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/detective-stylus/-/detective-stylus-5.0.1.tgz"
- integrity sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==
-
-detective-typescript@^14.1.0, detective-typescript@^14.1.1:
- version "14.1.2"
- resolved "https://registry.npmjs.org/detective-typescript/-/detective-typescript-14.1.2.tgz"
- integrity sha512-bIeEn0eVi/JRsE1YizBR2ilnMlWRAIBJJ6kXCKNFxEEWhUcEY3R6I3KYIAy48ieURbD1hcb3Ebvl8AqeoPMSzg==
- dependencies:
- "@typescript-eslint/typescript-estree" "^8.58.2"
- ast-module-types "^6.0.1"
- node-source-walk "^7.0.1"
-
-detective-vue2@^2.3.0:
- version "2.3.0"
- resolved "https://registry.npmjs.org/detective-vue2/-/detective-vue2-2.3.0.tgz"
- integrity sha512-3gwbZPqVTm9sL9XdZsgEJ7x4x99O853VVZHapQAiEkGuMJMpFPjHDrecSgfqnS5JW3FJfYXesLZGvUOibjn49g==
- dependencies:
- "@dependents/detective-less" "^5.0.1"
- "@vue/compiler-sfc" "^3.5.32"
- detective-es6 "^5.0.1"
- detective-sass "^6.0.1"
- detective-scss "^5.0.1"
- detective-stylus "^5.0.1"
- detective-typescript "^14.1.0"
-
-dettle@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/dettle/-/dettle-1.0.5.tgz"
- integrity sha512-ZVyjhAJ7sCe1PNXEGveObOH9AC8QvMga3HJIghHawtG7mE4K5pW9nz/vDGAr/U7a3LWgdOzEE7ac9MURnyfaTA==
-
devalue@^5.6.3, devalue@^5.6.4:
version "5.8.0"
resolved "https://registry.npmjs.org/devalue/-/devalue-5.8.0.tgz"
@@ -4244,14 +2627,7 @@ domutils@^3.0.1, domutils@^3.2.2:
domelementtype "^2.3.0"
domhandler "^5.0.3"
-dot-prop@9.0.0, dot-prop@^9.0.0:
- version "9.0.0"
- resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz"
- integrity sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==
- dependencies:
- type-fest "^4.18.2"
-
-dotenv@^16.3.1, dotenv@^16.4.7:
+dotenv@^16.4.7:
version "16.6.1"
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz"
integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==
@@ -4266,7 +2642,7 @@ dset@^3.1.4:
resolved "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz"
integrity sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==
-dunder-proto@^1.0.0, dunder-proto@^1.0.1:
+dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
@@ -4275,18 +2651,6 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1:
es-errors "^1.3.0"
gopd "^1.2.0"
-eastasianwidth@^0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"
- integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
-
-ecdsa-sig-formatter@1.0.11:
- version "1.0.11"
- resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
- integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
- dependencies:
- safe-buffer "^5.0.1"
-
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
@@ -4310,21 +2674,6 @@ emoji-regex@^8.0.0:
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-emoji-regex@^9.2.2:
- version "9.2.2"
- resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"
- integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
-
-empathic@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz"
- integrity sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==
-
-enabled@2.0.x:
- version "2.0.0"
- resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz"
- integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
-
encodeurl@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz"
@@ -4365,11 +2714,6 @@ env-paths@^2.2.1:
resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
-env-paths@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz"
- integrity sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==
-
error-ex@^1.3.1:
version "1.3.4"
resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz"
@@ -4377,72 +2721,7 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-error-stack-parser-es@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz"
- integrity sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==
-
-es-abstract@^1.23.5, es-abstract@^1.23.9:
- version "1.24.2"
- resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz"
- integrity sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==
- dependencies:
- array-buffer-byte-length "^1.0.2"
- arraybuffer.prototype.slice "^1.0.4"
- available-typed-arrays "^1.0.7"
- call-bind "^1.0.8"
- call-bound "^1.0.4"
- data-view-buffer "^1.0.2"
- data-view-byte-length "^1.0.2"
- data-view-byte-offset "^1.0.1"
- es-define-property "^1.0.1"
- es-errors "^1.3.0"
- es-object-atoms "^1.1.1"
- es-set-tostringtag "^2.1.0"
- es-to-primitive "^1.3.0"
- function.prototype.name "^1.1.8"
- get-intrinsic "^1.3.0"
- get-proto "^1.0.1"
- get-symbol-description "^1.1.0"
- globalthis "^1.0.4"
- gopd "^1.2.0"
- has-property-descriptors "^1.0.2"
- has-proto "^1.2.0"
- has-symbols "^1.1.0"
- hasown "^2.0.2"
- internal-slot "^1.1.0"
- is-array-buffer "^3.0.5"
- is-callable "^1.2.7"
- is-data-view "^1.0.2"
- is-negative-zero "^2.0.3"
- is-regex "^1.2.1"
- is-set "^2.0.3"
- is-shared-array-buffer "^1.0.4"
- is-string "^1.1.1"
- is-typed-array "^1.1.15"
- is-weakref "^1.1.1"
- math-intrinsics "^1.1.0"
- object-inspect "^1.13.4"
- object-keys "^1.1.1"
- object.assign "^4.1.7"
- own-keys "^1.0.1"
- regexp.prototype.flags "^1.5.4"
- safe-array-concat "^1.1.3"
- safe-push-apply "^1.0.0"
- safe-regex-test "^1.1.0"
- set-proto "^1.0.0"
- stop-iteration-iterator "^1.1.0"
- string.prototype.trim "^1.2.10"
- string.prototype.trimend "^1.0.9"
- string.prototype.trimstart "^1.0.8"
- typed-array-buffer "^1.0.3"
- typed-array-byte-length "^1.0.3"
- typed-array-byte-offset "^1.0.4"
- typed-array-length "^1.0.7"
- unbox-primitive "^1.1.0"
- which-typed-array "^1.1.19"
-
-es-define-property@^1.0.0, es-define-property@^1.0.1:
+es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
@@ -4452,11 +2731,6 @@ es-errors@^1.3.0:
resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
-es-module-lexer@^1.0.0, es-module-lexer@^1.5.3:
- version "1.7.0"
- resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz"
- integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==
-
es-module-lexer@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz"
@@ -4469,69 +2743,11 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
dependencies:
es-errors "^1.3.0"
-es-set-tostringtag@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
- integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
- dependencies:
- es-errors "^1.3.0"
- get-intrinsic "^1.2.6"
- has-tostringtag "^1.0.2"
- hasown "^2.0.2"
-
-es-shim-unscopables@^1.0.2:
- version "1.1.0"
- resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz"
- integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==
- dependencies:
- hasown "^2.0.2"
-
-es-to-primitive@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz"
- integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==
- dependencies:
- is-callable "^1.2.7"
- is-date-object "^1.0.5"
- is-symbol "^1.0.4"
-
es-toolkit@^1.39.3:
version "1.46.1"
resolved "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.46.1.tgz"
integrity sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==
-esbuild@0.27.3:
- version "0.27.3"
- resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz"
- integrity sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==
- optionalDependencies:
- "@esbuild/aix-ppc64" "0.27.3"
- "@esbuild/android-arm" "0.27.3"
- "@esbuild/android-arm64" "0.27.3"
- "@esbuild/android-x64" "0.27.3"
- "@esbuild/darwin-arm64" "0.27.3"
- "@esbuild/darwin-x64" "0.27.3"
- "@esbuild/freebsd-arm64" "0.27.3"
- "@esbuild/freebsd-x64" "0.27.3"
- "@esbuild/linux-arm" "0.27.3"
- "@esbuild/linux-arm64" "0.27.3"
- "@esbuild/linux-ia32" "0.27.3"
- "@esbuild/linux-loong64" "0.27.3"
- "@esbuild/linux-mips64el" "0.27.3"
- "@esbuild/linux-ppc64" "0.27.3"
- "@esbuild/linux-riscv64" "0.27.3"
- "@esbuild/linux-s390x" "0.27.3"
- "@esbuild/linux-x64" "0.27.3"
- "@esbuild/netbsd-arm64" "0.27.3"
- "@esbuild/netbsd-x64" "0.27.3"
- "@esbuild/openbsd-arm64" "0.27.3"
- "@esbuild/openbsd-x64" "0.27.3"
- "@esbuild/openharmony-arm64" "0.27.3"
- "@esbuild/sunos-x64" "0.27.3"
- "@esbuild/win32-arm64" "0.27.3"
- "@esbuild/win32-ia32" "0.27.3"
- "@esbuild/win32-x64" "0.27.3"
-
esbuild@^0.27.0, esbuild@^0.27.3:
version "0.27.7"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz"
@@ -4739,7 +2955,7 @@ estraverse@^5.1.0, estraverse@^5.2.0:
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
-estree-walker@2.0.2, estree-walker@^2.0.2:
+estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
@@ -4754,43 +2970,11 @@ etag@^1.8.1:
resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz"
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
-event-target-shim@^5.0.0:
- version "5.0.1"
- resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
- integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
-
eventemitter3@^5.0.1, eventemitter3@^5.0.4:
version "5.0.4"
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz"
integrity sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==
-events-universal@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz"
- integrity sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==
- dependencies:
- bare-events "^2.7.0"
-
-events@^3.3.0:
- version "3.3.0"
- resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz"
- integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
-
-execa@^8.0.0:
- version "8.0.1"
- resolved "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz"
- integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==
- dependencies:
- cross-spawn "^7.0.3"
- get-stream "^8.0.1"
- human-signals "^5.0.0"
- is-stream "^3.0.0"
- merge-stream "^2.0.0"
- npm-run-path "^5.1.0"
- onetime "^6.0.0"
- signal-exit "^4.1.0"
- strip-final-newline "^3.0.0"
-
express-rate-limit@^8.5.0:
version "8.5.0"
resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.0.tgz"
@@ -4848,26 +3032,11 @@ extract-zip@2.0.1, extract-zip@^2.0.1:
optionalDependencies:
"@types/yauzl" "^2.9.1"
-extract-zip@^1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
- integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
- dependencies:
- concat-stream "^1.6.2"
- debug "^2.6.9"
- mkdirp "^0.5.4"
- yauzl "^2.10.0"
-
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
-fast-fifo@^1.2.0, fast-fifo@^1.3.2:
- version "1.3.2"
- resolved "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz"
- integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==
-
fast-glob@^3.3.3:
version "3.3.3"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz"
@@ -4889,11 +3058,6 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
-fast-safe-stringify@^2.0.7, fast-safe-stringify@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz"
- integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
-
fast-string-truncated-width@^3.0.2:
version "3.0.3"
resolved "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz"
@@ -4937,26 +3101,6 @@ fdir@^6.5.0:
resolved "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz"
integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
-fecha@^4.2.0:
- version "4.2.3"
- resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz"
- integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
-
-fetch-blob@^3.1.2, fetch-blob@^3.1.4:
- version "3.2.0"
- resolved "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz"
- integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
- dependencies:
- node-domexception "^1.0.0"
- web-streams-polyfill "^3.0.3"
-
-figures@^6.0.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz"
- integrity sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==
- dependencies:
- is-unicode-supported "^2.0.0"
-
file-entry-cache@^8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz"
@@ -4964,11 +3108,6 @@ file-entry-cache@^8.0.0:
dependencies:
flat-cache "^4.0.0"
-file-uri-to-path@1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
- integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
-
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz"
@@ -4976,11 +3115,6 @@ fill-range@^7.1.1:
dependencies:
to-regex-range "^5.0.1"
-filter-obj@^6.0.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/filter-obj/-/filter-obj-6.1.0.tgz"
- integrity sha512-xdMtCAODmPloU9qtmPcdBV9Kd27NtMse+4ayThxqIHUES5Z2S6bGpap5PpdmNM56ub7y3i1eyr+vJJIIgWGKmA==
-
finalhandler@^2.1.0:
version "2.1.1"
resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz"
@@ -4998,11 +3132,6 @@ find-root@^1.1.0:
resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
-find-up-simple@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz"
- integrity sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==
-
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
@@ -5011,15 +3140,6 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
-find-up@^7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz"
- integrity sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==
- dependencies:
- locate-path "^7.2.0"
- path-exists "^5.0.0"
- unicorn-magic "^0.1.0"
-
flat-cache@^4.0.0:
version "4.0.1"
resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz"
@@ -5038,11 +3158,6 @@ flattie@^1.1.1:
resolved "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz"
integrity sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==
-fn.name@1.x.x:
- version "1.1.0"
- resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz"
- integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
-
fontace@~0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz"
@@ -5057,28 +3172,6 @@ fontkitten@^1.0.0, fontkitten@^1.0.2:
dependencies:
tiny-inflate "^1.0.3"
-for-each@^0.3.3, for-each@^0.3.5:
- version "0.3.5"
- resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz"
- integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==
- dependencies:
- is-callable "^1.2.7"
-
-foreground-child@^3.1.0:
- version "3.3.1"
- resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz"
- integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==
- dependencies:
- cross-spawn "^7.0.6"
- signal-exit "^4.0.1"
-
-formdata-polyfill@^4.0.10:
- version "4.0.10"
- resolved "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz"
- integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
- dependencies:
- fetch-blob "^3.1.2"
-
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
@@ -5118,47 +3211,17 @@ function-bind@^1.1.2:
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
-function.prototype.name@^1.1.6, function.prototype.name@^1.1.8:
- version "1.1.8"
- resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz"
- integrity sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==
- dependencies:
- call-bind "^1.0.8"
- call-bound "^1.0.3"
- define-properties "^1.2.1"
- functions-have-names "^1.2.3"
- hasown "^2.0.2"
- is-callable "^1.2.7"
-
-functions-have-names@^1.2.3:
- version "1.2.3"
- resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz"
- integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
-
-generator-function@^2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz"
- integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==
-
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
-get-amd-module-type@^6.0.2:
- version "6.0.2"
- resolved "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-6.0.2.tgz"
- integrity sha512-7zShVYAYtMnj9S65CfN+hvpBCByfuB1OY8xID01nZEzXTZbx4YyysAfi+nMl95JSR6odt4q8TCj2W63KAoyVLQ==
- dependencies:
- ast-module-types "^6.0.1"
- node-source-walk "^7.0.1"
-
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
-get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0:
+get-intrinsic@^1.2.5, get-intrinsic@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
@@ -5174,16 +3237,6 @@ get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@
hasown "^2.0.2"
math-intrinsics "^1.1.0"
-get-port-please@^3.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/get-port-please/-/get-port-please-3.2.0.tgz"
- integrity sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==
-
-get-port@^7.0.0, get-port@^7.1.0:
- version "7.2.0"
- resolved "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz"
- integrity sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==
-
get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz"
@@ -5199,20 +3252,6 @@ get-stream@^5.1.0:
dependencies:
pump "^3.0.0"
-get-stream@^8.0.1:
- version "8.0.1"
- resolved "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz"
- integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==
-
-get-symbol-description@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz"
- integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==
- dependencies:
- call-bound "^1.0.3"
- es-errors "^1.3.0"
- get-intrinsic "^1.2.6"
-
get-tsconfig@5.0.0-beta.4:
version "5.0.0-beta.4"
resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz"
@@ -5248,39 +3287,6 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
-glob@^10.0.0, glob@^10.4.5:
- version "10.5.0"
- resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz"
- integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==
- dependencies:
- foreground-child "^3.1.0"
- jackspeak "^3.1.2"
- minimatch "^9.0.4"
- minipass "^7.1.2"
- package-json-from-dist "^1.0.0"
- path-scurry "^1.11.1"
-
-glob@^13.0.0:
- version "13.0.6"
- resolved "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz"
- integrity sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==
- dependencies:
- minimatch "^10.2.2"
- minipass "^7.1.3"
- path-scurry "^2.0.2"
-
-glob@^7.1.3:
- version "7.2.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
- integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.1.1"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
glob@^9.2.0:
version "9.3.5"
resolved "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz"
@@ -5296,49 +3302,12 @@ globals@^16.0.0:
resolved "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz"
integrity sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==
-globalthis@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz"
- integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
- dependencies:
- define-properties "^1.2.1"
- gopd "^1.0.1"
-
-gonzales-pe@^4.3.0:
- version "4.3.0"
- resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz"
- integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==
- dependencies:
- minimist "^1.2.5"
-
-gopd@^1.0.1, gopd@^1.2.0:
+gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
-got@^11.5.1:
- version "11.8.6"
- resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a"
- integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==
- dependencies:
- "@sindresorhus/is" "^4.0.0"
- "@szmarczak/http-timer" "^4.0.5"
- "@types/cacheable-request" "^6.0.1"
- "@types/responselike" "^1.0.0"
- cacheable-lookup "^5.0.3"
- cacheable-request "^7.0.2"
- decompress-response "^6.0.0"
- http2-wrapper "^1.0.0-beta.5.2"
- lowercase-keys "^2.0.0"
- p-cancelable "^2.0.0"
- responselike "^2.0.0"
-
-graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.9:
- version "4.2.11"
- resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz"
- integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
-
-h3@^1.15.10, h3@^1.15.11, h3@^1.15.3:
+h3@^1.15.10:
version "1.15.11"
resolved "https://registry.npmjs.org/h3/-/h3-1.15.11.tgz"
integrity sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==
@@ -5353,11 +3322,6 @@ h3@^1.15.10, h3@^1.15.11, h3@^1.15.3:
ufo "^1.6.3"
uncrypto "^0.1.3"
-has-bigints@^1.0.2:
- version "1.1.0"
- resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz"
- integrity sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==
-
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
@@ -5368,32 +3332,11 @@ has-flag@^4.0.0:
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz"
- integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
- dependencies:
- es-define-property "^1.0.0"
-
-has-proto@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz"
- integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==
- dependencies:
- dunder-proto "^1.0.0"
-
-has-symbols@^1.0.3, has-symbols@^1.1.0:
+has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
-has-tostringtag@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
- integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
- dependencies:
- has-symbols "^1.0.3"
-
hasown@^2.0.2:
version "2.0.3"
resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz"
@@ -5525,13 +3468,6 @@ hoist-non-react-statics@^3.3.1:
dependencies:
react-is "^16.7.0"
-hosted-git-info@^7.0.0:
- version "7.0.2"
- resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz"
- integrity sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==
- dependencies:
- lru-cache "^10.0.1"
-
html-escaper@3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz"
@@ -5552,7 +3488,7 @@ htmlparser2@^10.1.0:
domutils "^3.2.2"
entities "^7.0.1"
-http-cache-semantics@^4.0.0, http-cache-semantics@^4.2.0:
+http-cache-semantics@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz"
integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==
@@ -5576,19 +3512,6 @@ http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1:
agent-base "^7.1.0"
debug "^4.3.4"
-http-shutdown@^1.2.2:
- version "1.2.2"
- resolved "https://registry.npmjs.org/http-shutdown/-/http-shutdown-1.2.2.tgz"
- integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==
-
-http2-wrapper@^1.0.0-beta.5.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
- integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
- dependencies:
- quick-lru "^5.1.1"
- resolve-alpn "^1.0.0"
-
https-proxy-agent@5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz"
@@ -5597,7 +3520,7 @@ https-proxy-agent@5.0.1:
agent-base "6"
debug "4"
-https-proxy-agent@^7.0.5, https-proxy-agent@^7.0.6:
+https-proxy-agent@^7.0.6:
version "7.0.6"
resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz"
integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==
@@ -5605,11 +3528,6 @@ https-proxy-agent@^7.0.5, https-proxy-agent@^7.0.6:
agent-base "^7.1.2"
debug "4"
-human-signals@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz"
- integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==
-
iconv-lite@0.6.3, iconv-lite@^0.6.3:
version "0.6.3"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz"
@@ -5624,7 +3542,7 @@ iconv-lite@^0.7.0, iconv-lite@~0.7.0:
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
-ieee754@^1.1.13, ieee754@^1.2.1:
+ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@@ -5639,16 +3557,6 @@ ignore@^5.2.0:
resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz"
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
-image-meta@^0.2.1:
- version "0.2.2"
- resolved "https://registry.npmjs.org/image-meta/-/image-meta-0.2.2.tgz"
- integrity sha512-3MOLanc3sb3LNGWQl1RlQlNWURE5g32aUphrDyFeCsxBTk08iE3VNe4CwsUZ0Qs1X+EfX0+r29Sxdpza4B+yRA==
-
-image-size@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz"
- integrity sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==
-
immer@^10.1.1:
version "10.2.0"
resolved "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz"
@@ -5672,53 +3580,16 @@ import-fresh@^3.2.1, import-fresh@^3.3.0:
parent-module "^1.0.0"
resolve-from "^4.0.0"
-import-in-the-middle@^1.8.1:
- version "1.15.0"
- resolved "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz"
- integrity sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==
- dependencies:
- acorn "^8.14.0"
- acorn-import-attributes "^1.9.5"
- cjs-module-lexer "^1.2.2"
- module-details-from-path "^1.0.3"
-
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
-indent-string@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz"
- integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==
-
-index-to-position@^1.1.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz"
- integrity sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==
-
-inflight@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
- integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
- dependencies:
- once "^1.3.0"
- wrappy "1"
-
-inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4:
+inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-internal-slot@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz"
- integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==
- dependencies:
- es-errors "^1.3.0"
- hasown "^2.0.2"
- side-channel "^1.1.0"
-
"internmap@1 - 2":
version "2.0.3"
resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz"
@@ -5744,65 +3615,16 @@ ipaddr.js@1.9.1:
resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz"
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
-ipx@^3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/ipx/-/ipx-3.1.1.tgz"
- integrity sha512-7Xnt54Dco7uYkfdAw0r2vCly3z0rSaVhEXMzPvl3FndsTVm5p26j+PO+gyinkYmcsEUvX2Rh7OGK7KzYWRu6BA==
- dependencies:
- "@fastify/accept-negotiator" "^2.0.1"
- citty "^0.1.6"
- consola "^3.4.2"
- defu "^6.1.4"
- destr "^2.0.5"
- etag "^1.8.1"
- h3 "^1.15.3"
- image-meta "^0.2.1"
- listhen "^1.9.0"
- ofetch "^1.4.1"
- pathe "^2.0.3"
- sharp "^0.34.3"
- svgo "^4.0.0"
- ufo "^1.6.1"
- unstorage "^1.16.1"
- xss "^1.0.15"
-
iron-webcrypto@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz"
integrity sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==
-is-array-buffer@^3.0.4, is-array-buffer@^3.0.5:
- version "3.0.5"
- resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz"
- integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==
- dependencies:
- call-bind "^1.0.8"
- call-bound "^1.0.3"
- get-intrinsic "^1.2.6"
-
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
-is-async-function@^2.0.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz"
- integrity sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==
- dependencies:
- async-function "^1.0.0"
- call-bound "^1.0.3"
- get-proto "^1.0.1"
- has-tostringtag "^1.0.2"
- safe-regex-test "^1.1.0"
-
-is-bigint@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz"
- integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==
- dependencies:
- has-bigints "^1.0.2"
-
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
@@ -5810,19 +3632,6 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
-is-boolean-object@^1.2.1:
- version "1.2.2"
- resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz"
- integrity sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==
- dependencies:
- call-bound "^1.0.3"
- has-tostringtag "^1.0.2"
-
-is-callable@^1.2.7:
- version "1.2.7"
- resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
- integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
-
is-core-module@^2.16.1:
version "2.16.1"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz"
@@ -5830,23 +3639,6 @@ is-core-module@^2.16.1:
dependencies:
hasown "^2.0.2"
-is-data-view@^1.0.1, is-data-view@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz"
- integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==
- dependencies:
- call-bound "^1.0.2"
- get-intrinsic "^1.2.6"
- is-typed-array "^1.1.13"
-
-is-date-object@^1.0.5, is-date-object@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz"
- integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==
- dependencies:
- call-bound "^1.0.2"
- has-tostringtag "^1.0.2"
-
is-docker@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz"
@@ -5862,29 +3654,11 @@ is-extglob@^2.1.1:
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
-is-finalizationregistry@^1.1.0:
- version "1.1.1"
- resolved "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz"
- integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==
- dependencies:
- call-bound "^1.0.3"
-
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
-is-generator-function@^1.0.10:
- version "1.1.2"
- resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz"
- integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==
- dependencies:
- call-bound "^1.0.4"
- generator-function "^2.0.0"
- get-proto "^1.0.1"
- has-tostringtag "^1.0.2"
- safe-regex-test "^1.1.0"
-
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
@@ -5899,156 +3673,27 @@ is-inside-container@^1.0.0:
dependencies:
is-docker "^3.0.0"
-is-map@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz"
- integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
-
-is-negative-zero@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz"
- integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==
-
-is-network-error@^1.0.0:
- version "1.3.1"
- resolved "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz"
- integrity sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==
-
-is-number-object@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz"
- integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==
- dependencies:
- call-bound "^1.0.3"
- has-tostringtag "^1.0.2"
-
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
- integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-
-is-path-inside@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz"
- integrity sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==
-
-is-plain-obj@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz"
- integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
-
-is-plain-obj@^4.0.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz"
- integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==
-
-is-promise@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz"
- integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
-
-is-reference@^3.0.3:
- version "3.0.3"
- resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz"
- integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
- dependencies:
- "@types/estree" "^1.0.6"
-
-is-regex@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz"
- integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==
- dependencies:
- call-bound "^1.0.2"
- gopd "^1.2.0"
- has-tostringtag "^1.0.2"
- hasown "^2.0.2"
-
-is-set@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz"
- integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==
-
-is-shared-array-buffer@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz"
- integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==
- dependencies:
- call-bound "^1.0.3"
-
-is-stream@^2.0.0, is-stream@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz"
- integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
-
-is-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz"
- integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
-
-is-stream@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz"
- integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==
-
-is-string@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz"
- integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==
- dependencies:
- call-bound "^1.0.3"
- has-tostringtag "^1.0.2"
-
-is-symbol@^1.0.4, is-symbol@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz"
- integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==
- dependencies:
- call-bound "^1.0.2"
- has-symbols "^1.1.0"
- safe-regex-test "^1.1.0"
-
-is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15:
- version "1.1.15"
- resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz"
- integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
- dependencies:
- which-typed-array "^1.1.16"
-
-is-unicode-supported@^2.0.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz"
- integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==
-
-is-url-superb@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz"
- integrity sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==
-
-is-url@^1.2.4:
- version "1.2.4"
- resolved "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz"
- integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-is-weakmap@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz"
- integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==
+is-plain-obj@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz"
+ integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==
-is-weakref@^1.0.2, is-weakref@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz"
- integrity sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==
- dependencies:
- call-bound "^1.0.3"
+is-promise@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz"
+ integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
-is-weakset@^2.0.3:
- version "2.0.4"
- resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz"
- integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==
+is-reference@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz"
+ integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
dependencies:
- call-bound "^1.0.3"
- get-intrinsic "^1.2.6"
+ "@types/estree" "^1.0.6"
is-wsl@^3.1.1:
version "3.1.1"
@@ -6057,47 +3702,11 @@ is-wsl@^3.1.1:
dependencies:
is-inside-container "^1.0.0"
-isarray@^2.0.5:
- version "2.0.5"
- resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz"
- integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
-
-isarray@~1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
- integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
-
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
-jackspeak@^3.1.2:
- version "3.4.3"
- resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz"
- integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
- dependencies:
- "@isaacs/cliui" "^8.0.2"
- optionalDependencies:
- "@pkgjs/parseargs" "^0.11.0"
-
-jiti@^2.6.1:
- version "2.6.1"
- resolved "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz"
- integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==
-
-jpeg-js@^0.4.2:
- version "0.4.4"
- resolved "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz"
- integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==
-
-js-image-generator@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/js-image-generator/-/js-image-generator-1.0.4.tgz"
- integrity sha512-ckb7kyVojGAnArouVR+5lBIuwU1fcrn7E/YYSd0FK7oIngAkMmRvHASLro9Zt5SQdWToaI66NybG+OGxPw/HlQ==
- dependencies:
- jpeg-js "^0.4.2"
-
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
@@ -6155,55 +3764,7 @@ jsonc-parser@^3.0.0, jsonc-parser@^3.3.1:
resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz"
integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==
-jsonpointer@^5.0.0:
- version "5.0.1"
- resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz"
- integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==
-
-jsonwebtoken@9.0.3:
- version "9.0.3"
- resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz"
- integrity sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==
- dependencies:
- jws "^4.0.1"
- lodash.includes "^4.3.0"
- lodash.isboolean "^3.0.3"
- lodash.isinteger "^4.0.4"
- lodash.isnumber "^3.0.3"
- lodash.isplainobject "^4.0.6"
- lodash.isstring "^4.0.1"
- lodash.once "^4.0.0"
- ms "^2.1.1"
- semver "^7.5.4"
-
-junk@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz"
- integrity sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==
-
-jwa@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz"
- integrity sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==
- dependencies:
- buffer-equal-constant-time "^1.0.1"
- ecdsa-sig-formatter "1.0.11"
- safe-buffer "^5.0.1"
-
-jws@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz"
- integrity sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==
- dependencies:
- jwa "^2.0.1"
- safe-buffer "^5.0.1"
-
-jwt-decode@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz"
- integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==
-
-keyv@^4.0.0, keyv@^4.5.4:
+keyv@^4.5.4:
version "4.5.4"
resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz"
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
@@ -6215,32 +3776,6 @@ kleur@^4.1.5:
resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz"
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
-kuler@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz"
- integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
-
-lambda-local@^2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/lambda-local/-/lambda-local-2.2.0.tgz"
- integrity sha512-bPcgpIXbHnVGfI/omZIlgucDqlf4LrsunwoKue5JdZeGybt8L6KyJz2Zu19ffuZwIwLj2NAI2ZyaqNT6/cetcg==
- dependencies:
- commander "^10.0.1"
- dotenv "^16.3.1"
- winston "^3.10.0"
-
-lazystream@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz"
- integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==
- dependencies:
- readable-stream "^2.0.5"
-
-"leven@^3.1.0 < 4":
- version "3.1.0"
- resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz"
- integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
-
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
@@ -6254,30 +3789,6 @@ lines-and-columns@^1.1.6:
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
-listhen@^1.9.0:
- version "1.10.0"
- resolved "https://registry.npmjs.org/listhen/-/listhen-1.10.0.tgz"
- integrity sha512-kfz4C0OrC6IpaVMtYDJtf6PFjurxe9NBBoDAh/o2p587INryFOO4DQ9OetbCdDrWFt1m1CJKvYrzkGsuPHw8nQ==
- dependencies:
- "@parcel/watcher" "^2.5.6"
- "@parcel/watcher-wasm" "^2.5.6"
- citty "^0.2.2"
- consola "^3.4.2"
- crossws ">=0.2.0 <0.5.0"
- defu "^6.1.7"
- get-port-please "^3.2.0"
- h3 "^1.15.11"
- http-shutdown "^1.2.2"
- jiti "^2.6.1"
- mlly "^1.8.2"
- node-forge "^1.4.0"
- pathe "^2.0.3"
- std-env "^4.1.0"
- tinyclip "^0.1.12"
- ufo "^1.6.4"
- untun "^0.1.3"
- uqr "^0.1.3"
-
locate-character@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz"
@@ -6290,65 +3801,6 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
-locate-path@^7.0.0, locate-path@^7.2.0:
- version "7.2.0"
- resolved "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz"
- integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==
- dependencies:
- p-locate "^6.0.0"
-
-lodash.includes@^4.3.0:
- version "4.3.0"
- resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz"
- integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==
-
-lodash.isboolean@^3.0.3:
- version "3.0.3"
- resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz"
- integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==
-
-lodash.isinteger@^4.0.4:
- version "4.0.4"
- resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz"
- integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==
-
-lodash.isnumber@^3.0.3:
- version "3.0.3"
- resolved "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz"
- integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==
-
-lodash.isplainobject@^4.0.6:
- version "4.0.6"
- resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz"
- integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
-
-lodash.isstring@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz"
- integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
-
-lodash.once@^4.0.0:
- version "4.1.1"
- resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz"
- integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
-
-lodash@^4.17.15:
- version "4.18.1"
- resolved "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz"
- integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==
-
-logform@^2.7.0:
- version "2.7.0"
- resolved "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz"
- integrity sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==
- dependencies:
- "@colors/colors" "1.6.0"
- "@types/triple-beam" "^1.3.2"
- fecha "^4.2.0"
- ms "^2.1.1"
- safe-stable-stringify "^2.3.1"
- triple-beam "^1.3.0"
-
longest-streak@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz"
@@ -6361,17 +3813,12 @@ loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
-lowercase-keys@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
- integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-
-lru-cache@^10.0.1, lru-cache@^10.2.0:
+lru-cache@^10.2.0:
version "10.4.3"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
-lru-cache@^11.0.0, lru-cache@^11.2.7:
+lru-cache@^11.2.7:
version "11.3.6"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz"
integrity sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==
@@ -6388,11 +3835,6 @@ lru-cache@^7.14.1:
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
-luxon@^3.2.1:
- version "3.7.2"
- resolved "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz"
- integrity sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==
-
magic-string@^0.30.11, magic-string@^0.30.21:
version "0.30.21"
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz"
@@ -6409,11 +3851,6 @@ magicast@^0.5.2:
"@babel/types" "^7.29.0"
source-map-js "^1.2.1"
-map-obj@^5.0.0:
- version "5.0.2"
- resolved "https://registry.npmjs.org/map-obj/-/map-obj-5.0.2.tgz"
- integrity sha512-K6K2NgKnTXimT3779/4KxSvobxOtMmx1LBZ3NwRxT/MDIR3Br/fQ4Q+WCX5QxjyUR8zg5+RV9Tbf2c5pAWTD2A==
-
markdown-table@^3.0.0:
version "3.0.4"
resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz"
@@ -6591,18 +4028,6 @@ merge-descriptors@^2.0.0:
resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz"
integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==
-merge-options@^3.0.4:
- version "3.0.4"
- resolved "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz"
- integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==
- dependencies:
- is-plain-obj "^2.1.0"
-
-merge-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
- integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
@@ -6901,33 +4326,6 @@ mime-types@^3.0.0, mime-types@^3.0.2:
dependencies:
mime-db "^1.54.0"
-mimic-fn@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz"
- integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
-
-mimic-response@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
- integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
-
-mimic-response@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
- integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
-
-miniflare@4.20260430.0:
- version "4.20260430.0"
- resolved "https://registry.npmjs.org/miniflare/-/miniflare-4.20260430.0.tgz"
- integrity sha512-MWvMm3Siho9Yj7lbJZidLs8hbrRvIcOrif2mnsHQZdvoKfedpea+GaN8XJxbpRcq0B2WzNI1BB1ihdnqes3/ZA==
- dependencies:
- "@cspotcode/source-map-support" "0.8.1"
- sharp "^0.34.5"
- undici "7.24.8"
- workerd "1.20260430.1"
- ws "8.18.0"
- youch "4.1.0-beta.10"
-
minimatch@^10.2.1, minimatch@^10.2.2, minimatch@^10.2.4:
version "10.2.5"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz"
@@ -6935,20 +4333,6 @@ minimatch@^10.2.1, minimatch@^10.2.2, minimatch@^10.2.4:
dependencies:
brace-expansion "^5.0.5"
-minimatch@^3.1.1:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e"
- integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==
- dependencies:
- brace-expansion "^1.1.7"
-
-minimatch@^5.1.0:
- version "5.1.9"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz"
- integrity sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==
- dependencies:
- brace-expansion "^2.0.1"
-
minimatch@^8.0.2:
version "8.0.7"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-8.0.7.tgz"
@@ -6956,35 +4340,16 @@ minimatch@^8.0.2:
dependencies:
brace-expansion "^2.0.1"
-minimatch@^9.0.4:
- version "9.0.9"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz"
- integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==
- dependencies:
- brace-expansion "^2.0.2"
-
-minimist@^1.2.5, minimist@^1.2.6:
- version "1.2.8"
- resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
- integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-
minipass@^4.2.4:
version "4.2.8"
resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz"
integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==
-"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4, minipass@^7.1.2, minipass@^7.1.3:
+"minipass@^5.0.0 || ^6.0.2 || ^7.0.0":
version "7.1.3"
resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz"
integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==
-minizlib@^3.1.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz"
- integrity sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==
- dependencies:
- minipass "^7.1.2"
-
mitt@3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz"
@@ -7000,36 +4365,6 @@ mkdirp-classic@^0.5.2:
resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
-mkdirp@^0.5.4:
- version "0.5.6"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
- integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
- dependencies:
- minimist "^1.2.6"
-
-mlly@^1.7.4, mlly@^1.8.2:
- version "1.8.2"
- resolved "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz"
- integrity sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==
- dependencies:
- acorn "^8.16.0"
- pathe "^2.0.3"
- pkg-types "^1.3.1"
- ufo "^1.6.3"
-
-module-definition@^6.0.1:
- version "6.0.2"
- resolved "https://registry.npmjs.org/module-definition/-/module-definition-6.0.2.tgz"
- integrity sha512-SvAU3lB0+Yjbq55yHY3wkRZBOh+fhU1SnIF3IFbTewv6mtAh7yUT8ACHAJ2mGIJ7tCes2QuCL/cl6m0JSZ/ArA==
- dependencies:
- ast-module-types "^6.0.1"
- node-source-walk "^7.0.1"
-
-module-details-from-path@^1.0.3:
- version "1.0.4"
- resolved "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz"
- integrity sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==
-
motion-dom@^12.38.0:
version "12.38.0"
resolved "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz"
@@ -7047,17 +4382,12 @@ mrmime@^2.0.1:
resolved "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz"
integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==
-ms@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
-
ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-ms@^2.1.1, ms@^2.1.3:
+ms@^2.1.3:
version "2.1.3"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -7072,11 +4402,6 @@ nanoid@^3.3.11:
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz"
integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==
-napi-wasm@^1.1.0:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/napi-wasm/-/napi-wasm-1.1.3.tgz#7bb95c88e6561f84880bb67195437b1cfbe99224"
- integrity sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg==
-
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
@@ -7092,11 +4417,6 @@ neotraverse@^0.6.18:
resolved "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz"
integrity sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==
-netlify-redirector@^0.5.0:
- version "0.5.0"
- resolved "https://registry.npmjs.org/netlify-redirector/-/netlify-redirector-0.5.0.tgz"
- integrity sha512-4zdzIP+6muqPCuE8avnrgDJ6KW/2+UpHTRcTbMXCIRxiRmyrX+IZ4WSJGZdHPWF3WmQpXpy603XxecZ9iygN7w==
-
netmask@^2.0.2:
version "2.1.1"
resolved "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz"
@@ -7114,21 +4434,6 @@ node-addon-api@^7.0.0:
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz"
integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==
-node-domexception@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz"
- integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
-
-node-exports-info@^1.6.0:
- version "1.6.0"
- resolved "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz"
- integrity sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==
- dependencies:
- array.prototype.flatmap "^1.3.3"
- es-errors "^1.3.0"
- object.entries "^1.1.9"
- semver "^6.3.1"
-
node-fetch-native@^1.6.7:
version "1.6.7"
resolved "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz"
@@ -7141,32 +4446,6 @@ node-fetch@2.6.7:
dependencies:
whatwg-url "^5.0.0"
-node-fetch@^2.6.7:
- version "2.7.0"
- resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz"
- integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
- dependencies:
- whatwg-url "^5.0.0"
-
-node-fetch@^3.0.0:
- version "3.3.2"
- resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz"
- integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==
- dependencies:
- data-uri-to-buffer "^4.0.0"
- fetch-blob "^3.1.4"
- formdata-polyfill "^4.0.10"
-
-node-forge@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz"
- integrity sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==
-
-node-gyp-build@^4.2.2:
- version "4.8.4"
- resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz"
- integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==
-
node-mock-http@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz"
@@ -7177,18 +4456,6 @@ node-releases@^2.0.36:
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz"
integrity sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==
-node-source-walk@^7.0.1:
- version "7.0.2"
- resolved "https://registry.npmjs.org/node-source-walk/-/node-source-walk-7.0.2.tgz"
- integrity sha512-71kFFjYaSshDTA8/a2HiTYPLdASWjLJxUyJxGE+ffxU+KhxSBtM9kiLUX+R2yooFdSFKMFpi4n3PFtDy6qXv8A==
- dependencies:
- "@babel/parser" "^7.29.0"
-
-node-stream-zip@^1.15.0:
- version "1.15.0"
- resolved "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz"
- integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==
-
nodemon@^3.1.14:
version "3.1.14"
resolved "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz"
@@ -7205,46 +4472,11 @@ nodemon@^3.1.14:
touch "^3.1.0"
undefsafe "^2.0.5"
-nopt@^8.0.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz"
- integrity sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==
- dependencies:
- abbrev "^3.0.0"
-
-normalize-package-data@^6.0.0:
- version "6.0.2"
- resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz"
- integrity sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==
- dependencies:
- hosted-git-info "^7.0.0"
- semver "^7.3.5"
- validate-npm-package-license "^3.0.4"
-
-normalize-path@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz"
- integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==
- dependencies:
- remove-trailing-separator "^1.0.1"
-
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-normalize-url@^6.0.1:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
- integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
-
-npm-run-path@^5.1.0:
- version "5.3.0"
- resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz"
- integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==
- dependencies:
- path-key "^4.0.0"
-
nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz"
@@ -7262,39 +4494,12 @@ object-inspect@^1.13.3, object-inspect@^1.13.4:
resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz"
integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
-object-keys@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-object.assign@^4.1.7:
- version "4.1.7"
- resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz"
- integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==
- dependencies:
- call-bind "^1.0.8"
- call-bound "^1.0.3"
- define-properties "^1.2.1"
- es-object-atoms "^1.0.0"
- has-symbols "^1.1.0"
- object-keys "^1.1.1"
-
-object.entries@^1.1.9:
- version "1.1.9"
- resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz"
- integrity sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==
- dependencies:
- call-bind "^1.0.8"
- call-bound "^1.0.4"
- define-properties "^1.2.1"
- es-object-atoms "^1.1.1"
-
obug@^2.1.0, obug@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz"
integrity sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==
-ofetch@^1.4.1, ofetch@^1.5.1:
+ofetch@^1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz"
integrity sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==
@@ -7308,11 +4513,6 @@ ohash@^2.0.11:
resolved "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz"
integrity sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==
-omit.js@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/omit.js/-/omit.js-2.0.2.tgz"
- integrity sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==
-
on-finished@^2.4.1:
version "2.4.1"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
@@ -7320,27 +4520,13 @@ on-finished@^2.4.1:
dependencies:
ee-first "1.1.1"
-once@^1.3.0, once@^1.3.1, once@^1.4.0:
+once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
-one-time@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz"
- integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
- dependencies:
- fn.name "1.x.x"
-
-onetime@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz"
- integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
- dependencies:
- mimic-fn "^4.0.0"
-
oniguruma-parser@^0.12.2:
version "0.12.2"
resolved "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz"
@@ -7367,32 +4553,6 @@ optionator@^0.9.3:
type-check "^0.4.0"
word-wrap "^1.2.5"
-os-tmpdir@~1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
- integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
-
-own-keys@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz"
- integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==
- dependencies:
- get-intrinsic "^1.2.6"
- object-keys "^1.1.1"
- safe-push-apply "^1.0.0"
-
-p-cancelable@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
- integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
-
-p-event@^6.0.0:
- version "6.0.1"
- resolved "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz"
- integrity sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==
- dependencies:
- p-timeout "^6.1.2"
-
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz"
@@ -7400,13 +4560,6 @@ p-limit@^3.0.2:
dependencies:
yocto-queue "^0.1.0"
-p-limit@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz"
- integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==
- dependencies:
- yocto-queue "^1.0.0"
-
p-limit@^7.3.0:
version "7.3.0"
resolved "https://registry.npmjs.org/p-limit/-/p-limit-7.3.0.tgz"
@@ -7421,18 +4574,6 @@ p-locate@^5.0.0:
dependencies:
p-limit "^3.0.2"
-p-locate@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz"
- integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==
- dependencies:
- p-limit "^4.0.0"
-
-p-map@^7.0.0:
- version "7.0.4"
- resolved "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz"
- integrity sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==
-
p-queue@^9.1.0:
version "9.2.0"
resolved "https://registry.npmjs.org/p-queue/-/p-queue-9.2.0.tgz"
@@ -7441,32 +4582,11 @@ p-queue@^9.1.0:
eventemitter3 "^5.0.4"
p-timeout "^7.0.0"
-p-retry@^6.0.0:
- version "6.2.1"
- resolved "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz"
- integrity sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==
- dependencies:
- "@types/retry" "0.12.2"
- is-network-error "^1.0.0"
- retry "^0.13.1"
-
-p-timeout@^6.0.0, p-timeout@^6.1.2:
- version "6.1.4"
- resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz"
- integrity sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==
-
p-timeout@^7.0.0:
version "7.0.1"
resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz"
integrity sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==
-p-wait-for@^5.0.0:
- version "5.0.2"
- resolved "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz"
- integrity sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==
- dependencies:
- p-timeout "^6.0.0"
-
pac-proxy-agent@^7.1.0:
version "7.2.0"
resolved "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz"
@@ -7489,11 +4609,6 @@ pac-resolver@^7.0.1:
degenerator "^5.0.0"
netmask "^2.0.2"
-package-json-from-dist@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz"
- integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
-
package-manager-detector@^1.6.0:
version "1.6.0"
resolved "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz"
@@ -7506,19 +4621,6 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
-parse-gitignore@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-2.0.0.tgz"
- integrity sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==
-
-parse-imports@^2.2.1:
- version "2.2.1"
- resolved "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz"
- integrity sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==
- dependencies:
- es-module-lexer "^1.5.3"
- slashes "^3.0.12"
-
parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
@@ -7529,15 +4631,6 @@ parse-json@^5.0.0, parse-json@^5.2.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
-parse-json@^8.0.0:
- version "8.3.0"
- resolved "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz"
- integrity sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==
- dependencies:
- "@babel/code-frame" "^7.26.2"
- index-to-position "^1.1.0"
- type-fest "^4.39.1"
-
parse-latin@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz"
@@ -7587,32 +4680,17 @@ path-exists@^4.0.0:
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
-path-exists@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz"
- integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==
-
-path-is-absolute@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
- integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
-
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
-path-key@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz"
- integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
-
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
-path-scurry@^1.11.1, path-scurry@^1.6.1:
+path-scurry@^1.6.1:
version "1.11.1"
resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz"
integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
@@ -7620,25 +4698,7 @@ path-scurry@^1.11.1, path-scurry@^1.6.1:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
-path-scurry@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz"
- integrity sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==
- dependencies:
- lru-cache "^11.0.0"
- minipass "^7.1.2"
-
-"path-to-regexp-updated@npm:path-to-regexp@6.3.0":
- version "6.3.0"
- resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz"
- integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==
-
-path-to-regexp@6.1.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.1.0.tgz"
- integrity sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==
-
-path-to-regexp@6.3.0, path-to-regexp@^6.3.0:
+path-to-regexp@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4"
integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==
@@ -7653,31 +4713,11 @@ path-type@^4.0.0:
resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-path-type@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz"
- integrity sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==
-
-pathe@^1.1.1:
- version "1.1.2"
- resolved "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz"
- integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==
-
-pathe@^2.0.1, pathe@^2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz"
- integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
-
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
-pg-gateway@0.3.0-beta.4:
- version "0.3.0-beta.4"
- resolved "https://registry.npmjs.org/pg-gateway/-/pg-gateway-0.3.0-beta.4.tgz"
- integrity sha512-CTjsM7Z+0Nx2/dyZ6r8zRsc3f9FScoD5UAOlfUx1Fdv/JOIWvRbF7gou6l6vP+uypXQVoYPgw8xZDXgMGvBa4Q==
-
piccolore@^0.1.3:
version "0.1.3"
resolved "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz"
@@ -7693,25 +4733,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1, picomatch@^2.3.2, picomatc
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601"
integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==
-picoquery@^2.5.0:
- version "2.5.0"
- resolved "https://registry.npmjs.org/picoquery/-/picoquery-2.5.0.tgz"
- integrity sha512-j1kgOFxtaCyoFCkpoYG2Oj3OdGakadO7HZ7o5CqyRazlmBekKhbDoUnNnXASE07xSY4nDImWZkrZv7toSxMi/g==
-
-pkg-types@^1.3.1:
- version "1.3.1"
- resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz"
- integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
- dependencies:
- confbox "^0.1.8"
- mlly "^1.7.4"
- pathe "^2.0.1"
-
-possible-typed-array-names@^1.0.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz"
- integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
-
postcss-selector-parser@^7.0.0:
version "7.1.1"
resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz"
@@ -7720,16 +4741,7 @@ postcss-selector-parser@^7.0.0:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
-postcss-values-parser@^6.0.2:
- version "6.0.2"
- resolved "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz"
- integrity sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==
- dependencies:
- color-name "^1.1.4"
- is-url-superb "^4.0.0"
- quote-unquote "^1.0.0"
-
-postcss@^8.4.14, postcss@^8.5.10, postcss@^8.5.6:
+postcss@^8.4.14, postcss@^8.5.6:
version "8.5.14"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz"
integrity sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==
@@ -7738,27 +4750,6 @@ postcss@^8.4.14, postcss@^8.5.10, postcss@^8.5.6:
picocolors "^1.1.1"
source-map-js "^1.2.1"
-precinct@^12.0.0:
- version "12.3.1"
- resolved "https://registry.npmjs.org/precinct/-/precinct-12.3.1.tgz"
- integrity sha512-wGyTIvtxh2S2NAHxTJj0YymxWOIcEDotu17yHoQUd2Bz2C07LrS28L1nvXDMxrCHvHmV6KTlaIQy5PzRm7Y8rg==
- dependencies:
- "@dependents/detective-less" "^5.0.1"
- commander "^12.1.0"
- detective-amd "^6.0.1"
- detective-cjs "^6.1.0"
- detective-es6 "^5.0.1"
- detective-postcss "^7.0.1"
- detective-sass "^6.0.1"
- detective-scss "^5.0.1"
- detective-stylus "^5.0.1"
- detective-typescript "^14.1.1"
- detective-vue2 "^2.3.0"
- module-definition "^6.0.1"
- node-source-walk "^7.0.1"
- postcss "^8.5.10"
- typescript "^5.9.3"
-
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
@@ -7783,16 +4774,6 @@ prismjs@^1.30.0:
resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz"
integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==
-process-nextick-args@~2.0.0:
- version "2.0.1"
- resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
- integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-process@^0.11.10:
- version "0.11.10"
- resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
- integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
-
progress@2.0.3, progress@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
@@ -7934,16 +4915,6 @@ queue-microtask@^1.2.2:
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
-quick-lru@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
- integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
-
-quote-unquote@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz"
- integrity sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==
-
radix3@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz"
@@ -8031,40 +5002,7 @@ react@^19.2.5:
resolved "https://registry.npmjs.org/react/-/react-19.2.5.tgz"
integrity sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==
-read-package-up@^11.0.0:
- version "11.0.0"
- resolved "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz"
- integrity sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==
- dependencies:
- find-up-simple "^1.0.0"
- read-pkg "^9.0.0"
- type-fest "^4.6.0"
-
-read-pkg@^9.0.0:
- version "9.0.1"
- resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz"
- integrity sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==
- dependencies:
- "@types/normalize-package-data" "^2.4.3"
- normalize-package-data "^6.0.0"
- parse-json "^8.0.0"
- type-fest "^4.6.0"
- unicorn-magic "^0.1.0"
-
-readable-stream@^2.0.5, readable-stream@^2.2.2:
- version "2.3.8"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
- integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
- dependencies:
- core-util-is "~1.0.0"
- inherits "~2.0.3"
- isarray "~1.0.0"
- process-nextick-args "~2.0.0"
- safe-buffer "~5.1.1"
- string_decoder "~1.1.1"
- util-deprecate "~1.0.1"
-
-readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.2:
+readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.2"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
@@ -8073,24 +5011,6 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.2:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
-readable-stream@^4.0.0:
- version "4.7.0"
- resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz"
- integrity sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==
- dependencies:
- abort-controller "^3.0.0"
- buffer "^6.0.3"
- events "^3.3.0"
- process "^0.11.10"
- string_decoder "^1.3.0"
-
-readdir-glob@^1.1.2:
- version "1.1.3"
- resolved "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz"
- integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==
- dependencies:
- minimatch "^5.1.0"
-
readdirp@^4.0.1:
version "4.1.2"
resolved "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz"
@@ -8135,20 +5055,6 @@ redux@^5.0.1:
resolved "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz"
integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==
-reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9:
- version "1.0.10"
- resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz"
- integrity sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==
- dependencies:
- call-bind "^1.0.8"
- define-properties "^1.2.1"
- es-abstract "^1.23.9"
- es-errors "^1.3.0"
- es-object-atoms "^1.0.0"
- get-intrinsic "^1.2.7"
- get-proto "^1.0.1"
- which-builtin-type "^1.2.1"
-
regex-recursion@^6.0.2:
version "6.0.2"
resolved "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz"
@@ -8168,18 +5074,6 @@ regex@^6.1.0:
dependencies:
regex-utilities "^2.3.0"
-regexp.prototype.flags@^1.5.4:
- version "1.5.4"
- resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz"
- integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==
- dependencies:
- call-bind "^1.0.8"
- define-properties "^1.2.1"
- es-errors "^1.3.0"
- get-proto "^1.0.1"
- gopd "^1.2.0"
- set-function-name "^2.0.2"
-
rehype-parse@^9.0.0:
version "9.0.1"
resolved "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz"
@@ -8269,11 +5163,6 @@ remark-stringify@^11.0.0:
mdast-util-to-markdown "^2.0.0"
unified "^11.0.0"
-remove-trailing-separator@^1.0.1:
- version "1.1.0"
- resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz"
- integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==
-
request-light@^0.5.7:
version "0.5.8"
resolved "https://registry.npmjs.org/request-light/-/request-light-0.5.8.tgz"
@@ -8294,46 +5183,22 @@ require-from-string@^2.0.2:
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
-require-in-the-middle@^7.1.1:
- version "7.5.2"
- resolved "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz"
- integrity sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==
- dependencies:
- debug "^4.3.5"
- module-details-from-path "^1.0.3"
- resolve "^1.22.8"
-
-require-package-name@^2.0.1:
- version "2.0.1"
- resolved "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz"
- integrity sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==
-
reselect@5.1.1, reselect@^5.1.0:
version "5.1.1"
resolved "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz"
integrity sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==
-resolve-alpn@^1.0.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
- integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
-
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-resolve-from@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz"
- integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
-
resolve-pkg-maps@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz"
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
-resolve@^1.19.0, resolve@^1.22.8:
+resolve@^1.19.0:
version "1.22.12"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz"
integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==
@@ -8343,25 +5208,6 @@ resolve@^1.19.0, resolve@^1.22.8:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-resolve@^2.0.0-next.1:
- version "2.0.0-next.6"
- resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz"
- integrity sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==
- dependencies:
- es-errors "^1.3.0"
- is-core-module "^2.16.1"
- node-exports-info "^1.6.0"
- object-keys "^1.1.1"
- path-parse "^1.0.7"
- supports-preserve-symlinks-flag "^1.0.0"
-
-responselike@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc"
- integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==
- dependencies:
- lowercase-keys "^2.0.0"
-
retext-latin@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz"
@@ -8399,11 +5245,6 @@ retext@^9.0.0:
retext-stringify "^4.0.0"
unified "^11.0.0"
-retry@^0.13.1:
- version "0.13.1"
- resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz"
- integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==
-
reusify@^1.0.4:
version "1.1.0"
resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz"
@@ -8416,13 +5257,6 @@ rimraf@4.4.0:
dependencies:
glob "^9.2.0"
-rimraf@^2.7.1:
- version "2.7.1"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
- integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
- dependencies:
- glob "^7.1.3"
-
rollup@^4.43.0:
version "4.60.3"
resolved "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz"
@@ -8487,49 +5321,11 @@ s.color@0.0.15:
resolved "https://registry.npmjs.org/s.color/-/s.color-0.0.15.tgz"
integrity sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==
-safe-array-concat@^1.1.3:
- version "1.1.4"
- resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz"
- integrity sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==
- dependencies:
- call-bind "^1.0.9"
- call-bound "^1.0.4"
- get-intrinsic "^1.3.0"
- has-symbols "^1.1.0"
- isarray "^2.0.5"
-
-safe-buffer@^5.0.1, safe-buffer@~5.2.0:
+safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safe-push-apply@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz"
- integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==
- dependencies:
- es-errors "^1.3.0"
- isarray "^2.0.5"
-
-safe-regex-test@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz"
- integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==
- dependencies:
- call-bound "^1.0.2"
- es-errors "^1.3.0"
- is-regex "^1.2.1"
-
-safe-stable-stringify@^2.3.1:
- version "2.5.0"
- resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz"
- integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==
-
"safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
@@ -8573,12 +5369,12 @@ semver@^6.3.1:
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-semver@^7.3.5, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.2, semver@^7.6.3, semver@^7.7.2, semver@^7.7.3, semver@^7.7.4:
+semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.2, semver@^7.7.3, semver@^7.7.4:
version "7.7.4"
resolved "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz"
integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==
-send@^1.1.0, send@^1.2.0, send@^1.2.1:
+send@^1.1.0, send@^1.2.0:
version "1.2.1"
resolved "https://registry.npmjs.org/send/-/send-1.2.1.tgz"
integrity sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==
@@ -8605,53 +5401,17 @@ serve-static@^2.2.0:
parseurl "^1.3.3"
send "^1.2.0"
-server-destroy@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz"
- integrity sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==
-
set-cookie-parser@^2.6.0:
version "2.7.2"
resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz"
integrity sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==
-set-function-length@^1.2.2:
- version "1.2.2"
- resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz"
- integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
- dependencies:
- define-data-property "^1.1.4"
- es-errors "^1.3.0"
- function-bind "^1.1.2"
- get-intrinsic "^1.2.4"
- gopd "^1.0.1"
- has-property-descriptors "^1.0.2"
-
-set-function-name@^2.0.2:
- version "2.0.2"
- resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz"
- integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==
- dependencies:
- define-data-property "^1.1.4"
- es-errors "^1.3.0"
- functions-have-names "^1.2.3"
- has-property-descriptors "^1.0.2"
-
-set-proto@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz"
- integrity sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==
- dependencies:
- dunder-proto "^1.0.1"
- es-errors "^1.3.0"
- es-object-atoms "^1.0.0"
-
setprototypeof@~1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
-sharp@^0.34.0, sharp@^0.34.3, sharp@^0.34.5:
+sharp@^0.34.0:
version "0.34.5"
resolved "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz"
integrity sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==
@@ -8756,11 +5516,6 @@ side-channel@^1.1.0:
side-channel-map "^1.0.1"
side-channel-weakmap "^1.0.2"
-signal-exit@^4.0.1, signal-exit@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz"
- integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
-
simple-update-notifier@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz"
@@ -8783,11 +5538,6 @@ sitemap@^9.0.0:
arg "^5.0.0"
sax "^1.4.1"
-slashes@^3.0.12:
- version "3.0.12"
- resolved "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz"
- integrity sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==
-
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz"
@@ -8820,20 +5570,12 @@ socks@^2.8.3:
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
-source-map-support@^0.5.21:
- version "0.5.21"
- resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz"
- integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
-source-map@^0.6.0, source-map@~0.6.1:
+source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -8843,78 +5585,16 @@ space-separated-tokens@^2.0.0:
resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz"
integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==
-spdx-correct@^3.0.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz"
- integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==
- dependencies:
- spdx-expression-parse "^3.0.0"
- spdx-license-ids "^3.0.0"
-
-spdx-exceptions@^2.1.0:
- version "2.5.0"
- resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz"
- integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==
-
-spdx-expression-parse@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz"
- integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
- dependencies:
- spdx-exceptions "^2.1.0"
- spdx-license-ids "^3.0.0"
-
-spdx-license-ids@^3.0.0:
- version "3.0.23"
- resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz"
- integrity sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==
-
-stack-trace@0.0.x:
- version "0.0.10"
- resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz"
- integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==
-
statuses@^2.0.1, statuses@^2.0.2, statuses@~2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz"
integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==
-std-env@^4.1.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz"
- integrity sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==
-
-stop-iteration-iterator@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz"
- integrity sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==
- dependencies:
- es-errors "^1.3.0"
- internal-slot "^1.1.0"
-
stream-replace-string@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz"
integrity sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==
-streamx@^2.12.5, streamx@^2.15.0, streamx@^2.25.0:
- version "2.25.0"
- resolved "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz"
- integrity sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==
- dependencies:
- events-universal "^1.0.0"
- fast-fifo "^1.3.2"
- text-decoder "^1.1.0"
-
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
@@ -8924,61 +5604,13 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
-string-width@^5.0.1, string-width@^5.1.2:
- version "5.1.2"
- resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz"
- integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
- dependencies:
- eastasianwidth "^0.2.0"
- emoji-regex "^9.2.2"
- strip-ansi "^7.0.1"
-
-string.prototype.trim@^1.2.10:
- version "1.2.10"
- resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz"
- integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==
- dependencies:
- call-bind "^1.0.8"
- call-bound "^1.0.2"
- define-data-property "^1.1.4"
- define-properties "^1.2.1"
- es-abstract "^1.23.5"
- es-object-atoms "^1.0.0"
- has-property-descriptors "^1.0.2"
-
-string.prototype.trimend@^1.0.9:
- version "1.0.9"
- resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz"
- integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==
- dependencies:
- call-bind "^1.0.8"
- call-bound "^1.0.2"
- define-properties "^1.2.1"
- es-object-atoms "^1.0.0"
-
-string.prototype.trimstart@^1.0.8:
- version "1.0.8"
- resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz"
- integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==
- dependencies:
- call-bind "^1.0.7"
- define-properties "^1.2.1"
- es-object-atoms "^1.0.0"
-
-string_decoder@^1.1.1, string_decoder@^1.3.0:
+string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
-string_decoder@~1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
- integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
- dependencies:
- safe-buffer "~5.1.0"
-
stringify-entities@^4.0.0:
version "4.0.4"
resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz"
@@ -8987,13 +5619,6 @@ stringify-entities@^4.0.0:
character-entities-html4 "^2.0.0"
character-entities-legacy "^3.0.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
- version "6.0.1"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
@@ -9001,18 +5626,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
dependencies:
ansi-regex "^5.0.1"
-strip-ansi@^7.0.1:
- version "7.2.0"
- resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz"
- integrity sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==
- dependencies:
- ansi-regex "^6.2.2"
-
-strip-final-newline@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz"
- integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
-
stylis@4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz"
@@ -9032,11 +5645,6 @@ supports-color@8.1.1:
dependencies:
has-flag "^4.0.0"
-supports-color@^10.0.0:
- version "10.2.2"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz"
- integrity sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==
-
supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
@@ -9086,7 +5694,7 @@ svelte@^5.55.5:
magic-string "^0.30.11"
zimmerframe "^1.1.2"
-svgo@^4.0.0, svgo@^4.0.1:
+svgo@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz"
integrity sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==
@@ -9132,46 +5740,6 @@ tar-stream@^2.1.4:
inherits "^2.0.3"
readable-stream "^3.1.1"
-tar-stream@^3.0.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz"
- integrity sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==
- dependencies:
- b4a "^1.6.4"
- bare-fs "^4.5.5"
- fast-fifo "^1.2.0"
- streamx "^2.15.0"
-
-tar@^7.4.0, tar@^7.5.12:
- version "7.5.13"
- resolved "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz"
- integrity sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==
- dependencies:
- "@isaacs/fs-minipass" "^4.0.0"
- chownr "^3.0.0"
- minipass "^7.1.2"
- minizlib "^3.1.0"
- yallist "^5.0.0"
-
-teex@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz"
- integrity sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==
- dependencies:
- streamx "^2.12.5"
-
-text-decoder@^1.1.0:
- version "1.2.7"
- resolved "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz"
- integrity sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==
- dependencies:
- b4a "^1.6.4"
-
-text-hex@1.0.x:
- version "1.0.0"
- resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz"
- integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
-
through@^2.3.8:
version "2.3.8"
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
@@ -9205,25 +5773,6 @@ tinyglobby@^0.2.15, tinyglobby@^0.2.16:
fdir "^6.5.0"
picomatch "^4.0.4"
-tmp-promise@^3.0.2, tmp-promise@^3.0.3:
- version "3.0.3"
- resolved "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz"
- integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==
- dependencies:
- tmp "^0.2.0"
-
-tmp@0.0.33:
- version "0.0.33"
- resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
- integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
- dependencies:
- os-tmpdir "~1.0.2"
-
-tmp@^0.2.0:
- version "0.2.5"
- resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz"
- integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==
-
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
@@ -9236,16 +5785,6 @@ toidentifier@~1.0.1:
resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
-toml@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz"
- integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==
-
-tomlify-j0.4@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/tomlify-j0.4/-/tomlify-j0.4-3.0.0.tgz"
- integrity sha512-2Ulkc8T7mXJ2l0W476YC/A209PR38Nw8PuaCNtk9uI3t1zzFdGQeWYGQvmj2PZkVvRC/Yoi4xQKMRnWc/N29tQ==
-
topojson-client@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz"
@@ -9273,11 +5812,6 @@ trim-lines@^3.0.0:
resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz"
integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==
-triple-beam@^1.3.0:
- version "1.4.1"
- resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz"
- integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==
-
trough@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz"
@@ -9288,16 +5822,11 @@ ts-api-utils@^2.5.0:
resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz"
integrity sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==
-tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.3:
+tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0:
version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
-tunnel@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
- integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
-
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
@@ -9305,11 +5834,6 @@ type-check@^0.4.0, type-check@~0.4.0:
dependencies:
prelude-ls "^1.2.1"
-type-fest@^4.18.2, type-fest@^4.39.1, type-fest@^4.6.0:
- version "4.41.0"
- resolved "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz"
- integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==
-
type-is@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz"
@@ -9319,61 +5843,11 @@ type-is@^2.0.1:
media-typer "^1.1.0"
mime-types "^3.0.0"
-typed-array-buffer@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz"
- integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==
- dependencies:
- call-bound "^1.0.3"
- es-errors "^1.3.0"
- is-typed-array "^1.1.14"
-
-typed-array-byte-length@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz"
- integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==
- dependencies:
- call-bind "^1.0.8"
- for-each "^0.3.3"
- gopd "^1.2.0"
- has-proto "^1.2.0"
- is-typed-array "^1.1.14"
-
-typed-array-byte-offset@^1.0.4:
- version "1.0.4"
- resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz"
- integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==
- dependencies:
- available-typed-arrays "^1.0.7"
- call-bind "^1.0.8"
- for-each "^0.3.3"
- gopd "^1.2.0"
- has-proto "^1.2.0"
- is-typed-array "^1.1.15"
- reflect.getprototypeof "^1.0.9"
-
-typed-array-length@^1.0.7:
- version "1.0.7"
- resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz"
- integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==
- dependencies:
- call-bind "^1.0.7"
- for-each "^0.3.3"
- gopd "^1.0.1"
- is-typed-array "^1.1.13"
- possible-typed-array-names "^1.0.0"
- reflect.getprototypeof "^1.0.6"
-
typed-query-selector@^2.12.1:
version "2.12.2"
resolved "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz"
integrity sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==
-typedarray@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
- integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
-
typesafe-path@^0.2.2:
version "0.2.2"
resolved "https://registry.npmjs.org/typesafe-path/-/typesafe-path-0.2.2.tgz"
@@ -9386,41 +5860,21 @@ typescript-auto-import-cache@^0.3.5:
dependencies:
semver "^7.3.8"
-typescript@^5.9.3:
- version "5.9.3"
- resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz"
- integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
-
typescript@^6.0.3:
version "6.0.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz"
integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==
-ufo@^1.6.1, ufo@^1.6.3, ufo@^1.6.4:
+ufo@^1.6.1, ufo@^1.6.3:
version "1.6.4"
resolved "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz"
integrity sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==
-ulid@^3.0.0:
- version "3.0.2"
- resolved "https://registry.npmjs.org/ulid/-/ulid-3.0.2.tgz"
- integrity sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==
-
ultrahtml@^1.6.0:
version "1.6.0"
resolved "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz"
integrity sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==
-unbox-primitive@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz"
- integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==
- dependencies:
- call-bound "^1.0.3"
- has-bigints "^1.0.2"
- has-symbols "^1.1.0"
- which-boxed-primitive "^1.1.1"
-
unbzip2-stream@1.4.3:
version "1.4.3"
resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz"
@@ -9449,28 +5903,11 @@ undici-types@~7.19.0:
resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz"
integrity sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==
-undici@7.24.8:
- version "7.24.8"
- resolved "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz"
- integrity sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==
-
undici@^7.19.0:
version "7.25.0"
resolved "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz"
integrity sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==
-unenv@2.0.0-rc.24:
- version "2.0.0-rc.24"
- resolved "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz"
- integrity sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==
- dependencies:
- pathe "^2.0.3"
-
-unicorn-magic@^0.1.0:
- version "0.1.0"
- resolved "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz"
- integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==
-
unified@^11.0.0, unified@^11.0.4, unified@^11.0.5:
version "11.0.5"
resolved "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz"
@@ -9562,19 +5999,12 @@ unist-util-visit@^5.0.0, unist-util-visit@^5.1.0:
unist-util-is "^6.0.0"
unist-util-visit-parents "^6.0.0"
-unixify@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz"
- integrity sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==
- dependencies:
- normalize-path "^2.1.1"
-
unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
-unstorage@^1.16.1, unstorage@^1.17.5:
+unstorage@^1.17.5:
version "1.17.5"
resolved "https://registry.npmjs.org/unstorage/-/unstorage-1.17.5.tgz"
integrity sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==
@@ -9588,15 +6018,6 @@ unstorage@^1.16.1, unstorage@^1.17.5:
ofetch "^1.5.1"
ufo "^1.6.3"
-untun@^0.1.3:
- version "0.1.3"
- resolved "https://registry.npmjs.org/untun/-/untun-0.1.3.tgz"
- integrity sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==
- dependencies:
- citty "^0.1.5"
- consola "^3.2.3"
- pathe "^1.1.1"
-
update-browserslist-db@^1.2.3:
version "1.2.3"
resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz"
@@ -9605,11 +6026,6 @@ update-browserslist-db@^1.2.3:
escalade "^3.2.0"
picocolors "^1.1.1"
-uqr@^0.1.3:
- version "0.1.3"
- resolved "https://registry.npmjs.org/uqr/-/uqr-0.1.3.tgz"
- integrity sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==
-
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
@@ -9617,44 +6033,21 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
-urlpattern-polyfill@8.0.2:
- version "8.0.2"
- resolved "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz"
- integrity sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==
-
-urlpattern-polyfill@^10.0.0:
- version "10.1.0"
- resolved "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz"
- integrity sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==
-
use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0:
version "1.6.0"
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz"
integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==
-util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+util-deprecate@^1.0.1, util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
-uuid@^11.0.0, uuid@^13.0.0, uuid@^14.0.0:
+uuid@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-14.0.0.tgz#0af883220163d264ffe0c084f6b8a89b9666966d"
integrity sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==
-validate-npm-package-license@^3.0.4:
- version "3.0.4"
- resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz"
- integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
- dependencies:
- spdx-correct "^3.0.0"
- spdx-expression-parse "^3.0.0"
-
-validate-npm-package-name@^5.0.0:
- version "5.0.1"
- resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz"
- integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==
-
vary@^1, vary@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
@@ -9704,6 +6097,20 @@ victory-vendor@^37.0.2:
d3-time "^3.0.0"
d3-timer "^3.0.1"
+vite@^7.2.0:
+ version "7.3.3"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.3.tgz#d7e07a52b5873fb86f902a3f4b3d17410337450f"
+ integrity sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==
+ dependencies:
+ esbuild "^0.27.0"
+ fdir "^6.5.0"
+ picomatch "^4.0.3"
+ postcss "^8.5.6"
+ rollup "^4.43.0"
+ tinyglobby "^0.2.15"
+ optionalDependencies:
+ fsevents "~2.3.3"
+
vite@^7.3.2:
version "7.3.2"
resolved "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz"
@@ -9868,11 +6275,6 @@ web-namespaces@^2.0.0:
resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz"
integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==
-web-streams-polyfill@^3.0.3:
- version "3.3.3"
- resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz"
- integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==
-
webdriver-bidi-protocol@0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz"
@@ -9903,64 +6305,11 @@ whatwg-url@^5.0.0:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
-which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz"
- integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==
- dependencies:
- is-bigint "^1.1.0"
- is-boolean-object "^1.2.1"
- is-number-object "^1.1.1"
- is-string "^1.1.1"
- is-symbol "^1.1.1"
-
-which-builtin-type@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz"
- integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==
- dependencies:
- call-bound "^1.0.2"
- function.prototype.name "^1.1.6"
- has-tostringtag "^1.0.2"
- is-async-function "^2.0.0"
- is-date-object "^1.1.0"
- is-finalizationregistry "^1.1.0"
- is-generator-function "^1.0.10"
- is-regex "^1.2.1"
- is-weakref "^1.0.2"
- isarray "^2.0.5"
- which-boxed-primitive "^1.1.0"
- which-collection "^1.0.2"
- which-typed-array "^1.1.16"
-
-which-collection@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz"
- integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==
- dependencies:
- is-map "^2.0.3"
- is-set "^2.0.3"
- is-weakmap "^2.0.2"
- is-weakset "^2.0.3"
-
which-pm-runs@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz"
integrity sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==
-which-typed-array@^1.1.16, which-typed-array@^1.1.19:
- version "1.1.20"
- resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz"
- integrity sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==
- dependencies:
- available-typed-arrays "^1.0.7"
- call-bind "^1.0.8"
- call-bound "^1.0.4"
- for-each "^0.3.5"
- get-proto "^1.0.1"
- gopd "^1.2.0"
- has-tostringtag "^1.0.2"
-
which@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
@@ -9975,73 +6324,11 @@ whoiser@^2.0.0-beta.10:
dependencies:
punycode-esm "^1.0.15"
-winston-transport@^4.9.0:
- version "4.9.0"
- resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz"
- integrity sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==
- dependencies:
- logform "^2.7.0"
- readable-stream "^3.6.2"
- triple-beam "^1.3.0"
-
-winston@^3.10.0:
- version "3.19.0"
- resolved "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz"
- integrity sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==
- dependencies:
- "@colors/colors" "^1.6.0"
- "@dabh/diagnostics" "^2.0.8"
- async "^3.2.3"
- is-stream "^2.0.0"
- logform "^2.7.0"
- one-time "^1.0.0"
- readable-stream "^3.4.0"
- safe-stable-stringify "^2.3.1"
- stack-trace "0.0.x"
- triple-beam "^1.3.0"
- winston-transport "^4.9.0"
-
word-wrap@^1.2.5:
version "1.2.5"
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
-workerd@1.20260430.1:
- version "1.20260430.1"
- resolved "https://registry.npmjs.org/workerd/-/workerd-1.20260430.1.tgz"
- integrity sha512-KEgIWyiw3Jmn+DCd/L3ePo5fmiiYb/UcwKvDWPf/nLLOiwShDFzDSsegU5NY/JcwgvO/QsLHVi2FYrbkcXNY5Q==
- optionalDependencies:
- "@cloudflare/workerd-darwin-64" "1.20260430.1"
- "@cloudflare/workerd-darwin-arm64" "1.20260430.1"
- "@cloudflare/workerd-linux-64" "1.20260430.1"
- "@cloudflare/workerd-linux-arm64" "1.20260430.1"
- "@cloudflare/workerd-windows-64" "1.20260430.1"
-
-wrangler@4.87.0:
- version "4.87.0"
- resolved "https://registry.npmjs.org/wrangler/-/wrangler-4.87.0.tgz"
- integrity sha512-lfhfKwLfQlowwgV0xhlYgE9fU3n0I30d4ccGY/rTCEm/n42Mjvlr0Ng3ZPNqlsrsKBcDR531V7dsPkgELvrk/Q==
- dependencies:
- "@cloudflare/kv-asset-handler" "0.5.0"
- "@cloudflare/unenv-preset" "2.16.1"
- blake3-wasm "2.1.5"
- esbuild "0.27.3"
- miniflare "4.20260430.0"
- path-to-regexp "6.3.0"
- unenv "2.0.0-rc.24"
- workerd "1.20260430.1"
- optionalDependencies:
- fsevents "~2.3.2"
-
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
- version "7.0.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
@@ -10051,38 +6338,21 @@ wrap-ansi@^7.0.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
-wrap-ansi@^8.1.0:
- version "8.1.0"
- resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"
- integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
- dependencies:
- ansi-styles "^6.1.0"
- string-width "^5.0.1"
- strip-ansi "^7.0.1"
-
wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
-write-file-atomic@^5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz"
- integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==
- dependencies:
- imurmurhash "^0.1.4"
- signal-exit "^4.0.1"
+ws@8.12.1:
+ version "8.12.1"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f"
+ integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==
-ws@8.12.1, ws@^8.17.1, ws@^8.19.0:
+ws@^8.17.1, ws@^8.19.0:
version "8.20.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.0.tgz#4cd9532358eba60bc863aad1623dfb045a4d4af8"
integrity sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==
-ws@8.18.0:
- version "8.18.0"
- resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz"
- integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
-
xml2js@^0.6.2:
version "0.6.2"
resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz"
@@ -10096,14 +6366,6 @@ xmlbuilder@~11.0.0:
resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
-xss@^1.0.15:
- version "1.0.15"
- resolved "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz"
- integrity sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==
- dependencies:
- commander "^2.20.3"
- cssfilter "0.0.10"
-
xxhash-wasm@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz"
@@ -10119,11 +6381,6 @@ yallist@^3.0.2:
resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-yallist@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz"
- integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==
-
yaml-language-server@~1.20.0:
version "1.20.0"
resolved "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-1.20.0.tgz"
@@ -10141,7 +6398,7 @@ yaml-language-server@~1.20.0:
vscode-uri "^3.0.2"
yaml "2.7.1"
-yaml@2.7.1, yaml@^1.10.0, yaml@^2.8.0, yaml@^2.8.2, yaml@^2.8.3:
+yaml@2.7.1, yaml@^1.10.0, yaml@^2.8.2, yaml@^2.8.3:
version "2.8.4"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.4.tgz#4b5f411dd25f9544914d8673d4da7f29248e5e2e"
integrity sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==
@@ -10156,7 +6413,7 @@ yargs-parser@^22.0.0:
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz"
integrity sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==
-yargs@17.7.2, yargs@^17.0.0, yargs@^17.6.0, yargs@^17.7.2:
+yargs@17.7.2, yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
@@ -10182,50 +6439,22 @@ yocto-queue@^0.1.0:
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
-yocto-queue@^1.0.0, yocto-queue@^1.2.1:
+yocto-queue@^1.2.1:
version "1.2.2"
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz"
integrity sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==
-youch-core@^0.3.3:
- version "0.3.3"
- resolved "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz"
- integrity sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==
- dependencies:
- "@poppinss/exception" "^1.2.2"
- error-stack-parser-es "^1.0.5"
-
-youch@4.1.0-beta.10:
- version "4.1.0-beta.10"
- resolved "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz"
- integrity sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==
- dependencies:
- "@poppinss/colors" "^4.1.5"
- "@poppinss/dumper" "^0.6.4"
- "@speed-highlight/core" "^1.2.7"
- cookie "^1.0.2"
- youch-core "^0.3.3"
-
zimmerframe@^1.1.2:
version "1.1.4"
resolved "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz"
integrity sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==
-zip-stream@^6.0.1:
- version "6.0.1"
- resolved "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz"
- integrity sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==
- dependencies:
- archiver-utils "^5.0.0"
- compress-commons "^6.0.2"
- readable-stream "^4.0.0"
-
-zod@^3.23.8, zod@^3.24.1:
+zod@^3.24.1:
version "3.25.76"
resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz"
integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==
-zod@^4.0.5, zod@^4.3.6:
+zod@^4.3.6:
version "4.4.3"
resolved "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz"
integrity sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==