From cc94265786a70c4587dca881a476bb85081ba81a Mon Sep 17 00:00:00 2001 From: rf Date: Wed, 25 Feb 2026 07:57:59 +1100 Subject: [PATCH 1/2] feat(cwv): setup lcp stats container --- .dockerignore | 5 + Dockerfile | 23 ++++ docker-compose.yml | 13 ++ packages/cwv-stats/README.md | 123 ++++++++++++++++++ packages/cwv-stats/eslint.config.js | 19 +++ packages/cwv-stats/package.json | 13 ++ .../cwv-stats/src/frameworks/frameworks.ts | 3 + packages/cwv-stats/src/lcp/index.ts | 12 ++ packages/cwv-stats/src/lcp/lcp.ts | 92 +++++++++++++ packages/cwv-stats/src/query-client/client.ts | 19 +++ packages/cwv-stats/tsconfig.json | 21 +++ pnpm-workspace.yaml | 1 + 12 files changed, 344 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 packages/cwv-stats/README.md create mode 100644 packages/cwv-stats/eslint.config.js create mode 100644 packages/cwv-stats/package.json create mode 100644 packages/cwv-stats/src/frameworks/frameworks.ts create mode 100644 packages/cwv-stats/src/lcp/index.ts create mode 100644 packages/cwv-stats/src/lcp/lcp.ts create mode 100644 packages/cwv-stats/src/query-client/client.ts create mode 100644 packages/cwv-stats/tsconfig.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4f75c95 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +node_modules +.git +.gitignore +*.md +dist diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..31b59fc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Base +FROM node:24-slim AS base +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable + +FROM base AS build +COPY . /usr/src/app +WORKDIR /usr/src/app +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --filter @framework-tracker/cwv-stats... --prod --frozen-lockfile +RUN pnpm deploy --filter=@framework-tracker/cwv-stats --prod /prod/cwv-stats --legacy + +FROM base AS cwv-stats-base +ENV NODE_ENV=production +COPY --from=build /prod/cwv-stats/node_modules /app/node_modules +COPY --from=build /prod/cwv-stats/src /app/src +USER node +WORKDIR /app +CMD [ "node", "src/lcp/index.ts" ] + +# LCP Stats +FROM cwv-stats-base AS cwv-stats-lcp +CMD [ "node", "src/lcp/index.ts" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bb0dfc5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +services: + cwv-stats-lcp: + build: + context: . + dockerfile: Dockerfile + target: cwv-stats-lcp + image: cwv-stats-lcp + volumes: + - ~/.config/gcloud/application_default_credentials.json:/app/application_default_credentials.json:ro + - ./packages/cwv-stats/src:/app/src + environment: + - GOOGLE_APPLICATION_CREDENTIALS=/app/application_default_credentials.json + - GOOGLE_CLOUD_PROJECT=framework-tracker diff --git a/packages/cwv-stats/README.md b/packages/cwv-stats/README.md new file mode 100644 index 0000000..440bbc5 --- /dev/null +++ b/packages/cwv-stats/README.md @@ -0,0 +1,123 @@ +# CWV (Core Web Vitals) Stats – `cwv-stats` + +`cwv-stats` is a small Node.js utility that queries the public HTTP Archive dataset in Google BigQuery and +computes **Core Web Vitals statistics for popular JavaScript frameworks**, starting with: + +- React +- Next.js + +Right now it focuses on **Largest Contentful Paint (LCP)** and returns percentile statistics (p50, p75, p90, +p95, p99) plus basic counts for each framework. + +The code that runs the query lives in: + +- `src/frameworks/frameworks.ts` – list of frameworks +- `src/query-client/client.ts` – thin BigQuery client wrapper +- `src/lcp/lcp.ts` – LCP query + result shaping +- `src/lcp/index.ts` – entrypoint that runs the LCP query and logs the results + +--- + +## Prerequisites + +To run `cwv-stats` locally (inside Docker) you’ll need: + +- **Google Cloud Account & Project**. + Setup your Google Cloud Account and new project named `framework-tracker` which has access to BigQuery and the HTTP Archive public dataset + (e.g. `httparchive.sample_data.pages_10k`, or the full `httparchive.latest.pages` if you have billing enabled on this account). + Visit [Getting started accessing the HTTP Archive with BigQuery](https://har.fyi/guides/getting-started/) +- **Docker** installed and running on your machine. [Docker Mac Installation](https://docs.docker.com/desktop/setup/install/mac-install/) + +You do _not_ need Node or pnpm installed on your host machine if you only use the container workflow. + +### Google Cloud / BigQuery setup + +1. **Install the gcloud CLI** + This will be needed for authenticating with BigQuery. + If your running on a Mac you can install via Homebrew + + ``` + brew update && brew install --cask gcloud-cli + ``` + + More details on installing with Homebrew can be found [here](https://docs.cloud.google.com/sdk/docs/downloads-homebrew) + + For non Mac users try [Install the Google Cloud CLI](https://docs.cloud.google.com/sdk/docs/install-sdk) + +2. **Create credentials file for authenticating** + Once you have setup `gcloud-cli` you will need to authenticate with your account. + First Initialise the Google Cloud CLI by running: + + ``` + gcloud init + ``` + + Then create your local authentication credentials + + ``` + gcloud auth application-default login + ``` + + This will create the following file: + - Linux, macOS: `$HOME/.config/gcloud/application_default_credentials.json` + - Windows: `%APPDATA%\gcloud\application_default_credentials.json` + + When we run the container using `docker compose` on our local machine this file is mounted into the container for Mac users. For Window users + you may need to update the volume mount in the `docker-compose.yml` file. + +3. Set the **project ID** that should be billed for BigQuery queries. + In the `docker-compose.yml` you will need to set the `GOOGLE_CLOUD_PROJECT` env variable to the project ID used in your GCP account for querying + the http archive. **Note: This is just temporary until we have a GCP account with billing that we can use to query the full dataset.**. + +For general reference on the Node.js BigQuery client library, see: +[BigQuery API Client Libraries](https://docs.cloud.google.com/bigquery/docs/reference/libraries#client-libraries-usage-nodejs) + +--- + +## Running the container locally + +For local development, this repo uses **Docker Compose**. The `cwv-stats-lcp` service builds the image from +the repo root `Dockerfile` and runs the `src/lcp/index.ts` entrypoint to execute the LCP query. + +### 1. Authenticate (ADC) + +This service uses Google Cloud **Application Default Credentials (ADC)**. The simplest setup for local +development is: + +```bash +gcloud auth application-default login +``` + +### 2. Build the service image + +```bash +docker compose build cwv-stats-lcp +``` + +If you’ve recently changed/installed dependencies or Dockerfile stages, you may want a clean build: + +```bash +docker compose build --no-cache cwv-stats-lcp +``` + +### 3. Run it + +From the **repo root**: + +```bash +docker compose run cwv-stats-lcp +``` + +What Compose does (see `docker-compose.yml`): + +- Mounts your local ADC credentials file into the container. +- Sets `GOOGLE_APPLICATION_CREDENTIALS` so the BigQuery client can authenticate. +- Sets `GOOGLE_CLOUD_PROJECT` so BigQuery knows which project to bill. +- Mounts `./packages/cwv-stats/src` into `/app/src` so code changes are reflected without rebuilding. + +--- + +## Adding a new image + +If you would like to add a new image you can build off of the `cwv-stats-base` image and set the `CMD` to run the project you are interested in. +Multi stage builds are used to keep the overall size of the image as small as possible. diff --git a/packages/cwv-stats/eslint.config.js b/packages/cwv-stats/eslint.config.js new file mode 100644 index 0000000..8bcdb32 --- /dev/null +++ b/packages/cwv-stats/eslint.config.js @@ -0,0 +1,19 @@ +// @ts-check +import js from '@eslint/js' + +export default [ + { + ignores: ['node_modules/**'], + }, + js.configs.recommended, + { + languageOptions: { + globals: { + console: 'readonly', + process: 'readonly', + }, + ecmaVersion: 2022, + sourceType: 'module', + }, + }, +] diff --git a/packages/cwv-stats/package.json b/packages/cwv-stats/package.json new file mode 100644 index 0000000..b1c2201 --- /dev/null +++ b/packages/cwv-stats/package.json @@ -0,0 +1,13 @@ +{ + "name": "@framework-tracker/cwv-stats", + "version": "0.0.1", + "private": true, + "type": "module", + "devDependencies": { + "@types/node": "^25.0.3" + }, + "dependencies": { + "@google-cloud/bigquery": "^8.1.1", + "zod": "^4.3.6" + } +} diff --git a/packages/cwv-stats/src/frameworks/frameworks.ts b/packages/cwv-stats/src/frameworks/frameworks.ts new file mode 100644 index 0000000..6030a16 --- /dev/null +++ b/packages/cwv-stats/src/frameworks/frameworks.ts @@ -0,0 +1,3 @@ +export const frameworks = ['REACT', 'NEXT.JS'] as const + +export type Framework = (typeof frameworks)[number] diff --git a/packages/cwv-stats/src/lcp/index.ts b/packages/cwv-stats/src/lcp/index.ts new file mode 100644 index 0000000..511363c --- /dev/null +++ b/packages/cwv-stats/src/lcp/index.ts @@ -0,0 +1,12 @@ +import { getFrameworksLCP } from './lcp.ts' +import { frameworks } from '../frameworks/frameworks.ts' + +async function main() { + console.info('Starting LCP Query') + const stats = await getFrameworksLCP([...frameworks]) + console.info(stats) +} + +main() + .catch(console.error) + .finally(() => console.info('Finished LCP Query')) diff --git a/packages/cwv-stats/src/lcp/lcp.ts b/packages/cwv-stats/src/lcp/lcp.ts new file mode 100644 index 0000000..d7172d4 --- /dev/null +++ b/packages/cwv-stats/src/lcp/lcp.ts @@ -0,0 +1,92 @@ +import { type Framework, frameworks } from '../frameworks/frameworks.ts' +import { runQuery } from '../query-client/client.ts' +import * as z from 'zod' + +const lcpSchema = z.object({ + framework: z.enum(frameworks), + total_sites: z.number(), + min_lcp: z.number(), + p50_lcp: z.number(), + p75_lcp: z.number(), + p90_lcp: z.number(), + p95_lcp: z.number(), + p99_lcp: z.number(), + max_lcp: z.number(), +}) + +type CoreWebVital = 'LCP' + +type PercentileStatistics = { + numericUnit: string + p50: number + p75: number + p90: number + p95: number + p99: number +} + +type FrameworkMetric = { + framework: Framework + coreWebVital: CoreWebVital + numSitesMeasured: number + stats: PercentileStatistics +} + +// TODO - Once we have GCP credits replace httparchive.sample_data.pages_10k with httparchive.latest.pages +// httparchive.latest.pages is a view that reflects the latest monthly snapshot. +// httparchive.crawl.pages is all data from 2011 + +export async function getFrameworksLCP( + frameworks: Array, +): Promise> { + console.info(`Running LCP Query for frameworks: [${frameworks.join(',')}]`) + + // We use APPROX_QUANTILES for better performance on large datasets + // https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/approximate_aggregate_functions#approx_quantiles + const query = ` + WITH framework_metrics AS ( + SELECT + tech.technology AS framework, + SAFE.FLOAT64(JSON_EXTRACT(lighthouse, '$.audits.largest-contentful-paint.numericValue')) AS lcp_ms + FROM + \`httparchive.sample_data.pages_10k\`, + UNNEST(technologies) AS tech + WHERE + client = 'desktop' AND + LOWER(tech.technology) IN ('react', 'next.js') + ) + SELECT + UPPER(framework) AS framework, + COUNT(lcp_ms) AS total_sites, + MIN(lcp_ms) AS min_lcp, + APPROX_QUANTILES(lcp_ms, 100)[OFFSET(50)] AS p50_lcp, + APPROX_QUANTILES(lcp_ms, 100)[OFFSET(75)] AS p75_lcp, + APPROX_QUANTILES(lcp_ms, 100)[OFFSET(90)] AS p90_lcp, + APPROX_QUANTILES(lcp_ms, 100)[OFFSET(95)] AS p95_lcp, + APPROX_QUANTILES(lcp_ms, 100)[OFFSET(99)] AS p99_lcp, + MAX(lcp_ms) AS max_lcp + FROM + framework_metrics + WHERE + lcp_ms IS NOT NULL + GROUP BY framework_metrics.framework + ` + + const rows = await runQuery(query) + + const metrics = rows.map((row) => lcpSchema.parse(row)) + + return metrics.map((metric) => ({ + framework: metric.framework, + coreWebVital: 'LCP', + numSitesMeasured: metric.total_sites, + stats: { + numericUnit: 'ms', + p50: metric.p50_lcp, + p75: metric.p75_lcp, + p90: metric.p90_lcp, + p95: metric.p95_lcp, + p99: metric.p99_lcp, + }, + })) +} diff --git a/packages/cwv-stats/src/query-client/client.ts b/packages/cwv-stats/src/query-client/client.ts new file mode 100644 index 0000000..bad1e50 --- /dev/null +++ b/packages/cwv-stats/src/query-client/client.ts @@ -0,0 +1,19 @@ +import { BigQuery } from '@google-cloud/bigquery' + +const bigquery = new BigQuery() + +export async function runQuery(query: string): Promise> { + // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query + const options = { + query: query, + // Location must match that of the dataset(s) referenced in the query. + location: 'US', + } + + const [job] = await bigquery.createQueryJob(options) + console.info(`Job ${job.id} started.`) + + const [rows] = await job.getQueryResults() + + return rows +} diff --git a/packages/cwv-stats/tsconfig.json b/packages/cwv-stats/tsconfig.json new file mode 100644 index 0000000..e5c095b --- /dev/null +++ b/packages/cwv-stats/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "ESNext", + "allowImportingTsExtensions": true, + "moduleResolution": "bundler", + "noEmit": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "types": ["node"], + "erasableSyntaxOnly": true, + "preserveSymlinks": false + }, + "include": ["apps/**/*.ts", "src/lcp/index.ts"], + "exclude": ["node_modules"] +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7192586..a366615 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,7 @@ packages: - 'packages/docs' - 'packages/stats-generator' + - 'packages/cwv-stats' ignoredBuiltDependencies: - esbuild From b4872dec16641427bad9560e588f39eba21f20fc Mon Sep 17 00:00:00 2001 From: rf Date: Wed, 25 Feb 2026 08:02:47 +1100 Subject: [PATCH 2/2] update lock file --- pnpm-lock.yaml | 518 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 518 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 175f24f..8f88231 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,19 @@ importers: specifier: ^8.51.0 version: 8.51.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + packages/cwv-stats: + dependencies: + '@google-cloud/bigquery': + specifier: ^8.1.1 + version: 8.1.1 + zod: + specifier: ^4.3.6 + version: 4.3.6 + devDependencies: + '@types/node': + specifier: ^25.0.3 + version: 25.0.6 + packages/docs: dependencies: astro: @@ -506,6 +519,34 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@google-cloud/bigquery@8.1.1': + resolution: {integrity: sha512-2GHlohfA/VJffTvibMazMsZi6jPRx8MmaMberyDTL8rnhVs/frKSXVVRtLU83uSAy2j/5SD4mOs4jMQgJPON2g==} + engines: {node: '>=18'} + + '@google-cloud/common@6.0.0': + resolution: {integrity: sha512-IXh04DlkLMxWgYLIUYuHHKXKOUwPDzDgke1ykkkJPe48cGIS9kkL2U/o0pm4ankHLlvzLF/ma1eO86n/bkumIA==} + engines: {node: '>=18'} + + '@google-cloud/paginator@6.0.0': + resolution: {integrity: sha512-g5nmMnzC+94kBxOKkLGpK1ikvolTFCC3s2qtE4F+1EuArcJ7HHC23RDQVt3Ra3CqpUYZ+oXNKZ8n5Cn5yug8DA==} + engines: {node: '>=18'} + + '@google-cloud/precise-date@5.0.0': + resolution: {integrity: sha512-9h0Gvw92EvPdE8AK8AgZPbMnH5ftDyPtKm7/KUfcJVaPEPjwGDsJd1QV0H8esBDV4II41R/2lDWH1epBqIoKUw==} + engines: {node: '>=18'} + + '@google-cloud/projectify@4.0.0': + resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} + engines: {node: '>=14.0.0'} + + '@google-cloud/promisify@4.1.0': + resolution: {integrity: sha512-G/FQx5cE/+DqBbOpA5jKsegGwdPniU6PuIEMt+qxWgFxvxuFOzVmp6zYchtYuwAWV5/8Dgs0yAmjvNZv3uXLQg==} + engines: {node: '>=18'} + + '@google-cloud/promisify@5.0.0': + resolution: {integrity: sha512-N8qS6dlORGHwk7WjGXKOSsLjIjNINCPicsOX6gyyLiYk7mq3MtII96NZ9N2ahwA2vnkLmZODOIH9rlNniYWvCQ==} + engines: {node: '>=18'} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -662,6 +703,10 @@ packages: '@ioredis/commands@1.4.0': resolution: {integrity: sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -744,6 +789,10 @@ packages: '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.2.9': resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -912,6 +961,10 @@ packages: '@swc/helpers@0.5.18': resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + '@types/d3-array@3.2.2': resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} @@ -1139,6 +1192,14 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + ajv-draft-04@1.0.0: resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} peerDependencies: @@ -1186,6 +1247,14 @@ packages: array-iterate@2.0.1: resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + + arrify@3.0.0: + resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} + engines: {node: '>=12'} + astro-eslint-parser@1.2.2: resolution: {integrity: sha512-JepyLROIad6f44uyqMF6HKE2QbunNzp3mYKRcPoDGt0QkxXmH222FAFC64WTyQu2Kg8NNEXHTN/sWuUId9sSxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1221,6 +1290,12 @@ packages: resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} hasBin: true + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -1241,6 +1316,9 @@ packages: brotli@1.3.3: resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -1498,6 +1576,10 @@ packages: resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} engines: {node: '>=12'} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + db0@0.3.4: resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} peerDependencies: @@ -1594,6 +1676,15 @@ packages: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + emmet@2.4.11: resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} @@ -1603,6 +1694,12 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1730,6 +1827,10 @@ packages: picomatch: optional: true + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -1759,11 +1860,27 @@ packages: fontkit@2.0.4: resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + gaxios@7.1.3: + resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} + engines: {node: '>=18'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + engines: {node: '>=18'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -1786,6 +1903,11 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1794,6 +1916,18 @@ packages: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} + google-auth-library@10.5.0: + resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} + engines: {node: '>=18'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + + gtoken@8.0.0: + resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==} + engines: {node: '>=18'} + h3@1.15.4: resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} @@ -1831,6 +1965,9 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + html-escaper@3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} @@ -1840,6 +1977,18 @@ packages: http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -1863,6 +2012,9 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + internmap@2.0.3: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} @@ -1911,6 +2063,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -1919,6 +2074,9 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -1937,6 +2095,12 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2197,6 +2361,10 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -2243,9 +2411,18 @@ packages: nlcst-to-string@4.0.0: resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} @@ -2262,6 +2439,9 @@ packages: ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} @@ -2292,6 +2472,9 @@ packages: resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} @@ -2319,6 +2502,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + piccolore@0.1.3: resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} @@ -2398,6 +2585,10 @@ packages: resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -2483,10 +2674,18 @@ packages: retext@9.0.0: resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + retry-request@8.0.2: + resolution: {integrity: sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==} + engines: {node: '>=18'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} @@ -2504,6 +2703,9 @@ packages: s.color@0.0.15: resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -2542,6 +2744,10 @@ packages: shiki@3.21.0: resolution: {integrity: sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -2566,14 +2772,27 @@ packages: standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + stream-events@1.0.5: + resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -2589,6 +2808,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + stubs@3.0.0: + resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} + styled-jsx@5.1.6: resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} @@ -2618,6 +2840,10 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} + teeny-request@10.1.0: + resolution: {integrity: sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==} + engines: {node: '>=18'} + terser@5.44.1: resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} engines: {node: '>=10'} @@ -2971,6 +3197,10 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + which-pm-runs@1.1.0: resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} engines: {node: '>=4'} @@ -2992,10 +3222,17 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrap-ansi@9.0.2: resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} engines: {node: '>=18'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xxhash-wasm@1.1.0: resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} @@ -3397,6 +3634,47 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@google-cloud/bigquery@8.1.1': + dependencies: + '@google-cloud/common': 6.0.0 + '@google-cloud/paginator': 6.0.0 + '@google-cloud/precise-date': 5.0.0 + '@google-cloud/promisify': 5.0.0 + arrify: 3.0.0 + big.js: 6.2.2 + duplexify: 4.1.3 + extend: 3.0.2 + stream-events: 1.0.5 + teeny-request: 10.1.0 + transitivePeerDependencies: + - supports-color + + '@google-cloud/common@6.0.0': + dependencies: + '@google-cloud/projectify': 4.0.0 + '@google-cloud/promisify': 4.1.0 + arrify: 2.0.1 + duplexify: 4.1.3 + extend: 3.0.2 + google-auth-library: 10.5.0 + html-entities: 2.6.0 + retry-request: 8.0.2 + teeny-request: 10.1.0 + transitivePeerDependencies: + - supports-color + + '@google-cloud/paginator@6.0.0': + dependencies: + extend: 3.0.2 + + '@google-cloud/precise-date@5.0.0': {} + + '@google-cloud/projectify@4.0.0': {} + + '@google-cloud/promisify@4.1.0': {} + + '@google-cloud/promisify@5.0.0': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -3508,6 +3786,15 @@ snapshots: '@ioredis/commands@1.4.0': optional: true + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3571,6 +3858,9 @@ snapshots: '@oslojs/encoding@1.1.0': {} + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/core@0.2.9': {} '@rollup/pluginutils@5.3.0(rollup@4.54.0)': @@ -3719,6 +4009,8 @@ snapshots: dependencies: tslib: 2.8.1 + '@tootallnate/once@2.0.0': {} + '@types/d3-array@3.2.2': {} '@types/d3-axis@3.0.6': @@ -4023,6 +4315,14 @@ snapshots: acorn@8.15.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + ajv-draft-04@1.0.0(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -4066,6 +4366,10 @@ snapshots: array-iterate@2.0.1: {} + arrify@2.0.1: {} + + arrify@3.0.0: {} + astro-eslint-parser@1.2.2: dependencies: '@astrojs/compiler': 2.13.0 @@ -4202,6 +4506,10 @@ snapshots: baseline-browser-mapping@2.9.11: {} + big.js@6.2.2: {} + + bignumber.js@9.3.1: {} + boolbase@1.0.0: {} boxen@8.0.1: @@ -4232,6 +4540,8 @@ snapshots: dependencies: base64-js: 1.5.1 + buffer-equal-constant-time@1.0.1: {} + buffer-from@1.1.2: optional: true @@ -4490,6 +4800,8 @@ snapshots: d3-transition: 3.0.1(d3-selection@3.0.0) d3-zoom: 3.0.0 + data-uri-to-buffer@4.0.1: {} + db0@0.3.4: optional: true @@ -4555,6 +4867,19 @@ snapshots: dset@3.1.4: {} + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + eastasianwidth@0.2.0: {} + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + emmet@2.4.11: dependencies: '@emmetio/abbreviation': 2.3.3 @@ -4564,6 +4889,12 @@ snapshots: emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + entities@4.5.0: {} entities@6.0.1: {} @@ -4756,6 +5087,11 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -4795,9 +5131,35 @@ snapshots: unicode-properties: 1.4.1 unicode-trie: 2.0.0 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + fsevents@2.3.3: optional: true + gaxios@7.1.3: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + node-fetch: 3.3.2 + rimraf: 5.0.10 + transitivePeerDependencies: + - supports-color + + gcp-metadata@8.1.2: + dependencies: + gaxios: 7.1.3 + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + get-caller-file@2.0.5: {} get-east-asian-width@1.4.0: {} @@ -4817,10 +5179,40 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + globals@14.0.0: {} globals@16.5.0: {} + google-auth-library@10.5.0: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.3 + gcp-metadata: 8.1.2 + google-logging-utils: 1.1.3 + gtoken: 8.0.0 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-logging-utils@1.1.3: {} + + gtoken@8.0.0: + dependencies: + gaxios: 7.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + h3@1.15.4: dependencies: cookie-es: 1.2.2 @@ -4922,12 +5314,36 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 + html-entities@2.6.0: {} + html-escaper@3.0.3: {} html-void-elements@3.0.0: {} http-cache-semantics@4.2.0: {} + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -4945,6 +5361,8 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: {} + internmap@2.0.3: {} ioredis@5.8.2: @@ -4988,6 +5406,12 @@ snapshots: isexe@2.0.0: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jiti@2.6.1: optional: true @@ -4995,6 +5419,10 @@ snapshots: dependencies: argparse: 2.0.1 + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} @@ -5007,6 +5435,17 @@ snapshots: jsonc-parser@3.3.1: {} + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -5430,6 +5869,8 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minipass@7.1.3: {} + mrmime@2.0.1: {} ms@2.1.3: {} @@ -5470,8 +5911,16 @@ snapshots: dependencies: '@types/nlcst': 2.0.3 + node-domexception@1.0.0: {} + node-fetch-native@1.6.7: {} + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-mock-http@1.0.4: {} normalize-path@3.0.0: {} @@ -5488,6 +5937,10 @@ snapshots: ohash@2.0.11: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 + oniguruma-parser@0.12.1: {} oniguruma-to-es@4.3.4: @@ -5524,6 +5977,8 @@ snapshots: p-timeout@6.1.4: {} + package-json-from-dist@1.0.1: {} + package-manager-detector@1.6.0: {} pako@0.2.9: {} @@ -5551,6 +6006,11 @@ snapshots: path-key@3.1.1: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + piccolore@0.1.3: {} picocolors@1.1.1: {} @@ -5616,6 +6076,12 @@ snapshots: react@19.2.3: {} + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + readdirp@4.1.2: {} redis-errors@1.2.0: @@ -5742,8 +6208,19 @@ snapshots: retext-stringify: 4.0.0 unified: 11.0.5 + retry-request@8.0.2: + dependencies: + extend: 3.0.2 + teeny-request: 10.1.0 + transitivePeerDependencies: + - supports-color + reusify@1.1.0: {} + rimraf@5.0.10: + dependencies: + glob: 10.5.0 + robust-predicates@3.0.2: {} rollup@4.54.0: @@ -5782,6 +6259,8 @@ snapshots: s.color@0.0.15: {} + safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} sass-formatter@0.7.9: @@ -5856,6 +6335,8 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 + signal-exit@4.1.0: {} + sisteransi@1.0.5: {} smol-toml@1.6.0: {} @@ -5876,18 +6357,34 @@ snapshots: standard-as-callback@2.1.0: optional: true + stream-events@1.0.5: + dependencies: + stubs: 3.0.0 + + stream-shift@1.0.3: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + string-width@7.2.0: dependencies: emoji-regex: 10.6.0 get-east-asian-width: 1.4.0 strip-ansi: 7.1.2 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 @@ -5903,6 +6400,8 @@ snapshots: strip-json-comments@3.1.1: {} + stubs@3.0.0: {} + styled-jsx@5.1.6(react@19.2.3): dependencies: client-only: 0.0.1 @@ -5930,6 +6429,15 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 + teeny-request@10.1.0: + dependencies: + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + node-fetch: 3.3.2 + stream-events: 1.0.5 + transitivePeerDependencies: + - supports-color + terser@5.44.1: dependencies: '@jridgewell/source-map': 0.3.11 @@ -6233,6 +6741,8 @@ snapshots: web-namespaces@2.0.1: {} + web-streams-polyfill@3.3.3: {} + which-pm-runs@1.1.0: {} which@2.0.2: @@ -6251,12 +6761,20 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.3 string-width: 7.2.0 strip-ansi: 7.1.2 + wrappy@1.0.2: {} + xxhash-wasm@1.1.0: {} y18n@5.0.8: {}