From 38ea8983d47e92c4bbdc3ccd41acec97797bfdb0 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Wed, 24 May 2023 13:29:18 -0700 Subject: [PATCH] Split the web player into it's own repo. https://github.com/kixelated/moq-js --- .github/workflows/{server.yml => check.yml} | 6 +- .github/workflows/web.yml | 29 - .gitignore | 4 +- server/.rustfmt.toml => .rustfmt.toml | 0 server/Cargo.lock => Cargo.lock | 0 server/Cargo.toml => Cargo.toml | 0 README.md | 65 +- cert/.dockerignore | 3 - cert/Dockerfile | 22 - cert/generate | 3 +- docker-compose.yml | 45 - media/.dockerignore | 1 - media/.gitignore | 2 - media/Dockerfile | 25 - media/{fragment => generate} | 0 server/.dockerignore | 1 - server/.gitignore | 1 - server/Dockerfile | 42 - src/.DS_Store | Bin 0 -> 6148 bytes {server/src => src}/lib.rs | 0 {server/src => src}/main.rs | 0 {server/src => src}/media/mod.rs | 0 {server/src => src}/media/source.rs | 0 {server/src => src}/session/message.rs | 0 {server/src => src}/session/mod.rs | 0 {server/src => src}/transport/app.rs | 0 {server/src => src}/transport/connection.rs | 0 {server/src => src}/transport/mod.rs | 0 {server/src => src}/transport/server.rs | 0 {server/src => src}/transport/streams.rs | 0 web/.dockerignore | 4 - web/.eslintrc.cjs | 23 - web/.gitignore | 3 - web/.prettierignore | 2 - web/.prettierrc.yaml | 4 - web/.proxyrc.js | 7 - web/Dockerfile | 26 - web/fingerprint.hex | 1 - web/package.json | 28 - web/src/broadcaster/encoder.ts | 104 - web/src/broadcaster/index.ts | 5 - web/src/index.css | 75 - web/src/index.html | 33 - web/src/index.ts | 42 - web/src/mp4/index.ts | 14 - web/src/mp4/mp4box.d.ts | 231 -- web/src/player/audio.ts | 79 - web/src/player/decoder.ts | 214 -- web/src/player/index.ts | 88 - web/src/player/message.ts | 21 - web/src/player/renderer.ts | 36 - web/src/player/ring.ts | 155 -- web/src/player/video.ts | 98 - web/src/player/worker.ts | 24 - web/src/player/worklet.ts | 53 - web/src/stream/index.ts | 2 - web/src/stream/reader.ts | 195 -- web/src/stream/writer.ts | 100 - web/src/transport/index.ts | 96 - web/src/transport/interface.ts | 14 - web/src/transport/message.ts | 7 - web/src/transport/webtransport.d.ts | 84 - web/src/util/deferred.ts | 20 - web/src/util/index.ts | 1 - web/tsconfig.json | 9 - web/yarn.lock | 2292 ------------------- 66 files changed, 33 insertions(+), 4406 deletions(-) rename .github/workflows/{server.yml => check.yml} (85%) delete mode 100644 .github/workflows/web.yml rename server/.rustfmt.toml => .rustfmt.toml (100%) rename server/Cargo.lock => Cargo.lock (100%) rename server/Cargo.toml => Cargo.toml (100%) delete mode 100644 cert/.dockerignore delete mode 100644 cert/Dockerfile delete mode 100644 docker-compose.yml delete mode 100644 media/.dockerignore delete mode 100644 media/Dockerfile rename media/{fragment => generate} (100%) delete mode 100644 server/.dockerignore delete mode 100644 server/.gitignore delete mode 100644 server/Dockerfile create mode 100644 src/.DS_Store rename {server/src => src}/lib.rs (100%) rename {server/src => src}/main.rs (100%) rename {server/src => src}/media/mod.rs (100%) rename {server/src => src}/media/source.rs (100%) rename {server/src => src}/session/message.rs (100%) rename {server/src => src}/session/mod.rs (100%) rename {server/src => src}/transport/app.rs (100%) rename {server/src => src}/transport/connection.rs (100%) rename {server/src => src}/transport/mod.rs (100%) rename {server/src => src}/transport/server.rs (100%) rename {server/src => src}/transport/streams.rs (100%) delete mode 100644 web/.dockerignore delete mode 100644 web/.eslintrc.cjs delete mode 100644 web/.gitignore delete mode 100644 web/.prettierignore delete mode 100644 web/.prettierrc.yaml delete mode 100644 web/.proxyrc.js delete mode 100644 web/Dockerfile delete mode 120000 web/fingerprint.hex delete mode 100644 web/package.json delete mode 100644 web/src/broadcaster/encoder.ts delete mode 100644 web/src/broadcaster/index.ts delete mode 100644 web/src/index.css delete mode 100644 web/src/index.html delete mode 100644 web/src/index.ts delete mode 100644 web/src/mp4/index.ts delete mode 100644 web/src/mp4/mp4box.d.ts delete mode 100644 web/src/player/audio.ts delete mode 100644 web/src/player/decoder.ts delete mode 100644 web/src/player/index.ts delete mode 100644 web/src/player/message.ts delete mode 100644 web/src/player/renderer.ts delete mode 100644 web/src/player/ring.ts delete mode 100644 web/src/player/video.ts delete mode 100644 web/src/player/worker.ts delete mode 100644 web/src/player/worklet.ts delete mode 100644 web/src/stream/index.ts delete mode 100644 web/src/stream/reader.ts delete mode 100644 web/src/stream/writer.ts delete mode 100644 web/src/transport/index.ts delete mode 100644 web/src/transport/interface.ts delete mode 100644 web/src/transport/message.ts delete mode 100644 web/src/transport/webtransport.d.ts delete mode 100644 web/src/util/deferred.ts delete mode 100644 web/src/util/index.ts delete mode 100644 web/tsconfig.json delete mode 100644 web/yarn.lock diff --git a/.github/workflows/server.yml b/.github/workflows/check.yml similarity index 85% rename from .github/workflows/server.yml rename to .github/workflows/check.yml index fe72953..b39df93 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/check.yml @@ -1,4 +1,4 @@ -name: server +name: moq.rs on: pull_request: @@ -11,10 +11,6 @@ jobs: check: runs-on: ubuntu-latest - defaults: - run: - working-directory: ./server - steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml deleted file mode 100644 index 40fd3b5..0000000 --- a/.github/workflows/web.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: web - -on: - pull_request: - branches: [ "main" ] - -jobs: - check: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ./web - - steps: - - uses: actions/checkout@v3 - - - name: install - run: yarn install - - - name: cert - working-directory: cert - run: ./generate - - - name: build - run: yarn build - - - name: lint - run: yarn lint diff --git a/.gitignore b/.gitignore index 2c9e147..e7199cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -*.mp4 -logs/ .DS_Store +target/ +logs/ diff --git a/server/.rustfmt.toml b/.rustfmt.toml similarity index 100% rename from server/.rustfmt.toml rename to .rustfmt.toml diff --git a/server/Cargo.lock b/Cargo.lock similarity index 100% rename from server/Cargo.lock rename to Cargo.lock diff --git a/server/Cargo.toml b/Cargo.toml similarity index 100% rename from server/Cargo.toml rename to Cargo.toml diff --git a/README.md b/README.md index 43e6dc6..c9cc1c5 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,55 @@ -# Warp -Live media delivery protocol utilizing QUIC streams. See the [Warp draft](https://datatracker.ietf.org/doc/draft-lcurley-warp/). +# Media over QUIC -Warp works by delivering media over independent QUIC stream. These streams are assigned a priority such that old video will arrive last and can be dropped. This avoids buffering in many cases, offering the viewer a potentially better experience. +Media over QUIC (MoQ) is a live media delivery protocol utilizing QUIC streams. +See the [Warp draft](https://datatracker.ietf.org/doc/draft-lcurley-warp/). -This demo requires WebTransport and WebCodecs, which currently (May 2023) only works on Chrome. - -# Development -## Easy Mode -Requires Docker *only*. - -``` -docker-compose up --build -``` - -Then open [https://localhost:4444/](https://localhost:4444) in a browser. You'll have to click past the TLS error, but that's the price you pay for being lazy. Follow the more in-depth instructions if you want a better development experience. +This repository is a Rust server that supports both contribution (ingest) and distribution (playback). +It requires a client, such as [moq-js](https://github.com/kixelated/moq-js). ## Requirements -* Go -* Rust -* ffmpeg -* openssl -* Chrome + +- _Chrome_: currently (May 2023) the only browser to support both WebTransport and WebCodecs. +- _yarn_: required to install dependencies. + +## Requirements + +- _rust_: duh +- _ffmpeg_: (optional) used to generate fragmented media +- _go_: (optional) used to generate self-signed certificates +- _openssl_: (options) ...also used to generate self-signed certificates ## Media + This demo simulates a live stream by reading a file from disk and sleeping based on media timestamps. Obviously you should hook this up to a real live stream to do anything useful. -Download your favorite media file and convert it to fragmented MP4: +Download your favorite media file and convert it to fragmented MP4, by default `media/fragmented.mp4`: + ``` wget http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 -O media/source.mp4 -./media/fragment +./media/generate ``` ## Certificates + Unfortunately, QUIC mandates TLS and makes local development difficult. If you have a valid certificate you can use it instead of self-signing. Otherwise, we use [mkcert](https://github.com/FiloSottile/mkcert) to install a self-signed CA: + ``` -./generate/cert +./cert/generate ``` -With no arguments, the server will generate self-signed cert using this root CA. This certificate is only valid for *2 weeks* due to how WebTransport performs certificate fingerprinting. +With no arguments, the server will generate self-signed cert using this root CA. +This certificate is only valid for _2 weeks_ due to how WebTransport performs certificate fingerprinting. ## Server -The Warp server supports WebTransport, pushing media over streams once a connection has been established. A more refined implementation would load content based on the WebTransport URL or some other messaging scheme. + +`The Warp server supports WebTransport, pushing media over streams once a connection has been established. ``` -cd server cargo run ``` -This listens for WebTransport connections (not HTTP) on `https://localhost:4443` by default. - -## Web -The web assets need to be hosted with a HTTPS server. - -``` -cd web -yarn install -yarn serve -``` - -These can be accessed on `https://localhost:4444` by default. \ No newline at end of file +This listens for WebTransport connections on `https://localhost:4443` by default. +Use a [MoQ client](https://github.com/kixelated/moq-js) to connect to the server. diff --git a/cert/.dockerignore b/cert/.dockerignore deleted file mode 100644 index 9879661..0000000 --- a/cert/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -*.crt -*.key -*.hex \ No newline at end of file diff --git a/cert/Dockerfile b/cert/Dockerfile deleted file mode 100644 index df5be10..0000000 --- a/cert/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -# Use ubuntu because it's ez -FROM ubuntu:latest - -WORKDIR /build - -# Use openssl and golang to generate certificates -RUN apt-get update && \ - apt-get install -y ca-certificates openssl golang xxd - - -# Download the go modules -COPY go.mod go.sum ./ -RUN go mod download - -# Copy over the remaining files. -COPY . . - -# Save the certificates to a volume -VOLUME /cert - -# TODO support an output directory -CMD ./generate && cp localhost.* /cert \ No newline at end of file diff --git a/cert/generate b/cert/generate index 63bb335..5a6bc35 100755 --- a/cert/generate +++ b/cert/generate @@ -17,4 +17,5 @@ go run filippo.io/mkcert -ecdsa -install go run filippo.io/mkcert -ecdsa -days 10 -cert-file "$CRT" -key-file "$KEY" localhost 127.0.0.1 ::1 # Compute the sha256 fingerprint of the certificate for WebTransport -openssl x509 -in "$CRT" -outform der | openssl dgst -sha256 -binary | xxd -p -c 256 > localhost.hex \ No newline at end of file +# TODO remove openssl as a requirement +openssl x509 -in "$CRT" -outform der | openssl dgst -sha256 -binary | xxd -p -c 256 > localhost.hex diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index c2ad05d..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: '3' - -services: - # Generate certificates only valid for 14 days. - cert: - build: ./cert - volumes: - - cert:/cert - - # Generate a fragmented MP4 file for testing. - media: - build: ./media - volumes: - - media:/media - - # Serve the web code once we have certificates. - web: - build: ./web - ports: - - "4444:4444" - volumes: - - cert:/cert - depends_on: - cert: - condition: service_completed_successfully - - # Run the server once we have certificates and media. - server: - build: ./server - environment: - - RUST_LOG=debug - ports: - - "4443:4443/udp" - volumes: - - cert:/cert - - media:/media - depends_on: - cert: - condition: service_completed_successfully - media: - condition: service_completed_successfully - -volumes: - cert: - media: diff --git a/media/.dockerignore b/media/.dockerignore deleted file mode 100644 index fa48555..0000000 --- a/media/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -fragmented.mp4 diff --git a/media/.gitignore b/media/.gitignore index b8cea22..2641667 100644 --- a/media/.gitignore +++ b/media/.gitignore @@ -1,3 +1 @@ *.mp4 -*.mpd -*.m4s diff --git a/media/Dockerfile b/media/Dockerfile deleted file mode 100644 index 372db90..0000000 --- a/media/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Create a build image -FROM ubuntu:latest - -# Create the working directory. -WORKDIR /build - -# Install necessary packages -RUN apt-get update && \ - apt-get install -y \ - ca-certificates \ - wget \ - ffmpeg - -# Download a file from the internet, in this case my boy big buck bunny -RUN wget http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 -O source.mp4 - -# Copy an run a script to create a fragmented mp4 (more overhead, easier to split) -COPY fragment . - -# Create a media volume -VOLUME /media - -# Fragment the media -# TODO support an output directory -CMD ./fragment && cp fragmented.mp4 /media \ No newline at end of file diff --git a/media/fragment b/media/generate similarity index 100% rename from media/fragment rename to media/generate diff --git a/server/.dockerignore b/server/.dockerignore deleted file mode 100644 index eb5a316..0000000 --- a/server/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index eb5a316..0000000 --- a/server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/server/Dockerfile b/server/Dockerfile deleted file mode 100644 index b903dc9..0000000 --- a/server/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -# Use the official Rust image as the base image -FROM rust:latest as build - -# Quiche requires docker -RUN apt-get update && \ - apt-get install -y cmake - -# Set the build directory -WORKDIR /warp - -# Create an empty project -RUN cargo init --bin - -# Copy the Cargo.toml and Cargo.lock files to the container -COPY Cargo.toml Cargo.lock ./ - -# Build the empty project so we download/cache dependencies -RUN cargo build --release - -# Copy the entire project to the container -COPY . . - -# Build the project -RUN cargo build --release - -# Make a new image to run the binary -FROM ubuntu:latest - -# Use a volume to access certificates -VOLUME /cert - -# Use another volume to access the media -VOLUME /media - -# Expose port 4443 for the server -EXPOSE 4443/udp - -# Copy the built binary -COPY --from=build /warp/target/release/warp /bin - -# Set the startup command to run the binary -CMD warp --cert /cert/localhost.crt --key /cert/localhost.key --media /media/fragmented.mp4 \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5111b4f214ed3f24caee1b3757e393cfab637a8f GIT binary patch literal 6148 zcmeHKJ5Iwu5SFE0$hU|&~XbcLdTok zk>g*WKtc%3M7z(Po!K3~U3)S_WQOH^+E>I~YyV zBx~5J;%_p*d$&so-B3(3s_owiZ+mGpNuy{oPbbg@j}Py!SBG!sb&L2Li|np^LQdgM zd$hv(EBt1Z(xQ5XjxL)P8q)$1Wr%1=>uOAADPn4| zD#!KmT*TFCxryy-%W8c3V)21dQ3jNOA2WcQ%@XW;)Lt1-29$w<0scN%G{#Uc_vk(y z=v)Z^>_Y7X*IY}mj};6BbB`E-81D-7u0~1>Y@|XlZgtFW zojIA%qxQ;xGEik;$KUoj|6gpc|Eo@Vrwk|q|B3W#CsC_yn}2a!~*P literal 0 HcmV?d00001 diff --git a/server/src/lib.rs b/src/lib.rs similarity index 100% rename from server/src/lib.rs rename to src/lib.rs diff --git a/server/src/main.rs b/src/main.rs similarity index 100% rename from server/src/main.rs rename to src/main.rs diff --git a/server/src/media/mod.rs b/src/media/mod.rs similarity index 100% rename from server/src/media/mod.rs rename to src/media/mod.rs diff --git a/server/src/media/source.rs b/src/media/source.rs similarity index 100% rename from server/src/media/source.rs rename to src/media/source.rs diff --git a/server/src/session/message.rs b/src/session/message.rs similarity index 100% rename from server/src/session/message.rs rename to src/session/message.rs diff --git a/server/src/session/mod.rs b/src/session/mod.rs similarity index 100% rename from server/src/session/mod.rs rename to src/session/mod.rs diff --git a/server/src/transport/app.rs b/src/transport/app.rs similarity index 100% rename from server/src/transport/app.rs rename to src/transport/app.rs diff --git a/server/src/transport/connection.rs b/src/transport/connection.rs similarity index 100% rename from server/src/transport/connection.rs rename to src/transport/connection.rs diff --git a/server/src/transport/mod.rs b/src/transport/mod.rs similarity index 100% rename from server/src/transport/mod.rs rename to src/transport/mod.rs diff --git a/server/src/transport/server.rs b/src/transport/server.rs similarity index 100% rename from server/src/transport/server.rs rename to src/transport/server.rs diff --git a/server/src/transport/streams.rs b/src/transport/streams.rs similarity index 100% rename from server/src/transport/streams.rs rename to src/transport/streams.rs diff --git a/web/.dockerignore b/web/.dockerignore deleted file mode 100644 index 93e58d7..0000000 --- a/web/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -dist -.parcel-cache -node_modules -fingerprint.hex \ No newline at end of file diff --git a/web/.eslintrc.cjs b/web/.eslintrc.cjs deleted file mode 100644 index b76eb47..0000000 --- a/web/.eslintrc.cjs +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-env node */ -module.exports = { - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], - parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint", "prettier"], - root: true, - ignorePatterns: ["dist", "node_modules"], - rules: { - "@typescript-eslint/ban-ts-comment": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-explicit-any": "off", - "no-unused-vars": "off", // note you must disable the base rule as it can report incorrect errors - "@typescript-eslint/no-unused-vars": [ - "warn", // or "error" - { - argsIgnorePattern: "^_", - varsIgnorePattern: "^_", - caughtErrorsIgnorePattern: "^_", - }, - ], - "prettier/prettier": 2, // Means error - }, -} diff --git a/web/.gitignore b/web/.gitignore deleted file mode 100644 index 2610592..0000000 --- a/web/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -.parcel-cache -dist \ No newline at end of file diff --git a/web/.prettierignore b/web/.prettierignore deleted file mode 100644 index de4d1f0..0000000 --- a/web/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -node_modules diff --git a/web/.prettierrc.yaml b/web/.prettierrc.yaml deleted file mode 100644 index 708c01a..0000000 --- a/web/.prettierrc.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# note: root .editorconfig is used - -# Don't insert semi-colons unless needed -semi: false diff --git a/web/.proxyrc.js b/web/.proxyrc.js deleted file mode 100644 index 3554d52..0000000 --- a/web/.proxyrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = function (app) { - app.use((req, res, next) => { - res.setHeader("Cross-Origin-Opener-Policy", "same-origin") - res.setHeader("Cross-Origin-Embedder-Policy", "require-corp") - next() - }) -} diff --git a/web/Dockerfile b/web/Dockerfile deleted file mode 100644 index 25c9320..0000000 --- a/web/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# Use the official Node.js image as the build image -FROM node:latest - -# Set the build directory -WORKDIR /build - -# Copy the package.json and yarn.lock files to the container -COPY package*.json yarn.lock ./ - -# Install dependencies -RUN yarn install - -# Copy the entire project to the container -COPY . . - -# Expose port 4444 for serving the project -EXPOSE 4444 - -# Copy the certificate hash before running -VOLUME /cert - -# Make a symlink to the certificate fingerprint -RUN ln -s /cert/localhost.hex fingerprint.hex - -# Copy the certificate fingerprint and start the web server -CMD yarn parcel serve --https --cert /cert/localhost.crt --key /cert/localhost.key --port 4444 \ No newline at end of file diff --git a/web/fingerprint.hex b/web/fingerprint.hex deleted file mode 120000 index 387f554..0000000 --- a/web/fingerprint.hex +++ /dev/null @@ -1 +0,0 @@ -../cert/localhost.hex \ No newline at end of file diff --git a/web/package.json b/web/package.json deleted file mode 100644 index 0121fcd..0000000 --- a/web/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "license": "Apache-2.0", - "source": "src/index.html", - "scripts": { - "serve": "parcel serve --https --cert ../cert/localhost.crt --key ../cert/localhost.key --port 4444 --open", - "build": "parcel build", - "check": "tsc --noEmit", - "lint": "eslint .", - "fmt": "prettier --write ." - }, - "devDependencies": { - "@parcel/transformer-inline-string": "2.8.3", - "@parcel/validator-typescript": "^2.6.0", - "@types/audioworklet": "^0.0.41", - "@types/dom-webcodecs": "^0.1.6", - "@typescript-eslint/eslint-plugin": "^5.59.7", - "@typescript-eslint/parser": "^5.59.7", - "eslint": "^8.41.0", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", - "parcel": "^2.8.0", - "prettier": "^2.8.8", - "typescript": "^5.0.4" - }, - "dependencies": { - "mp4box": "^0.5.2" - } -} diff --git a/web/src/broadcaster/encoder.ts b/web/src/broadcaster/encoder.ts deleted file mode 100644 index 4ba7ff7..0000000 --- a/web/src/broadcaster/encoder.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as MP4 from "../mp4" - -export class Encoder { - container: MP4.ISOFile - audio: AudioEncoder - video: VideoEncoder - - constructor() { - this.container = new MP4.ISOFile() - - this.audio = new AudioEncoder({ - output: this.onAudio.bind(this), - error: console.warn, - }) - - this.video = new VideoEncoder({ - output: this.onVideo.bind(this), - error: console.warn, - }) - - this.container.init() - - this.audio.configure({ - codec: "mp4a.40.2", - numberOfChannels: 2, - sampleRate: 44100, - - // TODO bitrate - }) - - this.video.configure({ - codec: "avc1.42002A", // TODO h.264 baseline - avc: { format: "avc" }, // or annexb - width: 1280, - height: 720, - - // TODO bitrate - // TODO bitrateMode - // TODO framerate - // TODO latencyMode - }) - } - - onAudio(frame: EncodedAudioChunk, metadata: EncodedAudioChunkMetadata) { - const config = metadata.decoderConfig! - const track_id = 1 - - if (!this.container.getTrackById(track_id)) { - this.container.addTrack({ - id: track_id, - type: "mp4a", // TODO wrong - timescale: 1000, // TODO verify - - channel_count: config.numberOfChannels, - samplerate: config.sampleRate, - - description: config.description, // TODO verify - // TODO description_boxes?: Box[]; - }) - } - - const buffer = new Uint8Array(frame.byteLength) - frame.copyTo(buffer) - - // TODO cts? - const sample = this.container.addSample(track_id, buffer, { - is_sync: frame.type == "key", - duration: frame.duration!, - dts: frame.timestamp, - }) - - const _stream = this.container.createSingleSampleMoof(sample) - } - - onVideo(frame: EncodedVideoChunk, metadata?: EncodedVideoChunkMetadata) { - const config = metadata!.decoderConfig! - const track_id = 2 - - if (!this.container.getTrackById(track_id)) { - this.container.addTrack({ - id: 2, - type: "avc1", - width: config.codedWidth, - height: config.codedHeight, - timescale: 1000, // TODO verify - - description: config.description, // TODO verify - // TODO description_boxes?: Box[]; - }) - } - - const buffer = new Uint8Array(frame.byteLength) - frame.copyTo(buffer) - - // TODO cts? - const sample = this.container.addSample(track_id, buffer, { - is_sync: frame.type == "key", - duration: frame.duration!, - dts: frame.timestamp, - }) - - const _stream = this.container.createSingleSampleMoof(sample) - } -} diff --git a/web/src/broadcaster/index.ts b/web/src/broadcaster/index.ts deleted file mode 100644 index fa40b01..0000000 --- a/web/src/broadcaster/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default class Broadcaster { - constructor() { - // TODO - } -} diff --git a/web/src/index.css b/web/src/index.css deleted file mode 100644 index c3d1639..0000000 --- a/web/src/index.css +++ /dev/null @@ -1,75 +0,0 @@ -html, -body, -#player { - width: 100%; -} - -body { - background: #000000; - color: #ffffff; - padding: 0; - margin: 0; - display: flex; - justify-content: center; - font-family: sans-serif; -} - -#screen { - position: relative; -} - -#screen #play { - position: absolute; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.5); - - display: flex; - justify-content: center; - align-items: center; - - z-index: 1; -} - -#controls { - display: flex; - flex-wrap: wrap; - padding: 8px 16px; -} - -#controls > * { - margin-right: 8px; -} - -#controls label { - margin-right: 8px; -} - -#stats { - display: grid; - grid-template-columns: auto 1fr; -} - -#stats label { - padding: 0 1rem; -} - -.buffer { - position: relative; - width: 100%; -} - -.buffer .fill { - position: absolute; - transition-duration: 0.1s; - transition-property: left, right, background-color; - background-color: RebeccaPurple; - height: 100%; - text-align: right; - padding-right: 0.5rem; - overflow: hidden; -} - -.buffer .fill.net { - background-color: Purple; -} diff --git a/web/src/index.html b/web/src/index.html deleted file mode 100644 index 4171b09..0000000 --- a/web/src/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - WARP - - - - - -
-
-
click to play
- -
- -
- - -
- -
- -
- - -
-
-
- - - - diff --git a/web/src/index.ts b/web/src/index.ts deleted file mode 100644 index 5c04336..0000000 --- a/web/src/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -import Player from "./player" -import Transport from "./transport" - -// @ts-ignore embed the certificate fingerprint using bundler -import fingerprintHex from "bundle-text:../fingerprint.hex" - -// Convert the hex to binary. -const fingerprint = [] -for (let c = 0; c < fingerprintHex.length - 1; c += 2) { - fingerprint.push(parseInt(fingerprintHex.substring(c, c + 2), 16)) -} - -const params = new URLSearchParams(window.location.search) - -const url = params.get("url") || "https://localhost:4443/watch" -const canvas = document.querySelector("canvas#video")! - -const transport = new Transport({ - url: url, - fingerprint: { - // TODO remove when Chrome accepts the system CA - algorithm: "sha-256", - value: new Uint8Array(fingerprint), - }, -}) - -const player = new Player({ - transport, - canvas: canvas.transferControlToOffscreen(), -}) - -const play = document.querySelector("#screen #play")! - -const playFunc = (e: Event) => { - player.play() - e.preventDefault() - - play.removeEventListener("click", playFunc) - play.style.display = "none" -} - -play.addEventListener("click", playFunc) diff --git a/web/src/mp4/index.ts b/web/src/mp4/index.ts deleted file mode 100644 index f520a0e..0000000 --- a/web/src/mp4/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Rename some stuff so it's on brand. -export { - createFile as New, - MP4File as File, - MP4ArrayBuffer as ArrayBuffer, - MP4Info as Info, - MP4Track as Track, - MP4AudioTrack as AudioTrack, - MP4VideoTrack as VideoTrack, - DataStream as Stream, - Box, - ISOFile, - Sample, -} from "mp4box" diff --git a/web/src/mp4/mp4box.d.ts b/web/src/mp4/mp4box.d.ts deleted file mode 100644 index 607e55f..0000000 --- a/web/src/mp4/mp4box.d.ts +++ /dev/null @@ -1,231 +0,0 @@ -// https://github.com/gpac/mp4box.js/issues/233 - -declare module "mp4box" { - export interface MP4MediaTrack { - id: number - created: Date - modified: Date - movie_duration: number - layer: number - alternate_group: number - volume: number - track_width: number - track_height: number - timescale: number - duration: number - bitrate: number - codec: string - language: string - nb_samples: number - } - - export interface MP4VideoData { - width: number - height: number - } - - export interface MP4VideoTrack extends MP4MediaTrack { - video: MP4VideoData - } - - export interface MP4AudioData { - sample_rate: number - channel_count: number - sample_size: number - } - - export interface MP4AudioTrack extends MP4MediaTrack { - audio: MP4AudioData - } - - export type MP4Track = MP4VideoTrack | MP4AudioTrack - - export interface MP4Info { - duration: number - timescale: number - fragment_duration: number - isFragmented: boolean - isProgressive: boolean - hasIOD: boolean - brands: string[] - created: Date - modified: Date - tracks: MP4Track[] - mime: string - audioTracks: MP4AudioTrack[] - videoTracks: MP4VideoTrack[] - } - - export type MP4ArrayBuffer = ArrayBuffer & { fileStart: number } - - export interface MP4File { - onMoovStart?: () => void - onReady?: (info: MP4Info) => void - onError?: (e: string) => void - onSamples?: (id: number, user: any, samples: Sample[]) => void - - appendBuffer(data: MP4ArrayBuffer): number - start(): void - stop(): void - flush(): void - - setExtractionOptions(id: number, user: any, options: ExtractionOptions): void - } - - export function createFile(): MP4File - - export interface Sample { - number: number - track_id: number - timescale: number - description_index: number - description: any - data: ArrayBuffer - size: number - alreadyRead?: number - duration: number - cts: number - dts: number - is_sync: boolean - is_leading: number - depends_on: number - is_depended_on: number - has_redundancy: number - degration_priority: number - offset: number - subsamples: any - } - - export interface ExtractionOptions { - nbSamples: number - } - - const BIG_ENDIAN: boolean - const LITTLE_ENDIAN: boolean - - export class DataStream { - constructor(buffer?: ArrayBuffer, byteOffset?: number, littleEndian?: boolean) - getPosition(): number - - get byteLength(): number - get buffer(): ArrayBuffer - set buffer(v: ArrayBuffer) - get byteOffset(): number - set byteOffset(v: number) - get dataView(): DataView - set dataView(v: DataView) - - seek(pos: number): void - isEof(): boolean - - mapUint8Array(length: number): Uint8Array - readInt32Array(length: number, littleEndian: boolean): Int32Array - readInt16Array(length: number, littleEndian: boolean): Int16Array - readInt8Array(length: number): Int8Array - readUint32Array(length: number, littleEndian: boolean): Uint32Array - readUint16Array(length: number, littleEndian: boolean): Uint16Array - readUint8Array(length: number): Uint8Array - readFloat64Array(length: number, littleEndian: boolean): Float64Array - readFloat32Array(length: number, littleEndian: boolean): Float32Array - - readInt32(littleEndian: boolean): number - readInt16(littleEndian: boolean): number - readInt8(): number - readUint32(littleEndian: boolean): number - readUint16(littleEndian: boolean): number - readUint8(): number - readFloat32(littleEndian: boolean): number - readFloat64(littleEndian: boolean): number - - endianness: boolean - - memcpy( - dst: ArrayBufferLike, - dstOffset: number, - src: ArrayBufferLike, - srcOffset: number, - byteLength: number - ): void - - // TODO I got bored porting the remaining functions - } - - export class Box { - write(stream: DataStream): void - } - - export interface TrackOptions { - id?: number - type?: string - width?: number - height?: number - duration?: number - layer?: number - timescale?: number - media_duration?: number - language?: string - hdlr?: string - - // video - avcDecoderConfigRecord?: any - - // audio - balance?: number - channel_count?: number - samplesize?: number - samplerate?: number - - //captions - namespace?: string - schema_location?: string - auxiliary_mime_types?: string - - description?: any - description_boxes?: Box[] - - default_sample_description_index_id?: number - default_sample_duration?: number - default_sample_size?: number - default_sample_flags?: number - } - - export interface FileOptions { - brands?: string[] - timescale?: number - rate?: number - duration?: number - width?: number - } - - export interface SampleOptions { - sample_description_index?: number - duration?: number - cts?: number - dts?: number - is_sync?: boolean - is_leading?: number - depends_on?: number - is_depended_on?: number - has_redundancy?: number - degradation_priority?: number - subsamples?: any - } - - // TODO add the remaining functions - // TODO move to another module - export class ISOFile { - constructor(stream?: DataStream) - - init(options?: FileOptions): ISOFile - addTrack(options?: TrackOptions): number - addSample(track: number, data: ArrayBuffer, options?: SampleOptions): Sample - - createSingleSampleMoof(sample: Sample): Box - - // helpers - getTrackById(id: number): Box | undefined - getTrexById(id: number): Box | undefined - } - - export {} -} diff --git a/web/src/player/audio.ts b/web/src/player/audio.ts deleted file mode 100644 index f989dff..0000000 --- a/web/src/player/audio.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as Message from "./message" -import { Ring } from "./ring" - -export default class Audio { - ring?: Ring - queue: Array - - render?: number // non-zero if requestAnimationFrame has been called - last?: number // the timestamp of the last rendered frame, in microseconds - - constructor(_config: Message.Config) { - this.queue = [] - } - - push(frame: AudioData) { - // Drop any old frames - if (this.last && frame.timestamp <= this.last) { - frame.close() - return - } - - // Insert the frame into the queue sorted by timestamp. - if (this.queue.length > 0 && this.queue[this.queue.length - 1].timestamp <= frame.timestamp) { - // Fast path because we normally append to the end. - this.queue.push(frame) - } else { - // Do a full binary search - let low = 0 - let high = this.queue.length - - while (low < high) { - const mid = (low + high) >>> 1 - if (this.queue[mid].timestamp < frame.timestamp) low = mid + 1 - else high = mid - } - - this.queue.splice(low, 0, frame) - } - - this.emit() - } - - emit() { - const ring = this.ring - if (!ring) { - return - } - - while (this.queue.length) { - const frame = this.queue[0] - if (ring.size() + frame.numberOfFrames > ring.capacity) { - // Buffer is full - break - } - - const size = ring.write(frame) - if (size < frame.numberOfFrames) { - throw new Error("audio buffer is full") - } - - this.last = frame.timestamp - - frame.close() - this.queue.shift() - } - } - - play(play: Message.Play) { - this.ring = new Ring(play.buffer) - - if (!this.render) { - const sampleRate = 44100 // TODO dynamic - - // Refresh every half buffer - const refresh = ((play.buffer.capacity / sampleRate) * 1000) / 2 - this.render = setInterval(this.emit.bind(this), refresh) - } - } -} diff --git a/web/src/player/decoder.ts b/web/src/player/decoder.ts deleted file mode 100644 index 889cfaa..0000000 --- a/web/src/player/decoder.ts +++ /dev/null @@ -1,214 +0,0 @@ -import * as Message from "./message" -import * as MP4 from "../mp4" -import * as Stream from "../stream" - -import Renderer from "./renderer" -import { Deferred } from "../util" - -export default class Decoder { - decoders: Map - renderer: Renderer - - init: Deferred - - constructor(renderer: Renderer) { - this.init = new Deferred() - this.decoders = new Map() - this.renderer = renderer - } - - async receiveInit(msg: Message.Init) { - const init = new Array() - let offset = 0 - - const stream = new Stream.Reader(msg.reader, msg.buffer) - for (;;) { - const data = await stream.read() - if (!data) break - - // Make a copy of the atom because mp4box only accepts an ArrayBuffer unfortunately - const box = new Uint8Array(data.byteLength) - box.set(data) - - // and for some reason we need to modify the underlying ArrayBuffer with fileStart - const buffer = box.buffer as MP4.ArrayBuffer - buffer.fileStart = offset - - // Add the box to our queue of chunks - init.push(buffer) - - offset += data.byteLength - } - - this.init.resolve(init) - } - - async receiveSegment(msg: Message.Segment) { - // Wait for the init segment to be fully received and parsed - const input = MP4.New() - - input.onSamples = this.onSamples.bind(this) - input.onReady = (info: MP4.Info) => { - // Extract all of the tracks, because we don't know if it's audio or video. - for (const track of info.tracks) { - input.setExtractionOptions(track.id, track, { nbSamples: 1 }) - } - - input.start() - } - - // MP4box requires us to parse the init segment for each segment unfortunately - // TODO If this sees production usage, I would recommend caching this somehow. - let offset = 0 - - const init = await this.init.promise - for (const raw of init) { - offset = input.appendBuffer(raw) - } - - const stream = new Stream.Reader(msg.reader, msg.buffer) - - // For whatever reason, mp4box doesn't work until you read an atom at a time. - while (!(await stream.done())) { - const raw = await stream.peek(4) - - // TODO this doesn't support when size = 0 (until EOF) or size = 1 (extended size) - const size = new DataView(raw.buffer, raw.byteOffset, raw.byteLength).getUint32(0) - const atom = await stream.bytes(size) - - // Make a copy of the atom because mp4box only accepts an ArrayBuffer unfortunately - const box = new Uint8Array(atom.byteLength) - box.set(atom) - - // and for some reason we need to modify the underlying ArrayBuffer with offset - const buffer = box.buffer as MP4.ArrayBuffer - buffer.fileStart = offset - - // Parse the data - offset = input.appendBuffer(buffer) - input.flush() - } - } - - onSamples(_track_id: number, track: MP4.Track, samples: MP4.Sample[]) { - if (!track.track_width) { - // TODO ignoring audio to debug - return - } - - let decoder - if (isVideoTrack(track)) { - // We need a sample to initalize the video decoder, because of mp4box limitations. - decoder = this.videoDecoder(track, samples[0]) - } else if (isAudioTrack(track)) { - decoder = this.audioDecoder(track) - } else { - throw new Error("unknown track type") - } - - for (const sample of samples) { - // Convert to microseconds - const timestamp = (1000 * 1000 * sample.dts) / sample.timescale - const duration = (1000 * 1000 * sample.duration) / sample.timescale - - if (!decoder) { - throw new Error("decoder not initialized") - } else if (isAudioDecoder(decoder)) { - decoder.decode( - new EncodedAudioChunk({ - type: sample.is_sync ? "key" : "delta", - data: sample.data, - duration: duration, - timestamp: timestamp, - }) - ) - } else if (isVideoDecoder(decoder)) { - decoder.decode( - new EncodedVideoChunk({ - type: sample.is_sync ? "key" : "delta", - data: sample.data, - duration: duration, - timestamp: timestamp, - }) - ) - } else { - throw new Error("unknown decoder type") - } - } - } - - audioDecoder(track: MP4.AudioTrack): AudioDecoder { - // Reuse the audio decoder when possible to avoid glitches. - // TODO detect when the codec changes and make a new decoder. - const decoder = this.decoders.get(track.id) - if (decoder && isAudioDecoder(decoder)) { - return decoder - } - - const audioDecoder = new AudioDecoder({ - output: this.renderer.push.bind(this.renderer), - error: console.error, - }) - - audioDecoder.configure({ - codec: track.codec, - numberOfChannels: track.audio.channel_count, - sampleRate: track.audio.sample_rate, - }) - - this.decoders.set(track.id, audioDecoder) - - return audioDecoder - } - - videoDecoder(track: MP4.VideoTrack, sample: MP4.Sample): VideoDecoder { - // Make a new video decoder for each keyframe. - if (!sample.is_sync) { - const decoder = this.decoders.get(track.id) - if (decoder && isVideoDecoder(decoder)) { - return decoder - } - } - - // Configure the decoder using the AVC box for H.264 - // TODO it should be easy to support other codecs, just need to know the right boxes. - const avcc = sample.description.avcC - if (!avcc) throw new Error("TODO only h264 is supported") - - const description = new MP4.Stream(new Uint8Array(avcc.size), 0, false) - avcc.write(description) - - const videoDecoder = new VideoDecoder({ - output: this.renderer.push.bind(this.renderer), - error: console.error, - }) - - videoDecoder.configure({ - codec: track.codec, - codedHeight: track.video.height, - codedWidth: track.video.width, - description: description.buffer?.slice(8), - // optimizeForLatency: true - }) - - this.decoders.set(track.id, videoDecoder) - - return videoDecoder - } -} - -function isAudioDecoder(decoder: AudioDecoder | VideoDecoder): decoder is AudioDecoder { - return decoder instanceof AudioDecoder -} - -function isVideoDecoder(decoder: AudioDecoder | VideoDecoder): decoder is VideoDecoder { - return decoder instanceof VideoDecoder -} - -function isAudioTrack(track: MP4.Track): track is MP4.AudioTrack { - return (track as MP4.AudioTrack).audio !== undefined -} - -function isVideoTrack(track: MP4.Track): track is MP4.VideoTrack { - return (track as MP4.VideoTrack).video !== undefined -} diff --git a/web/src/player/index.ts b/web/src/player/index.ts deleted file mode 100644 index 3ead68d..0000000 --- a/web/src/player/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -import * as Message from "./message" -import * as Ring from "./ring" -import Transport from "../transport" - -export interface Config { - transport: Transport - canvas: OffscreenCanvas -} - -// This class must be created on the main thread due to AudioContext. -export default class Player { - context: AudioContext - worker: Worker - worklet: Promise - - transport: Transport - - constructor(config: Config) { - this.transport = config.transport - this.transport.callback = this - - this.context = new AudioContext({ - latencyHint: "interactive", - sampleRate: 44100, - }) - - this.worker = this.setupWorker(config) - this.worklet = this.setupWorklet(config) - } - - private setupWorker(config: Config): Worker { - const url = new URL("worker.ts", import.meta.url) - - const worker = new Worker(url, { - type: "module", - name: "media", - }) - - const msg = { - canvas: config.canvas, - } - - worker.postMessage({ config: msg }, [msg.canvas]) - - return worker - } - - private async setupWorklet(_config: Config): Promise { - // Load the worklet source code. - const url = new URL("worklet.ts", import.meta.url) - await this.context.audioWorklet.addModule(url) - - const volume = this.context.createGain() - volume.gain.value = 2.0 - - // Create a worklet - const worklet = new AudioWorkletNode(this.context, "renderer") - worklet.onprocessorerror = (e: Event) => { - console.error("Audio worklet error:", e) - } - - // Connect the worklet to the volume node and then to the speakers - worklet.connect(volume) - volume.connect(this.context.destination) - - return worklet - } - - onInit(init: Message.Init) { - this.worker.postMessage({ init }, [init.buffer.buffer, init.reader]) - } - - onSegment(segment: Message.Segment) { - this.worker.postMessage({ segment }, [segment.buffer.buffer, segment.reader]) - } - - async play() { - this.context.resume() - - const play = { - buffer: new Ring.Buffer(2, 44100 / 10), // 100ms of audio - } - - const worklet = await this.worklet - worklet.port.postMessage({ play }) - this.worker.postMessage({ play }) - } -} diff --git a/web/src/player/message.ts b/web/src/player/message.ts deleted file mode 100644 index 2a82acc..0000000 --- a/web/src/player/message.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as Ring from "./ring" - -export interface Config { - // video stuff - canvas: OffscreenCanvas -} - -export interface Init { - buffer: Uint8Array // unread buffered data - reader: ReadableStream // unread unbuffered data -} - -export interface Segment { - buffer: Uint8Array // unread buffered data - reader: ReadableStream // unread unbuffered data -} - -export interface Play { - timestamp?: number - buffer: Ring.Buffer -} diff --git a/web/src/player/renderer.ts b/web/src/player/renderer.ts deleted file mode 100644 index a74ac68..0000000 --- a/web/src/player/renderer.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as Message from "./message" -import Audio from "./audio" -import Video from "./video" - -export default class Renderer { - audio: Audio - video: Video - - constructor(config: Message.Config) { - this.audio = new Audio(config) - this.video = new Video(config) - } - - push(frame: AudioData | VideoFrame) { - if (isAudioData(frame)) { - this.audio.push(frame) - } else if (isVideoFrame(frame)) { - this.video.push(frame) - } else { - throw new Error("unknown frame type") - } - } - - play(play: Message.Play) { - this.audio.play(play) - this.video.play(play) - } -} - -function isAudioData(frame: AudioData | VideoFrame): frame is AudioData { - return frame instanceof AudioData -} - -function isVideoFrame(frame: AudioData | VideoFrame): frame is VideoFrame { - return frame instanceof VideoFrame -} diff --git a/web/src/player/ring.ts b/web/src/player/ring.ts deleted file mode 100644 index 8d27faf..0000000 --- a/web/src/player/ring.ts +++ /dev/null @@ -1,155 +0,0 @@ -// Ring buffer with audio samples. - -enum STATE { - READ_POS = 0, // The current read position - WRITE_POS, // The current write position - LENGTH, // Clever way of saving the total number of enums values. -} - -// No prototype to make this easier to send via postMessage -export class Buffer { - state: SharedArrayBuffer - - channels: SharedArrayBuffer[] - capacity: number - - constructor(channels: number, capacity: number) { - // Store the current state in a separate ring buffer. - this.state = new SharedArrayBuffer(STATE.LENGTH * Int32Array.BYTES_PER_ELEMENT) - - // Create a buffer for each audio channel - this.channels = [] - for (let i = 0; i < channels; i += 1) { - const buffer = new SharedArrayBuffer(capacity * Float32Array.BYTES_PER_ELEMENT) - this.channels.push(buffer) - } - - this.capacity = capacity - } -} - -export class Ring { - state: Int32Array - channels: Float32Array[] - capacity: number - - constructor(buffer: Buffer) { - this.state = new Int32Array(buffer.state) - - this.channels = [] - for (const channel of buffer.channels) { - this.channels.push(new Float32Array(channel)) - } - - this.capacity = buffer.capacity - } - - // Write samples for single audio frame, returning the total number written. - write(frame: AudioData): number { - const readPos = Atomics.load(this.state, STATE.READ_POS) - const writePos = Atomics.load(this.state, STATE.WRITE_POS) - - const startPos = writePos - let endPos = writePos + frame.numberOfFrames - - if (endPos > readPos + this.capacity) { - endPos = readPos + this.capacity - if (endPos <= startPos) { - // No space to write - return 0 - } - } - - const startIndex = startPos % this.capacity - const endIndex = endPos % this.capacity - - // Loop over each channel - for (let i = 0; i < this.channels.length; i += 1) { - const channel = this.channels[i] - - if (startIndex < endIndex) { - // One continuous range to copy. - const full = channel.subarray(startIndex, endIndex) - - frame.copyTo(full, { - planeIndex: i, - frameCount: endIndex - startIndex, - }) - } else { - const first = channel.subarray(startIndex) - const second = channel.subarray(0, endIndex) - - frame.copyTo(first, { - planeIndex: i, - frameCount: first.length, - }) - - // We need this conditional when startIndex == 0 and endIndex == 0 - // When capacity=4410 and frameCount=1024, this was happening 52s into the audio. - if (second.length) { - frame.copyTo(second, { - planeIndex: i, - frameOffset: first.length, - frameCount: second.length, - }) - } - } - } - - Atomics.store(this.state, STATE.WRITE_POS, endPos) - - return endPos - startPos - } - - read(dst: Float32Array[]): number { - const readPos = Atomics.load(this.state, STATE.READ_POS) - const writePos = Atomics.load(this.state, STATE.WRITE_POS) - - const startPos = readPos - let endPos = startPos + dst[0].length - - if (endPos > writePos) { - endPos = writePos - if (endPos <= startPos) { - // Nothing to read - return 0 - } - } - - const startIndex = startPos % this.capacity - const endIndex = endPos % this.capacity - - // Loop over each channel - for (let i = 0; i < dst.length; i += 1) { - if (i >= this.channels.length) { - // ignore excess channels - } - - const input = this.channels[i] - const output = dst[i] - - if (startIndex < endIndex) { - const full = input.subarray(startIndex, endIndex) - output.set(full) - } else { - const first = input.subarray(startIndex) - const second = input.subarray(0, endIndex) - - output.set(first) - output.set(second, first.length) - } - } - - Atomics.store(this.state, STATE.READ_POS, endPos) - - return endPos - startPos - } - - size() { - // TODO is this thread safe? - const readPos = Atomics.load(this.state, STATE.READ_POS) - const writePos = Atomics.load(this.state, STATE.WRITE_POS) - - return writePos - readPos - } -} diff --git a/web/src/player/video.ts b/web/src/player/video.ts deleted file mode 100644 index 8b4a18d..0000000 --- a/web/src/player/video.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as Message from "./message" - -export default class Video { - canvas: OffscreenCanvas - queue: Array - - render: number // non-zero if requestAnimationFrame has been called - sync?: number // the wall clock value for timestamp 0, in microseconds - last?: number // the timestamp of the last rendered frame, in microseconds - - constructor(config: Message.Config) { - this.canvas = config.canvas - this.queue = [] - - this.render = 0 - } - - push(frame: VideoFrame) { - // Drop any old frames - if (this.last && frame.timestamp <= this.last) { - frame.close() - return - } - - // Insert the frame into the queue sorted by timestamp. - if (this.queue.length > 0 && this.queue[this.queue.length - 1].timestamp <= frame.timestamp) { - // Fast path because we normally append to the end. - this.queue.push(frame) - } else { - // Do a full binary search - let low = 0 - let high = this.queue.length - - while (low < high) { - const mid = (low + high) >>> 1 - if (this.queue[mid].timestamp < frame.timestamp) low = mid + 1 - else high = mid - } - - this.queue.splice(low, 0, frame) - } - } - - draw(now: number) { - // Draw and then queue up the next draw call. - this.drawOnce(now) - - // Queue up the new draw frame. - this.render = self.requestAnimationFrame(this.draw.bind(this)) - } - - drawOnce(now: number) { - // Convert to microseconds - now *= 1000 - - if (!this.queue.length) { - return - } - - let frame = this.queue[0] - - if (!this.sync) { - this.sync = now - frame.timestamp - } - - // Determine the target timestamp. - const target = now - this.sync - - if (frame.timestamp >= target) { - // nothing to render yet, wait for the next animation frame - return - } - - this.queue.shift() - - // Check if we should skip some frames - while (this.queue.length) { - const next = this.queue[0] - if (next.timestamp > target) break - - frame.close() - frame = this.queue.shift()! - } - - const ctx = this.canvas.getContext("2d") - ctx!.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height) // TODO aspect ratio - - this.last = frame.timestamp - frame.close() - } - - play(_play: Message.Play) { - // Queue up to render the next frame. - if (!this.render) { - this.render = self.requestAnimationFrame(this.draw.bind(this)) - } - } -} diff --git a/web/src/player/worker.ts b/web/src/player/worker.ts deleted file mode 100644 index f30dd22..0000000 --- a/web/src/player/worker.ts +++ /dev/null @@ -1,24 +0,0 @@ -import Renderer from "./renderer" -import Decoder from "./decoder" -import * as Message from "./message" - -let decoder: Decoder -let renderer: Renderer - -self.addEventListener("message", async (e: MessageEvent) => { - if (e.data.config) { - const config = e.data.config as Message.Config - - renderer = new Renderer(config) - decoder = new Decoder(renderer) - } else if (e.data.init) { - const init = e.data.init as Message.Init - await decoder.receiveInit(init) - } else if (e.data.segment) { - const segment = e.data.segment as Message.Segment - await decoder.receiveSegment(segment) - } else if (e.data.play) { - const play = e.data.play as Message.Play - await renderer.play(play) - } -}) diff --git a/web/src/player/worklet.ts b/web/src/player/worklet.ts deleted file mode 100644 index 77759e9..0000000 --- a/web/src/player/worklet.ts +++ /dev/null @@ -1,53 +0,0 @@ -// This is an AudioWorklet that acts as a media source. -// The renderer copies audio samples to a ring buffer read by this worklet. -// The worklet then outputs those samples to emit audio. - -import * as Message from "./message" - -import { Ring } from "./ring" - -class Renderer extends AudioWorkletProcessor { - ring?: Ring - base: number - - constructor(_params: AudioWorkletNodeOptions) { - // The super constructor call is required. - super() - - this.base = 0 - this.port.onmessage = this.onMessage.bind(this) - } - - onMessage(e: MessageEvent) { - if (e.data.play) { - this.onPlay(e.data.play) - } - } - - onPlay(play: Message.Play) { - this.ring = new Ring(play.buffer) - } - - // Inputs and outputs in groups of 128 samples. - process(inputs: Float32Array[][], outputs: Float32Array[][], _parameters: Record): boolean { - if (!this.ring) { - // Paused - return true - } - - if (inputs.length != 1 && outputs.length != 1) { - throw new Error("only a single track is supported") - } - - const output = outputs[0] - - const size = this.ring.read(output) - if (size < output.length) { - // TODO trigger rebuffering event - } - - return true - } -} - -registerProcessor("renderer", Renderer) diff --git a/web/src/stream/index.ts b/web/src/stream/index.ts deleted file mode 100644 index 31453af..0000000 --- a/web/src/stream/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Reader } from "./reader" -export { default as Writer } from "./writer" diff --git a/web/src/stream/reader.ts b/web/src/stream/reader.ts deleted file mode 100644 index 06adf2a..0000000 --- a/web/src/stream/reader.ts +++ /dev/null @@ -1,195 +0,0 @@ -// Reader wraps a stream and provides convience methods for reading pieces from a stream -export default class Reader { - reader: ReadableStream - buffer: Uint8Array - - constructor(reader: ReadableStream, buffer: Uint8Array = new Uint8Array(0)) { - this.reader = reader - this.buffer = buffer - } - - // Returns any number of bytes - async read(): Promise { - if (this.buffer.byteLength) { - const buffer = this.buffer - this.buffer = new Uint8Array() - return buffer - } - - const r = this.reader.getReader() - const result = await r.read() - - r.releaseLock() - - return result.value - } - - async readAll(): Promise { - const r = this.reader.getReader() - - for (;;) { - const result = await r.read() - if (result.done) { - break - } - - const buffer = new Uint8Array(result.value) - - if (this.buffer.byteLength == 0) { - this.buffer = buffer - } else { - const temp = new Uint8Array(this.buffer.byteLength + buffer.byteLength) - temp.set(this.buffer) - temp.set(buffer, this.buffer.byteLength) - this.buffer = temp - } - } - - const result = this.buffer - this.buffer = new Uint8Array() - - r.releaseLock() - - return result - } - - async bytes(size: number): Promise { - const r = this.reader.getReader() - - while (this.buffer.byteLength < size) { - const result = await r.read() - if (result.done) { - throw "short buffer" - } - - const buffer = new Uint8Array(result.value) - - if (this.buffer.byteLength == 0) { - this.buffer = buffer - } else { - const temp = new Uint8Array(this.buffer.byteLength + buffer.byteLength) - temp.set(this.buffer) - temp.set(buffer, this.buffer.byteLength) - this.buffer = temp - } - } - - const result = new Uint8Array(this.buffer.buffer, this.buffer.byteOffset, size) - this.buffer = new Uint8Array(this.buffer.buffer, this.buffer.byteOffset + size) - - r.releaseLock() - - return result - } - - async peek(size: number): Promise { - const r = this.reader.getReader() - - while (this.buffer.byteLength < size) { - const result = await r.read() - if (result.done) { - throw "short buffer" - } - - const buffer = new Uint8Array(result.value) - - if (this.buffer.byteLength == 0) { - this.buffer = buffer - } else { - const temp = new Uint8Array(this.buffer.byteLength + buffer.byteLength) - temp.set(this.buffer) - temp.set(buffer, this.buffer.byteLength) - this.buffer = temp - } - } - - const result = new Uint8Array(this.buffer.buffer, this.buffer.byteOffset, size) - - r.releaseLock() - - return result - } - - async view(size: number): Promise { - const buf = await this.bytes(size) - return new DataView(buf.buffer, buf.byteOffset, buf.byteLength) - } - - async uint8(): Promise { - const view = await this.view(1) - return view.getUint8(0) - } - - async uint16(): Promise { - const view = await this.view(2) - return view.getUint16(0) - } - - async uint32(): Promise { - const view = await this.view(4) - return view.getUint32(0) - } - - // Returns a Number using 52-bits, the max Javascript can use for integer math - async uint52(): Promise { - const v = await this.uint64() - if (v > Number.MAX_SAFE_INTEGER) { - throw "overflow" - } - - return Number(v) - } - - // Returns a Number using 52-bits, the max Javascript can use for integer math - async vint52(): Promise { - const v = await this.vint64() - if (v > Number.MAX_SAFE_INTEGER) { - throw "overflow" - } - - return Number(v) - } - - // NOTE: Returns a BigInt instead of a Number - async uint64(): Promise { - const view = await this.view(8) - return view.getBigUint64(0) - } - - // NOTE: Returns a BigInt instead of a Number - async vint64(): Promise { - const peek = await this.peek(1) - const first = new DataView(peek.buffer, peek.byteOffset, peek.byteLength).getUint8(0) - const size = (first & 0xc0) >> 6 - - switch (size) { - case 0: { - const v = await this.uint8() - return BigInt(v) & 0x3fn - } - case 1: { - const v = await this.uint16() - return BigInt(v) & 0x3fffn - } - case 2: { - const v = await this.uint32() - return BigInt(v) & 0x3fffffffn - } - case 3: { - const v = await this.uint64() - return v & 0x3fffffffffffffffn - } - default: - throw "impossible" - } - } - - async done(): Promise { - try { - await this.peek(1) - return false - } catch (err) { - return true // Assume EOF - } - } -} diff --git a/web/src/stream/writer.ts b/web/src/stream/writer.ts deleted file mode 100644 index 0210051..0000000 --- a/web/src/stream/writer.ts +++ /dev/null @@ -1,100 +0,0 @@ -// Writer wraps a stream and writes chunks of data -export default class Writer { - buffer: ArrayBuffer - writer: WritableStreamDefaultWriter - - constructor(stream: WritableStream) { - this.buffer = new ArrayBuffer(8) - this.writer = stream.getWriter() - } - - release() { - this.writer.releaseLock() - } - - async close() { - return this.writer.close() - } - - async uint8(v: number) { - const view = new DataView(this.buffer, 0, 1) - view.setUint8(0, v) - return this.writer.write(view) - } - - async uint16(v: number) { - const view = new DataView(this.buffer, 0, 2) - view.setUint16(0, v) - return this.writer.write(view) - } - - async uint24(v: number) { - const v1 = (v >> 16) & 0xff - const v2 = (v >> 8) & 0xff - const v3 = v & 0xff - - const view = new DataView(this.buffer, 0, 3) - view.setUint8(0, v1) - view.setUint8(1, v2) - view.setUint8(2, v3) - - return this.writer.write(view) - } - - async uint32(v: number) { - const view = new DataView(this.buffer, 0, 4) - view.setUint32(0, v) - return this.writer.write(view) - } - - async uint52(v: number) { - if (v > Number.MAX_SAFE_INTEGER) { - throw "value too large" - } - - this.uint64(BigInt(v)) - } - - async vint52(v: number) { - if (v > Number.MAX_SAFE_INTEGER) { - throw "value too large" - } - - if (v < 1 << 6) { - return this.uint8(v) - } else if (v < 1 << 14) { - return this.uint16(v | 0x4000) - } else if (v < 1 << 30) { - return this.uint32(v | 0x80000000) - } else { - return this.uint64(BigInt(v) | 0xc000000000000000n) - } - } - - async uint64(v: bigint) { - const view = new DataView(this.buffer, 0, 8) - view.setBigUint64(0, v) - return this.writer.write(view) - } - - async vint64(v: bigint) { - if (v < 1 << 6) { - return this.uint8(Number(v)) - } else if (v < 1 << 14) { - return this.uint16(Number(v) | 0x4000) - } else if (v < 1 << 30) { - return this.uint32(Number(v) | 0x80000000) - } else { - return this.uint64(v | 0xc000000000000000n) - } - } - - async bytes(buffer: ArrayBuffer) { - return this.writer.write(buffer) - } - - async string(str: string) { - const data = new TextEncoder().encode(str) - return this.writer.write(data) - } -} diff --git a/web/src/transport/index.ts b/web/src/transport/index.ts deleted file mode 100644 index d2e4e55..0000000 --- a/web/src/transport/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -import * as Stream from "../stream" -import * as Interface from "./interface" - -export interface Config { - url: string - fingerprint?: WebTransportHash // the certificate fingerprint, temporarily needed for local development -} - -export default class Transport { - quic: Promise - api: Promise - callback?: Interface.Callback - - constructor(config: Config) { - this.quic = this.connect(config) - - // Create a unidirectional stream for all of our messages - this.api = this.quic.then((q) => { - return q.createUnidirectionalStream() - }) - - // async functions - this.receiveStreams() - } - - async close() { - ;(await this.quic).close() - } - - // Helper function to make creating a promise easier - private async connect(config: Config): Promise { - const options: WebTransportOptions = {} - if (config.fingerprint) { - options.serverCertificateHashes = [config.fingerprint] - } - - const quic = new WebTransport(config.url, options) - await quic.ready - return quic - } - - async sendMessage(msg: any) { - const payload = JSON.stringify(msg) - const size = payload.length + 8 - - const stream = await this.api - - const writer = new Stream.Writer(stream) - await writer.uint32(size) - await writer.string("warp") - await writer.string(payload) - writer.release() - } - - async receiveStreams() { - const q = await this.quic - const streams = q.incomingUnidirectionalStreams.getReader() - - for (;;) { - const result = await streams.read() - if (result.done) break - - const stream = result.value - this.handleStream(stream) // don't await - } - } - - async handleStream(stream: ReadableStream) { - const r = new Stream.Reader(stream) - - while (!(await r.done())) { - const size = await r.uint32() - const typ = new TextDecoder("utf-8").decode(await r.bytes(4)) - - if (typ != "warp") throw "expected warp atom" - if (size < 8) throw "atom too small" - - const payload = new TextDecoder("utf-8").decode(await r.bytes(size - 8)) - const msg = JSON.parse(payload) - - if (msg.init) { - return this.callback?.onInit({ - buffer: r.buffer, - reader: r.reader, - }) - } else if (msg.segment) { - return this.callback?.onSegment({ - buffer: r.buffer, - reader: r.reader, - }) - } else { - console.warn("unknown message", msg) - } - } - } -} diff --git a/web/src/transport/interface.ts b/web/src/transport/interface.ts deleted file mode 100644 index 84a4276..0000000 --- a/web/src/transport/interface.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface Callback { - onInit(init: Init): any - onSegment(segment: Segment): any -} - -export interface Init { - buffer: Uint8Array // unread buffered data - reader: ReadableStream // unread unbuffered data -} - -export interface Segment { - buffer: Uint8Array // unread buffered data - reader: ReadableStream // unread unbuffered data -} diff --git a/web/src/transport/message.ts b/web/src/transport/message.ts deleted file mode 100644 index 6dee40c..0000000 --- a/web/src/transport/message.ts +++ /dev/null @@ -1,7 +0,0 @@ -// TODO fill in required fields -export type Init = any -export type Segment = any - -export interface Debug { - max_bitrate: number -} diff --git a/web/src/transport/webtransport.d.ts b/web/src/transport/webtransport.d.ts deleted file mode 100644 index 7ac6b8d..0000000 --- a/web/src/transport/webtransport.d.ts +++ /dev/null @@ -1,84 +0,0 @@ -declare module "webtransport" - -/* - There's no WebTransport support in TypeScript yet. Use this script to update definitions: - - npx webidl2ts -i https://www.w3.org/TR/webtransport/ -o webtransport.d.ts - You'll have to fix the constructors by hand. -*/ - -interface WebTransportDatagramDuplexStream { - readonly readable: ReadableStream - readonly writable: WritableStream - readonly maxDatagramSize: number - incomingMaxAge: number - outgoingMaxAge: number - incomingHighWaterMark: number - outgoingHighWaterMark: number -} - -interface WebTransport { - getStats(): Promise - readonly ready: Promise - readonly closed: Promise - close(closeInfo?: WebTransportCloseInfo): undefined - readonly datagrams: WebTransportDatagramDuplexStream - createBidirectionalStream(): Promise - readonly incomingBidirectionalStreams: ReadableStream - createUnidirectionalStream(): Promise - readonly incomingUnidirectionalStreams: ReadableStream -} - -declare const WebTransport: { - prototype: WebTransport - new (url: string, options?: WebTransportOptions): WebTransport -} - -interface WebTransportHash { - algorithm?: string - value?: BufferSource -} - -interface WebTransportOptions { - allowPooling?: boolean - serverCertificateHashes?: Array -} - -interface WebTransportCloseInfo { - closeCode?: number - reason?: string -} - -interface WebTransportStats { - timestamp?: DOMHighResTimeStamp - bytesSent?: number - packetsSent?: number - numOutgoingStreamsCreated?: number - numIncomingStreamsCreated?: number - bytesReceived?: number - packetsReceived?: number - minRtt?: DOMHighResTimeStamp - numReceivedDatagramsDropped?: number -} - -interface WebTransportBidirectionalStream { - readonly readable: ReadableStream - readonly writable: WritableStream -} - -interface WebTransportError extends DOMException { - readonly source: WebTransportErrorSource - readonly streamErrorCode: number -} - -declare const WebTransportError: { - prototype: WebTransportError - new (init?: WebTransportErrorInit): WebTransportError -} - -interface WebTransportErrorInit { - streamErrorCode?: number - message?: string -} - -type WebTransportErrorSource = "stream" | "session" diff --git a/web/src/util/deferred.ts b/web/src/util/deferred.ts deleted file mode 100644 index 4ef9ee1..0000000 --- a/web/src/util/deferred.ts +++ /dev/null @@ -1,20 +0,0 @@ -export default class Deferred { - promise: Promise - resolve: (value: T | PromiseLike) => void - reject: (value: T | PromiseLike) => void - - constructor() { - // Set initial values so TS stops being annoying. - this.resolve = (_value: T | PromiseLike) => { - /* noop */ - } - this.reject = (_value: T | PromiseLike) => { - /* noop */ - } - - this.promise = new Promise((resolve, reject) => { - this.resolve = resolve - this.reject = reject - }) - } -} diff --git a/web/src/util/index.ts b/web/src/util/index.ts deleted file mode 100644 index adcfc49..0000000 --- a/web/src/util/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as Deferred } from "./deferred" diff --git a/web/tsconfig.json b/web/tsconfig.json deleted file mode 100644 index d1a39a8..0000000 --- a/web/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "include": ["src/**/*"], - "compilerOptions": { - "target": "es2022", - "module": "es2022", - "moduleResolution": "node", - "strict": true - } -} diff --git a/web/yarn.lock b/web/yarn.lock deleted file mode 100644 index 6abab3f..0000000 --- a/web/yarn.lock +++ /dev/null @@ -1,2292 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/helper-validator-identifier@^7.18.6": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.41.0": - version "8.41.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz" - integrity sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA== - -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@lezer/common@^0.15.0", "@lezer/common@^0.15.7": - version "0.15.12" - resolved "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz" - integrity sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig== - -"@lezer/lr@^0.15.4": - version "0.15.8" - resolved "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz" - integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== - dependencies: - "@lezer/common" "^0.15.0" - -"@lmdb/lmdb-darwin-arm64@2.5.2": - version "2.5.2" - resolved "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz" - integrity sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A== - -"@lmdb/lmdb-darwin-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz#89d8390041bce6bab24a82a20392be22faf54ffc" - integrity sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA== - -"@lmdb/lmdb-linux-arm64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz#14fe4c96c2bb1285f93797f45915fa35ee047268" - integrity sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ== - -"@lmdb/lmdb-linux-arm@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz#05bde4573ab10cf21827339fe687148f2590cfa1" - integrity sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw== - -"@lmdb/lmdb-linux-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz#d2f85afd857d2c33d2caa5b057944574edafcfee" - integrity sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q== - -"@lmdb/lmdb-win32-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz#28f643fbc0bec30b07fbe95b137879b6b4d1c9c5" - integrity sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA== - -"@mischnic/json-sourcemap@^0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz" - integrity sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA== - dependencies: - "@lezer/common" "^0.15.7" - "@lezer/lr" "^0.15.4" - json5 "^2.2.1" - -"@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2": - version "3.0.2" - resolved "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz" - integrity sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ== - -"@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz#f954f34355712212a8e06c465bc06c40852c6bb3" - integrity sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw== - -"@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz#45c63037f045c2b15c44f80f0393fa24f9655367" - integrity sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg== - -"@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz#35707efeafe6d22b3f373caf9e8775e8920d1399" - integrity sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA== - -"@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz#091b1218b66c341f532611477ef89e83f25fae4f" - integrity sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA== - -"@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz#0f164b726869f71da3c594171df5ebc1c4b0a407" - integrity sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@parcel/bundler-default@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.8.3.tgz" - integrity sha512-yJvRsNWWu5fVydsWk3O2L4yIy3UZiKWO2cPDukGOIWMgp/Vbpp+2Ct5IygVRtE22bnseW/E/oe0PV3d2IkEJGg== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/graph" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - -"@parcel/cache@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/cache/-/cache-2.8.3.tgz" - integrity sha512-k7xv5vSQrJLdXuglo+Hv3yF4BCSs1tQ/8Vbd6CHTkOhf7LcGg6CPtLw053R/KdMpd/4GPn0QrAsOLdATm1ELtQ== - dependencies: - "@parcel/fs" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/utils" "2.8.3" - lmdb "2.5.2" - -"@parcel/codeframe@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.8.3.tgz" - integrity sha512-FE7sY53D6n/+2Pgg6M9iuEC6F5fvmyBkRE4d9VdnOoxhTXtkEqpqYgX7RJ12FAQwNlxKq4suBJQMgQHMF2Kjeg== - dependencies: - chalk "^4.1.0" - -"@parcel/compressor-raw@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.8.3.tgz" - integrity sha512-bVDsqleBUxRdKMakWSlWC9ZjOcqDKE60BE+Gh3JSN6WJrycJ02P5wxjTVF4CStNP/G7X17U+nkENxSlMG77ySg== - dependencies: - "@parcel/plugin" "2.8.3" - -"@parcel/config-default@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.8.3.tgz" - integrity sha512-o/A/mbrO6X/BfGS65Sib8d6SSG45NYrNooNBkH/o7zbOBSRQxwyTlysleK1/3Wa35YpvFyLOwgfakqCtbGy4fw== - dependencies: - "@parcel/bundler-default" "2.8.3" - "@parcel/compressor-raw" "2.8.3" - "@parcel/namer-default" "2.8.3" - "@parcel/optimizer-css" "2.8.3" - "@parcel/optimizer-htmlnano" "2.8.3" - "@parcel/optimizer-image" "2.8.3" - "@parcel/optimizer-svgo" "2.8.3" - "@parcel/optimizer-terser" "2.8.3" - "@parcel/packager-css" "2.8.3" - "@parcel/packager-html" "2.8.3" - "@parcel/packager-js" "2.8.3" - "@parcel/packager-raw" "2.8.3" - "@parcel/packager-svg" "2.8.3" - "@parcel/reporter-dev-server" "2.8.3" - "@parcel/resolver-default" "2.8.3" - "@parcel/runtime-browser-hmr" "2.8.3" - "@parcel/runtime-js" "2.8.3" - "@parcel/runtime-react-refresh" "2.8.3" - "@parcel/runtime-service-worker" "2.8.3" - "@parcel/transformer-babel" "2.8.3" - "@parcel/transformer-css" "2.8.3" - "@parcel/transformer-html" "2.8.3" - "@parcel/transformer-image" "2.8.3" - "@parcel/transformer-js" "2.8.3" - "@parcel/transformer-json" "2.8.3" - "@parcel/transformer-postcss" "2.8.3" - "@parcel/transformer-posthtml" "2.8.3" - "@parcel/transformer-raw" "2.8.3" - "@parcel/transformer-react-refresh-wrap" "2.8.3" - "@parcel/transformer-svg" "2.8.3" - -"@parcel/core@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/core/-/core-2.8.3.tgz" - integrity sha512-Euf/un4ZAiClnlUXqPB9phQlKbveU+2CotZv7m7i+qkgvFn5nAGnrV4h1OzQU42j9dpgOxWi7AttUDMrvkbhCQ== - dependencies: - "@mischnic/json-sourcemap" "^0.1.0" - "@parcel/cache" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/events" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/graph" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/package-manager" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - abortcontroller-polyfill "^1.1.9" - base-x "^3.0.8" - browserslist "^4.6.6" - clone "^2.1.1" - dotenv "^7.0.0" - dotenv-expand "^5.1.0" - json5 "^2.2.0" - msgpackr "^1.5.4" - nullthrows "^1.1.1" - semver "^5.7.1" - -"@parcel/diagnostic@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.8.3.tgz" - integrity sha512-u7wSzuMhLGWZjVNYJZq/SOViS3uFG0xwIcqXw12w54Uozd6BH8JlhVtVyAsq9kqnn7YFkw6pXHqAo5Tzh4FqsQ== - dependencies: - "@mischnic/json-sourcemap" "^0.1.0" - nullthrows "^1.1.1" - -"@parcel/events@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/events/-/events-2.8.3.tgz" - integrity sha512-hoIS4tAxWp8FJk3628bsgKxEvR7bq2scCVYHSqZ4fTi/s0+VymEATrRCUqf+12e5H47uw1/ZjoqrGtBI02pz4w== - -"@parcel/fs-search@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/fs-search/-/fs-search-2.8.3.tgz" - integrity sha512-DJBT2N8knfN7Na6PP2mett3spQLTqxFrvl0gv+TJRp61T8Ljc4VuUTb0hqBj+belaASIp3Q+e8+SgaFQu7wLiQ== - dependencies: - detect-libc "^1.0.3" - -"@parcel/fs@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/fs/-/fs-2.8.3.tgz" - integrity sha512-y+i+oXbT7lP0e0pJZi/YSm1vg0LDsbycFuHZIL80pNwdEppUAtibfJZCp606B7HOjMAlNZOBo48e3hPG3d8jgQ== - dependencies: - "@parcel/fs-search" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/watcher" "^2.0.7" - "@parcel/workers" "2.8.3" - -"@parcel/graph@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/graph/-/graph-2.8.3.tgz" - integrity sha512-26GL8fYZPdsRhSXCZ0ZWliloK6DHlMJPWh6Z+3VVZ5mnDSbYg/rRKWmrkhnr99ZWmL9rJsv4G74ZwvDEXTMPBg== - dependencies: - nullthrows "^1.1.1" - -"@parcel/hash@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/hash/-/hash-2.8.3.tgz" - integrity sha512-FVItqzjWmnyP4ZsVgX+G00+6U2IzOvqDtdwQIWisCcVoXJFCqZJDy6oa2qDDFz96xCCCynjRjPdQx2jYBCpfYw== - dependencies: - detect-libc "^1.0.3" - xxhash-wasm "^0.4.2" - -"@parcel/logger@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/logger/-/logger-2.8.3.tgz" - integrity sha512-Kpxd3O/Vs7nYJIzkdmB6Bvp3l/85ydIxaZaPfGSGTYOfaffSOTkhcW9l6WemsxUrlts4za6CaEWcc4DOvaMOPA== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/events" "2.8.3" - -"@parcel/markdown-ansi@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.8.3.tgz" - integrity sha512-4v+pjyoh9f5zuU/gJlNvNFGEAb6J90sOBwpKJYJhdWXLZMNFCVzSigxrYO+vCsi8G4rl6/B2c0LcwIMjGPHmFQ== - dependencies: - chalk "^4.1.0" - -"@parcel/namer-default@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.8.3.tgz" - integrity sha512-tJ7JehZviS5QwnxbARd8Uh63rkikZdZs1QOyivUhEvhN+DddSAVEdQLHGPzkl3YRk0tjFhbqo+Jci7TpezuAMw== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - nullthrows "^1.1.1" - -"@parcel/node-resolver-core@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-2.8.3.tgz" - integrity sha512-12YryWcA5Iw2WNoEVr/t2HDjYR1iEzbjEcxfh1vaVDdZ020PiGw67g5hyIE/tsnG7SRJ0xdRx1fQ2hDgED+0Ww== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - semver "^5.7.1" - -"@parcel/optimizer-css@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.8.3.tgz" - integrity sha512-JotGAWo8JhuXsQDK0UkzeQB0UR5hDAKvAviXrjqB4KM9wZNLhLleeEAW4Hk8R9smCeQFP6Xg/N/NkLDpqMwT3g== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - browserslist "^4.6.6" - lightningcss "^1.16.1" - nullthrows "^1.1.1" - -"@parcel/optimizer-htmlnano@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.8.3.tgz" - integrity sha512-L8/fHbEy8Id2a2E0fwR5eKGlv9VYDjrH9PwdJE9Za9v1O/vEsfl/0T/79/x129l5O0yB6EFQkFa20MiK3b+vOg== - dependencies: - "@parcel/plugin" "2.8.3" - htmlnano "^2.0.0" - nullthrows "^1.1.1" - posthtml "^0.16.5" - svgo "^2.4.0" - -"@parcel/optimizer-image@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.8.3.tgz" - integrity sha512-SD71sSH27SkCDNUNx9A3jizqB/WIJr3dsfp+JZGZC42tpD/Siim6Rqy9M4To/BpMMQIIiEXa5ofwS+DgTEiEHQ== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - detect-libc "^1.0.3" - -"@parcel/optimizer-svgo@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/optimizer-svgo/-/optimizer-svgo-2.8.3.tgz" - integrity sha512-9KQed99NZnQw3/W4qBYVQ7212rzA9EqrQG019TIWJzkA9tjGBMIm2c/nXpK1tc3hQ3e7KkXkFCQ3C+ibVUnHNA== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - svgo "^2.4.0" - -"@parcel/optimizer-terser@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/optimizer-terser/-/optimizer-terser-2.8.3.tgz" - integrity sha512-9EeQlN6zIeUWwzrzu6Q2pQSaYsYGah8MtiQ/hog9KEPlYTP60hBv/+utDyYEHSQhL7y5ym08tPX5GzBvwAD/dA== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - terser "^5.2.0" - -"@parcel/package-manager@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.8.3.tgz" - integrity sha512-tIpY5pD2lH53p9hpi++GsODy6V3khSTX4pLEGuMpeSYbHthnOViobqIlFLsjni+QA1pfc8NNNIQwSNdGjYflVA== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - semver "^5.7.1" - -"@parcel/packager-css@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.8.3.tgz" - integrity sha512-WyvkMmsurlHG8d8oUVm7S+D+cC/T3qGeqogb7sTI52gB6uiywU7lRCizLNqGFyFGIxcVTVHWnSHqItBcLN76lA== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - -"@parcel/packager-html@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.8.3.tgz" - integrity sha512-OhPu1Hx1RRKJodpiu86ZqL8el2Aa4uhBHF6RAL1Pcrh2EhRRlPf70Sk0tC22zUpYL7es+iNKZ/n0Rl+OWSHWEw== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - posthtml "^0.16.5" - -"@parcel/packager-js@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.8.3.tgz" - integrity sha512-0pGKC3Ax5vFuxuZCRB+nBucRfFRz4ioie19BbDxYnvBxrd4M3FIu45njf6zbBYsI9eXqaDnL1b3DcZJfYqtIzw== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - globals "^13.2.0" - nullthrows "^1.1.1" - -"@parcel/packager-raw@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.8.3.tgz" - integrity sha512-BA6enNQo1RCnco9MhkxGrjOk59O71IZ9DPKu3lCtqqYEVd823tXff2clDKHK25i6cChmeHu6oB1Rb73hlPqhUA== - dependencies: - "@parcel/plugin" "2.8.3" - -"@parcel/packager-svg@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.8.3.tgz" - integrity sha512-mvIoHpmv5yzl36OjrklTDFShLUfPFTwrmp1eIwiszGdEBuQaX7JVI3Oo2jbVQgcN4W7J6SENzGQ3Q5hPTW3pMw== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - posthtml "^0.16.4" - -"@parcel/plugin@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.3.tgz" - integrity sha512-jZ6mnsS4D9X9GaNnvrixDQwlUQJCohDX2hGyM0U0bY2NWU8Km97SjtoCpWjq+XBCx/gpC4g58+fk9VQeZq2vlw== - dependencies: - "@parcel/types" "2.8.3" - -"@parcel/reporter-cli@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.8.3.tgz" - integrity sha512-3sJkS6tFFzgIOz3u3IpD/RsmRxvOKKiQHOTkiiqRt1l44mMDGKS7zANRnJYsQzdCsgwc9SOP30XFgJwtoVlMbw== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - chalk "^4.1.0" - term-size "^2.2.1" - -"@parcel/reporter-dev-server@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.8.3.tgz" - integrity sha512-Y8C8hzgzTd13IoWTj+COYXEyCkXfmVJs3//GDBsH22pbtSFMuzAZd+8J9qsCo0EWpiDow7V9f1LischvEh3FbQ== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - -"@parcel/resolver-default@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.8.3.tgz" - integrity sha512-k0B5M/PJ+3rFbNj4xZSBr6d6HVIe6DH/P3dClLcgBYSXAvElNDfXgtIimbjCyItFkW9/BfcgOVKEEIZOeySH/A== - dependencies: - "@parcel/node-resolver-core" "2.8.3" - "@parcel/plugin" "2.8.3" - -"@parcel/runtime-browser-hmr@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.8.3.tgz" - integrity sha512-2O1PYi2j/Q0lTyGNV3JdBYwg4rKo6TEVFlYGdd5wCYU9ZIN9RRuoCnWWH2qCPj3pjIVtBeppYxzfVjPEHINWVg== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - -"@parcel/runtime-js@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.8.3.tgz" - integrity sha512-IRja0vNKwvMtPgIqkBQh0QtRn0XcxNC8HU1jrgWGRckzu10qJWO+5ULgtOeR4pv9krffmMPqywGXw6l/gvJKYQ== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - -"@parcel/runtime-react-refresh@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.8.3.tgz" - integrity sha512-2v/qFKp00MfG0234OdOgQNAo6TLENpFYZMbVbAsPMY9ITiqG73MrEsrGXVoGbYiGTMB/Toer/lSWlJxtacOCuA== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - react-error-overlay "6.0.9" - react-refresh "^0.9.0" - -"@parcel/runtime-service-worker@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.8.3.tgz" - integrity sha512-/Skkw+EeRiwzOJso5fQtK8c9b452uWLNhQH1ISTodbmlcyB4YalAiSsyHCtMYD0c3/t5Sx4ZS7vxBAtQd0RvOw== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - -"@parcel/source-map@^2.1.1": - version "2.1.1" - resolved "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz" - integrity sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew== - dependencies: - detect-libc "^1.0.3" - -"@parcel/transformer-babel@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.8.3.tgz" - integrity sha512-L6lExfpvvC7T/g3pxf3CIJRouQl+sgrSzuWQ0fD4PemUDHvHchSP4SNUVnd6gOytF3Y1KpnEZIunQGi5xVqQCQ== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - browserslist "^4.6.6" - json5 "^2.2.0" - nullthrows "^1.1.1" - semver "^5.7.0" - -"@parcel/transformer-css@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.8.3.tgz" - integrity sha512-xTqFwlSXtnaYen9ivAgz+xPW7yRl/u4QxtnDyDpz5dr8gSeOpQYRcjkd4RsYzKsWzZcGtB5EofEk8ayUbWKEUg== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - browserslist "^4.6.6" - lightningcss "^1.16.1" - nullthrows "^1.1.1" - -"@parcel/transformer-html@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.8.3.tgz" - integrity sha512-kIZO3qsMYTbSnSpl9cnZog+SwL517ffWH54JeB410OSAYF1ouf4n5v9qBnALZbuCCmPwJRGs4jUtE452hxwN4g== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - nullthrows "^1.1.1" - posthtml "^0.16.5" - posthtml-parser "^0.10.1" - posthtml-render "^3.0.0" - semver "^5.7.1" - srcset "4" - -"@parcel/transformer-image@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.8.3.tgz" - integrity sha512-cO4uptcCGTi5H6bvTrAWEFUsTNhA4kCo8BSvRSCHA2sf/4C5tGQPHt3JhdO0GQLPwZRCh/R41EkJs5HZ8A8DAg== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - nullthrows "^1.1.1" - -"@parcel/transformer-inline-string@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-inline-string/-/transformer-inline-string-2.8.3.tgz" - integrity sha512-TBMk2H9nV8JMOsLztalhzS6HgthG5SCHKYkR2MaW7eSZuSGotbSP22aJip8HgQZ/lPMdOMb1lknHmd8WROxWHg== - dependencies: - "@parcel/plugin" "2.8.3" - -"@parcel/transformer-js@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.8.3.tgz" - integrity sha512-9Qd6bib+sWRcpovvzvxwy/PdFrLUXGfmSW9XcVVG8pvgXsZPFaNjnNT8stzGQj1pQiougCoxMY4aTM5p1lGHEQ== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - "@swc/helpers" "^0.4.12" - browserslist "^4.6.6" - detect-libc "^1.0.3" - nullthrows "^1.1.1" - regenerator-runtime "^0.13.7" - semver "^5.7.1" - -"@parcel/transformer-json@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.8.3.tgz" - integrity sha512-B7LmVq5Q7bZO4ERb6NHtRuUKWGysEeaj9H4zelnyBv+wLgpo4f5FCxSE1/rTNmP9u1qHvQ3scGdK6EdSSokGPg== - dependencies: - "@parcel/plugin" "2.8.3" - json5 "^2.2.0" - -"@parcel/transformer-postcss@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.8.3.tgz" - integrity sha512-e8luB/poIlz6jBsD1Izms+6ElbyzuoFVa4lFVLZnTAChI3UxPdt9p/uTsIO46HyBps/Bk8ocvt3J4YF84jzmvg== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - clone "^2.1.1" - nullthrows "^1.1.1" - postcss-value-parser "^4.2.0" - semver "^5.7.1" - -"@parcel/transformer-posthtml@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.8.3.tgz" - integrity sha512-pkzf9Smyeaw4uaRLsT41RGrPLT5Aip8ZPcntawAfIo+KivBQUV0erY1IvHYjyfFzq1ld/Fo2Ith9He6mxpPifA== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - nullthrows "^1.1.1" - posthtml "^0.16.5" - posthtml-parser "^0.10.1" - posthtml-render "^3.0.0" - semver "^5.7.1" - -"@parcel/transformer-raw@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.8.3.tgz" - integrity sha512-G+5cXnd2/1O3nV/pgRxVKZY/HcGSseuhAe71gQdSQftb8uJEURyUHoQ9Eh0JUD3MgWh9V+nIKoyFEZdf9T0sUQ== - dependencies: - "@parcel/plugin" "2.8.3" - -"@parcel/transformer-react-refresh-wrap@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.8.3.tgz" - integrity sha512-q8AAoEvBnCf/nPvgOwFwKZfEl/thwq7c2duxXkhl+tTLDRN2vGmyz4355IxCkavSX+pLWSQ5MexklSEeMkgthg== - dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - react-refresh "^0.9.0" - -"@parcel/transformer-svg@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.8.3.tgz" - integrity sha512-3Zr/gBzxi1ZH1fftH/+KsZU7w5GqkmxlB0ZM8ovS5E/Pl1lq1t0xvGJue9m2VuQqP8Mxfpl5qLFmsKlhaZdMIQ== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - nullthrows "^1.1.1" - posthtml "^0.16.5" - posthtml-parser "^0.10.1" - posthtml-render "^3.0.0" - semver "^5.7.1" - -"@parcel/ts-utils@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/ts-utils/-/ts-utils-2.8.3.tgz" - integrity sha512-4HMt9B9LF2pDFvSKGImho48tlCvCUl7ly1ZMXvQdmEq2i0yoS81tDsmxX3yly/RVUVeUCGAj1JRuuy1lw5zw1A== - dependencies: - nullthrows "^1.1.1" - -"@parcel/types@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/types/-/types-2.8.3.tgz" - integrity sha512-FECA1FB7+0UpITKU0D6TgGBpGxYpVSMNEENZbSJxFSajNy3wrko+zwBKQmFOLOiPcEtnGikxNs+jkFWbPlUAtw== - dependencies: - "@parcel/cache" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/package-manager" "2.8.3" - "@parcel/source-map" "^2.1.1" - "@parcel/workers" "2.8.3" - utility-types "^3.10.0" - -"@parcel/utils@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/utils/-/utils-2.8.3.tgz" - integrity sha512-IhVrmNiJ+LOKHcCivG5dnuLGjhPYxQ/IzbnF2DKNQXWBTsYlHkJZpmz7THoeLtLliGmSOZ3ZCsbR8/tJJKmxjA== - dependencies: - "@parcel/codeframe" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/markdown-ansi" "2.8.3" - "@parcel/source-map" "^2.1.1" - chalk "^4.1.0" - -"@parcel/validator-typescript@^2.6.0": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/validator-typescript/-/validator-typescript-2.8.3.tgz" - integrity sha512-2UYGCAwrxh7HIGcrXl8Vu9Sisd8vAu/6Jp/oJV5n9ZQuT5O9pQAlK2lZGSocYRucBtmb4WajII2S2GTzUZeEuQ== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/ts-utils" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - -"@parcel/watcher@^2.0.7": - version "2.1.0" - resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz" - integrity sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw== - dependencies: - is-glob "^4.0.3" - micromatch "^4.0.5" - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - -"@parcel/workers@2.8.3": - version "2.8.3" - resolved "https://registry.npmjs.org/@parcel/workers/-/workers-2.8.3.tgz" - integrity sha512-+AxBnKgjqVpUHBcHLWIHcjYgKIvHIpZjN33mG5LG9XXvrZiqdWvouEzqEXlVLq5VzzVbKIQQcmsvRy138YErkg== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - chrome-trace-event "^1.0.2" - nullthrows "^1.1.1" - -"@swc/helpers@^0.4.12": - version "0.4.14" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz" - integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== - dependencies: - tslib "^2.4.0" - -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - -"@types/audioworklet@^0.0.41": - version "0.0.41" - resolved "https://registry.npmjs.org/@types/audioworklet/-/audioworklet-0.0.41.tgz" - integrity sha512-8BWffzGoSRz436IviQVPye75YYWfac4OKdcLgkZxb3APZxSmAOp2SMtsH1yuM1x57/z/J7bsm05Yq98Hzk1t/w== - -"@types/dom-webcodecs@^0.1.6": - version "0.1.6" - resolved "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.6.tgz" - integrity sha512-m+Y2WRIKvLwFzyToNGA5XV+sfihtrfcOaMrXzsZULVdqYyKy4yn0XZ8lES9RRwZTzW7TKcz84xed3e5FBk3wCg== - -"@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@typescript-eslint/eslint-plugin@^5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz" - integrity sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/type-utils" "5.59.7" - "@typescript-eslint/utils" "5.59.7" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz" - integrity sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ== - dependencies: - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/typescript-estree" "5.59.7" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz" - integrity sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/visitor-keys" "5.59.7" - -"@typescript-eslint/type-utils@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz" - integrity sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.7" - "@typescript-eslint/utils" "5.59.7" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz" - integrity sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A== - -"@typescript-eslint/typescript-estree@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz" - integrity sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/visitor-keys" "5.59.7" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz" - integrity sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.7" - "@typescript-eslint/types" "5.59.7" - "@typescript-eslint/typescript-estree" "5.59.7" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.7": - version "5.59.7" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz" - integrity sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ== - dependencies: - "@typescript-eslint/types" "5.59.7" - eslint-visitor-keys "^3.3.0" - -abortcontroller-polyfill@^1.1.9: - version "1.7.5" - resolved "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz" - integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== - -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.5.0, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.8: - version "3.0.9" - resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -boolbase@^1.0.0: - version "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.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.6.6: - version "4.21.5" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== - dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" - -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== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -caniuse-lite@^1.0.30001449: - version "1.0.30001470" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz" - integrity sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" - integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -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== - -commander@^2.20.0: - 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@^7.0.0, commander@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -cosmiconfig@^7.0.1: - version "7.1.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-what@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -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== - -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz" - integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - -domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== - -dotenv@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz" - integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== - -electron-to-chromium@^1.4.284: - version "1.4.340" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.340.tgz" - integrity sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg== - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-prettier@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" - integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== - -eslint-plugin-prettier@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" - integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@^8.41.0: - version "8.41.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz" - integrity sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.41.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -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-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -get-port@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz" - integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - 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" - -globals@^13.19.0, globals@^13.2.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -htmlnano@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/htmlnano/-/htmlnano-2.0.3.tgz" - integrity sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A== - dependencies: - cosmiconfig "^7.0.1" - posthtml "^0.16.5" - timsort "^0.3.0" - -htmlparser2@^7.1.1: - version "7.2.0" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz" - integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.2" - domutils "^2.8.0" - entities "^3.0.1" - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -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-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-json@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz" - integrity sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA== - -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@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^2.2.0, json5@^2.2.1: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lightningcss-darwin-arm64@1.19.0: - version "1.19.0" - resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz" - integrity sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg== - -lightningcss-darwin-x64@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.19.0.tgz#c867308b88859ba61a2c46c82b1ca52ff73a1bd0" - integrity sha512-Lif1wD6P4poaw9c/4Uh2z+gmrWhw/HtXFoeZ3bEsv6Ia4tt8rOJBdkfVaUJ6VXmpKHALve+iTyP2+50xY1wKPw== - -lightningcss-linux-arm-gnueabihf@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.19.0.tgz#0f921dc45f2e5c3aea70fab98844ac0e5f2f81be" - integrity sha512-P15VXY5682mTXaiDtbnLYQflc8BYb774j2R84FgDLJTN6Qp0ZjWEFyN1SPqyfTj2B2TFjRHRUvQSSZ7qN4Weig== - -lightningcss-linux-arm64-gnu@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.19.0.tgz#027f9df9c7f4ffa127c37a71726245a5794d7ba2" - integrity sha512-zwXRjWqpev8wqO0sv0M1aM1PpjHz6RVIsBcxKszIG83Befuh4yNysjgHVplF9RTU7eozGe3Ts7r6we1+Qkqsww== - -lightningcss-linux-arm64-musl@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.19.0.tgz#85ea987da868524eac6db94f8e1eaa23d0b688a3" - integrity sha512-vSCKO7SDnZaFN9zEloKSZM5/kC5gbzUjoJQ43BvUpyTFUX7ACs/mDfl2Eq6fdz2+uWhUh7vf92c4EaaP4udEtA== - -lightningcss-linux-x64-gnu@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.19.0.tgz#02bec89579ab4153dccc0def755d1fd9e3ee7f3c" - integrity sha512-0AFQKvVzXf9byrXUq9z0anMGLdZJS+XSDqidyijI5njIwj6MdbvX2UZK/c4FfNmeRa2N/8ngTffoIuOUit5eIQ== - -lightningcss-linux-x64-musl@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.19.0.tgz#e36a5df8193ae961d22974635e4c100a1823bb8c" - integrity sha512-SJoM8CLPt6ECCgSuWe+g0qo8dqQYVcPiW2s19dxkmSI5+Uu1GIRzyKA0b7QqmEXolA+oSJhQqCmJpzjY4CuZAg== - -lightningcss-win32-x64-msvc@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz#0854dbd153035eca1396e2227c708ad43655a61c" - integrity sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg== - -lightningcss@^1.16.1: - version "1.19.0" - resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.19.0.tgz" - integrity sha512-yV5UR7og+Og7lQC+70DA7a8ta1uiOPnWPJfxa0wnxylev5qfo4P+4iMpzWAdYWOca4jdNQZii+bDL/l+4hUXIA== - dependencies: - detect-libc "^1.0.3" - optionalDependencies: - lightningcss-darwin-arm64 "1.19.0" - lightningcss-darwin-x64 "1.19.0" - lightningcss-linux-arm-gnueabihf "1.19.0" - lightningcss-linux-arm64-gnu "1.19.0" - lightningcss-linux-arm64-musl "1.19.0" - lightningcss-linux-x64-gnu "1.19.0" - lightningcss-linux-x64-musl "1.19.0" - lightningcss-win32-x64-msvc "1.19.0" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lmdb@2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz" - integrity sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA== - dependencies: - msgpackr "^1.5.4" - node-addon-api "^4.3.0" - node-gyp-build-optional-packages "5.0.3" - ordered-binary "^1.2.4" - weak-lru-cache "^1.2.2" - optionalDependencies: - "@lmdb/lmdb-darwin-arm64" "2.5.2" - "@lmdb/lmdb-darwin-x64" "2.5.2" - "@lmdb/lmdb-linux-arm" "2.5.2" - "@lmdb/lmdb-linux-arm64" "2.5.2" - "@lmdb/lmdb-linux-x64" "2.5.2" - "@lmdb/lmdb-win32-x64" "2.5.2" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -mp4box@^0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/mp4box/-/mp4box-0.5.2.tgz" - integrity sha512-zRmGlvxy+YdW3Dmt+TR4xPHynbxwXtAQDTN/Fo9N3LMxaUlB2C5KmZpzYyGKy4c7k4Jf3RCR0A2pm9SZELOLXw== - -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== - -msgpackr-extract@^3.0.1: - version "3.0.2" - resolved "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz" - integrity sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A== - dependencies: - node-gyp-build-optional-packages "5.0.7" - optionalDependencies: - "@msgpackr-extract/msgpackr-extract-darwin-arm64" "3.0.2" - "@msgpackr-extract/msgpackr-extract-darwin-x64" "3.0.2" - "@msgpackr-extract/msgpackr-extract-linux-arm" "3.0.2" - "@msgpackr-extract/msgpackr-extract-linux-arm64" "3.0.2" - "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.2" - "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.2" - -msgpackr@^1.5.4: - version "1.8.5" - resolved "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.5.tgz" - integrity sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg== - optionalDependencies: - msgpackr-extract "^3.0.1" - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -node-addon-api@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-addon-api@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - -node-gyp-build-optional-packages@5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz" - integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== - -node-gyp-build-optional-packages@5.0.7: - version "5.0.7" - resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz" - integrity sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w== - -node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== - -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -nullthrows@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz" - integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== - -once@^1.3.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" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -ordered-binary@^1.2.4: - version "1.4.0" - resolved "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz" - integrity sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ== - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -parcel@^2.8.0: - version "2.8.3" - resolved "https://registry.npmjs.org/parcel/-/parcel-2.8.3.tgz" - integrity sha512-5rMBpbNE72g6jZvkdR5gS2nyhwIXaJy8i65osOqs/+5b7zgf3eMKgjSsDrv6bhz3gzifsba6MBJiZdBckl+vnA== - dependencies: - "@parcel/config-default" "2.8.3" - "@parcel/core" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/events" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/package-manager" "2.8.3" - "@parcel/reporter-cli" "2.8.3" - "@parcel/reporter-dev-server" "2.8.3" - "@parcel/utils" "2.8.3" - chalk "^4.1.0" - commander "^7.0.0" - get-port "^4.2.0" - v8-compile-cache "^2.0.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - 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-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -posthtml-parser@^0.10.1: - version "0.10.2" - resolved "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.10.2.tgz" - integrity sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg== - dependencies: - htmlparser2 "^7.1.1" - -posthtml-parser@^0.11.0: - version "0.11.0" - resolved "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz" - integrity sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw== - dependencies: - htmlparser2 "^7.1.1" - -posthtml-render@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz" - integrity sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA== - dependencies: - is-json "^2.0.1" - -posthtml@^0.16.4, posthtml@^0.16.5: - version "0.16.6" - resolved "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz" - integrity sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ== - dependencies: - posthtml-parser "^0.11.0" - posthtml-render "^3.0.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier@^2.8.8: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -react-error-overlay@6.0.9: - version "6.0.9" - resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz" - integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== - -react-refresh@^0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz" - integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== - -regenerator-runtime@^0.13.7: - version "0.13.11" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -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== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@^5.0.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -semver@^5.7.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^7.3.7: - version "7.5.1" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz" - integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== - dependencies: - lru-cache "^6.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-support@~0.5.20: - 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.6.0, 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== - -srcset@4: - version "4.0.0" - resolved "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz" - integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -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-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -svgo@^2.4.0: - version "2.8.0" - resolved "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - picocolors "^1.0.0" - stable "^0.1.8" - -term-size@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz" - integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== - -terser@^5.2.0: - version "5.16.8" - resolved "https://registry.npmjs.org/terser/-/terser-5.16.8.tgz" - integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== - dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz" - integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A== - -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" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.4.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -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" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -typescript@^5.0.4: - version "5.0.4" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== - -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -utility-types@^3.10.0: - version "3.10.0" - resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz" - integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== - -v8-compile-cache@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -weak-lru-cache@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz" - integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xxhash-wasm@^0.4.2: - version "0.4.2" - resolved "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz" - integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==