From 507046da2c1be86b80d2b3422a541e5d18a19919 Mon Sep 17 00:00:00 2001 From: Sameh Abouel-saad Date: Wed, 3 Jun 2026 04:42:10 +0300 Subject: [PATCH] feat(bridge): batch withdraw/refund proposals (force_batch API + E2E harness) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Batching-focused extraction of the remaining unique work from the old #1079 draft, rebuilt cleanly on current development. Contains the batching API layer (unwired) and the local E2E test harness; the handler integration is intentionally NOT included — it must be rebuilt on top of the per-tx idempotency work (#1096) when this is picked up. Batching API: - clients/tfchain-client-go/batch.go: BatchCalls — submits N calls in a single Utility.force_batch extrinsic (continues through per-item failures, unlike batch/batch_all). Returns a BatchResult. - pkg/substrate/client.go: BurnProposal/RefundProposal + BatchProposeAll (batched propose) and BatchSetWithdrawExecuted/BatchSetRefundTransaction- Executed (batched confirm), each with single-item + whole-batch fallback to the existing Retry* paths. - pkg/substrate/events.go: populate the (already-declared) RefundCreatedEvents so the batch proposer can see RefundTransactionCreated events. Local E2E test harness (scripts/ + Makefile + docs): - scripts/bridge_*.js + wait_for_node.js: single- and multi-validator (2-of-3) end-to-end scenarios incl. crash recovery, double-spend, and backlog-drain. - Makefile: bridge-dev / bridge-test / bridge-mv-* targets to spin up TFChain + bridge(s) and run the suite. - bridge/docs/local_development_setup.md. KNOWN FOLLOW-UPS before this is production-ready (from review of #1079): 1. force_batch ItemFailed carries no index — re-derive true per-item outcomes (IsBurnedAlready / signature presence) instead of trusting the aggregate count, or use Utility.batch + BatchInterrupted.Index. 2. Failure count is whole-block, phase-unfiltered — filter Utility_ItemFailed by the batch extrinsic's phase (mirror checkForError) and clamp. 3. No size cap — chunk calls into bounded sub-batches (avoid block-weight cliff on backlog drain). 4. Wire the handler integration on top of #1096's per-tx submit, and add Go unit tests for BatchCalls / the proposal mapping. Motivating issues: #1053 (Ready-processing delays / accumulating txs), #1054 (bridge atomicity). Co-Authored-By: Claude Opus 4.8 (1M context) --- Makefile | 326 +- bridge/docs/local_development_setup.md | 256 + bridge/tfchain_bridge/pkg/substrate/client.go | 165 + bridge/tfchain_bridge/pkg/substrate/events.go | 16 + clients/tfchain-client-go/batch.go | 69 + scripts/bridge_accounts.js | 165 + scripts/bridge_helpers.js | 209 + scripts/bridge_instrumentation.js | 1067 ++++ scripts/bridge_mv_accounts.js | 205 + scripts/bridge_mv_setup.js | 185 + scripts/bridge_mv_tests.js | 728 +++ scripts/bridge_setup.js | 123 + scripts/bridge_tests.js | 654 +++ scripts/package-lock.json | 4690 +++++++++++++++++ scripts/package.json | 1 + scripts/wait_for_node.js | 55 + scripts/yarn.lock | 1138 ++-- 17 files changed, 9633 insertions(+), 419 deletions(-) create mode 100644 bridge/docs/local_development_setup.md create mode 100644 clients/tfchain-client-go/batch.go create mode 100644 scripts/bridge_accounts.js create mode 100644 scripts/bridge_helpers.js create mode 100644 scripts/bridge_instrumentation.js create mode 100644 scripts/bridge_mv_accounts.js create mode 100644 scripts/bridge_mv_setup.js create mode 100644 scripts/bridge_mv_tests.js create mode 100644 scripts/bridge_setup.js create mode 100644 scripts/bridge_tests.js create mode 100644 scripts/package-lock.json create mode 100644 scripts/wait_for_node.js diff --git a/Makefile b/Makefile index cc94da7cf..f74cb2edf 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,323 @@ +SHELL := /bin/bash +.SHELLFLAGS := -eu -o pipefail -c + +# ───────────────────────────────────────────────────────────────────────────── +# Bridge local development environment +# ───────────────────────────────────────────────────────────────────────────── +# +# Quick start (first run builds TFChain — takes 20-40 min): +# make bridge-dev # single validator +# make bridge-mv-dev # 3 validators, 2-of-3 multi-sig +# +# Configurable: +# TFCHAIN_URL WebSocket URL (default: ws://localhost:9944) +# BRIDGE_ENV_FILE Env file path (default: /tmp/bridge_local_env.sh) +# BRIDGE_MV_ENV_FILE MV env file (default: /tmp/bridge_mv_env.sh) +# TFCHAIN_BIN TFChain binary path (default: release; use debug to skip 30-min build) +# e.g. TFCHAIN_BIN=substrate-node/target/debug/tfchain make bridge-dev +# BRIDGE_NETWORK Bridge --network flag (default: local) +# TFCHAIN_PORT TFChain WS port (default: 9944) + +BRIDGE_DIR := bridge/tfchain_bridge +BRIDGE_BIN := $(BRIDGE_DIR)/tfchain_bridge_local +TFCHAIN_BIN ?= substrate-node/target/release/tfchain +SCRIPTS_DIR := scripts + +BRIDGE_LOG := /tmp/bridge_local.log +BRIDGE_PID_FILE := /tmp/bridge_local.pid +TFCHAIN_LOG := /tmp/tfchain_local.log +TFCHAIN_PID_FILE := /tmp/tfchain_local.pid + +BRIDGE_ENV_FILE ?= /tmp/bridge_local_env.sh +BRIDGE_MV_ENV_FILE ?= /tmp/bridge_mv_env.sh +TFCHAIN_URL ?= ws://localhost:9944 +BRIDGE_NETWORK ?= local +TFCHAIN_PORT ?= 9944 + +# Bridge validator dev seeds (from substrate-node/node/src/chain_spec.rs) +# Single source of truth — passed as env vars to scripts via Makefile recipes. +VAL1_TFCHAIN_SEED ?= quarter between satisfy three sphere six soda boss cute decade old trend +VAL2_TFCHAIN_SEED ?= employ split promote annual couple elder remain cricket company fitness senior fiscal +VAL3_TFCHAIN_SEED ?= remind bird banner word spread volume card keep want faith insect mind + +.PHONY: bridge-help bridge-build bridge-build-tfchain \ + bridge-accounts bridge-mv-accounts \ + bridge-tfchain-start bridge-tfchain-stop \ + bridge-setup bridge-mv-setup \ + bridge-start bridge-stop bridge-test bridge-clean bridge-dev \ + bridge-mv-start bridge-mv-stop bridge-mv-test bridge-mv-clean bridge-mv-dev + +# ───────────────────────────────────────────────────────────────────────────── +# Daemon helpers +# ───────────────────────────────────────────────────────────────────────────── + +# Start a daemon, write its PID, verify it's alive after 1s. +# Usage: $(call start_daemon,Name,command,logfile,pidfile) +define start_daemon + @echo "==> Starting $(1)..." + @nohup $(2) > $(3) 2>&1 & echo $$! > $(4) + @sleep 1 + @PID=$$(cat $(4)); \ + if kill -0 $$PID 2>/dev/null; then \ + echo "==> $(1) started (PID $$PID)"; \ + else \ + echo "ERROR: $(1) failed to start. Check $(3)"; \ + exit 1; \ + fi +endef + +# Like start_daemon but sources an env file first (in the same shell as nohup, +# so exported variables are inherited by the child process). +# +# IMPORTANT: uses ";" not "&&" between the source and nohup commands. +# With "&&", bash backgrounds the entire compound command as a subshell, +# so $! captures the subshell PID — not the bridge PID. When stop_daemon +# later kills that (already-exited) subshell PID, the bridge process +# becomes an orphan and keeps running. With ";", the source runs in the +# foreground shell and only "nohup cmd &" is backgrounded, so $! is the +# actual bridge PID. set -e (from .SHELLFLAGS) still ensures a failed +# source aborts before nohup runs. +# +# Usage: $(call start_daemon_with_env,Name,envfile,command,logfile,pidfile) +define start_daemon_with_env + @echo "==> Starting $(1)..." + @. $(2); nohup $(3) > $(4) 2>&1 & echo $$! > $(5) + @sleep 1 + @PID=$$(cat $(5)); \ + if kill -0 $$PID 2>/dev/null; then \ + echo "==> $(1) started (PID $$PID)"; \ + else \ + echo "ERROR: $(1) failed to start. Check $(4)"; \ + exit 1; \ + fi +endef + +# Stop a daemon via its PID file and wait for it to fully exit. +# Sends SIGTERM, waits up to 10s, then SIGKILL if still alive. +# No pkill — avoids terminating the make shell. +# Usage: $(call stop_daemon,Name,pidfile) +define stop_daemon + @if [ -f $(2) ]; then \ + PID=$$(cat $(2)); \ + if kill -0 $$PID 2>/dev/null; then \ + kill $$PID; \ + i=0; \ + while kill -0 $$PID 2>/dev/null && [ $$i -lt 10 ]; do \ + sleep 1; i=$$((i+1)); \ + done; \ + if kill -0 $$PID 2>/dev/null; then \ + echo "==> $(1): SIGTERM ignored, sending SIGKILL..."; \ + kill -9 $$PID 2>/dev/null || true; \ + fi; \ + echo "==> $(1) stopped (PID $$PID)"; \ + else \ + echo "==> $(1) process not running (stale PID $$PID)"; \ + fi; \ + rm -f $(2); \ + else \ + echo "==> $(1) not running (no PID file)"; \ + fi +endef + +# ───────────────────────────────────────────────────────────────────────────── +# Help +# ───────────────────────────────────────────────────────────────────────────── + +bridge-help: + @grep -E '^bridge-[a-z-]+:' $(MAKEFILE_LIST) | sed 's/:.*//' | sort + +# ───────────────────────────────────────────────────────────────────────────── +# Build +# ───────────────────────────────────────────────────────────────────────────── + +bridge-build: + @echo "==> Building bridge..." + cd $(BRIDGE_DIR) && go build -o tfchain_bridge_local . + @echo "==> Bridge binary: $(BRIDGE_BIN)" + +bridge-build-tfchain: + @echo "==> Building TFChain (may take 20-40 min first time)..." + cd substrate-node && cargo build --release + @echo "==> TFChain binary: $(TFCHAIN_BIN)" + +# ───────────────────────────────────────────────────────────────────────────── +# Accounts +# ───────────────────────────────────────────────────────────────────────────── + +bridge-accounts: + cd $(SCRIPTS_DIR) && npm install --silent + BRIDGE_ENV_FILE=$(BRIDGE_ENV_FILE) node $(SCRIPTS_DIR)/bridge_accounts.js + +bridge-mv-accounts: + cd $(SCRIPTS_DIR) && npm install --silent + BRIDGE_MV_ENV_FILE=$(BRIDGE_MV_ENV_FILE) node $(SCRIPTS_DIR)/bridge_mv_accounts.js + +# ───────────────────────────────────────────────────────────────────────────── +# TFChain +# ───────────────────────────────────────────────────────────────────────────── + +bridge-tfchain-start: + @test -f $(TFCHAIN_BIN) || { echo "Run: make bridge-build-tfchain"; exit 1; } + $(call stop_daemon,TFChain,$(TFCHAIN_PID_FILE)) + @lsof -ti tcp:$(TFCHAIN_PORT) | xargs kill 2>/dev/null && sleep 1 || true + $(call start_daemon,TFChain,$(TFCHAIN_BIN) --dev --tmp,$(TFCHAIN_LOG),$(TFCHAIN_PID_FILE)) + @echo "==> Waiting for node..." + TFCHAIN_URL=$(TFCHAIN_URL) node $(SCRIPTS_DIR)/wait_for_node.js + +bridge-tfchain-stop: + $(call stop_daemon,TFChain,$(TFCHAIN_PID_FILE)) + @lsof -ti tcp:$(TFCHAIN_PORT) | xargs kill 2>/dev/null && sleep 1 || true + +# ───────────────────────────────────────────────────────────────────────────── +# Bridge setup +# ───────────────────────────────────────────────────────────────────────────── + +bridge-setup: + @test -f $(BRIDGE_ENV_FILE) || { echo "Run: make bridge-accounts"; exit 1; } + TFCHAIN_URL=$(TFCHAIN_URL) \ + BRIDGE_ENV_FILE=$(BRIDGE_ENV_FILE) \ + node $(SCRIPTS_DIR)/bridge_setup.js + +bridge-mv-setup: + @test -f $(BRIDGE_MV_ENV_FILE) || { echo "Run: make bridge-mv-accounts"; exit 1; } + TFCHAIN_URL=$(TFCHAIN_URL) \ + BRIDGE_MV_ENV_FILE=$(BRIDGE_MV_ENV_FILE) \ + VAL2_TFCHAIN_SEED="$(VAL2_TFCHAIN_SEED)" \ + VAL3_TFCHAIN_SEED="$(VAL3_TFCHAIN_SEED)" \ + node $(SCRIPTS_DIR)/bridge_mv_setup.js + +# ───────────────────────────────────────────────────────────────────────────── +# Bridge daemon (single-validator) +# ───────────────────────────────────────────────────────────────────────────── +# +# Note: start_daemon_with_env sources BRIDGE_ENV_FILE inside the same shell +# as nohup so that BRIDGE_SECRET and BRIDGE_ADDRESS are inherited by the +# child process. Sourcing in a separate @-line would not work — each @-line +# is an independent shell invocation. + +bridge-start: + @test -f $(BRIDGE_BIN) || { echo "Run: make bridge-build"; exit 1; } + @test -f $(BRIDGE_ENV_FILE) || { echo "Run: make bridge-accounts"; exit 1; } + $(call start_daemon_with_env,Bridge,$(BRIDGE_ENV_FILE),$(BRIDGE_BIN) \ + --secret "$$BRIDGE_SECRET" \ + --tfchainurl $(TFCHAIN_URL) \ + --tfchainseed "$(VAL1_TFCHAIN_SEED)" \ + --bridgewallet "$$BRIDGE_ADDRESS" \ + --persistency $(BRIDGE_DIR)/signer_local.json \ + --network $(BRIDGE_NETWORK),$(BRIDGE_LOG),$(BRIDGE_PID_FILE)) + @echo "==> Waiting for bridge to be ready..." + @i=0; \ + while [ $$i -lt 30 ] && ! grep -q "bridge_started" $(BRIDGE_LOG) 2>/dev/null; do \ + sleep 1; i=$$((i+1)); \ + done; \ + if grep -q "bridge_started" $(BRIDGE_LOG) 2>/dev/null; then \ + echo "==> Bridge ready."; \ + else \ + echo "==> Warning: bridge_started not seen in 30s, check $(BRIDGE_LOG)"; \ + fi + +bridge-stop: + $(call stop_daemon,Bridge,$(BRIDGE_PID_FILE)) + +bridge-test: + @test -f $(BRIDGE_ENV_FILE) || { echo "Run: make bridge-accounts"; exit 1; } + @echo "==> Running bridge E2E tests..." + TFCHAIN_URL=$(TFCHAIN_URL) \ + BRIDGE_ENV_FILE=$(BRIDGE_ENV_FILE) \ + BRIDGE_PID_FILE=$(BRIDGE_PID_FILE) \ + BRIDGE_LOG_FILE=$(BRIDGE_LOG) \ + BRIDGE_BIN=$(BRIDGE_BIN) \ + VAL1_TFCHAIN_SEED="$(VAL1_TFCHAIN_SEED)" \ + node $(SCRIPTS_DIR)/bridge_tests.js + +bridge-clean: bridge-stop bridge-tfchain-stop + rm -f $(BRIDGE_DIR)/signer_local.json + rm -f $(BRIDGE_DIR)/signer_local.json.idem.db + rm -f $(BRIDGE_LOG) $(TFCHAIN_LOG) + rm -f $(BRIDGE_PID_FILE) $(TFCHAIN_PID_FILE) + rm -f $(BRIDGE_ENV_FILE) + +bridge-dev: bridge-clean bridge-build $(TFCHAIN_BIN) bridge-accounts \ + bridge-tfchain-start bridge-setup bridge-start bridge-test + +# ───────────────────────────────────────────────────────────────────────────── +# Multi-validator bridge +# ───────────────────────────────────────────────────────────────────────────── + +bridge-mv-start: + @test -f $(BRIDGE_BIN) || { echo "Run: make bridge-build"; exit 1; } + @test -f $(BRIDGE_MV_ENV_FILE) || { echo "Run: make bridge-mv-accounts"; exit 1; } + $(call start_daemon_with_env,Val1,$(BRIDGE_MV_ENV_FILE),$(BRIDGE_BIN) \ + --secret "$$VAL1_STELLAR_SECRET" \ + --tfchainurl $(TFCHAIN_URL) \ + --tfchainseed "$(VAL1_TFCHAIN_SEED)" \ + --bridgewallet "$$BRIDGE_ADDRESS" \ + --persistency $(BRIDGE_DIR)/signer_mv_1.json \ + --network $(BRIDGE_NETWORK),/tmp/bridge_mv_1.log,/tmp/bridge_mv_1.pid) + $(call start_daemon_with_env,Val2,$(BRIDGE_MV_ENV_FILE),$(BRIDGE_BIN) \ + --secret "$$VAL2_STELLAR_SECRET" \ + --tfchainurl $(TFCHAIN_URL) \ + --tfchainseed "$(VAL2_TFCHAIN_SEED)" \ + --bridgewallet "$$BRIDGE_ADDRESS" \ + --persistency $(BRIDGE_DIR)/signer_mv_2.json \ + --network $(BRIDGE_NETWORK),/tmp/bridge_mv_2.log,/tmp/bridge_mv_2.pid) + $(call start_daemon_with_env,Val3,$(BRIDGE_MV_ENV_FILE),$(BRIDGE_BIN) \ + --secret "$$VAL3_STELLAR_SECRET" \ + --tfchainurl $(TFCHAIN_URL) \ + --tfchainseed "$(VAL3_TFCHAIN_SEED)" \ + --bridgewallet "$$BRIDGE_ADDRESS" \ + --persistency $(BRIDGE_DIR)/signer_mv_3.json \ + --network $(BRIDGE_NETWORK),/tmp/bridge_mv_3.log,/tmp/bridge_mv_3.pid) + @echo "==> Waiting for validators to be ready..." + @for i in 1 2 3; do \ + j=0; \ + while [ $$j -lt 30 ] && ! grep -q bridge_started /tmp/bridge_mv_$$i.log 2>/dev/null; do \ + sleep 1; j=$$((j+1)); \ + done; \ + if grep -q bridge_started /tmp/bridge_mv_$$i.log 2>/dev/null; then \ + echo "==> Val$$i ready"; \ + else \ + echo "==> WARNING: Val$$i bridge_started not seen in 30s. Last lines:"; \ + tail -5 /tmp/bridge_mv_$$i.log 2>/dev/null || echo "(no log)"; \ + fi; \ + done + +bridge-mv-stop: + $(call stop_daemon,Val1,/tmp/bridge_mv_1.pid) + $(call stop_daemon,Val2,/tmp/bridge_mv_2.pid) + $(call stop_daemon,Val3,/tmp/bridge_mv_3.pid) + +bridge-mv-test: + @test -f $(BRIDGE_MV_ENV_FILE) || { echo "Run: make bridge-mv-accounts"; exit 1; } + @echo "==> Running multi-validator E2E tests..." + TFCHAIN_URL=$(TFCHAIN_URL) \ + BRIDGE_MV_ENV_FILE=$(BRIDGE_MV_ENV_FILE) \ + BRIDGE_BIN=$(BRIDGE_BIN) \ + BRIDGE_DIR=$(BRIDGE_DIR) \ + VAL1_TFCHAIN_SEED="$(VAL1_TFCHAIN_SEED)" \ + VAL2_TFCHAIN_SEED="$(VAL2_TFCHAIN_SEED)" \ + VAL3_TFCHAIN_SEED="$(VAL3_TFCHAIN_SEED)" \ + node $(SCRIPTS_DIR)/bridge_mv_tests.js + +bridge-mv-clean: bridge-mv-stop bridge-tfchain-stop + rm -f $(BRIDGE_DIR)/signer_mv_*.json + rm -f $(BRIDGE_DIR)/signer_mv_*.json.idem.db + rm -f /tmp/bridge_mv_*.log + rm -f /tmp/bridge_mv_*.pid + rm -f $(TFCHAIN_LOG) $(TFCHAIN_PID_FILE) + rm -f $(BRIDGE_MV_ENV_FILE) + +bridge-mv-dev: bridge-mv-clean bridge-build $(TFCHAIN_BIN) bridge-mv-accounts \ + bridge-tfchain-start bridge-mv-setup bridge-mv-start bridge-mv-test + +# Build TFChain only if binary is missing (expensive Rust build) +$(TFCHAIN_BIN): + $(MAKE) bridge-build-tfchain + +# ───────────────────────────────────────────────────────────────────────────── +# End bridge local development environment +# ───────────────────────────────────────────────────────────────────────────── + .PHONY: version-bump # * Usage Examples:* @@ -16,8 +336,8 @@ version-bump: branch_name="$$default_branch-bump-version-to-$$new_version"; \ git checkout -b $$branch_name; \ current_spec_version=$$(sed -n -e 's/^.*spec_version: \([0-9]\+\),$$/\1/p' substrate-node/runtime/src/lib.rs); \ - if [ -z "$${retain_spec_version}" ]; then \ - current_spec_version=$$(sed -n -e 's/^.*spec_version: \([0-9]\+\),$$/\1/p' substrate-node/runtime/src/lib.rs); \ + new_spec_version=""; \ + if [ -z "$${retain_spec_version:-}" ]; then \ echo "Current spec_version: $$current_spec_version"; \ new_spec_version=$$((current_spec_version + 1)); \ echo "New spec_version: $$new_spec_version"; \ @@ -36,7 +356,7 @@ version-bump: sed -i "s/^appVersion: .*/appVersion: '$$new_version'/" activation-service/helm/tfchainactivationservice/Chart.yaml; \ cd substrate-node && cargo metadata -q 1> /dev/null && cd ..; \ git add substrate-node/Cargo.toml substrate-node/Cargo.lock substrate-node/charts/substrate-node/Chart.yaml bridge/tfchain_bridge/chart/tfchainbridge/Chart.yaml activation-service/helm/tfchainactivationservice/Chart.yaml activation-service/package.json clients/tfchain-client-js/package.json scripts/package.json tools/fork-off-substrate/package.json substrate-node/runtime/src/lib.rs; \ - if [ -z "$${new_spec_version}" ]; then \ + if [ -z "$${new_spec_version:-}" ]; then \ git commit -m "Bump version to $$new_version"; \ else \ git commit -m "Bump version to $$new_version (spec v$$new_spec_version)"; \ diff --git a/bridge/docs/local_development_setup.md b/bridge/docs/local_development_setup.md new file mode 100644 index 000000000..a3e35b181 --- /dev/null +++ b/bridge/docs/local_development_setup.md @@ -0,0 +1,256 @@ +# Bridge Local Development Setup + +This document describes how to run a complete local bridge environment for development and +testing — single-validator and multi-validator — using the Make targets provided in the +repository root. + +--- + +## Prerequisites + +| Tool | Minimum version | Notes | +|---|---|---| +| Go | 1.21 | `go version` | +| Rust + Cargo | stable | via [rustup](https://rustup.rs/) | +| Node.js + npm | 18 | `node --version` | +| Internet | — | Stellar testnet (Friendbot + Horizon) | + +--- + +## Quick Start + +### Single-validator + +```bash +make bridge-dev +``` + +That's it. On first run this builds TFChain (Rust, ~20–40 min). Every subsequent run reuses +the existing binary and takes ~1 min. + +### Multi-validator (3 daemons, 2-of-3 threshold) + +```bash +make bridge-mv-dev +``` + +Same one-shot command. Spins up 3 bridge daemons (Alice, Bob, Charlie), configures the bridge +Stellar account as a 2-of-3 multi-sig, and runs the full MV test suite. + +--- + +## What `make bridge-dev` Does + +| Step | Target | What happens | +|---|---|---| +| 1 | `bridge-clean` | Kill any running bridge/TFChain processes, delete persistency files and logs | +| 2 | `bridge-build` | `go build` the bridge binary (fast, ~5s) | +| 3 | _(auto)_ | Build TFChain node if binary missing (`substrate-node/target/release/tfchain`) | +| 4 | `bridge-accounts` | Generate fresh Stellar keypairs; fund via Friendbot; create TFT trustlines; issue TFT to bridge via `path_payment_strict_send` and to user via `payment`; write `/tmp/bridge_local_env.sh` | +| 5 | `bridge-tfchain-start` | Start TFChain `--dev --tmp`; poll WS until node is ready | +| 6 | `bridge-setup` | Register Alice as bridge validator; set bridge wallet, fee account, deposit/withdraw fees via sudo | +| 7 | `bridge-start` | Start bridge daemon; wait for `bridge_started` log entry | +| 8 | `bridge-test` | Run 4-scenario E2E test suite | + +TFChain is built once via Make's file-dependency model. If `substrate-node/target/release/tfchain` +already exists, the Rust build step is skipped entirely. + +--- + +## Individual Targets + +```bash +# Build +make bridge-build # Go build only (fast) +make bridge-build-tfchain # Rust build (slow, one-time) + +# Environment lifecycle +make bridge-accounts # (Re)generate Stellar accounts → /tmp/bridge_local_env.sh +make bridge-tfchain-start # Start TFChain dev node +make bridge-setup # Configure bridge pallet on TFChain +make bridge-start # Start bridge daemon +make bridge-stop # Stop bridge daemon +make bridge-tfchain-stop # Stop TFChain node +make bridge-clean # Stop everything + delete all local state + +# Testing +make bridge-test # Run E2E tests against a running environment +``` + +### Configuration overrides + +All targets accept environment variable overrides: + +```bash +TFCHAIN_URL=ws://localhost:9944 \ # default +BRIDGE_TFT_FLOAT=20000 \ # TFT issued to bridge wallet +USER_TFT_AMOUNT=1000 \ # TFT issued to test user +DEPOSIT_FEE=10000000 \ # 1 TFT (7 decimal places) +WITHDRAW_FEE=10000000 \ # 1 TFT +BRIDGE_ENV_FILE=/tmp/bridge_local_env.sh \ + make bridge-dev +``` + +--- + +## Account Sharing Between Steps + +All scripts share account details via a single env file written by `make bridge-accounts`: + +``` +/tmp/bridge_local_env.sh # single-validator +/tmp/bridge_mv_env.sh # multi-validator +``` + +Each subsequent script (`bridge_setup.js`, `bridge_tests.js`, etc.) calls `loadEnv()` at +startup to read this file into `process.env`. The Makefile shell targets source it for +`BRIDGE_SECRET`, `BRIDGE_ADDRESS`, etc. + +Re-running `make bridge-accounts` generates fresh Stellar keypairs and invalidates the current +environment — you would need to re-run `bridge-setup` and `bridge-start` as well. The +`make bridge-clean` + `make bridge-dev` cycle handles this automatically. + +--- + +## Logs + +```bash +tail -f /tmp/bridge_local.log # bridge daemon +tail -f /tmp/tfchain_local.log # TFChain node + +# Multi-validator +tail -f /tmp/bridge_mv_1.log # Val1 (Alice) +tail -f /tmp/bridge_mv_2.log # Val2 (Bob) +tail -f /tmp/bridge_mv_3.log # Val3 (Charlie) +``` + +--- + +## Tests + +### Single-validator tests (`make bridge-test`) + +| Test | Description | Expected outcome | +|---|---|---| +| 1 | Normal withdraw | Swap 2 TFT on TFChain → receive 1 TFT on Stellar (1 TFT fee) | +| 2 | Batch withdraws | 5 simultaneous swaps in one block → all 5 delivered | +| 3 | Bad deposit | Send TFT to bridge without memo → full refund on Stellar | +| 4 | Crash recovery | SIGKILL bridge mid-withdraw → restart → delivery completes | + +### Multi-validator tests (`make bridge-mv-test`) + +| Test | Description | Expected outcome | +|---|---|---| +| MV1 | Normal withdraw | 3 validators, threshold=2; 1 TFT delivered | +| MV2 | Deposit/mint | All 3 validators propose; mint threshold met | +| MV3 | Bad deposit | All 3 detect bad deposit; full refund delivered | +| MV4 | Validator offline | Val3 killed; Val1+Val2 meet threshold=2; refund works; Val3 restarted after | +| MV5 | Batch withdraws | 3 simultaneous burns; all 3 delivered (uses expiry recovery if sequence collision) | + +The test runner exits non-zero on any failure, making it composable with CI. + +--- + +## Multi-validator Setup Details + +### What `make bridge-mv-dev` does + +| Step | Target | What happens | +|---|---|---| +| 1 | `bridge-mv-clean` | Kill all 3 daemons, delete MV persistency files and logs | +| 2 | `bridge-build` | Build bridge binary | +| 3 | _(auto)_ | Build TFChain if binary missing | +| 4 | `bridge-mv-accounts` | Generate 4 keypairs (val1=bridge, val2, val3, user); fund via Friendbot; create trustlines; fund bridge via `path_payment_strict_send`; configure bridge as 2-of-3 multi-sig (val1 master key, val2+val3 added as signers, thresholds: low=1, med=2, high=3); write `/tmp/bridge_mv_env.sh` | +| 5 | `bridge-tfchain-start` | Start TFChain dev node | +| 6 | `bridge-mv-setup` | Create twins for Alice, Bob, Charlie; register all 3 as validators; set bridge wallet, fee account, fees | +| 7 | `bridge-mv-start` | Start 3 bridge daemons; wait for all 3 to log `bridge_started` | +| 8 | `bridge-mv-test` | Run MV1–MV5 test suite | + +### Multi-sig architecture + +``` +Bridge Stellar account = Val1's keypair (master key, weight=1) +Val2 keypair added as signer (weight=1) +Val3 keypair added as signer (weight=1) + +Thresholds: + low = 1 (any 1 of 3 can change account options) + med = 2 (any 2 of 3 must sign TFT payment transactions) + high = 3 (all 3 must sign for account deletion etc.) +``` + +Each bridge daemon signs with its own validator Stellar key and stores its signature on TFChain. +When `BurnTransactionReady` or `RefundTransactionReady` fires, the first validator to receive it +fetches all stored signatures from TFChain and builds a multi-sig Stellar transaction meeting +the threshold. + +--- + +## Fee Mechanics + +TFT uses 7 decimal places: `1 TFT = 10,000,000 base units`. +Default fees are 1 TFT each (configurable via `DEPOSIT_FEE` and `WITHDRAW_FEE`). + +### Deposit (Stellar → TFChain) + +Two enforcement layers: + +1. **Bridge** (`mint.go`): if incoming Stellar amount ≤ `DepositFee`, bridge refunds on Stellar + without proposing a mint (avoids an on-chain tx that would fail anyway). +2. **Pallet** (`execute_mint_transaction`): deducts `DepositFee` and mints `amount - deposit_fee` + to the user's TFChain account. + +### Withdraw (TFChain → Stellar) + +One enforcement layer: + +1. **Pallet** (`swap_to_stellar`): rejects if `amount ≤ WithdrawFee` with + `AmountIsLessThanWithdrawFee`. If valid, stores `burn_amount = amount - withdraw_fee` in the + event. The bridge reads this value directly and sends it to Stellar — no additional fee applied. + +--- + +## Bridge Funding: Why `path_payment_strict_send` + +The bridge Stellar deposit monitor only watches `payment` operations on the bridge account. +A `path_payment_strict_send` operation is structurally different and is not picked up by the +monitor — so funding the bridge wallet this way does not trigger a spurious refund on startup +rescan. Always use `path_payment_strict_send` when issuing TFT to the bridge account in test +setup. + +--- + +## Idempotency and Crash Recovery + +The bridge writes an idempotency record (bbolt DB at `.idem.db`) before submitting +any Stellar transaction: + +- `PROCESSING`: Stellar tx may or may not have been submitted +- `COMPLETED`: Stellar tx submitted and TFChain confirmation done + +On restart, `reconcilePendingTransactions` scans all `PROCESSING` entries. For each: + +1. Fetch recent outgoing Stellar transactions from Horizon (single request, reused for all checks) +2. Search by memo text (primary) then by sequence number (fallback) +3. If found: proceed directly to TFChain confirmation — no double-spend +4. If not found: log `"no Stellar tx found by memo or sequence, safe to retry"` — re-submit on + next Ready event + +--- + +## Known Limitations + +1. **Sequence coordination under load**: All validators sign Stellar transactions at proposal time + with a fixed sequence number. If another Stellar transaction from the bridge account is + submitted between proposal and `Ready` events, the stored signatures reference a stale + sequence → all validators get `tx_bad_seq` on first attempt. Recovery is automatic via the + expiry cycle (~20 blocks, ~2 min delay). This is a pre-existing design constraint, not + introduced by this PR. + +2. **Stellar testnet Friendbot rate limits**: If Friendbot rejects account funding (rate limited + or account already exists with funds), re-running `make bridge-accounts` generates fresh + keypairs. This requires re-running `make bridge-setup` and `make bridge-start` as well — + or simply re-run `make bridge-dev` for a clean slate. + +3. **`--tmp` chain**: State is lost on TFChain restart. For persistent sessions, replace + `--tmp` with `--base-path /tmp/tfchain-data` in the `bridge-tfchain-start` Makefile target. diff --git a/bridge/tfchain_bridge/pkg/substrate/client.go b/bridge/tfchain_bridge/pkg/substrate/client.go index 614a1d27b..a47587e53 100644 --- a/bridge/tfchain_bridge/pkg/substrate/client.go +++ b/bridge/tfchain_bridge/pkg/substrate/client.go @@ -187,3 +187,168 @@ func (s *SubstrateClient) RetryProposeMintOrVote(ctx context.Context, txID strin return nil } + +// BurnProposal holds the parameters for a single propose_burn_transaction_or_add_sig call. +type BurnProposal struct { + TxID uint64 + Target string + Amount *big.Int + Signature string + StellarAddress string + SequenceNumber uint64 +} + +// RefundProposal holds the parameters for a single create_refund_transaction_or_add_sig call. +type RefundProposal struct { + TxHash string + Target string + Amount int64 + Signature string + StellarAddress string + SequenceNumber uint64 +} + +// BatchProposeAll submits all burn and refund proposal calls as a single +// Utility.force_batch extrinsic. Burns are submitted first, then refunds. +// Individual call failures do not abort the batch. +func (s *SubstrateClient) BatchProposeAll(ctx context.Context, burnProposals []BurnProposal, refundProposals []RefundProposal) (*substrate.BatchResult, error) { + total := len(burnProposals) + len(refundProposals) + if total == 0 { + return &substrate.BatchResult{}, nil + } + + _, meta, err := s.GetClient() + if err != nil { + return nil, err + } + + calls := make([]types.Call, 0, total) + for _, p := range burnProposals { + c, err := types.NewCall(meta, "TFTBridgeModule.propose_burn_transaction_or_add_sig", + p.TxID, p.Target, types.U64(p.Amount.Uint64()), p.Signature, p.StellarAddress, p.SequenceNumber, + ) + if err != nil { + return nil, err + } + calls = append(calls, c) + } + for _, p := range refundProposals { + c, err := types.NewCall(meta, "TFTBridgeModule.create_refund_transaction_or_add_sig", + p.TxHash, p.Target, types.U64(uint64(p.Amount)), p.Signature, p.StellarAddress, p.SequenceNumber, + ) + if err != nil { + return nil, err + } + calls = append(calls, c) + } + + return s.BatchCalls(s.identity, calls) +} + +// BatchSetWithdrawExecuted batches multiple set_burn_transaction_executed calls +// into a single Utility.force_batch extrinsic. Falls back to individual +// RetrySetWithdrawExecuted calls if the batch submission fails. +// +// Safety: set_burn_transaction_executed is idempotent (first-writer-wins). +// ItemFailed events in the batch are expected when another validator already +// executed the burn — force_batch continues through all calls regardless. +func (s *SubstrateClient) BatchSetWithdrawExecuted(ctx context.Context, txIDs []uint64) error { + if len(txIDs) == 0 { + return nil + } + // Single item — use existing retry path (more robust error handling + // with IsBurnedAlready polling for multi-validator races) + if len(txIDs) == 1 { + return s.RetrySetWithdrawExecuted(ctx, txIDs[0]) + } + + _, meta, err := s.GetClient() + if err != nil { + log.Warn().Err(err).Msg("batch SetWithdrawExecuted: client error, falling back to individual") + return s.fallbackRetryWithdraws(ctx, txIDs) + } + + calls := make([]types.Call, 0, len(txIDs)) + for _, txID := range txIDs { + call, err := types.NewCall(meta, "TFTBridgeModule.set_burn_transaction_executed", types.U64(txID)) + if err != nil { + return err + } + calls = append(calls, call) + } + + result, err := s.BatchCalls(s.identity, calls) + if err != nil { + log.Warn().Err(err).Int("count", len(txIDs)). + Msg("batch SetWithdrawExecuted failed, falling back to individual retries") + return s.fallbackRetryWithdraws(ctx, txIDs) + } + + log.Info(). + Int("success", result.SuccessCount). + Int("failed", result.FailedCount). + Int("total", len(txIDs)). + Msg("batch SetWithdrawExecuted completed") + + return nil +} + +func (s *SubstrateClient) fallbackRetryWithdraws(ctx context.Context, txIDs []uint64) error { + for _, txID := range txIDs { + if err := s.RetrySetWithdrawExecuted(ctx, txID); err != nil { + return err + } + } + return nil +} + +// BatchSetRefundTransactionExecuted batches multiple set_refund_transaction_executed +// calls into a single Utility.force_batch extrinsic. Falls back to individual +// RetrySetRefundTransactionExecutedTx calls if the batch submission fails. +func (s *SubstrateClient) BatchSetRefundTransactionExecuted(ctx context.Context, txHashes []string) error { + if len(txHashes) == 0 { + return nil + } + if len(txHashes) == 1 { + return s.RetrySetRefundTransactionExecutedTx(ctx, txHashes[0]) + } + + _, meta, err := s.GetClient() + if err != nil { + log.Warn().Err(err).Msg("batch SetRefundExecuted: client error, falling back to individual") + return s.fallbackRetryRefunds(ctx, txHashes) + } + + calls := make([]types.Call, 0, len(txHashes)) + for _, txHash := range txHashes { + call, err := types.NewCall(meta, "TFTBridgeModule.set_refund_transaction_executed", txHash) + if err != nil { + return err + } + calls = append(calls, call) + } + + result, err := s.BatchCalls(s.identity, calls) + if err != nil { + log.Warn().Err(err).Int("count", len(txHashes)). + Msg("batch SetRefundExecuted failed, falling back to individual retries") + return s.fallbackRetryRefunds(ctx, txHashes) + } + + log.Info(). + Int("success", result.SuccessCount). + Int("failed", result.FailedCount). + Int("total", len(txHashes)). + Msg("batch SetRefundTransactionExecuted completed") + + return nil +} + +func (s *SubstrateClient) fallbackRetryRefunds(ctx context.Context, txHashes []string) error { + for _, txHash := range txHashes { + if err := s.RetrySetRefundTransactionExecutedTx(ctx, txHash); err != nil { + return err + } + } + return nil +} diff --git a/bridge/tfchain_bridge/pkg/substrate/events.go b/bridge/tfchain_bridge/pkg/substrate/events.go index 466ac8655..0fa0f4ccc 100644 --- a/bridge/tfchain_bridge/pkg/substrate/events.go +++ b/bridge/tfchain_bridge/pkg/substrate/events.go @@ -130,12 +130,27 @@ func (client *SubstrateClient) processEventsForHeight(height uint32) (Events, er } func (client *SubstrateClient) processEventRecords(events *substrate.EventRecords) Events { + var refundCreatedEvents []RefundTransactionCreatedEvent var refundTransactionReadyEvents []RefundTransactionReadyEvent var refundTransactionExpiredEvents []RefundTransactionExpiredEvent var withdrawCreatedEvents []WithdrawCreatedEvent var withdrawReadyEvents []WithdrawReadyEvent var withdrawExpiredEvents []WithdrawExpiredEvent + for _, e := range events.TFTBridgeModule_RefundTransactionCreated { + log.Info(). + Str("trace_id", string(e.RefundTransactionHash)). + Str("event_action", "event_refund_tx_created_received"). + Str("event_kind", "event"). + Str("category", "refund"). + Msg("found RefundTransactionCreated event") + refundCreatedEvents = append(refundCreatedEvents, RefundTransactionCreatedEvent{ + Hash: string(e.RefundTransactionHash), + Target: string(e.Target), + Amount: uint64(e.Amount), + }) + } + for _, e := range events.TFTBridgeModule_RefundTransactionReady { log.Info(). Str("trace_id", string(e.RefundTransactionHash)). @@ -233,6 +248,7 @@ func (client *SubstrateClient) processEventRecords(events *substrate.EventRecord WithdrawCreatedEvents: withdrawCreatedEvents, WithdrawReadyEvents: withdrawReadyEvents, WithdrawExpiredEvents: withdrawExpiredEvents, + RefundCreatedEvents: refundCreatedEvents, RefundReadyEvents: refundTransactionReadyEvents, RefundExpiredEvents: refundTransactionExpiredEvents, } diff --git a/clients/tfchain-client-go/batch.go b/clients/tfchain-client-go/batch.go new file mode 100644 index 000000000..742003328 --- /dev/null +++ b/clients/tfchain-client-go/batch.go @@ -0,0 +1,69 @@ +package substrate + +import ( + "github.com/centrifuge/go-substrate-rpc-client/v4/types" + "github.com/pkg/errors" +) + +// BatchResult holds the outcome of a Utility.batch call. +type BatchResult struct { + SuccessCount int + FailedCount int + // FailedIndexes is only populated for BatchInterrupted (older runtimes), + // where we know the exact index that caused interruption. + FailedIndexes []int +} + +// BatchCalls submits multiple calls in a single Utility.force_batch extrinsic. +// Unlike Utility.batch_all (aborts + reverts on first failure) and Utility.batch +// (stops at first failure, remaining calls not executed), Utility.force_batch +// continues through all calls regardless of individual failures. Failed calls emit +// Utility.ItemFailed events; the overall batch always completes. +// This is the correct choice for bridge proposals: a BurnSignatureExists error on +// one proposal must not prevent the remaining proposals from being submitted. +func (s *Substrate) BatchCalls(identity Identity, calls []types.Call) (*BatchResult, error) { + if len(calls) == 0 { + return &BatchResult{}, nil + } + + cl, meta, err := s.GetClient() + if err != nil { + return nil, err + } + + batchCall, err := types.NewCall(meta, "Utility.force_batch", calls) + if err != nil { + return nil, errors.Wrap(err, "failed to create force_batch call") + } + + resp, err := s.Call(cl, meta, identity, batchCall) + if err != nil { + return nil, errors.Wrap(err, "failed to execute force_batch call") + } + + result := &BatchResult{ + SuccessCount: len(calls), + } + + if resp.Events != nil { + // ItemFailed events are emitted by force_batch for each failed call. + // The event payload does not carry the batch-call index — only a DispatchError. + // We count failures but cannot reliably map them to specific call positions. + // + // IMPORTANT: getEventRecords reads ALL events from the block, not just + // those emitted by this extrinsic. In multi-validator setups, multiple + // validators may submit force_batch extrinsics in the same block. Each + // validator sees ItemFailed events from ALL batches, inflating the count. + // Cap failedCount at len(calls) to prevent negative SuccessCount. + failedCount := len(resp.Events.Utility_ItemFailed) + if failedCount > len(calls) { + failedCount = len(calls) + } + if failedCount > 0 { + result.FailedCount = failedCount + result.SuccessCount = len(calls) - failedCount + } + } + + return result, nil +} diff --git a/scripts/bridge_accounts.js b/scripts/bridge_accounts.js new file mode 100644 index 000000000..004e76a4c --- /dev/null +++ b/scripts/bridge_accounts.js @@ -0,0 +1,165 @@ +#!/usr/bin/env node +/** + * bridge_accounts.js + * + * Sets up all Stellar accounts needed for a local bridge dev environment: + * - Issuer account (mints local TFT) + * - Bridge account (multi-sig wallet; holds TFT float) + * - User account (sends/receives TFT) + * + * Steps: + * 1. Generate fresh keypairs for issuer, bridge, user + * 2. Fund all three via Stellar testnet Friendbot + * 3. Create TFT trustlines on bridge and user accounts + * 4. Issue TFT from issuer → bridge (via path_payment_strict_send so the bridge + * deposit monitor ignores it — it only watches `payment` ops) + * 5. Issue TFT from issuer → user (regular payment; user is not monitored by bridge) + * 6. Write /tmp/bridge_local_env.sh for sourcing by Make targets and other scripts + * + * Usage: + * node scripts/bridge_accounts.js + * + * Override any account by setting env vars before running: + * BRIDGE_SECRET=S... BRIDGE_ADDRESS=G... node scripts/bridge_accounts.js + */ + +'use strict' + +const StellarSdk = require('@stellar/stellar-sdk') +const fs = require('fs') +const { friendbot, waitForAccount } = require('./bridge_helpers') + +const HORIZON_URL = process.env.STELLAR_HORIZON_URL || 'https://horizon-testnet.stellar.org' +const NETWORK_PASSPHRASE = StellarSdk.Networks.TESTNET +const ENV_FILE = process.env.BRIDGE_ENV_FILE || '/tmp/bridge_local_env.sh' + +const BRIDGE_TFT_FLOAT = process.env.BRIDGE_TFT_FLOAT || '20000' +const USER_TFT_AMOUNT = process.env.USER_TFT_AMOUNT || '1000' +const TFT_ASSET_CODE = 'TFT' + +const server = new StellarSdk.Horizon.Server(HORIZON_URL) + +function log (msg) { console.log(`[accounts] ${msg}`) } +function err (msg) { console.error(`[accounts] ERROR: ${msg}`); process.exit(1) } + +async function main () { + // 1. Generate or reuse keypairs + const issuerKp = process.env.ISSUER_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.ISSUER_SECRET) + : StellarSdk.Keypair.random() + + const bridgeKp = process.env.BRIDGE_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.BRIDGE_SECRET) + : StellarSdk.Keypair.random() + + const userKp = process.env.USER_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.USER_SECRET) + : StellarSdk.Keypair.random() + + log(`Issuer: ${issuerKp.publicKey()}`) + log(`Bridge: ${bridgeKp.publicKey()}`) + log(`User: ${userKp.publicKey()}`) + + const TFT = new StellarSdk.Asset(TFT_ASSET_CODE, issuerKp.publicKey()) + + // 2. Fund all three via Friendbot + log('Funding accounts via Friendbot...') + await Promise.all([ + friendbot(issuerKp.publicKey()), + friendbot(bridgeKp.publicKey()), + friendbot(userKp.publicKey()) + ]) + log('Friendbot done. Waiting for accounts to appear on Horizon...') + + const [, bridgeAcc, userAcc] = await Promise.all([ + waitForAccount(issuerKp.publicKey(), server), + waitForAccount(bridgeKp.publicKey(), server), + waitForAccount(userKp.publicKey(), server) + ]) + + // 3. Create TFT trustlines on bridge and user + log('Creating TFT trustlines on bridge and user accounts...') + + async function addTrustline (kp, acc) { + const tx = new StellarSdk.TransactionBuilder(acc, { + fee: '1000', + networkPassphrase: NETWORK_PASSPHRASE + }) + .addOperation(StellarSdk.Operation.changeTrust({ asset: TFT })) + .setTimeout(30) + .build() + tx.sign(kp) + await server.submitTransaction(tx) + } + + await Promise.all([ + addTrustline(bridgeKp, bridgeAcc), + addTrustline(userKp, userAcc) + ]) + log('Trustlines created.') + + // Reload accounts after trustline txs + const [issuerAcc2] = await Promise.all([ + waitForAccount(issuerKp.publicKey(), server), + waitForAccount(bridgeKp.publicKey(), server), + waitForAccount(userKp.publicKey(), server) + ]) + + // 4. Fund bridge via path_payment_strict_send (invisible to bridge deposit monitor) + log(`Issuing ${BRIDGE_TFT_FLOAT} TFT to bridge via path_payment_strict_send...`) + const bridgeFundTx = new StellarSdk.TransactionBuilder(issuerAcc2, { + fee: '1000', + networkPassphrase: NETWORK_PASSPHRASE + }) + .addOperation(StellarSdk.Operation.pathPaymentStrictSend({ + sendAsset: TFT, + sendAmount: BRIDGE_TFT_FLOAT, + destination: bridgeKp.publicKey(), + destAsset: TFT, + destMin: String(Number(BRIDGE_TFT_FLOAT) - 1), + path: [] + })) + .setTimeout(30) + .build() + bridgeFundTx.sign(issuerKp) + await server.submitTransaction(bridgeFundTx) + log(`Bridge funded with ${BRIDGE_TFT_FLOAT} TFT.`) + + // Reload issuer after bridge funding tx + const issuerAcc3 = await waitForAccount(issuerKp.publicKey(), server) + + // 5. Fund user via regular payment (user account is not monitored by bridge) + log(`Issuing ${USER_TFT_AMOUNT} TFT to user...`) + const userFundTx = new StellarSdk.TransactionBuilder(issuerAcc3, { + fee: '1000', + networkPassphrase: NETWORK_PASSPHRASE + }) + .addOperation(StellarSdk.Operation.payment({ + destination: userKp.publicKey(), + asset: TFT, + amount: USER_TFT_AMOUNT + })) + .setTimeout(30) + .build() + userFundTx.sign(issuerKp) + await server.submitTransaction(userFundTx) + log(`User funded with ${USER_TFT_AMOUNT} TFT.`) + + // 6. Write env file + const envContent = `# Auto-generated by bridge_accounts.js — do not edit manually +export ISSUER_ADDRESS="${issuerKp.publicKey()}" +export ISSUER_SECRET="${issuerKp.secret()}" +export BRIDGE_ADDRESS="${bridgeKp.publicKey()}" +export BRIDGE_SECRET="${bridgeKp.secret()}" +export USER_ADDRESS="${userKp.publicKey()}" +export USER_SECRET="${userKp.secret()}" +export TFT_ASSET_CODE="${TFT_ASSET_CODE}" +export STELLAR_HORIZON_URL="${HORIZON_URL}" +export STELLAR_NETWORK="testnet" +` + fs.writeFileSync(ENV_FILE, envContent) + log(`Environment written to ${ENV_FILE}`) + log('Done.') +} + +main().catch(e => err(e.message || String(e))) diff --git a/scripts/bridge_helpers.js b/scripts/bridge_helpers.js new file mode 100644 index 000000000..a55abe405 --- /dev/null +++ b/scripts/bridge_helpers.js @@ -0,0 +1,209 @@ +#!/usr/bin/env node +/** + * bridge_helpers.js + * + * Shared helpers for bridge E2E test scripts. Extracted from bridge_tests.js + * and bridge_mv_tests.js to eliminate duplication. + */ + +'use strict' + +const fs = require('fs') +const https = require('https') +const StellarSdk = require('@stellar/stellar-sdk') + +// ─── Logging & test result helpers ────────────────────────────────────────── + +function log (msg) { console.log(` ${msg}`) } +function pass (name, counter) { console.log(`\u2705 PASS: ${name}`); counter.passed++ } +function fail (name, reason, counter) { console.error(`\u274c FAIL: ${name} \u2014 ${reason}`); counter.failed++ } + +// ─── Env helpers ──────────────────────────────────────────────────────────── + +/** + * Load a shell-style env file (export KEY="value") into process.env. + * @param {string} envFile - Path to the env file + * @param {string} [label='tests'] - Label for error messages + */ +function loadEnv (envFile, label = 'tests') { + if (!fs.existsSync(envFile)) { + console.error(`[${label}] Env file not found: ${envFile}. Run the accounts target first.`) + process.exit(1) + } + const lines = fs.readFileSync(envFile, 'utf8').split('\n') + for (const line of lines) { + const m = line.match(/^export\s+(\w+)="([^"]*)"/) + if (m) process.env[m[1]] = m[2] + } +} + +/** + * Get a required env var or exit with an error. + */ +function getEnv (key) { + const val = process.env[key] + if (!val) { console.error(`Missing env var: ${key}`); process.exit(1) } + return val +} + +// ─── Stellar helpers ──────────────────────────────────────────────────────── + +/** + * Get TFT balance for a Stellar address. + * @param {string} address - Stellar public key + * @param {object} horizon - Horizon.Server instance + * @param {string} issuerAddress - TFT issuer public key + */ +async function stellarTFTBalance (address, horizon, issuerAddress) { + const acc = await horizon.loadAccount(address) + const tft = acc.balances.find(b => b.asset_code === 'TFT' && b.asset_issuer === issuerAddress) + return tft ? parseFloat(tft.balance) : 0 +} + +/** + * Fund a Stellar address via Friendbot (testnet). + * Treats HTTP 400 as success (already funded). + * @param {string} address - Stellar public key + * @param {string} [friendbotUrl='https://friendbot.stellar.org'] - Friendbot URL + */ +async function friendbot (address, friendbotUrl = 'https://friendbot.stellar.org') { + return new Promise((resolve, reject) => { + https.get(`${friendbotUrl}?addr=${address}`, (res) => { + let data = '' + res.on('data', c => { data += c }) + res.on('end', () => { + if (res.statusCode === 200 || res.statusCode === 400) resolve() + else reject(new Error(`Friendbot ${res.statusCode}: ${data.slice(0, 200)}`)) + }) + }).on('error', reject) + }) +} + +/** + * Wait for a Stellar account to appear on Horizon. + * @param {string} address - Stellar public key + * @param {object} server - Horizon.Server instance + * @param {number} [retries=12] - Max retry attempts (2s apart) + */ +async function waitForAccount (address, server, retries = 12) { + for (let i = 0; i < retries; i++) { + try { return await server.loadAccount(address) } catch {} + if (i < retries - 1) await new Promise(r => setTimeout(r, 2000)) + } + throw new Error(`Account ${address} not found after ${retries} attempts`) +} + +/** + * Send a Stellar payment (TFT asset) with optional memo. + * @param {object} horizon - Horizon.Server instance + * @param {string} issuerAddress - TFT issuer public key + * @param {string} networkPassphrase - Stellar network passphrase + * @param {string} fromSecret - Sender's Stellar secret key + * @param {string} toAddress - Destination Stellar public key + * @param {string|number} amount - Amount to send (string for Stellar precision) + * @param {string|null} [memo=null] - Optional text memo (e.g. "twin_") + * @returns {Promise} Horizon submit result (includes .hash) + */ +async function sendStellarPayment (horizon, issuerAddress, networkPassphrase, fromSecret, toAddress, amount, memo = null) { + const kp = StellarSdk.Keypair.fromSecret(fromSecret) + const TFTAsset = new StellarSdk.Asset('TFT', issuerAddress) + const acc = await horizon.loadAccount(kp.publicKey()) + + const builder = new StellarSdk.TransactionBuilder(acc, { + fee: '1000', + networkPassphrase + }).addOperation(StellarSdk.Operation.payment({ + destination: toAddress, + asset: TFTAsset, + amount: String(amount) + })).setTimeout(30) + + if (memo) builder.addMemo(StellarSdk.Memo.text(String(memo))) + + const tx = builder.build() + tx.sign(kp) + return horizon.submitTransaction(tx) +} + +// ─── Polling helper ───────────────────────────────────────────────────────── + +/** + * Poll until condition() returns truthy or timeout. + * @param {function} condition - Async function; return truthy to stop + * @param {object} opts + * @param {number} [opts.timeoutMs=180000] - Timeout in ms + * @param {number} [opts.intervalMs=3000] - Poll interval in ms + * @param {string} [opts.desc=''] - Description for timeout error + */ +async function waitUntil (condition, { timeoutMs = 180_000, intervalMs = 3000, desc = '' } = {}) { + const deadline = Date.now() + timeoutMs + while (Date.now() < deadline) { + const result = await condition() + if (result) return result + await new Promise(r => setTimeout(r, intervalMs)) + } + throw new Error(`Timeout waiting for: ${desc}`) +} + +// ─── TFChain helpers ──────────────────────────────────────────────────────── + +// TFT has 7 decimal places: 1 TFT = 10_000_000 base units +const TFT_DECIMALS = 1e7 +const TFT = (amount) => Math.round(amount * TFT_DECIMALS) + +/** + * Get free TFT balance for a TFChain address (returns float in TFT units). + * @param {object} api - ApiPromise instance + * @param {string} address - TFChain SS58 address + */ +async function tfchainBalance (api, address) { + const { data } = await api.query.system.account(address) + return Number(data.free) / TFT_DECIMALS +} + +/** + * Submit a swapToStellar extrinsic on TFChain. + * @param {object} api - ApiPromise instance + * @param {object} signer - Keyring pair (e.g. alice) + * @param {number} amountTFT - Amount in whole TFT + * @param {object} opts + * @param {string} opts.userAddress - Stellar destination address + * @param {number} [opts.nonce=-1] - Explicit nonce (-1 = auto) + */ +async function swapToStellar (api, signer, amountTFT, { userAddress, nonce = -1 } = {}) { + return new Promise((resolve, reject) => { + api.tx.tftBridgeModule.swapToStellar(userAddress, TFT(amountTFT)) + .signAndSend(signer, { nonce }, ({ status, dispatchError, events }) => { + if (dispatchError?.isModule) { + const d = api.registry.findMetaError(dispatchError.asModule) + reject(new Error(`${d.section}.${d.name}`)); return + } + if (status.isInBlock) { + let burnId = null + events.forEach(({ event }) => { + if (event.section === 'tftBridgeModule' && event.method === 'BurnTransactionCreated') { + burnId = event.data[0].toNumber() + } + }) + resolve(burnId) + } + }) + }) +} + +module.exports = { + log, + pass, + fail, + loadEnv, + getEnv, + stellarTFTBalance, + tfchainBalance, + friendbot, + waitForAccount, + waitUntil, + sendStellarPayment, + swapToStellar, + TFT, + TFT_DECIMALS +} diff --git a/scripts/bridge_instrumentation.js b/scripts/bridge_instrumentation.js new file mode 100644 index 000000000..eb0837676 --- /dev/null +++ b/scripts/bridge_instrumentation.js @@ -0,0 +1,1067 @@ +#!/usr/bin/env node +/** + * bridge_instrumentation.js + * + * Event collector and analysis engine for bridge E2E tests. + * Subscribes to every finalized block, captures all tftBridgeModule and utility + * events with block numbers and wall-clock timestamps, then generates a + * structured report mapping each transaction's full lifecycle. + * + * Usage (from bridge_mv_tests.js): + * const { startEventCollector, markTestPhase, generateReport } = require('./bridge_instrumentation') + * const collector = await startEventCollector(api) + * markTestPhase(collector, 'MV1', 'start') + * // ... test body ... + * markTestPhase(collector, 'MV1', 'end') + * await generateReport(collector, '/tmp/bridge_mv_analysis.json', api) + * collector.stop() + */ + +'use strict' + +const fs = require('fs') + +// ─── Event Collector ──────────────────────────────────────────────────────── + +/** + * Start a background event collector that captures all bridge-related events + * from every finalized block. + * + * @param {object} api - Connected ApiPromise instance + * @returns {object} collector with events, indexes, and stop() + */ +async function startEventCollector (api) { + const collector = { + events: [], + blockTimestamps: {}, + burnEvents: {}, + refundEvents: {}, + mintEvents: {}, + utilityEvents: [], + blockEventLog: {}, + testPhases: [], + _unsub: null, + _startTime: Date.now(), + _firstBlock: null, + _lastBlock: null, + + stop () { + if (this._unsub) { + this._unsub() + this._unsub = null + } + } + } + + collector._unsub = await api.rpc.chain.subscribeFinalizedHeads(async (header) => { + const blockNum = header.number.toNumber() + const blockHash = header.hash + collector.blockTimestamps[blockNum] = Date.now() + if (collector._firstBlock === null) collector._firstBlock = blockNum + collector._lastBlock = blockNum + + try { + const apiAt = await api.at(blockHash) + const records = await apiAt.query.system.events() + + records.forEach((record, idx) => { + const { event, phase } = record + const section = event.section + const method = event.method + + // Only capture bridge and utility events + if (section !== 'tftBridgeModule' && section !== 'utility') return + + const entry = { + block: blockNum, + timestamp: collector.blockTimestamps[blockNum], + index: idx, + section, + method, + data: event.data.map(d => d.toString()), + phase: phase.toString() + } + + collector.events.push(entry) + + // Index by block + if (!collector.blockEventLog[blockNum]) collector.blockEventLog[blockNum] = [] + collector.blockEventLog[blockNum].push(entry) + + // Index bridge events by transaction ID + if (section === 'tftBridgeModule') { + indexBridgeEvent(collector, entry) + } + if (section === 'utility') { + collector.utilityEvents.push(entry) + } + }) + } catch (err) { + // Silently ignore block fetch errors — don't disrupt the tests + } + }) + + return collector +} + +/** + * Index a bridge event into the collector's transaction maps. + */ +function indexBridgeEvent (collector, entry) { + const { method, data } = entry + + switch (method) { + // ── Burn lifecycle ── + case 'BurnTransactionCreated': { + const burnId = data[0] + if (!collector.burnEvents[burnId]) collector.burnEvents[burnId] = [] + collector.burnEvents[burnId].push({ ...entry, state: 'created' }) + break + } + case 'BurnTransactionProposed': { + const burnId = data[0] + if (!collector.burnEvents[burnId]) collector.burnEvents[burnId] = [] + collector.burnEvents[burnId].push({ ...entry, state: 'proposed' }) + break + } + case 'BurnTransactionSignatureAdded': { + const burnId = data[0] + if (!collector.burnEvents[burnId]) collector.burnEvents[burnId] = [] + collector.burnEvents[burnId].push({ ...entry, state: 'sig_added' }) + break + } + case 'BurnTransactionReady': { + const burnId = data[0] + if (!collector.burnEvents[burnId]) collector.burnEvents[burnId] = [] + collector.burnEvents[burnId].push({ ...entry, state: 'ready' }) + break + } + case 'BurnTransactionProcessed': { + // BurnTransactionProcessed carries the full BurnTransaction struct, not the burn_id. + // Store globally for post-collection reconciliation. + if (!collector.burnEvents._processed) collector.burnEvents._processed = [] + collector.burnEvents._processed.push({ ...entry, state: 'processed' }) + break + } + case 'BurnTransactionExpired': { + const burnId = data[0] + if (!collector.burnEvents[burnId]) collector.burnEvents[burnId] = [] + collector.burnEvents[burnId].push({ ...entry, state: 'expired' }) + break + } + + // ── Refund lifecycle ── + case 'RefundTransactionCreated': { + const txHash = data[0] + if (!collector.refundEvents[txHash]) collector.refundEvents[txHash] = [] + collector.refundEvents[txHash].push({ ...entry, state: 'created' }) + break + } + case 'RefundTransactionsignatureAdded': { + // Note: lowercase 's' — that's a typo in the pallet, not here. + const txHash = data[0] + if (!collector.refundEvents[txHash]) collector.refundEvents[txHash] = [] + collector.refundEvents[txHash].push({ ...entry, state: 'sig_added' }) + break + } + case 'RefundTransactionReady': { + const txHash = data[0] + if (!collector.refundEvents[txHash]) collector.refundEvents[txHash] = [] + collector.refundEvents[txHash].push({ ...entry, state: 'ready' }) + break + } + case 'RefundTransactionProcessed': { + if (!collector.refundEvents._processed) collector.refundEvents._processed = [] + collector.refundEvents._processed.push({ ...entry, state: 'processed' }) + break + } + case 'RefundTransactionExpired': { + const txHash = data[0] + if (!collector.refundEvents[txHash]) collector.refundEvents[txHash] = [] + collector.refundEvents[txHash].push({ ...entry, state: 'expired' }) + break + } + + // ── Mint lifecycle ── + case 'MintTransactionProposed': { + const txId = data[0] + if (!collector.mintEvents[txId]) collector.mintEvents[txId] = [] + collector.mintEvents[txId].push({ ...entry, state: 'proposed' }) + break + } + case 'MintTransactionVoted': { + const txId = data[0] + if (!collector.mintEvents[txId]) collector.mintEvents[txId] = [] + collector.mintEvents[txId].push({ ...entry, state: 'voted' }) + break + } + case 'MintCompleted': { + // MintCompleted data: (MintTransaction, tx_id) + const txId = data[1] + if (!collector.mintEvents[txId]) collector.mintEvents[txId] = [] + collector.mintEvents[txId].push({ ...entry, state: 'completed' }) + break + } + case 'MintTransactionExpired': { + const txId = data[0] + if (!collector.mintEvents[txId]) collector.mintEvents[txId] = [] + collector.mintEvents[txId].push({ ...entry, state: 'expired' }) + break + } + } +} + +// ─── Test Phase Markers ───────────────────────────────────────────────────── + +/** + * Mark the start or end of a test phase for event correlation. + * Uses block numbers (not timestamps) to avoid async lag between + * finalized head subscription and test code execution. + */ +function markTestPhase (collector, testName, phase) { + collector.testPhases.push({ + test: testName, + phase, + timestamp: Date.now(), + block: collector._lastBlock || 0 + }) +} + +// ─── Transaction Lifecycle Analysis ───────────────────────────────────────── + +function analyzeBurn (collector, burnId) { + const events = collector.burnEvents[burnId] || [] + if (events.length === 0) return null + + const record = { + burnId: Number(burnId), + type: 'burn', + createdBlock: null, + firstSigBlock: null, + readyBlock: null, + processedBlock: null, + expiryCount: 0, + expiryBlocks: [], + sigCount: 0, + blocksCreatedToReady: null, + blocksReadyToProcessed: null, + blocksCreatedToProcessed: null, + wallClockMs: null, + transitions: [] + } + + for (const evt of events) { + record.transitions.push({ + state: evt.state, + block: evt.block, + timestamp: evt.timestamp + }) + + switch (evt.state) { + case 'created': + record.createdBlock = evt.block + break + case 'sig_added': + record.sigCount++ + if (!record.firstSigBlock) record.firstSigBlock = evt.block + break + case 'ready': + record.readyBlock = evt.block + break + case 'processed': + record.processedBlock = evt.block + break + case 'expired': + record.expiryCount++ + record.expiryBlocks.push(evt.block) + break + } + } + + // Compute deltas + if (record.createdBlock != null && record.readyBlock != null) { + record.blocksCreatedToReady = record.readyBlock - record.createdBlock + } + if (record.readyBlock != null && record.processedBlock != null) { + record.blocksReadyToProcessed = record.processedBlock - record.readyBlock + } + if (record.createdBlock != null && record.processedBlock != null) { + record.blocksCreatedToProcessed = record.processedBlock - record.createdBlock + } + + // Wall-clock time + if (events.length >= 2) { + record.wallClockMs = events[events.length - 1].timestamp - events[0].timestamp + } + + return record +} + +function analyzeRefund (collector, txHash) { + const events = collector.refundEvents[txHash] || [] + if (events.length === 0) return null + + const record = { + txHash, + type: 'refund', + createdBlock: null, + readyBlock: null, + processedBlock: null, + expiryCount: 0, + sigCount: 0, + blocksCreatedToReady: null, + blocksCreatedToProcessed: null, + wallClockMs: null, + transitions: [] + } + + for (const evt of events) { + record.transitions.push({ state: evt.state, block: evt.block, timestamp: evt.timestamp }) + switch (evt.state) { + case 'created': record.createdBlock = evt.block; break + case 'sig_added': record.sigCount++; break + case 'ready': record.readyBlock = evt.block; break + case 'processed': record.processedBlock = evt.block; break + case 'expired': record.expiryCount++; break + } + } + + if (!record.processedBlock && collector.refundEvents._processed) { + for (const pe of collector.refundEvents._processed) { + if (record.readyBlock && pe.block >= record.readyBlock && !record.processedBlock) { + record.processedBlock = pe.block + } + } + } + + if (record.createdBlock != null && record.readyBlock != null) { + record.blocksCreatedToReady = record.readyBlock - record.createdBlock + } + if (record.createdBlock != null && record.processedBlock != null) { + record.blocksCreatedToProcessed = record.processedBlock - record.createdBlock + } + if (events.length >= 2) { + record.wallClockMs = events[events.length - 1].timestamp - events[0].timestamp + } + + return record +} + +function analyzeMint (collector, txId) { + const events = collector.mintEvents[txId] || [] + if (events.length === 0) return null + + const record = { + txId, + type: 'mint', + proposedBlock: null, + completedBlock: null, + voteCount: 0, + expiryCount: 0, + blocksProposedToCompleted: null, + wallClockMs: null, + transitions: [] + } + + for (const evt of events) { + record.transitions.push({ state: evt.state, block: evt.block, timestamp: evt.timestamp }) + switch (evt.state) { + case 'proposed': record.proposedBlock = evt.block; break + case 'voted': record.voteCount++; break + case 'completed': record.completedBlock = evt.block; break + case 'expired': record.expiryCount++; break + } + } + + if (record.proposedBlock != null && record.completedBlock != null) { + record.blocksProposedToCompleted = record.completedBlock - record.proposedBlock + } + if (events.length >= 2) { + record.wallClockMs = events[events.length - 1].timestamp - events[0].timestamp + } + + return record +} + +// ─── Test Phase Correlation ───────────────────────────────────────────────── + +/** + * Determine which test a block belongs to, using block-number ranges + * from the test phase markers. This avoids the async lag issue where + * finalized-head events arrive after the test code has already moved on. + * + * Phase markers record collector._lastBlock at the time markTestPhase is + * called. A block B belongs to test T if: + * T.start.block <= B <= T.end.block (or T has no end yet and B >= T.start.block) + */ +function getTestForBlock (collector, block) { + // Build sorted phase marker pairs + const tests = {} + for (const marker of collector.testPhases) { + if (!tests[marker.test]) tests[marker.test] = {} + tests[marker.test][marker.phase] = marker.block + } + + // Walk test order (use testPhases order of first appearance) + const testOrder = [] + const seen = new Set() + for (const marker of collector.testPhases) { + if (marker.phase === 'start' && !seen.has(marker.test)) { + seen.add(marker.test) + testOrder.push(marker.test) + } + } + + // Find the test whose block range contains this block + for (let i = testOrder.length - 1; i >= 0; i--) { + const test = testOrder[i] + const startBlock = tests[test].start + const endBlock = tests[test].end + + if (startBlock == null) continue + + if (endBlock != null) { + // Completed test: block must be in range [startBlock, endBlock] + if (block >= startBlock && block <= endBlock) return test + } else { + // Still running: block must be >= startBlock + if (block >= startBlock) return test + } + } + + // Blocks before any test started — assign to first test if close + if (testOrder.length > 0) { + const firstStart = tests[testOrder[0]].start + if (block < firstStart) return 'pre-test' + } + + return 'unknown' +} + +function groupEventsByTest (collector) { + const testGroups = {} + + // Group burn events by test phase (using block of first event) + for (const [burnId, events] of Object.entries(collector.burnEvents)) { + if (burnId === '_processed') continue + if (events.length === 0) continue + const test = getTestForBlock(collector, events[0].block) + if (!testGroups[test]) testGroups[test] = { burns: [], refunds: [], mints: [] } + testGroups[test].burns.push(burnId) + } + + // Group refund events by test phase + for (const [txHash, events] of Object.entries(collector.refundEvents)) { + if (txHash === '_processed') continue + if (events.length === 0) continue + const test = getTestForBlock(collector, events[0].block) + if (!testGroups[test]) testGroups[test] = { burns: [], refunds: [], mints: [] } + testGroups[test].refunds.push(txHash) + } + + // Group mint events by test phase + for (const [txId, events] of Object.entries(collector.mintEvents)) { + if (events.length === 0) continue + const test = getTestForBlock(collector, events[0].block) + if (!testGroups[test]) testGroups[test] = { burns: [], refunds: [], mints: [] } + testGroups[test].mints.push(txId) + } + + return testGroups +} + +// ─── Batch Analysis ───────────────────────────────────────────────────────── + +/** + * Analyze how set_burn_transaction_executed / set_refund_transaction_executed + * calls are batched. For each block, count how many Processed events arrived + * in a single batch (paired with ItemCompleted inside a BatchCompleted or + * BatchCompletedWithErrors). + * + * Returns an array of batch records: + * { block, type, processedCount, failedCount, batchType } + */ +function analyzeBatches (collector) { + const batches = [] + const blockNums = Object.keys(collector.blockEventLog).map(Number).sort((a, b) => a - b) + + for (const blockNum of blockNums) { + const events = collector.blockEventLog[blockNum] + + // Walk through events and group by batch boundaries + let currentBatch = null + + for (const evt of events) { + if (evt.section === 'tftBridgeModule' && + (evt.method === 'BurnTransactionProcessed' || evt.method === 'RefundTransactionProcessed')) { + if (!currentBatch) { + currentBatch = { + block: blockNum, + type: evt.method === 'BurnTransactionProcessed' ? 'burn_executed' : 'refund_executed', + processedCount: 0, + failedCount: 0, + batchType: 'standalone' + } + } + currentBatch.processedCount++ + } + if (evt.section === 'utility' && evt.method === 'ItemFailed' && currentBatch) { + currentBatch.failedCount++ + } + if (evt.section === 'utility' && evt.method === 'BatchCompleted' && currentBatch) { + currentBatch.batchType = 'BatchCompleted' + batches.push(currentBatch) + currentBatch = null + } + if (evt.section === 'utility' && evt.method === 'BatchCompletedWithErrors' && currentBatch) { + currentBatch.batchType = 'BatchCompletedWithErrors' + batches.push(currentBatch) + currentBatch = null + } + } + + // If we have a dangling batch (Processed events without a Batch* wrapper) + if (currentBatch && currentBatch.processedCount > 0) { + batches.push(currentBatch) + } + } + + return batches +} + +/** + * Analyze signature proposal batches (propose_stellar_burn_transaction_or_add_sig). + * For each block, count how many BurnTransactionSignatureAdded events arrived + * inside a single force_batch. + */ +function analyzeSignatureBatches (collector) { + const batches = [] + const blockNums = Object.keys(collector.blockEventLog).map(Number).sort((a, b) => a - b) + + for (const blockNum of blockNums) { + const events = collector.blockEventLog[blockNum] + let currentBatch = null + + for (const evt of events) { + if (evt.section === 'tftBridgeModule' && evt.method === 'BurnTransactionSignatureAdded') { + if (!currentBatch) { + currentBatch = { + block: blockNum, + type: 'sig_proposal', + sigCount: 0, + readyCount: 0, + failedCount: 0, + batchType: 'standalone' + } + } + currentBatch.sigCount++ + } + if (evt.section === 'tftBridgeModule' && evt.method === 'BurnTransactionReady' && currentBatch) { + currentBatch.readyCount++ + } + if (evt.section === 'utility' && evt.method === 'ItemFailed' && currentBatch) { + currentBatch.failedCount++ + } + if (evt.section === 'utility' && evt.method === 'BatchCompleted' && currentBatch) { + currentBatch.batchType = 'BatchCompleted' + batches.push(currentBatch) + currentBatch = null + } + if (evt.section === 'utility' && evt.method === 'BatchCompletedWithErrors' && currentBatch) { + currentBatch.batchType = 'BatchCompletedWithErrors' + batches.push(currentBatch) + currentBatch = null + } + } + + if (currentBatch && currentBatch.sigCount > 0) { + batches.push(currentBatch) + } + } + + return batches +} + +// ─── Statistics Helpers ───────────────────────────────────────────────────── + +function mean (arr) { return arr.length ? arr.reduce((a, b) => a + b, 0) / arr.length : 0 } +function median (arr) { + if (!arr.length) return 0 + const s = [...arr].sort((a, b) => a - b) + const mid = Math.floor(s.length / 2) + return s.length % 2 ? s[mid] : (s[mid - 1] + s[mid]) / 2 +} +function percentile (arr, p) { + if (!arr.length) return 0 + const s = [...arr].sort((a, b) => a - b) + const idx = Math.ceil(p / 100 * s.length) - 1 + return s[Math.max(0, idx)] +} + +// ─── Anomaly Detection ────────────────────────────────────────────────────── + +function detectAnomalies (collector, testGroups) { + const anomalies = [] + + // Tests that should have zero expiries + const noExpiryTests = ['MV1', 'MV2', 'MV3', 'MV4', 'MV6'] + for (const test of noExpiryTests) { + const group = testGroups[test] + if (!group) continue + + for (const burnId of group.burns) { + const rec = analyzeBurn(collector, burnId) + if (rec && rec.expiryCount > 0) { + anomalies.push({ + severity: 'warning', + test, + message: `Burn ${burnId} expired ${rec.expiryCount} time(s) in ${test} (expected 0)`, + burnId + }) + } + } + for (const txHash of group.refunds) { + const rec = analyzeRefund(collector, txHash) + if (rec && rec.expiryCount > 0) { + anomalies.push({ + severity: 'warning', + test, + message: `Refund ${txHash.slice(0, 16)}... expired ${rec.expiryCount} time(s) in ${test} (expected 0)`, + txHash + }) + } + } + } + + // MV4 should have exactly 2 sigs per refund (Val3 offline) + if (testGroups.MV4) { + for (const txHash of testGroups.MV4.refunds) { + const rec = analyzeRefund(collector, txHash) + if (rec && rec.sigCount > 2) { + anomalies.push({ + severity: 'warning', + test: 'MV4', + message: `Refund got ${rec.sigCount} sigs (expected 2, Val3 should be offline)`, + txHash + }) + } + } + } + + // MV9: check all 50 burns reached processed state + if (testGroups.MV9) { + const unprocessed = [] + for (const burnId of testGroups.MV9.burns) { + const rec = analyzeBurn(collector, burnId) + if (rec && rec.processedBlock == null) { + unprocessed.push(burnId) + } + } + if (unprocessed.length > 0) { + anomalies.push({ + severity: 'error', + test: 'MV9', + message: `${unprocessed.length} burns never reached Processed state (event missed by collector)`, + burnIds: unprocessed + }) + } + } + + // Utility ItemFailed events + const itemFailedCount = collector.utilityEvents.filter(e => e.method === 'ItemFailed').length + if (itemFailedCount > 0) { + anomalies.push({ + severity: 'info', + test: 'global', + message: `${itemFailedCount} Utility.ItemFailed events total (expected in multi-validator races)` + }) + } + + return anomalies +} + +// ─── Chain-State Reconciliation ───────────────────────────────────────────── + +/** + * Query the on-chain ExecutedBurnTransactions and ExecutedRefundTransactions + * maps to reconcile any burns/refunds whose Processed events were missed + * by the finalized-head subscription (e.g. late-arriving blocks). + * + * Also waits for all active transaction maps to drain (like MV7), so we + * know all transactions have been fully processed before generating the report. + */ +async function reconcileFromChain (collector, api) { + // Wait for active burn/refund maps to drain (up to 60s — same signal as MV7) + const started = Date.now() + while (Date.now() - started < 60_000) { + const burns = await api.query.tftBridgeModule.burnTransactions.entries() + const refunds = await api.query.tftBridgeModule.refundTransactions.entries() + if (burns.length === 0 && refunds.length === 0) break + await new Promise(r => setTimeout(r, 3000)) + } + + // Wait a bit more for any in-flight finalized head events + await new Promise(r => setTimeout(r, 5000)) + + let reconciled = 0 + + // Reconcile burns + for (const [burnId, events] of Object.entries(collector.burnEvents)) { + if (burnId === '_processed') continue + const hasProcessed = events.some(e => e.state === 'processed') + if (hasProcessed) continue + + try { + const executed = (await api.query.tftBridgeModule.executedBurnTransactions(Number(burnId))).toJSON() + if (executed && executed.target) { + events.push({ + block: collector._lastBlock, + timestamp: Date.now(), + index: -1, + section: 'tftBridgeModule', + method: 'BurnTransactionProcessed', + data: ['reconciled-from-chain-state'], + phase: 'reconciled', + state: 'processed', + _reconciled: true + }) + reconciled++ + } + } catch {} + } + + // Reconcile refunds + for (const [txHash, events] of Object.entries(collector.refundEvents)) { + if (txHash === '_processed') continue + const hasProcessed = events.some(e => e.state === 'processed') + if (hasProcessed) continue + + try { + const entries = await api.query.tftBridgeModule.executedRefundTransactions.entries() + const found = entries.some(([key]) => key.args[0].toString() === txHash) + if (found) { + events.push({ + block: collector._lastBlock, + timestamp: Date.now(), + index: -1, + section: 'tftBridgeModule', + method: 'RefundTransactionProcessed', + data: ['reconciled-from-chain-state'], + phase: 'reconciled', + state: 'processed', + _reconciled: true + }) + reconciled++ + } + } catch {} + } + + return reconciled +} + +// ─── Report Generator ─────────────────────────────────────────────────────── + +/** + * @param {object} collector - The event collector + * @param {string} outputPath - Path to write the JSON report + * @param {object} [api] - Optional ApiPromise for chain-state reconciliation + */ +async function generateReport (collector, outputPath, api) { + // Reconcile missing Processed events from chain state + let reconciledCount = 0 + if (api) { + reconciledCount = await reconcileFromChain(collector, api) + if (reconciledCount > 0) { + console.log(`[instrumentation] Reconciled ${reconciledCount} Processed events from chain state`) + } + } else { + // Fallback: just wait a bit for in-flight events + await new Promise(r => setTimeout(r, 3000)) + } + + const testGroups = groupEventsByTest(collector) + const anomalies = detectAnomalies(collector, testGroups) + + // Build burn analysis + const allBurnIds = Object.keys(collector.burnEvents).filter(k => k !== '_processed') + const burnRecords = allBurnIds.map(id => analyzeBurn(collector, id)).filter(Boolean) + + // Build refund analysis + const allRefundHashes = Object.keys(collector.refundEvents).filter(k => k !== '_processed') + const refundRecords = allRefundHashes.map(h => analyzeRefund(collector, h)).filter(Boolean) + + // Build mint analysis + const allMintIds = Object.keys(collector.mintEvents) + const mintRecords = allMintIds.map(id => analyzeMint(collector, id)).filter(Boolean) + + // Batch analysis + const executeBatches = analyzeBatches(collector) + const sigBatches = analyzeSignatureBatches(collector) + + // KPIs + const blocksToReady = burnRecords.map(b => b.blocksCreatedToReady).filter(v => v != null) + const blocksToProcessed = burnRecords.map(b => b.blocksCreatedToProcessed).filter(v => v != null) + const wallClockSecs = burnRecords.map(b => b.wallClockMs).filter(v => v != null).map(v => v / 1000) + + const kpis = { + burns: { + total: burnRecords.length, + avgBlocksToReady: Math.round(mean(blocksToReady) * 10) / 10, + medianBlocksToReady: median(blocksToReady), + avgBlocksToProcessed: Math.round(mean(blocksToProcessed) * 10) / 10, + medianBlocksToProcessed: median(blocksToProcessed), + p95BlocksToProcessed: percentile(blocksToProcessed, 95), + avgWallClockSecs: Math.round(mean(wallClockSecs) * 10) / 10, + totalExpiries: burnRecords.reduce((s, b) => s + b.expiryCount, 0), + burnsWithExpiry: burnRecords.filter(b => b.expiryCount > 0).length, + maxExpiryCycles: Math.max(...burnRecords.map(b => b.expiryCount), 0), + reconciledFromChain: reconciledCount + }, + refunds: { + total: refundRecords.length, + totalExpiries: refundRecords.reduce((s, r) => s + r.expiryCount, 0) + }, + mints: { + total: mintRecords.length + }, + utilityBatches: { + batchCompleted: collector.utilityEvents.filter(e => e.method === 'BatchCompleted').length, + batchCompletedWithErrors: collector.utilityEvents.filter(e => e.method === 'BatchCompletedWithErrors').length, + itemFailed: collector.utilityEvents.filter(e => e.method === 'ItemFailed').length, + itemCompleted: collector.utilityEvents.filter(e => e.method === 'ItemCompleted').length + } + } + + // Per-test summary + const perTest = {} + const testOrder = ['MV1', 'MV2', 'MV3', 'MV4', 'MV5', 'MV6', 'MV8', 'MV9', 'MV7'] + for (const test of testOrder) { + const group = testGroups[test] + if (!group) { perTest[test] = { burns: 0, refunds: 0, mints: 0, expiries: 0, blocks: 0, wallClockSecs: 0 }; continue } + + const burns = group.burns.map(id => analyzeBurn(collector, id)).filter(Boolean) + const refunds = group.refunds.map(h => analyzeRefund(collector, h)).filter(Boolean) + const mints = group.mints.map(id => analyzeMint(collector, id)).filter(Boolean) + + const allTransitions = [ + ...burns.flatMap(b => b.transitions), + ...refunds.flatMap(r => r.transitions), + ...mints.flatMap(m => m.transitions) + ] + const blocks = allTransitions.map(t => t.block).filter(Boolean) + const blockSpan = blocks.length ? Math.max(...blocks) - Math.min(...blocks) : 0 + + const timestamps = allTransitions.map(t => t.timestamp).filter(Boolean) + const timeSpan = timestamps.length ? (Math.max(...timestamps) - Math.min(...timestamps)) / 1000 : 0 + + perTest[test] = { + burns: group.burns.length, + refunds: group.refunds.length, + mints: group.mints.length, + expiries: burns.reduce((s, b) => s + b.expiryCount, 0) + refunds.reduce((s, r) => s + r.expiryCount, 0), + blocks: blockSpan, + wallClockSecs: Math.round(timeSpan) + } + } + + // Build timeline (block-by-block, only blocks with events) + const timeline = [] + const blockNums = Object.keys(collector.blockEventLog).map(Number).sort((a, b) => a - b) + for (const blockNum of blockNums) { + const events = collector.blockEventLog[blockNum] + timeline.push({ + block: blockNum, + timestamp: collector.blockTimestamps[blockNum], + events: events.map(e => ({ + section: e.section, + method: e.method, + data: e.data + })) + }) + } + + // Test phase markers (for debugging) + const phaseMarkers = collector.testPhases.map(m => ({ + test: m.test, + phase: m.phase, + block: m.block, + timestamp: m.timestamp + })) + + // Full report object + const report = { + metadata: { + generatedAt: new Date().toISOString(), + retryInterval: 20, + blockTimeSecs: 6, + validatorCount: 3, + threshold: 2, + totalBlocks: collector._lastBlock - collector._firstBlock + 1, + firstBlock: collector._firstBlock, + lastBlock: collector._lastBlock, + totalDurationSecs: Math.round((Date.now() - collector._startTime) / 1000), + reconciledFromChain: reconciledCount + }, + kpis, + perTest, + anomalies, + phaseMarkers, + batchAnalysis: { + executesBatches: executeBatches, + signatureBatches: sigBatches + }, + transactions: { + burns: burnRecords, + refunds: refundRecords, + mints: mintRecords + }, + timeline + } + + // Write JSON + fs.writeFileSync(outputPath, JSON.stringify(report, null, 2)) + + // Print human-readable summary + printSummary(report) + + return report +} + +// ─── Console Output ───────────────────────────────────────────────────────── + +function printSummary (report) { + const SEP = '─'.repeat(90) + const DSEP = '═'.repeat(90) + + console.log(`\n${DSEP}`) + console.log(' BRIDGE MV TEST ANALYSIS REPORT') + console.log(DSEP) + + // Metadata + const meta = report.metadata + console.log(` Duration: ${meta.totalDurationSecs}s | Blocks: ${meta.firstBlock}–${meta.lastBlock} (${meta.totalBlocks} blocks)`) + if (meta.reconciledFromChain > 0) { + console.log(` ⚠ ${meta.reconciledFromChain} Processed events reconciled from chain state (missed by event subscription)`) + } + console.log(SEP) + + // Per-test table + console.log(' Test │ Burns │ Refunds │ Mints │ Expiries │ Block Span │ Time') + console.log(' ' + '─'.repeat(78)) + const testOrder = ['MV1', 'MV2', 'MV3', 'MV4', 'MV5', 'MV6', 'MV8', 'MV9', 'MV7'] + for (const test of testOrder) { + const t = report.perTest[test] || {} + console.log( + ` ${test.padEnd(6)} │ ${String(t.burns || 0).padStart(5)} │ ${String(t.refunds || 0).padStart(7)} │ ${String(t.mints || 0).padStart(5)} │ ${String(t.expiries || 0).padStart(8)} │ ${String(t.blocks || 0).padStart(10)} │ ${t.wallClockSecs || 0}s` + ) + } + + console.log(SEP) + + // Burn KPIs + const bk = report.kpis.burns + console.log(' Burn KPIs:') + console.log(` Created→Ready: avg=${bk.avgBlocksToReady} blocks, median=${bk.medianBlocksToReady}`) + console.log(` Created→Processed: avg=${bk.avgBlocksToProcessed} blocks, median=${bk.medianBlocksToProcessed}, p95=${bk.p95BlocksToProcessed}`) + console.log(` Wall-clock: avg=${bk.avgWallClockSecs}s`) + console.log(` Expiries: total=${bk.totalExpiries}, burns_with_expiry=${bk.burnsWithExpiry}/${bk.total}, max_cycles=${bk.maxExpiryCycles}`) + + // Utility batch stats + const ub = report.kpis.utilityBatches + console.log(` Utility batches: completed=${ub.batchCompleted}, with_errors=${ub.batchCompletedWithErrors}, item_failed=${ub.itemFailed}, item_completed=${ub.itemCompleted}`) + + console.log(SEP) + + // Batch analysis + const ba = report.batchAnalysis + if (ba.executesBatches.length > 0) { + console.log(' SET_EXECUTED BATCH ANALYSIS:') + for (const b of ba.executesBatches) { + const status = b.failedCount > 0 + ? `✓ ${b.processedCount} processed, ${b.failedCount} failed (redundant validators)` + : `✓ ${b.processedCount} processed` + console.log(` Block ${b.block}: [${b.batchType}] ${b.type} — ${status}`) + } + console.log(SEP) + } + + if (ba.signatureBatches.length > 0) { + console.log(' SIGNATURE PROPOSAL BATCH ANALYSIS:') + for (const b of ba.signatureBatches) { + const readyTag = b.readyCount > 0 ? `, ${b.readyCount} → Ready` : '' + const failTag = b.failedCount > 0 ? `, ${b.failedCount} failed (validator race)` : '' + console.log(` Block ${b.block}: [${b.batchType}] ${b.sigCount} sigs${readyTag}${failTag}`) + } + console.log(SEP) + } + + // Anomalies + if (report.anomalies.length === 0) { + console.log(' ✅ Anomalies: none') + } else { + console.log(` Anomalies (${report.anomalies.length}):`) + for (const a of report.anomalies) { + const icon = a.severity === 'error' ? '\u274c' : a.severity === 'warning' ? '\u26a0\ufe0f' : '\u2139\ufe0f' + console.log(` ${icon} [${a.test}] ${a.message}`) + } + } + + // Phase markers (for debugging phasing issues) + console.log(`\n${DSEP}`) + console.log(' TEST PHASE MARKERS (block assignments)') + console.log(DSEP) + for (const m of report.phaseMarkers) { + console.log(` ${m.test}.${m.phase} → block ${m.block}`) + } + + // Print timeline for key tests + console.log(`\n${DSEP}`) + console.log(' BLOCK TIMELINE (bridge events only)') + console.log(DSEP) + + for (const entry of report.timeline) { + const events = entry.events + if (events.length === 0) continue + const ts = entry.timestamp ? new Date(entry.timestamp).toISOString().slice(11, 19) : '??:??:??' + console.log(` Block ${entry.block} [${ts}]:`) + for (const evt of events) { + const shortData = evt.data.map(d => d.length > 20 ? d.slice(0, 16) + '...' : d).join(', ') + console.log(` ${evt.section}.${evt.method}(${shortData})`) + } + } + + // Print per-burn lifecycle (compact) + console.log(`\n${DSEP}`) + console.log(' BURN LIFECYCLE DETAILS') + console.log(DSEP) + + for (const burn of report.transactions.burns) { + const states = burn.transitions.map(t => `${t.state}@${t.block}`).join(' → ') + const expTag = burn.expiryCount > 0 ? ` [${burn.expiryCount} expiry]` : '' + const timeTag = burn.wallClockMs != null ? ` (${Math.round(burn.wallClockMs / 1000)}s)` : '' + const reconTag = burn.transitions.some(t => t.state === 'processed') && burn.processedBlock === burn.transitions[burn.transitions.length - 1].block ? '' : '' + console.log(` Burn #${burn.burnId}: ${states}${expTag}${timeTag}${reconTag}`) + } + + for (const refund of report.transactions.refunds) { + const hash = typeof refund.txHash === 'string' ? refund.txHash.slice(0, 16) : String(refund.txHash).slice(0, 16) + const states = refund.transitions.map(t => `${t.state}@${t.block}`).join(' → ') + console.log(` Refund ${hash}...: ${states}`) + } + + for (const mint of report.transactions.mints) { + const id = typeof mint.txId === 'string' ? mint.txId.slice(0, 16) : String(mint.txId).slice(0, 16) + const states = mint.transitions.map(t => `${t.state}@${t.block}`).join(' → ') + console.log(` Mint ${id}...: ${states}`) + } + + console.log(DSEP) + console.log(` Full report: ${process.env.ANALYSIS_OUTPUT || '/tmp/bridge_mv_analysis.json'}`) + console.log(DSEP) +} + +module.exports = { + startEventCollector, + markTestPhase, + generateReport +} diff --git a/scripts/bridge_mv_accounts.js b/scripts/bridge_mv_accounts.js new file mode 100644 index 000000000..81f889bab --- /dev/null +++ b/scripts/bridge_mv_accounts.js @@ -0,0 +1,205 @@ +#!/usr/bin/env node +/** + * bridge_mv_accounts.js + * + * Sets up Stellar accounts for a 3-validator bridge dev environment. + * + * Multi-sig configuration (2-of-3): + * - Bridge account = Val1 Stellar keypair (master key, weight=1) + * - Val2 Stellar keypair added as signer (weight=1) + * - Val3 Stellar keypair added as signer (weight=1) + * - Thresholds: low=1, med=2 (any 2 of 3 can sign TFT payments), high=2 + * + * TFChain genesis bridge validators (from substrate-node/node/src/chain_spec.rs): + * Val1: "quarter between satisfy three sphere six soda boss cute decade old trend" (genesis) + * Val2: "employ split promote annual couple elder remain cricket company fitness senior fiscal" (added via council) + * Val3: "remind bird banner word spread volume card keep want faith insect mind" (added via council) + * + * Steps: + * 1. Generate keypairs: val1 (bridge master), val2, val3, user, issuer + * 2. Fund all via Stellar Friendbot + * 3. Create TFT trustline on bridge (val1) and user + * 4. Fund bridge via path_payment_strict_send (invisible to deposit monitor) + * 5. Fund user via regular payment + * 6. Configure bridge as 2-of-3 multi-sig (val1 master + val2 + val3 signers) + * 7. Write env file + * + * Usage: + * node scripts/bridge_mv_accounts.js + */ + +'use strict' + +const StellarSdk = require('@stellar/stellar-sdk') +const fs = require('fs') +const { friendbot, waitForAccount } = require('./bridge_helpers') + +const HORIZON_URL = process.env.STELLAR_HORIZON_URL || 'https://horizon-testnet.stellar.org' +const NETWORK_PASSPHRASE = StellarSdk.Networks.TESTNET +const ENV_FILE = process.env.BRIDGE_MV_ENV_FILE || '/tmp/bridge_mv_env.sh' + +const BRIDGE_TFT_FLOAT = process.env.BRIDGE_TFT_FLOAT || '20000' +const USER_TFT_AMOUNT = process.env.USER_TFT_AMOUNT || '1000' +const TFT_ASSET_CODE = 'TFT' + +const server = new StellarSdk.Horizon.Server(HORIZON_URL) + +function log (msg) { console.log(`[mv-accounts] ${msg}`) } +function die (msg) { console.error(`[mv-accounts] ERROR: ${msg}`); process.exit(1) } + +async function submitTx (kp, acc, ops) { + const builder = new StellarSdk.TransactionBuilder(acc, { + fee: '1000', + networkPassphrase: NETWORK_PASSPHRASE + }) + for (const op of ops) builder.addOperation(op) + const tx = builder.setTimeout(30).build() + tx.sign(kp) + return server.submitTransaction(tx) +} + +async function main () { + // 1. Generate keypairs + const val1Kp = process.env.VAL1_STELLAR_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.VAL1_STELLAR_SECRET) + : StellarSdk.Keypair.random() + + const val2Kp = process.env.VAL2_STELLAR_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.VAL2_STELLAR_SECRET) + : StellarSdk.Keypair.random() + + const val3Kp = process.env.VAL3_STELLAR_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.VAL3_STELLAR_SECRET) + : StellarSdk.Keypair.random() + + const userKp = process.env.USER_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.USER_SECRET) + : StellarSdk.Keypair.random() + + const issuerKp = process.env.ISSUER_SECRET + ? StellarSdk.Keypair.fromSecret(process.env.ISSUER_SECRET) + : StellarSdk.Keypair.random() + + const bridgeAddress = val1Kp.publicKey() + + log(`Issuer: ${issuerKp.publicKey()}`) + log(`Val1 / Bridge: ${val1Kp.publicKey()}`) + log(`Val2: ${val2Kp.publicKey()}`) + log(`Val3: ${val3Kp.publicKey()}`) + log(`User: ${userKp.publicKey()}`) + + const TFT = new StellarSdk.Asset(TFT_ASSET_CODE, issuerKp.publicKey()) + + // 2. Fund via Friendbot + log('Funding accounts via Friendbot...') + await Promise.all([ + friendbot(issuerKp.publicKey()), + friendbot(val1Kp.publicKey()), + friendbot(val2Kp.publicKey()), + friendbot(val3Kp.publicKey()), + friendbot(userKp.publicKey()) + ]) + log('Friendbot done. Waiting for accounts...') + + const [, bridgeAcc, , , userAcc] = await Promise.all([ + waitForAccount(issuerKp.publicKey(), server), + waitForAccount(val1Kp.publicKey(), server), + waitForAccount(val2Kp.publicKey(), server), + waitForAccount(val3Kp.publicKey(), server), + waitForAccount(userKp.publicKey(), server) + ]) + + // 3. TFT trustlines on bridge and user only (val2/val3 are signers, not holders) + log('Creating TFT trustlines on bridge and user...') + await Promise.all([ + submitTx(val1Kp, bridgeAcc, [StellarSdk.Operation.changeTrust({ asset: TFT })]), + submitTx(userKp, userAcc, [StellarSdk.Operation.changeTrust({ asset: TFT })]) + ]) + log('Trustlines created.') + + const [issuerAcc2] = await Promise.all([ + waitForAccount(issuerKp.publicKey(), server), + waitForAccount(val1Kp.publicKey(), server), + waitForAccount(val2Kp.publicKey(), server), + waitForAccount(val3Kp.publicKey(), server), + waitForAccount(userKp.publicKey(), server) + ]) + + // 4. Fund bridge via path_payment_strict_send (invisible to deposit monitor) + log(`Issuing ${BRIDGE_TFT_FLOAT} TFT to bridge via path_payment_strict_send...`) + await submitTx(issuerKp, issuerAcc2, [ + StellarSdk.Operation.pathPaymentStrictSend({ + sendAsset: TFT, + sendAmount: BRIDGE_TFT_FLOAT, + destination: bridgeAddress, + destAsset: TFT, + destMin: String(Number(BRIDGE_TFT_FLOAT) - 1), + path: [] + }) + ]) + log(`Bridge funded with ${BRIDGE_TFT_FLOAT} TFT.`) + + // 5. Fund user + const issuerAcc3 = await waitForAccount(issuerKp.publicKey(), server) + log(`Issuing ${USER_TFT_AMOUNT} TFT to user...`) + await submitTx(issuerKp, issuerAcc3, [ + StellarSdk.Operation.payment({ + destination: userKp.publicKey(), + asset: TFT, + amount: USER_TFT_AMOUNT + }) + ]) + log(`User funded with ${USER_TFT_AMOUNT} TFT.`) + + // 6. Configure bridge as 2-of-3 multi-sig + // Val1 is master (weight=1), val2 and val3 added as signers (weight=1 each) + // Any 2 of 3 signers needed for med ops (TFT payments) + const bridgeAcc3 = await waitForAccount(val1Kp.publicKey(), server) + log('Configuring bridge as 2-of-3 multi-sig (low=1, med=2, high=2)...') + await submitTx(val1Kp, bridgeAcc3, [ + StellarSdk.Operation.setOptions({ + signer: { ed25519PublicKey: val2Kp.publicKey(), weight: 1 } + }), + StellarSdk.Operation.setOptions({ + signer: { ed25519PublicKey: val3Kp.publicKey(), weight: 1 } + }), + StellarSdk.Operation.setOptions({ + lowThreshold: 1, + medThreshold: 2, + highThreshold: 2 + }) + ]) + + const finalAcc = await waitForAccount(bridgeAddress, server) + log(`Bridge thresholds: low=${finalAcc.thresholds.low_threshold} med=${finalAcc.thresholds.med_threshold} high=${finalAcc.thresholds.high_threshold}`) + log(`Bridge signers: ${finalAcc.signers.length} (expected 3: val1 master + val2 + val3)`) + + // 7. Write env file + const envContent = `# Auto-generated by bridge_mv_accounts.js — do not edit manually +# Multi-sig: 2-of-3 (val1 master + val2 + val3 all weight=1, med threshold=2) +# TFChain validator seeds (from substrate-node/node/src/chain_spec.rs): +# Val1: "quarter between satisfy three sphere six soda boss cute decade old trend" (genesis) +# Val2: "employ split promote annual couple elder remain cricket company fitness senior fiscal" (added via council) +# Val3: "remind bird banner word spread volume card keep want faith insect mind" (added via council) +export ISSUER_ADDRESS="${issuerKp.publicKey()}" +export ISSUER_SECRET="${issuerKp.secret()}" +export BRIDGE_ADDRESS="${bridgeAddress}" +export VAL1_STELLAR_SECRET="${val1Kp.secret()}" +export VAL1_STELLAR_ADDRESS="${val1Kp.publicKey()}" +export VAL2_STELLAR_SECRET="${val2Kp.secret()}" +export VAL2_STELLAR_ADDRESS="${val2Kp.publicKey()}" +export VAL3_STELLAR_SECRET="${val3Kp.secret()}" +export VAL3_STELLAR_ADDRESS="${val3Kp.publicKey()}" +export USER_ADDRESS="${userKp.publicKey()}" +export USER_SECRET="${userKp.secret()}" +export TFT_ASSET_CODE="${TFT_ASSET_CODE}" +export STELLAR_HORIZON_URL="${HORIZON_URL}" +export STELLAR_NETWORK="testnet" +export MV_MED_THRESHOLD="2" +` + fs.writeFileSync(ENV_FILE, envContent) + log(`Environment written to ${ENV_FILE}`) + log('Done.') +} + +main().catch(e => die(e.message || String(e))) diff --git a/scripts/bridge_mv_setup.js b/scripts/bridge_mv_setup.js new file mode 100644 index 000000000..e96155a49 --- /dev/null +++ b/scripts/bridge_mv_setup.js @@ -0,0 +1,185 @@ +#!/usr/bin/env node +/** + * bridge_mv_setup.js + * + * Configures TFChain for multi-validator bridge dev testing. + * + * Genesis pre-configures only validator 1 (dev key 1). This script uses + * council governance (Alice + Bob are genesis council members, 2-of-2) to + * add validators 2 and 3 to the bridge validator set. + * + * TFChain bridge validator dev seeds (from chain_spec.rs): + * Val1: "quarter between satisfy three sphere six soda boss cute decade old trend" (genesis) + * Val2: "employ split promote annual couple elder remain cricket company fitness senior fiscal" (added here) + * Val3: "remind bird banner word spread volume card keep want faith insect mind" (added here) + * + * Council flow per validator: Alice proposes → Bob votes yes → Alice votes yes → Alice closes. + * + * Usage: + * node scripts/bridge_mv_setup.js + */ + +'use strict' + +const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api') + +const TFCHAIN_URL = process.env.TFCHAIN_URL || 'ws://localhost:9944' + +// Bridge validator dev seeds — read from env (set by Makefile) with hardcoded defaults as fallback +const VAL2_SEED = process.env.VAL2_TFCHAIN_SEED || 'employ split promote annual couple elder remain cricket company fitness senior fiscal' +const VAL3_SEED = process.env.VAL3_TFCHAIN_SEED || 'remind bird banner word spread volume card keep want faith insect mind' + +function log (msg) { console.log(`[mv-setup] ${msg}`) } +function die (msg) { console.error(`[mv-setup] FATAL: ${msg}`); process.exit(1) } + +/** Sign a tx, wait for InBlock, and throw on dispatch error */ +function signAndWait (api, tx, signer) { + return new Promise((resolve, reject) => { + let unsub + tx.signAndSend(signer, ({ status, dispatchError, events }) => { + if (!status.isInBlock && !status.isFinalized) return + if (dispatchError) { + let msg = dispatchError.toString() + if (dispatchError.isModule) { + try { + const decoded = api.registry.findMetaError(dispatchError.asModule) + msg = `${decoded.section}.${decoded.name}: ${decoded.docs}` + } catch {} + } + if (unsub) unsub() + reject(new Error(msg)) + return + } + if (unsub) unsub() + resolve({ status, events }) + }).then(u => { unsub = u }).catch(reject) + }) +} + +/** Wait for N new blocks */ +async function waitBlocks (api, n = 1) { + return new Promise((resolve) => { + let count = 0 + const unsubPromise = api.rpc.chain.subscribeNewHeads(() => { + count++ + if (count >= n) { + unsubPromise.then(unsub => unsub()) + resolve() + } + }) + }) +} + +/** Add a bridge validator via council governance (Alice proposes, both vote, Alice closes) */ +async function addValidatorViaCouncil (api, alice, bob, validatorAddress, label) { + // Check if already registered + const validators = await api.query.tftBridgeModule.validators() + const valList = validators.toHuman() + log(`Current validators: ${JSON.stringify(valList)}`) + + if (valList.includes(validatorAddress)) { + log(`${label} (${validatorAddress}) already registered. Skipping.`) + return + } + + log(`Adding ${label} (${validatorAddress}) via council governance...`) + + // Build the addBridgeValidator call + const addValCall = api.tx.tftBridgeModule.addBridgeValidator(validatorAddress) + const encodedCall = addValCall.method.toHex() + const callLen = encodedCall.length / 2 - 1 // bytes + + // Alice proposes with threshold=2 (Alice + Bob must both vote) + log(`Alice proposing addBridgeValidator(${label})...`) + const { events: proposeEvents } = await signAndWait( + api, + api.tx.council.propose(2, addValCall, callLen), + alice + ) + + // Extract proposal hash and index from Proposed event + let proposalHash, proposalIndex + for (const { event } of proposeEvents) { + if (api.events.council.Proposed.is(event)) { + proposalHash = event.data[2].toHex() + proposalIndex = event.data[1].toNumber() + break + } + } + if (!proposalHash) die('Could not extract proposal hash from Proposed event') + log(`Proposal: hash=${proposalHash.slice(0, 12)}... index=${proposalIndex}`) + + // Bob votes yes + log('Bob voting yes...') + await signAndWait(api, api.tx.council.vote(proposalHash, proposalIndex, true), bob) + log('Bob voted yes.') + + // Alice votes yes + log('Alice voting yes...') + await signAndWait(api, api.tx.council.vote(proposalHash, proposalIndex, true), alice) + log('Alice voted yes.') + + // Close the proposal (executes the call) + log('Closing proposal...') + const maxWeight = { refTime: BigInt(1_000_000_000), proofSize: BigInt(1_000_000) } + await signAndWait(api, api.tx.council.close(proposalHash, proposalIndex, maxWeight, callLen), alice) + log('Proposal closed.') + + // Verify + await waitBlocks(api, 1) + const newValidators = await api.query.tftBridgeModule.validators() + const newValList = newValidators.toHuman() + log(`Updated validators: ${JSON.stringify(newValList)}`) + + if (!newValList.includes(validatorAddress)) { + die(`${label} was not added — council call may have failed`) + } + log(`${label} ✓ successfully added as bridge validator.`) +} + +async function main () { + log(`Connecting to TFChain at ${TFCHAIN_URL}...`) + const api = await ApiPromise.create({ provider: new WsProvider(TFCHAIN_URL) }) + + try { + const keyring = new Keyring({ type: 'sr25519' }) + + const alice = keyring.addFromUri('//Alice') + const bob = keyring.addFromUri('//Bob') + const val2 = keyring.addFromUri(VAL2_SEED) + const val3 = keyring.addFromUri(VAL3_SEED) + + log(`Val2 address: ${val2.address}`) + log(`Val3 address: ${val3.address}`) + + // Add val2 via council governance + await addValidatorViaCouncil(api, alice, bob, val2.address, 'Val2') + + // Add val3 via council governance + await addValidatorViaCouncil(api, alice, bob, val3.address, 'Val3') + + // Create Alice's twin (needed for MV2 deposit test) + // Alice must accept T&C before creating a twin + const aliceTwinOpt = await api.query.tfgridModule.twinIdByAccountID(alice.address) + const aliceTwinId = aliceTwinOpt.toJSON() + if (!aliceTwinId) { + log('Accepting T&C and creating Alice twin for deposit tests...') + await signAndWait(api, api.tx.tfgridModule.userAcceptTc('https://localhost/tc', 'deadbeef'), alice) + await signAndWait(api, api.tx.tfgridModule.createTwin(null, null), alice) + const newTwin = await api.query.tfgridModule.twinIdByAccountID(alice.address) + log(`Alice twin created (ID: ${newTwin.toJSON()})`) + } else { + log(`Alice twin already exists (ID: ${aliceTwinId})`) + } + + // Final state + const finalValidators = await api.query.tftBridgeModule.validators() + log(`Final validators: ${JSON.stringify(finalValidators.toHuman())}`) + + log('Setup complete.') + } finally { + await api.disconnect() + } +} + +main().catch(e => die(e.message || String(e))) diff --git a/scripts/bridge_mv_tests.js b/scripts/bridge_mv_tests.js new file mode 100644 index 000000000..98ff4be9c --- /dev/null +++ b/scripts/bridge_mv_tests.js @@ -0,0 +1,728 @@ +#!/usr/bin/env node +/** + * bridge_mv_tests.js + * + * Multi-validator E2E test suite for the TFChain bridge. + * Assumes 3 bridge daemons running (Val1=genesis-key-1, Val2=genesis-key-2, Val3=genesis-key-3), + * bridge Stellar account configured as 2-of-3 multi-sig (threshold=2). + * Val2 and Val3 are added via council governance in bridge-mv-setup. + * + * Tests (run sequentially): + * MV1 — Normal withdraw: 3 validators, 2-of-3 signatures, 1 TFT delivered + * MV2 — Deposit/mint: send TFT with valid memo, all 3 propose mint, threshold met + * MV3 — Bad deposit: no memo, all 3 detect and propose refund, full refund delivered + * MV4 — Validator offline: kill Val3 before deposit, Val1+Val2 alone complete refund (2-of-3) + * MV5 — Batch withdraws: 5 simultaneous swaps, all 5 eventually delivered (may use expiry) + * MV6 — Crash recovery: kill Val2 mid-withdraw, restart, verify delivery completes + * MV6a— Below-minimum: swap below fee, expect dispatch error (parity with SV test6) + * MV8 — Lost cursor: wipe all 3 persistency files, restart, verify no double-spend, + * then deposit to prove bridge is at Stellar tip (tx hash verified) + * MV9 — Expired batch: 50 swaps while all validators offline, wait for expiry, restart, all delivered + * MV7 — Clean state: verify no orphaned active transactions on-chain + * + * All tests assert exact TFT balances (Stellar + TFChain) and on-chain state. + * Non-zero exit on any failure. + * + * Usage: + * node scripts/bridge_mv_tests.js + */ + +'use strict' + +const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api') +const StellarSdk = require('@stellar/stellar-sdk') +const fs = require('fs') +const { spawn } = require('child_process') +const { + log, pass, fail, + loadEnv, getEnv, + stellarTFTBalance, + tfchainBalance, + waitUntil, + sendStellarPayment, + swapToStellar, + TFT_DECIMALS +} = require('./bridge_helpers') +const { startEventCollector, markTestPhase, generateReport } = require('./bridge_instrumentation') + +const TFCHAIN_URL = process.env.TFCHAIN_URL || 'ws://localhost:9944' +const HORIZON_URL = process.env.STELLAR_HORIZON_URL || 'https://horizon-testnet.stellar.org' +const NETWORK_PASSPHRASE = StellarSdk.Networks.TESTNET +const ENV_FILE = process.env.BRIDGE_MV_ENV_FILE || '/tmp/bridge_mv_env.sh' +const BRIDGE_BIN = process.env.BRIDGE_BIN || './bridge/tfchain_bridge/tfchain_bridge_local' +const BRIDGE_DIR = process.env.BRIDGE_DIR || './bridge/tfchain_bridge' + +const VAL_PID_FILES = [1, 2, 3].map(i => `/tmp/bridge_mv_${i}.pid`) +const VAL_LOG_FILES = [1, 2, 3].map(i => `/tmp/bridge_mv_${i}.log`) + +const WITHDRAW_FEE_TFT = 1 + +const counter = { passed: 0, failed: 0 } +let api, alice, horizon, issuerAddress, bridgeAddress, collector + +// ─── Validator lifecycle helpers ──────────────────────────────────────────── + +function getValPid (valIndex) { + const pidFile = VAL_PID_FILES[valIndex - 1] + if (!fs.existsSync(pidFile)) return null + return parseInt(fs.readFileSync(pidFile, 'utf8').trim()) +} + +function killValidator (valIndex, signal = 'SIGKILL') { + const pid = getValPid(valIndex) + if (pid) { + try { process.kill(pid, signal); log(`Val${valIndex} (PID ${pid}) killed`) } catch {} + } +} + +// Bridge validator dev seeds (from substrate-node/node/src/chain_spec.rs) +// Read from env vars (set by Makefile) with hardcoded defaults as fallback. +const VAL_TFCHAIN_SEEDS = [ + process.env.VAL1_TFCHAIN_SEED || 'quarter between satisfy three sphere six soda boss cute decade old trend', + process.env.VAL2_TFCHAIN_SEED || 'employ split promote annual couple elder remain cricket company fitness senior fiscal', + process.env.VAL3_TFCHAIN_SEED || 'remind bird banner word spread volume card keep want faith insect mind' +] + +function startValidator (valIndex) { + const secrets = ['VAL1_STELLAR_SECRET', 'VAL2_STELLAR_SECRET', 'VAL3_STELLAR_SECRET'] + const secret = getEnv(secrets[valIndex - 1]) + const seed = VAL_TFCHAIN_SEEDS[valIndex - 1] + const persistency = `${BRIDGE_DIR}/signer_mv_${valIndex}.json` + const logFile = VAL_LOG_FILES[valIndex - 1] + + // Use shell exec redirect — direct fd inheritance is unreliable on macOS after child.unref() + const cmd = [ + BRIDGE_BIN, + '--secret', secret, + '--tfchainurl', TFCHAIN_URL, + '--tfchainseed', `"${seed}"`, + '--bridgewallet', bridgeAddress, + '--persistency', persistency, + '--network', 'local' + ].join(' ') + + const child = spawn('/bin/sh', ['-c', `exec ${cmd} >> ${logFile} 2>&1`], { + detached: true, + stdio: 'ignore' + }) + child.unref() + fs.writeFileSync(VAL_PID_FILES[valIndex - 1], String(child.pid)) + log(`Val${valIndex} restarted (PID ${child.pid})`) +} + +// ─── On-chain assertion helpers ───────────────────────────────────────────── + +/** + * Poll until a burn tx moves to ExecutedBurnTransactions (not stuck in active map). + * Waits up to 30s for the on-chain state to settle — set_burn_transaction_executed + * may finalize a few blocks after the Stellar payment is visible. + */ +async function assertBurnExecuted (name, burnId) { + try { + await waitUntil(async () => { + const active = (await api.query.tftBridgeModule.burnTransactions(burnId)).toJSON() + if (active && active.target) return false + const executed = (await api.query.tftBridgeModule.executedBurnTransactions(burnId)).toJSON() + return executed && executed.target + }, { timeoutMs: 30_000, intervalMs: 3000, desc: `burn ${burnId} to reach ExecutedBurnTransactions` }) + return true + } catch { + const active = (await api.query.tftBridgeModule.burnTransactions(burnId)).toJSON() + if (active && active.target) { + fail(name, `burn ${burnId} still in active BurnTransactions after 30s`, counter) + } else { + fail(name, `burn ${burnId} not in ExecutedBurnTransactions after 30s`, counter) + } + return false + } +} + +/** + * Poll until at least one new refund reaches ExecutedRefundTransactions since `countBefore`. + * Waits up to 30s — set_refund_transaction_executed may finalize after the Stellar refund. + */ +async function assertRefundExecuted (name, countBefore) { + try { + await waitUntil(async () => { + const after = await api.query.tftBridgeModule.executedRefundTransactions.entries() + return after.length > countBefore + }, { timeoutMs: 30_000, intervalMs: 3000, desc: 'new refund in ExecutedRefundTransactions' }) + return true + } catch { + const after = await api.query.tftBridgeModule.executedRefundTransactions.entries() + fail(name, `no new refund in ExecutedRefundTransactions after 30s (before: ${countBefore}, after: ${after.length})`, counter) + return false + } +} + +// ─── Tests ──────────────────────────────────────────────────────────────────── + +async function testMV1_normalWithdraw () { + console.log('\n── MV1: Normal withdraw (3 validators, threshold=2) ──') + markTestPhase(collector, 'MV1', 'start') + const name = 'MV1_normalWithdraw' + const userAddress = getEnv('USER_ADDRESS') + const swapAmount = 2 + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const beforeTFChain = await tfchainBalance(api, alice.address) + log(`User Stellar TFT before: ${beforeStellar}`) + log(`Alice TFChain TFT before: ${beforeTFChain}`) + + const burnId = await swapToStellar(api, alice, swapAmount, { userAddress }) + log(`Burn ID: ${burnId}`) + + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal > beforeStellar) return bal + }, { timeoutMs: 300_000, intervalMs: 4000, desc: 'Stellar balance to increase' }) + + // Assert Stellar balance delta + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + const expected = swapAmount - WITHDRAW_FEE_TFT + log(`User Stellar TFT after: ${afterStellar} (+${delta} TFT)`) + if (Math.abs(delta - expected) > 1e-7) { + fail(name, `Expected Stellar +${expected} TFT, got +${delta}`, counter); return + } + + // Assert TFChain balance decreased by ~swapAmount (± 0.1 TFT for extrinsic fee). + const afterTFChain = await tfchainBalance(api, alice.address) + const tfDelta = Math.round((beforeTFChain - afterTFChain) * TFT_DECIMALS) / TFT_DECIMALS + log(`Alice TFChain TFT after: ${afterTFChain} (-${tfDelta} TFT)`) + if (Math.abs(tfDelta - swapAmount) > 0.1) { + fail(name, `TFChain balance should decrease by ~${swapAmount} (±0.1), decreased by ${tfDelta}`, counter); return + } + + // Assert on-chain: burn executed + if (!(await assertBurnExecuted(name, burnId))) return + + pass(name, counter) + } catch (e) { fail(name, e.message, counter) } + finally { markTestPhase(collector, 'MV1', 'end') } +} + +async function testMV2_deposit () { + console.log('\n── MV2: Deposit/mint (3 validators all propose) ──') + markTestPhase(collector, 'MV2', 'start') + const name = 'MV2_deposit' + const aliceAddress = alice.address + + try { + // Get Alice's twin ID — twinIdByAccountID returns Option + const twinOpt = await api.query.tfgridModule.twinIdByAccountID(aliceAddress) + const twinId = twinOpt.isSome ? twinOpt.unwrap().toNumber() : twinOpt.toJSON() + if (!twinId) throw new Error('Alice has no twin on TFChain — is bridge-setup complete?') + log(`Alice twin ID: ${twinId}`) + + const depositAmount = '2' + const depositFee = Number(await api.query.tftBridgeModule.depositFee()) / TFT_DECIMALS + const expectedMint = parseFloat(depositAmount) - depositFee + log(`Deposit fee: ${depositFee} TFT, expected mint: ${expectedMint} TFT`) + + const aliceBalBefore = await tfchainBalance(api, aliceAddress) + const mintsBefore = (await api.query.tftBridgeModule.executedMintTransactions.entries()).length + log(`Alice TFChain TFT before: ${aliceBalBefore}, executed mints: ${mintsBefore}`) + + // Memo format must be "twin_" (bridge parses "object_objectID") + const result = await sendStellarPayment( + horizon, issuerAddress, NETWORK_PASSPHRASE, + getEnv('USER_SECRET'), + bridgeAddress, + depositAmount, + `twin_${twinId}` + ) + log(`Deposit sent: ${result.hash.slice(0, 16)} (memo: twin_${twinId})`) + + // Wait for mint to be executed on TFChain + const mintsAfter = await waitUntil(async () => { + const mints = await api.query.tftBridgeModule.executedMintTransactions.entries() + if (mints.length > mintsBefore) return mints + }, { timeoutMs: 120_000, intervalMs: 4000, desc: 'executed mint count to increase' }) + + log(`Executed mints after: ${mintsAfter.length}`) + + // Assert Alice's TFChain balance increased by ~expectedMint (± 0.1 TFT for block author rewards). + const aliceBalAfter = await tfchainBalance(api, aliceAddress) + const balDelta = Math.round((aliceBalAfter - aliceBalBefore) * TFT_DECIMALS) / TFT_DECIMALS + log(`Alice TFChain TFT after: ${aliceBalAfter} (+${balDelta} TFT)`) + if (Math.abs(balDelta - expectedMint) > 0.1) { + fail(name, `Expected TFChain ~+${expectedMint} TFT (±0.1), got +${balDelta}`, counter); return + } + + pass(name, counter) + } catch (e) { fail(name, e.message, counter) } + finally { markTestPhase(collector, 'MV2', 'end') } +} + +async function testMV3_badDeposit () { + console.log('\n── MV3: Bad deposit (no memo -> full refund, 3 validators) ──') + markTestPhase(collector, 'MV3', 'start') + const name = 'MV3_badDeposit' + const userAddress = getEnv('USER_ADDRESS') + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const refundsBefore = (await api.query.tftBridgeModule.executedRefundTransactions.entries()).length + log(`User Stellar TFT before: ${beforeStellar}`) + + const result = await sendStellarPayment(horizon, issuerAddress, NETWORK_PASSPHRASE, getEnv('USER_SECRET'), bridgeAddress, '3') + log(`Bad deposit sent: ${result.hash.slice(0, 16)} (no memo)`) + + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal >= beforeStellar - 1e-7) return bal + }, { timeoutMs: 180_000, intervalMs: 4000, desc: 'balance restored after refund' }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after: ${afterStellar} (delta: ${delta >= 0 ? '+' : ''}${delta})`) + + if (Math.abs(delta) > 1e-7) { + fail(name, `Expected net 0 (full refund), got ${delta >= 0 ? '+' : ''}${delta}`, counter); return + } + + // Assert on-chain: refund executed + if (!(await assertRefundExecuted(name, refundsBefore))) return + + pass(name, counter) + } catch (e) { fail(name, e.message, counter) } + finally { markTestPhase(collector, 'MV3', 'end') } +} + +async function testMV4_validatorOffline () { + console.log('\n── MV4: Val3 offline — Val1+Val2 complete refund with 2-of-3 threshold ──') + markTestPhase(collector, 'MV4', 'start') + const name = 'MV4_validatorOffline' + const userAddress = getEnv('USER_ADDRESS') + + try { + // Kill Val3 before the deposit — threshold=2, so Val1+Val2 alone can complete + killValidator(3) + await new Promise(r => setTimeout(r, 2000)) + + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const refundsBefore = (await api.query.tftBridgeModule.executedRefundTransactions.entries()).length + log(`Val3 killed. User Stellar TFT before: ${beforeStellar}`) + + // Send bad deposit (no memo) — Val1+Val2 detect it, propose refund, threshold=2 met + const result = await sendStellarPayment(horizon, issuerAddress, NETWORK_PASSPHRASE, getEnv('USER_SECRET'), bridgeAddress, '4') + log(`Bad deposit sent: ${result.hash.slice(0, 16)} (no memo, Val3 offline)`) + + // Wait for refund to complete — Val1+Val2 have enough signatures (2-of-3) + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal >= beforeStellar - 1e-7) return bal + }, { timeoutMs: 180_000, intervalMs: 4000, desc: 'balance restored with Val3 offline' }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after: ${afterStellar} (delta: ${delta >= 0 ? '+' : ''}${delta})`) + + if (Math.abs(delta) > 1e-7) { + fail(name, `Expected net 0 (full refund), got ${delta >= 0 ? '+' : ''}${delta}`, counter) + } else if (!(await assertRefundExecuted(name, refundsBefore))) { + // assertRefundExecuted polls for 30s and logs failure itself + } else { + pass(name, counter) + } + } catch (e) { + fail(name, e.message, counter) + } finally { + // Restart Val3 for subsequent tests — best effort with fixed startup window. + try { + log('Restarting Val3 for subsequent tests...') + startValidator(3) + await new Promise(r => setTimeout(r, 8000)) + log('Val3 restarted.') + } catch (restartErr) { + log(`Warning: Val3 restart failed: ${restartErr.message}`) + } + markTestPhase(collector, 'MV4', 'end') + } +} + +async function testMV5_batchWithdraws () { + console.log('\n── MV5: Batch withdraws (5 simultaneous, all validators) ──') + markTestPhase(collector, 'MV5', 'start') + const name = 'MV5_batchWithdraws' + const userAddress = getEnv('USER_ADDRESS') + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before: ${beforeStellar}`) + + const nonce = await api.rpc.system.accountNextIndex(alice.address) + const burnIds = await Promise.all( + [0, 1, 2, 3, 4].map(i => swapToStellar(api, alice, 2, { userAddress, nonce: nonce.toNumber() + i })) + ) + log(`Burn IDs: ${burnIds.join(', ')}`) + + const expectedNet = 5 * (2 - WITHDRAW_FEE_TFT) + + // Use longer timeout — sequence collisions may require expiry cycle (~2 min each) + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal >= beforeStellar + expectedNet - 1e-7) return bal + }, { timeoutMs: 600_000, intervalMs: 4000, desc: `balance >= ${beforeStellar + expectedNet} (may need expiry cycles)` }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after: ${afterStellar} (+${delta}, expected +${expectedNet})`) + if (Math.abs(delta - expectedNet) > 1e-7) { + fail(name, `Expected +${expectedNet}, got +${delta}`, counter); return + } + + // Assert on-chain: all burns executed + for (const burnId of burnIds) { + if (!(await assertBurnExecuted(name, burnId))) return + } + + pass(name, counter) + } catch (e) { fail(name, e.message, counter) } + finally { markTestPhase(collector, 'MV5', 'end') } +} + +async function testMV6_crashRecovery () { + console.log('\n── MV6: Crash recovery (kill Val2 mid-withdraw, restart, verify delivery) ──') + markTestPhase(collector, 'MV6', 'start') + const name = 'MV6_crashRecovery' + const userAddress = getEnv('USER_ADDRESS') + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before: ${beforeStellar}`) + + const burnId = await swapToStellar(api, alice, 2, { userAddress }) + log(`Burn ID: ${burnId}`) + + // Wait for at least 1 signature (proposals submitted) + await waitUntil(async () => { + const burn = (await api.query.tftBridgeModule.burnTransactions(burnId)).toJSON() + return burn && burn.signatures && burn.signatures.length >= 1 + }, { timeoutMs: 60_000, desc: 'BurnTransactionReady (>=1 sig)' }) + + // Kill Val2 mid-flight + killValidator(2, 'SIGKILL') + log('Val2 killed. Waiting 3s...') + await new Promise(r => setTimeout(r, 3000)) + + // Restart Val2 + startValidator(2) + log('Val2 restarted. Waiting 10s for startup...') + await new Promise(r => setTimeout(r, 10_000)) + + // Val1+Val3 should complete it (2-of-3), or Val2 reconciles after restart + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal > beforeStellar) return bal + }, { timeoutMs: 300_000, intervalMs: 4000, desc: 'Stellar balance to increase after crash' }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + const expected = 2 - WITHDRAW_FEE_TFT + log(`User Stellar TFT after: ${afterStellar} (+${delta} TFT)`) + + if (Math.abs(delta - expected) > 1e-7) { + fail(name, `Expected +${expected} TFT after recovery, got +${delta}`, counter); return + } + + // Assert on-chain: burn executed + if (!(await assertBurnExecuted(name, burnId))) return + + pass(name, counter) + } catch (e) { fail(name, e.message, counter) } + finally { markTestPhase(collector, 'MV6', 'end') } +} + +async function testMV6a_belowMinimum () { + console.log('\n── MV6a: Withdraw below minimum (should be rejected) ──') + markTestPhase(collector, 'MV6a', 'start') + const name = 'MV6a_belowMinimum' + try { + await swapToStellar(api, alice, 0.5, { userAddress: getEnv('USER_ADDRESS') }) + fail(name, 'swapToStellar should have thrown, but succeeded', counter) + } catch (e) { + if (e.message.includes('AmountIsLessThanWithdrawFee')) { + log(`Correctly rejected: ${e.message}`) + pass(name, counter) + } else { + fail(name, `Expected AmountIsLessThanWithdrawFee, got: ${e.message}`, counter) + } + } + markTestPhase(collector, 'MV6a', 'end') +} + +async function testMV8_lostCursor () { + console.log('\n── MV8: Lost cursor (wipe all 3 persistency files → no double-spend) ──') + markTestPhase(collector, 'MV8', 'start') + const name = 'MV8_lostCursor' + const userAddress = getEnv('USER_ADDRESS') + + try { + // Kill all 3 validators + for (let i = 1; i <= 3; i++) killValidator(i) + await new Promise(r => setTimeout(r, 2000)) + + // Wipe all 3 persistency files. + // Without the cursor, bridges re-scan the Stellar account from the beginning. + // Protection against duplicate burns: IsBurnedAlready (ExecutedBurnTransactions) + // Protection against duplicate mints: IsMintedAlready (ExecutedMintTransactions) + for (let i = 1; i <= 3; i++) { + const p = `${BRIDGE_DIR}/signer_mv_${i}.json` + if (fs.existsSync(p)) { + fs.unlinkSync(p) + log(`Wiped: ${p}`) + } + } + + // Snapshot Stellar balance — should NOT change after restart + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before restart: ${beforeStellar}`) + + // Restart all 3 validators — they rescan with no local state + for (let i = 1; i <= 3; i++) startValidator(i) + log('All 3 validators restarted with wiped cursors. Waiting 15s for rescan...') + await new Promise(r => setTimeout(r, 15_000)) + + // Verify no double-spend — balance must be unchanged + const afterStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after rescan: ${afterStellar} (delta: ${delta >= 0 ? '+' : ''}${delta})`) + if (Math.abs(delta) > 1e-7) { + fail(name, `DOUBLE-SPEND: balance changed by ${delta} TFT after cursor wipe`, counter); return + } + log('No double-spend — IsMintedAlready + IsBurnedAlready held during rescan') + + // ─── Hardened: fresh DEPOSIT to prove bridge is at Stellar tip ─────── + // + // A withdraw (old approach) is event-driven from TFChain — it doesn't use + // the Stellar cursor at all, so it doesn't prove the bridge finished scanning. + // + // A deposit proves the bridge has caught up to the TIP of the Stellar account, + // because the bridge must reach our new transaction in the Horizon stream. + // + // Extra hardening: we verify the on-chain mint's tx_id matches our Stellar + // deposit hash, ruling out the case where an OLD deposit was re-processed + // and our new deposit is still un-seen. + log('Running fresh deposit to verify bridge scanned to Stellar tip...') + + const twinOpt = await api.query.tfgridModule.twinIdByAccountID(alice.address) + const twinId = twinOpt.isSome ? twinOpt.unwrap().toNumber() : twinOpt.toJSON() + if (!twinId) throw new Error('Alice has no twin on TFChain — is bridge-setup complete?') + + const depositAmount = '2' + const depositFee = Number(await api.query.tftBridgeModule.depositFee()) / TFT_DECIMALS + const expectedMint = parseFloat(depositAmount) - depositFee + log(`Deposit fee: ${depositFee} TFT, expected mint: ${expectedMint} TFT`) + + const aliceBalBefore = await tfchainBalance(api, alice.address) + const mintsBefore = (await api.query.tftBridgeModule.executedMintTransactions.entries()).length + log(`Alice TFChain TFT before: ${aliceBalBefore}, executed mints: ${mintsBefore}`) + + // Send deposit — capture the Stellar tx hash for verification + const result = await sendStellarPayment( + horizon, issuerAddress, NETWORK_PASSPHRASE, + getEnv('USER_SECRET'), + bridgeAddress, + depositAmount, + `twin_${twinId}` + ) + const depositTxHash = result.hash + log(`Fresh deposit sent: ${depositTxHash} (memo: twin_${twinId})`) + + // Wait for the mint to appear on-chain + await waitUntil(async () => { + const mints = await api.query.tftBridgeModule.executedMintTransactions.entries() + if (mints.length > mintsBefore) return mints + }, { timeoutMs: 300_000, intervalMs: 4000, desc: 'fresh deposit mint to complete' }) + + // ─── TX HASH VERIFICATION ────────────────────────────────────────── + // Query executedMintTransactions by our specific Stellar tx hash. + // On-chain key = Vec of the Stellar tx hash string (same as Go bridge passes). + // If found: our NEW deposit was processed (bridge is at tip). + // If not found: an OLD deposit was re-processed instead — FAIL. + const mintTx = (await api.query.tftBridgeModule.executedMintTransactions(depositTxHash)).toJSON() + if (!mintTx || !mintTx.amount || mintTx.amount === 0) { + fail(name, `Mint tx hash mismatch: executedMintTransactions["${depositTxHash.slice(0, 16)}..."] not found on-chain — an old deposit may have been re-processed instead`, counter) + return + } + log(`TX hash verified: executedMintTransactions["${depositTxHash.slice(0, 16)}..."] = {amount: ${mintTx.amount}, votes: ${mintTx.votes}}`) + + // Verify Alice's TFChain balance increased by expected amount (± 0.1 for block author rewards) + const aliceBalAfter = await tfchainBalance(api, alice.address) + const balDelta = Math.round((aliceBalAfter - aliceBalBefore) * TFT_DECIMALS) / TFT_DECIMALS + log(`Alice TFChain TFT after: ${aliceBalAfter} (+${balDelta} TFT)`) + if (Math.abs(balDelta - expectedMint) > 0.1) { + fail(name, `Fresh deposit: expected TFChain ~+${expectedMint} TFT (±0.1), got +${balDelta}`, counter); return + } + + // Verify exactly 1 new mint was processed (no old deposits re-minted) + const mintsAfter = (await api.query.tftBridgeModule.executedMintTransactions.entries()).length + const mintCountDelta = mintsAfter - mintsBefore + log(`Executed mints: ${mintsBefore} → ${mintsAfter} (+${mintCountDelta})`) + if (mintCountDelta !== 1) { + fail(name, `Expected exactly 1 new mint, got ${mintCountDelta} — old deposits may have been re-processed`, counter); return + } + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } finally { + markTestPhase(collector, 'MV8', 'end') + } +} + +async function testMV9_expiredBatchRecovery () { + console.log('\n── MV9: Expired batch recovery (50 swaps offline → expiry → restart) ──') + markTestPhase(collector, 'MV9', 'start') + const name = 'MV9_expiredBatchRecovery' + const userAddress = getEnv('USER_ADDRESS') + const N = 50 + + try { + // Kill all 3 validators + for (let i = 1; i <= 3; i++) killValidator(i) + await new Promise(r => setTimeout(r, 2000)) + log('All 3 validators killed') + + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before: ${beforeStellar}`) + + // Submit N swaps in one block using sequential nonces + log(`Submitting ${N} swaps (all validators offline)...`) + const nonce = await api.rpc.system.accountNextIndex(alice.address) + const burnIds = await Promise.all( + Array.from({ length: N }, (_, i) => + swapToStellar(api, alice, 2, { userAddress, nonce: nonce.toNumber() + i }) + ) + ) + log(`${N} burns created on-chain: IDs ${burnIds[0]}..${burnIds[burnIds.length - 1]}`) + + // Wait for all burns to expire (on_finalize clears signatures after RetryInterval=20 blocks ≈ 120s) + log('Waiting for burns to expire on-chain (RetryInterval=20 blocks)...') + await waitUntil(async () => { + const burn = (await api.query.tftBridgeModule.burnTransactions(burnIds[0])).toJSON() + return burn && burn.signatures && burn.signatures.length === 0 + }, { timeoutMs: 180_000, intervalMs: 6000, desc: 'first burn to expire (signatures cleared)' }) + log('All burns expired (signatures cleared, sequence_number reset to 0)') + + // Start all 3 validators — they catch the next BurnTransactionExpired events. + // handleProposalsBatch re-proposes all expired burns in a single force_batch tx with + // consecutive Stellar sequence numbers (SyncSequenceNumber + per-proposal increment). + // All validators sync the same base sequence (no Stellar tx submitted yet), so they + // produce matching signatures. Once threshold is met, all burns become Ready and + // handleWithdrawReady submits them sequentially — each using its stored sequence + // number, so all succeed in one pass. + // + // After all Stellar payments in a cycle complete, BatchSetWithdrawExecuted + // confirms all in one force_batch. Multiple expiry cycles may be needed. + for (let i = 1; i <= 3; i++) startValidator(i) + log('All 3 validators restarted. Recovering expired burns via batch re-proposal...') + log(`Expected: 1 force_batch re-proposes all ${N}, then all ${N} Stellar payments execute in sequence`) + + const expectedNet = N * (2 - WITHDRAW_FEE_TFT) + let lastReported = 0 + + const finalStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const delivered = Math.round((bal - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + const count = Math.round(delivered / (2 - WITHDRAW_FEE_TFT)) + if (count > lastReported) { + log(` Progress: ${count}/${N} burns delivered (+${delivered} TFT)`) + lastReported = count + } + if (bal >= beforeStellar + expectedNet - 1e-7) return bal + }, { timeoutMs: 900_000, intervalMs: 10_000, desc: `all ${N} burns delivered (+${expectedNet} TFT)` }) + + const delta = Math.round((finalStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`All ${N} burns delivered: +${delta} TFT (expected +${expectedNet})`) + if (Math.abs(delta - expectedNet) > 1e-7) { + fail(name, `Expected +${expectedNet}, got +${delta}`, counter); return + } + + // Assert on-chain: all burns executed + for (const burnId of burnIds) { + if (!(await assertBurnExecuted(name, burnId))) return + } + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } finally { + markTestPhase(collector, 'MV9', 'end') + } +} + +async function testMV7_cleanState () { + console.log('\n── MV7: Clean state (no orphaned active transactions) ──') + markTestPhase(collector, 'MV7', 'start') + const name = 'MV7_cleanState' + + try { + // Wait for all active transaction maps to drain (tolerates in-flight processing) + await waitUntil(async () => { + const burns = await api.query.tftBridgeModule.burnTransactions.entries() + const refunds = await api.query.tftBridgeModule.refundTransactions.entries() + const mints = await api.query.tftBridgeModule.mintTransactions.entries() + return burns.length === 0 && refunds.length === 0 && mints.length === 0 + }, { timeoutMs: 300_000, intervalMs: 5000, desc: 'all active tx maps to drain' }) + pass(name, counter) + } catch (e) { + // On timeout, report what's left + const burns = await api.query.tftBridgeModule.burnTransactions.entries() + const refunds = await api.query.tftBridgeModule.refundTransactions.entries() + const mints = await api.query.tftBridgeModule.mintTransactions.entries() + fail(name, `Orphaned: ${burns.length} burns, ${refunds.length} refunds, ${mints.length} mints`, counter) + } finally { + markTestPhase(collector, 'MV7', 'end') + } +} + +// ─── Main ──────────────────────────────────────────────────────────────────── + +async function main () { + loadEnv(ENV_FILE, 'mv-tests') + bridgeAddress = getEnv('BRIDGE_ADDRESS') + issuerAddress = getEnv('ISSUER_ADDRESS') + + console.log('[mv-tests] Connecting to TFChain and Stellar...') + api = await ApiPromise.create({ provider: new WsProvider(TFCHAIN_URL) }) + horizon = new StellarSdk.Horizon.Server(HORIZON_URL) + + try { + const keyring = new Keyring({ type: 'sr25519' }) + alice = keyring.addFromUri('//Alice') + + // Start event collector for deep analysis + collector = await startEventCollector(api) + console.log('[mv-tests] Event collector started — tracking all bridge events by block') + + console.log('[mv-tests] Starting multi-validator test suite...\n') + + await testMV1_normalWithdraw() + await testMV2_deposit() + await testMV3_badDeposit() + await testMV4_validatorOffline() // kills/restarts Val3 + await testMV5_batchWithdraws() + await testMV6_crashRecovery() // kills/restarts Val2 + await testMV6a_belowMinimum() // pure pallet test, no bridge needed + await testMV8_lostCursor() // kills/restarts all 3 with wiped cursors + await testMV9_expiredBatchRecovery() // kills all 3, 50 swaps, expiry, restart (long) + await testMV7_cleanState() + + console.log(`\n${'─'.repeat(50)}`) + console.log(`Results: ${counter.passed} passed, ${counter.failed} failed`) + console.log('─'.repeat(50)) + + // Generate analysis report (pass api for chain-state reconciliation) + const outputPath = process.env.ANALYSIS_OUTPUT || '/tmp/bridge_mv_analysis.json' + await generateReport(collector, outputPath, api) + } finally { + if (collector) collector.stop() + await api.disconnect() + } + + process.exit(counter.failed > 0 ? 1 : 0) +} + +main().catch(e => { + console.error(`[mv-tests] FATAL: ${e.message || e}`) + process.exit(1) +}) diff --git a/scripts/bridge_setup.js b/scripts/bridge_setup.js new file mode 100644 index 000000000..b569f5c17 --- /dev/null +++ b/scripts/bridge_setup.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node +/** + * bridge_setup.js + * + * Verifies that the TFChain dev chain genesis has the bridge pallet configured + * correctly for local development. The dev chain genesis pre-configures: + * - Bridge validators: Bob (//Bob) and Charlie (//Charlie) + * - Fee account: Ferdie (//Ferdie) + * - Deposit fee: 10,000,000 base units (1 TFT) + * - Withdraw fee: 10,000,000 base units (1 TFT) + * + * The dev chain genesis is sufficient for bridge configuration (no sudo needed). + * This script additionally creates Alice's twin (needed for deposit tests). + * + * Usage: + * node scripts/bridge_setup.js + */ + +'use strict' + +const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api') + +const TFCHAIN_URL = process.env.TFCHAIN_URL || 'ws://localhost:9944' + +function log (msg) { console.log(`[setup] ${msg}`) } +function warn (msg) { console.warn(`[setup] WARN: ${msg}`) } +function die (msg) { console.error(`[setup] ERROR: ${msg}`); process.exit(1) } + +/** Sign a tx, wait for InBlock, and throw on dispatch error */ +function signAndWait (api, tx, signer) { + return new Promise((resolve, reject) => { + let unsub + tx.signAndSend(signer, ({ status, dispatchError, events }) => { + if (!status.isInBlock && !status.isFinalized) return + if (dispatchError) { + let msg = dispatchError.toString() + if (dispatchError.isModule) { + try { + const decoded = api.registry.findMetaError(dispatchError.asModule) + msg = `${decoded.section}.${decoded.name}: ${decoded.docs}` + } catch {} + } + if (unsub) unsub() + reject(new Error(msg)) + return + } + if (unsub) unsub() + resolve({ status, events }) + }).then(u => { unsub = u }).catch(reject) + }) +} + +async function main () { + log(`Connecting to TFChain at ${TFCHAIN_URL}...`) + const api = await ApiPromise.create({ provider: new WsProvider(TFCHAIN_URL) }) + + try { + const keyring = new Keyring({ type: 'sr25519' }) + + const alice = keyring.addFromUri('//Alice') + const bob = keyring.addFromUri('//Bob') + const charlie = keyring.addFromUri('//Charlie') + const ferdie = keyring.addFromUri('//Ferdie') + + const validators = await api.query.tftBridgeModule.validators() + const valList = validators.toHuman() + const feeAccount = await api.query.tftBridgeModule.feeAccount() + const depositFee = await api.query.tftBridgeModule.depositFee() + const withdrawFee = await api.query.tftBridgeModule.withdrawFee() + + log('=== TFChain Bridge Genesis Configuration ===') + log(` Validators: ${JSON.stringify(valList)}`) + log(` Fee account: ${feeAccount.toHuman()}`) + log(` Deposit fee: ${Number(depositFee.toString()) / 1e7} TFT`) + log(` Withdraw fee: ${Number(withdrawFee.toString()) / 1e7} TFT`) + + // Verify expected validators are present + if (!valList.includes(bob.address)) { + warn(`Bob (${bob.address}) is not a genesis validator — bridge daemon using //Bob will be rejected`) + } else { + log(` Bob (//Bob) ✓ is a registered validator`) + } + + if (!valList.includes(charlie.address)) { + warn(`Charlie (${charlie.address}) is not a genesis validator`) + } else { + log(` Charlie (//Charlie) ✓ is a registered validator`) + } + + if (feeAccount.toHuman() !== ferdie.address) { + warn(`Fee account is ${feeAccount.toHuman()}, expected Ferdie (${ferdie.address})`) + } else { + log(` Fee account ✓ is Ferdie`) + } + + if (Number(depositFee.toString()) === 0) { + warn('Deposit fee is 0 — bridge may not charge fees') + } + + // Create Alice's twin (needed for test5_deposit) + // Alice must accept T&C before creating a twin + const aliceTwinOpt = await api.query.tfgridModule.twinIdByAccountID(alice.address) + const aliceTwinId = aliceTwinOpt.toJSON() + if (!aliceTwinId) { + log('Accepting T&C and creating Alice twin for deposit tests...') + await signAndWait(api, api.tx.tfgridModule.userAcceptTc('https://localhost/tc', 'deadbeef'), alice) + await signAndWait(api, api.tx.tfgridModule.createTwin(null, null), alice) + const newTwin = await api.query.tfgridModule.twinIdByAccountID(alice.address) + log(`Alice twin created (ID: ${newTwin.toJSON()})`) + } else { + log(`Alice twin already exists (ID: ${aliceTwinId})`) + } + + log('Setup verification complete.') + } finally { + await api.disconnect() + } +} + +main().catch(e => { + console.error(`[setup] FATAL: ${e.message || e}`) + process.exit(1) +}) diff --git a/scripts/bridge_tests.js b/scripts/bridge_tests.js new file mode 100644 index 000000000..5a0b859ef --- /dev/null +++ b/scripts/bridge_tests.js @@ -0,0 +1,654 @@ +#!/usr/bin/env node +/** + * bridge_tests.js + * + * E2E test suite for the TFChain bridge local dev environment. + * + * Tests (run sequentially): + * 1. Normal withdraw — swap 2 TFT on TFChain, receive 1 TFT on Stellar (1 TFT fee) + * 2. Batch withdraws — 5 simultaneous swaps in one block, all 5 delivered + * 3. Bad deposit — send TFT to bridge without memo, expect full refund + * 5. Deposit/mint — send TFT to bridge with twin memo, verify TFChain balance + * 6. Below-minimum — swap below fee, expect dispatch error + * 4. Crash recovery — SIGKILL bridge mid-withdraw, restart, verify delivery completes + * 8. Lost cursor — wipe persistency (BoltDB), restart, verify no double-spend, + * then deposit to prove bridge is at Stellar tip (tx hash verified) + * 9. Expired batch — 50 swaps while bridge offline, wait for expiry, restart, all delivered + * 7. Clean state — verify no orphaned active transactions on-chain + * + * All tests assert exact TFT balances (Stellar + TFChain) and on-chain state. + * Non-zero exit on any failure. + * + * Usage: + * node scripts/bridge_tests.js + * TFCHAIN_URL=ws://localhost:9944 BRIDGE_PID_FILE=/tmp/bridge_local.pid node scripts/bridge_tests.js + */ + +'use strict' + +const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api') +const StellarSdk = require('@stellar/stellar-sdk') +const fs = require('fs') +const { spawn } = require('child_process') +const { + log, pass, fail, + loadEnv, getEnv, + stellarTFTBalance, + tfchainBalance, + waitUntil, + sendStellarPayment, + swapToStellar, + TFT_DECIMALS +} = require('./bridge_helpers') + +const TFCHAIN_URL = process.env.TFCHAIN_URL || 'ws://localhost:9944' +const HORIZON_URL = process.env.STELLAR_HORIZON_URL || 'https://horizon-testnet.stellar.org' +const NETWORK_PASSPHRASE = StellarSdk.Networks.TESTNET +const ENV_FILE = process.env.BRIDGE_ENV_FILE || '/tmp/bridge_local_env.sh' +const BRIDGE_PID_FILE = process.env.BRIDGE_PID_FILE || '/tmp/bridge_local.pid' +const BRIDGE_LOG_FILE = process.env.BRIDGE_LOG_FILE || '/tmp/bridge_local.log' +const BRIDGE_BIN = process.env.BRIDGE_BIN || './bridge/tfchain_bridge/tfchain_bridge_local' +const BRIDGE_PERSISTENCY = process.env.BRIDGE_PERSISTENCY || './bridge/tfchain_bridge/signer_local.json' + +const WITHDRAW_FEE_TFT = 1 // 1 TFT fee + +const counter = { passed: 0, failed: 0 } +let api, alice, horizon, bridgeAddress, issuerAddress + +// ─── Bridge lifecycle helpers ─────────────────────────────────────────────── + +async function bridgeIsRunning () { + if (!fs.existsSync(BRIDGE_PID_FILE)) return false + const pid = parseInt(fs.readFileSync(BRIDGE_PID_FILE, 'utf8').trim()) + try { process.kill(pid, 0); return true } catch { return false } +} + +function getBridgePid () { + if (!fs.existsSync(BRIDGE_PID_FILE)) return null + return parseInt(fs.readFileSync(BRIDGE_PID_FILE, 'utf8').trim()) +} + +function killBridge (signal = 'SIGKILL') { + const pid = getBridgePid() + if (pid) { + try { process.kill(pid, signal); log(`Bridge (PID ${pid}) killed with ${signal}`) } catch {} + } +} + +function startBridge () { + const bridgeSecret = getEnv('BRIDGE_SECRET') + const tfchainSeed = process.env.VAL1_TFCHAIN_SEED || + 'quarter between satisfy three sphere six soda boss cute decade old trend' + + // Use shell exec + append redirect instead of fd inheritance. + // On macOS, passing a numeric fd to a detached child's stdio is unreliable: + // the fd silently becomes invalid after child.unref(), so the bridge writes nothing + // to the log. Shell exec replaces sh with the bridge binary (same PID), and + // >> redirect is handled by the shell before exec, so it works cross-platform. + const shellCmd = [ + 'exec', + `"${BRIDGE_BIN}"`, + '--secret', `"${bridgeSecret}"`, + '--tfchainurl', TFCHAIN_URL, + '--tfchainseed', `"${tfchainSeed}"`, + '--bridgewallet', bridgeAddress, + '--persistency', BRIDGE_PERSISTENCY, + '--network', 'local', + `>>"${BRIDGE_LOG_FILE}"`, '2>&1' + ].join(' ') + + const child = spawn('/bin/sh', ['-c', shellCmd], { + detached: true, + stdio: 'ignore' + }) + child.unref() + fs.writeFileSync(BRIDGE_PID_FILE, String(child.pid)) + log(`Bridge restarted (PID ${child.pid})`) + return child.pid +} + +// ─── On-chain assertion helpers ───────────────────────────────────────────── + +/** + * Poll until a burn tx moves to ExecutedBurnTransactions (not stuck in active map). + * Waits up to 30s for the on-chain state to settle — set_burn_transaction_executed + * may finalize a few blocks after the Stellar payment is visible. + */ +async function assertBurnExecuted (name, burnId) { + try { + await waitUntil(async () => { + const active = (await api.query.tftBridgeModule.burnTransactions(burnId)).toJSON() + if (active && active.target) return false + const executed = (await api.query.tftBridgeModule.executedBurnTransactions(burnId)).toJSON() + return executed && executed.target + }, { timeoutMs: 30_000, intervalMs: 3000, desc: `burn ${burnId} to reach ExecutedBurnTransactions` }) + return true + } catch { + const active = (await api.query.tftBridgeModule.burnTransactions(burnId)).toJSON() + if (active && active.target) { + fail(name, `burn ${burnId} still in active BurnTransactions after 30s`, counter) + } else { + fail(name, `burn ${burnId} not in ExecutedBurnTransactions after 30s`, counter) + } + return false + } +} + +/** + * Poll until at least one new refund reaches ExecutedRefundTransactions since `countBefore`. + * Waits up to 30s — set_refund_transaction_executed may finalize after the Stellar refund. + */ +async function assertRefundExecuted (name, countBefore) { + try { + await waitUntil(async () => { + const after = await api.query.tftBridgeModule.executedRefundTransactions.entries() + return after.length > countBefore + }, { timeoutMs: 30_000, intervalMs: 3000, desc: 'new refund in ExecutedRefundTransactions' }) + return true + } catch { + const after = await api.query.tftBridgeModule.executedRefundTransactions.entries() + fail(name, `no new refund in ExecutedRefundTransactions after 30s (before: ${countBefore}, after: ${after.length})`, counter) + return false + } +} + +// ─── Tests ──────────────────────────────────────────────────────────────────── + +async function test1_normalWithdraw () { + console.log('\n── TEST 1: Normal withdraw (2 TFT swap → 1 TFT net on Stellar) ──') + const name = 'test1_normalWithdraw' + const userAddress = getEnv('USER_ADDRESS') + const swapAmount = 2 + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const beforeTFChain = await tfchainBalance(api, alice.address) + log(`User Stellar TFT before: ${beforeStellar}`) + log(`Alice TFChain TFT before: ${beforeTFChain}`) + + const burnId = await swapToStellar(api, alice, swapAmount, { userAddress }) + log(`Burn ID: ${burnId}`) + + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal > beforeStellar) return bal + }, { timeoutMs: 180_000, desc: `Stellar balance to increase above ${beforeStellar}` }) + + // Assert Stellar balance delta + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + const expected = swapAmount - WITHDRAW_FEE_TFT + if (Math.abs(delta - expected) > 1e-7) { + fail(name, `Expected Stellar +${expected} TFT, got +${delta}`, counter); return + } + log(`User Stellar TFT after: ${afterStellar} (+${delta} TFT)`) + + // Assert TFChain balance decreased by ~swapAmount (± 0.1 TFT for extrinsic fee). + const afterTFChain = await tfchainBalance(api, alice.address) + const tfDelta = Math.round((beforeTFChain - afterTFChain) * TFT_DECIMALS) / TFT_DECIMALS + log(`Alice TFChain TFT after: ${afterTFChain} (-${tfDelta} TFT)`) + if (Math.abs(tfDelta - swapAmount) > 0.1) { + fail(name, `TFChain balance should decrease by ~${swapAmount} (±0.1), decreased by ${tfDelta}`, counter); return + } + + // Assert on-chain: burn executed + if (!(await assertBurnExecuted(name, burnId))) return + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test2_batchWithdraw () { + console.log('\n── TEST 2: Batch withdraw (5 simultaneous swaps in one block) ──') + const name = 'test2_batchWithdraw' + const userAddress = getEnv('USER_ADDRESS') + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before: ${beforeStellar}`) + + const nonce = await api.rpc.system.accountNextIndex(alice.address) + const burnIds = await Promise.all( + [0, 1, 2, 3, 4].map(i => swapToStellar(api, alice, 2, { userAddress, nonce: nonce.toNumber() + i })) + ) + log(`Burn IDs: ${burnIds.join(', ')}`) + + const expectedNet = 5 * (2 - WITHDRAW_FEE_TFT) + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal >= beforeStellar + expectedNet - 1e-7) return bal + }, { timeoutMs: 300_000, desc: `Stellar balance >= ${beforeStellar + expectedNet}` }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after: ${afterStellar} (+${delta} TFT, expected +${expectedNet})`) + if (Math.abs(delta - expectedNet) > 1e-7) { + fail(name, `Expected +${expectedNet} TFT, got +${delta}`, counter); return + } + + // Assert on-chain: all burns executed + for (const burnId of burnIds) { + if (!(await assertBurnExecuted(name, burnId))) return + } + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test3_badDeposit () { + console.log('\n── TEST 3: Bad deposit (no memo → full refund) ──') + const name = 'test3_badDeposit' + const userAddress = getEnv('USER_ADDRESS') + const userSecret = getEnv('USER_SECRET') + + try { + const depositAmount = '3' + + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const refundsBefore = (await api.query.tftBridgeModule.executedRefundTransactions.entries()).length + log(`User Stellar TFT before: ${beforeStellar}`) + + // Send TFT to bridge without a memo + const result = await sendStellarPayment(horizon, issuerAddress, NETWORK_PASSPHRASE, userSecret, bridgeAddress, depositAmount) + log(`Bad deposit sent: ${result.hash.slice(0, 16)}`) + + // Wait for refund — balance should return to (roughly) beforeStellar + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal >= beforeStellar - 1e-7) return bal + }, { timeoutMs: 180_000, desc: 'refund to restore balance' }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after: ${afterStellar} (delta: ${delta >= 0 ? '+' : ''}${delta})`) + // Balance should be within 0 (full refund, no deposit fee on refunds) + if (Math.abs(delta) > 1e-7) { + fail(name, `Expected net 0 change (full refund), got ${delta >= 0 ? '+' : ''}${delta}`, counter); return + } + + // Assert on-chain: refund executed + if (!(await assertRefundExecuted(name, refundsBefore))) return + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test5_deposit () { + console.log('\n── TEST 5: Deposit/mint (send TFT to bridge with twin memo) ──') + const name = 'test5_deposit' + + try { + // Get Alice's twin ID + const twinOpt = await api.query.tfgridModule.twinIdByAccountID(alice.address) + const twinId = twinOpt.isSome ? twinOpt.unwrap().toNumber() : twinOpt.toJSON() + if (!twinId) { fail(name, 'Alice has no twin on TFChain', counter); return } + log(`Alice twin ID: ${twinId}`) + + const depositAmount = '2' + const depositFee = Number(await api.query.tftBridgeModule.depositFee()) / TFT_DECIMALS + const expectedMint = parseFloat(depositAmount) - depositFee + log(`Deposit fee: ${depositFee} TFT, expected mint: ${expectedMint} TFT`) + + const aliceBalBefore = await tfchainBalance(api, alice.address) + const mintsBefore = (await api.query.tftBridgeModule.executedMintTransactions.entries()).length + log(`Alice TFChain TFT before: ${aliceBalBefore}, executed mints: ${mintsBefore}`) + + // Send TFT to bridge with twin_ memo + const userSecret = getEnv('USER_SECRET') + const result = await sendStellarPayment(horizon, issuerAddress, NETWORK_PASSPHRASE, userSecret, bridgeAddress, depositAmount, `twin_${twinId}`) + log(`Deposit sent: ${result.hash.slice(0, 16)} (memo: twin_${twinId})`) + + // Wait for mint to be executed on TFChain + await waitUntil(async () => { + const mints = await api.query.tftBridgeModule.executedMintTransactions.entries() + if (mints.length > mintsBefore) return true + }, { timeoutMs: 120_000, desc: 'executed mint count to increase' }) + + // Assert Alice's TFChain balance increased by ~expectedMint (± 0.1 TFT for block author rewards). + const aliceBalAfter = await tfchainBalance(api, alice.address) + const balDelta = Math.round((aliceBalAfter - aliceBalBefore) * TFT_DECIMALS) / TFT_DECIMALS + log(`Alice TFChain TFT after: ${aliceBalAfter} (+${balDelta} TFT)`) + if (Math.abs(balDelta - expectedMint) > 0.1) { + fail(name, `Expected TFChain ~+${expectedMint} TFT (±0.1), got +${balDelta}`, counter); return + } + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test6_belowMinimum () { + console.log('\n── TEST 6: Withdraw below minimum (should be rejected) ──') + const name = 'test6_belowMinimum' + const userAddress = getEnv('USER_ADDRESS') + + try { + // Attempt swap with 0.5 TFT (below 1 TFT withdraw fee) + await swapToStellar(api, alice, 0.5, { userAddress }) + fail(name, 'swapToStellar should have thrown, but succeeded', counter) + } catch (e) { + if (e.message.includes('AmountIsLessThanWithdrawFee')) { + log(`Correctly rejected: ${e.message}`) + pass(name, counter) + } else { + fail(name, `Expected AmountIsLessThanWithdrawFee, got: ${e.message}`, counter) + } + } +} + +async function test4_crashRecovery () { + console.log('\n── TEST 4: Crash recovery (SIGKILL mid-withdraw, restart, verify delivery) ──') + const name = 'test4_crashRecovery' + const userAddress = getEnv('USER_ADDRESS') + + try { + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before: ${beforeStellar}`) + + // Trigger a withdraw + const burnId = await swapToStellar(api, alice, 2, { userAddress }) + log(`Burn ID: ${burnId}`) + + // Wait for BurnTransactionReady on TFChain (signatures collected), then kill bridge + log('Waiting for BurnTransactionReady...') + await waitUntil(async () => { + const ready = await api.query.tftBridgeModule.burnTransactions(burnId) + const json = ready.toJSON() + return json && json.signatures && json.signatures.length >= 1 + }, { timeoutMs: 60_000, desc: 'BurnTransactionReady (>=1 sig)' }) + + // Kill bridge mid-flight + killBridge('SIGKILL') + log('Bridge killed. Waiting 3s...') + await new Promise(r => setTimeout(r, 3000)) + + // Restart bridge. + // Note: detecting bridge readiness via log file is unreliable on macOS because + // detached process stdout fd inheritance breaks after child.unref(). Instead, we + // give the bridge a fixed startup window and then verify the actual outcome. + startBridge() + log('Bridge restarted. Waiting 10s for startup...') + await new Promise(r => setTimeout(r, 10_000)) + + // Verify the withdrawal completed — either: + // (a) bridge completed before kill and balance is already updated, or + // (b) bridge restarted and completed via reconciliation / expiry recovery + const afterStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + if (bal > beforeStellar) return bal + }, { timeoutMs: 300_000, desc: 'Stellar balance to increase after crash recovery' }) + + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + const expected = 2 - WITHDRAW_FEE_TFT + log(`User Stellar TFT after: ${afterStellar} (+${delta} TFT)`) + + // Explicit double-spend guard: verify exactly +expected, not 2x expected + if (Math.abs(delta - expected) > 1e-7) { + fail(name, `Expected +${expected} TFT after recovery, got +${delta} (double-spend if 2x)`, counter); return + } + + // Assert on-chain: burn executed + if (!(await assertBurnExecuted(name, burnId))) return + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test8_lostCursor () { + console.log('\n── TEST 8: Lost cursor (wipe persistency → no double-spend) ──') + const name = 'test8_lostCursor' + const userAddress = getEnv('USER_ADDRESS') + + try { + // Bridge is running (restarted by T4). Kill it. + killBridge('SIGKILL') + await new Promise(r => setTimeout(r, 2000)) + + // Wipe the persistency file (BoltDB/JSON cursor). + // Without the cursor, bridge re-scans the Stellar account from the beginning. + // Protection against duplicate burns: IsBurnedAlready (ExecutedBurnTransactions) + // Protection against duplicate mints: IsMintedAlready (ExecutedMintTransactions) + if (fs.existsSync(BRIDGE_PERSISTENCY)) { + fs.unlinkSync(BRIDGE_PERSISTENCY) + log(`Persistency wiped: ${BRIDGE_PERSISTENCY}`) + } else { + log('Persistency file not found (nothing to wipe)') + } + + // Snapshot Stellar balance — should NOT change after restart + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before restart: ${beforeStellar}`) + + // Restart bridge — it rescans with no local state + startBridge() + log('Bridge restarted with wiped cursor. Waiting 15s for rescan...') + await new Promise(r => setTimeout(r, 15_000)) + + // Verify no double-spend — balance must be unchanged + const afterStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const delta = Math.round((afterStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`User Stellar TFT after rescan: ${afterStellar} (delta: ${delta >= 0 ? '+' : ''}${delta})`) + if (Math.abs(delta) > 1e-7) { + fail(name, `DOUBLE-SPEND: balance changed by ${delta} TFT after cursor wipe`, counter); return + } + log('No double-spend — IsMintedAlready + IsBurnedAlready held during rescan') + + // ─── Hardened: fresh DEPOSIT to prove bridge is at Stellar tip ─────── + // + // A withdraw (old approach) is event-driven from TFChain — it doesn't use + // the Stellar cursor at all, so it doesn't prove the bridge finished scanning. + // + // A deposit proves the bridge has caught up to the TIP of the Stellar account, + // because the bridge must reach our new transaction in the Horizon stream. + // + // Extra hardening: we verify the on-chain mint's tx_id matches our Stellar + // deposit hash, ruling out the case where an OLD deposit was re-processed + // and our new deposit is still un-seen. + log('Running fresh deposit to verify bridge scanned to Stellar tip...') + + const twinOpt = await api.query.tfgridModule.twinIdByAccountID(alice.address) + const twinId = twinOpt.isSome ? twinOpt.unwrap().toNumber() : twinOpt.toJSON() + if (!twinId) throw new Error('Alice has no twin on TFChain — is bridge-setup complete?') + + const depositAmount = '2' + const depositFee = Number(await api.query.tftBridgeModule.depositFee()) / TFT_DECIMALS + const expectedMint = parseFloat(depositAmount) - depositFee + log(`Deposit fee: ${depositFee} TFT, expected mint: ${expectedMint} TFT`) + + const aliceBalBefore = await tfchainBalance(api, alice.address) + const mintsBefore = (await api.query.tftBridgeModule.executedMintTransactions.entries()).length + log(`Alice TFChain TFT before: ${aliceBalBefore}, executed mints: ${mintsBefore}`) + + // Send deposit — capture the Stellar tx hash for verification + const userSecret = getEnv('USER_SECRET') + const result = await sendStellarPayment(horizon, issuerAddress, NETWORK_PASSPHRASE, userSecret, bridgeAddress, depositAmount, `twin_${twinId}`) + const depositTxHash = result.hash + log(`Fresh deposit sent: ${depositTxHash} (memo: twin_${twinId})`) + + // Wait for the mint to appear on-chain + await waitUntil(async () => { + const mints = await api.query.tftBridgeModule.executedMintTransactions.entries() + if (mints.length > mintsBefore) return mints + }, { timeoutMs: 300_000, desc: 'fresh deposit mint to complete' }) + + // ─── TX HASH VERIFICATION ────────────────────────────────────────── + // Query executedMintTransactions by our specific Stellar tx hash. + // On-chain key = Vec of the Stellar tx hash string (same as Go bridge passes). + // If found: our NEW deposit was processed (bridge is at tip). + // If not found: an OLD deposit was re-processed instead — FAIL. + const mintTx = (await api.query.tftBridgeModule.executedMintTransactions(depositTxHash)).toJSON() + if (!mintTx || !mintTx.amount || mintTx.amount === 0) { + fail(name, `Mint tx hash mismatch: executedMintTransactions["${depositTxHash.slice(0, 16)}..."] not found on-chain — an old deposit may have been re-processed instead`, counter) + return + } + log(`TX hash verified: executedMintTransactions["${depositTxHash.slice(0, 16)}..."] = {amount: ${mintTx.amount}, votes: ${mintTx.votes}}`) + + // Verify Alice's TFChain balance increased by expected amount (± 0.1 for block author rewards) + const aliceBalAfter = await tfchainBalance(api, alice.address) + const balDelta = Math.round((aliceBalAfter - aliceBalBefore) * TFT_DECIMALS) / TFT_DECIMALS + log(`Alice TFChain TFT after: ${aliceBalAfter} (+${balDelta} TFT)`) + if (Math.abs(balDelta - expectedMint) > 0.1) { + fail(name, `Fresh deposit: expected TFChain ~+${expectedMint} TFT (±0.1), got +${balDelta}`, counter); return + } + + // Verify exactly 1 new mint was processed (no old deposits re-minted) + const mintsAfter = (await api.query.tftBridgeModule.executedMintTransactions.entries()).length + const mintCountDelta = mintsAfter - mintsBefore + log(`Executed mints: ${mintsBefore} → ${mintsAfter} (+${mintCountDelta})`) + if (mintCountDelta !== 1) { + fail(name, `Expected exactly 1 new mint, got ${mintCountDelta} — old deposits may have been re-processed`, counter); return + } + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test9_expiredBatchRecovery () { + console.log('\n── TEST 9: Expired batch recovery (50 swaps offline → expiry → restart) ──') + const name = 'test9_expiredBatchRecovery' + const userAddress = getEnv('USER_ADDRESS') + const N = 50 + + try { + // Kill bridge before submitting swaps + killBridge('SIGKILL') + await new Promise(r => setTimeout(r, 2000)) + log('Bridge killed') + + const beforeStellar = await stellarTFTBalance(userAddress, horizon, issuerAddress) + log(`User Stellar TFT before: ${beforeStellar}`) + + // Submit N swaps in one block using sequential nonces + log(`Submitting ${N} swaps (bridge offline)...`) + const nonce = await api.rpc.system.accountNextIndex(alice.address) + const burnIds = await Promise.all( + Array.from({ length: N }, (_, i) => + swapToStellar(api, alice, 2, { userAddress, nonce: nonce.toNumber() + i }) + ) + ) + log(`${N} burns created on-chain: IDs ${burnIds[0]}..${burnIds[burnIds.length - 1]}`) + + // Wait for all burns to expire (on_finalize clears signatures after RetryInterval=20 blocks ≈ 120s) + log('Waiting for burns to expire on-chain (RetryInterval=20 blocks)...') + await waitUntil(async () => { + const burn = (await api.query.tftBridgeModule.burnTransactions(burnIds[0])).toJSON() + return burn && burn.signatures && burn.signatures.length === 0 + }, { timeoutMs: 180_000, intervalMs: 6000, desc: 'first burn to expire (signatures cleared)' }) + log('All burns expired (signatures cleared, sequence_number reset to 0)') + + // Start bridge — it subscribes to new blocks and catches the next BurnTransactionExpired events. + // handleProposalsBatch re-proposes all expired burns in a single force_batch tx with + // consecutive Stellar sequence numbers (SyncSequenceNumber + per-proposal increment). + // All burns become Ready in the same block, and handleWithdrawReady processes them + // sequentially — each Stellar submission uses its stored sequence number, so all + // succeed in one pass without sequence collisions. + // + // After all Stellar payments complete, each handleWithdrawReady calls + // SetWithdrawExecuted individually (could be batched in a future optimization). + startBridge() + log('Bridge restarted. Recovering expired burns via batch re-proposal...') + log(`Expected: 1 force_batch re-proposes all ${N}, then all ${N} Stellar payments execute in sequence`) + + const expectedNet = N * (2 - WITHDRAW_FEE_TFT) + let lastReported = 0 + + const finalStellar = await waitUntil(async () => { + const bal = await stellarTFTBalance(userAddress, horizon, issuerAddress) + const delivered = Math.round((bal - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + const count = Math.round(delivered / (2 - WITHDRAW_FEE_TFT)) + if (count > lastReported) { + log(` Progress: ${count}/${N} burns delivered (+${delivered} TFT)`) + lastReported = count + } + if (bal >= beforeStellar + expectedNet - 1e-7) return bal + }, { timeoutMs: 900_000, intervalMs: 10_000, desc: `all ${N} burns delivered (+${expectedNet} TFT)` }) + + const delta = Math.round((finalStellar - beforeStellar) * TFT_DECIMALS) / TFT_DECIMALS + log(`All ${N} burns delivered: +${delta} TFT (expected +${expectedNet})`) + if (Math.abs(delta - expectedNet) > 1e-7) { + fail(name, `Expected +${expectedNet}, got +${delta}`, counter); return + } + + // Assert on-chain: all burns executed + for (const burnId of burnIds) { + if (!(await assertBurnExecuted(name, burnId))) return + } + + pass(name, counter) + } catch (e) { + fail(name, e.message, counter) + } +} + +async function test7_cleanState () { + console.log('\n── TEST 7: Clean state (no orphaned active transactions) ──') + const name = 'test7_cleanState' + + try { + // Wait for all active transaction maps to drain (tolerates in-flight processing) + await waitUntil(async () => { + const burns = await api.query.tftBridgeModule.burnTransactions.entries() + const refunds = await api.query.tftBridgeModule.refundTransactions.entries() + const mints = await api.query.tftBridgeModule.mintTransactions.entries() + return burns.length === 0 && refunds.length === 0 && mints.length === 0 + }, { timeoutMs: 300_000, intervalMs: 5000, desc: 'all active tx maps to drain' }) + pass(name, counter) + } catch (e) { + // On timeout, report what's left + const burns = await api.query.tftBridgeModule.burnTransactions.entries() + const refunds = await api.query.tftBridgeModule.refundTransactions.entries() + const mints = await api.query.tftBridgeModule.mintTransactions.entries() + fail(name, `Orphaned: ${burns.length} burns, ${refunds.length} refunds, ${mints.length} mints`, counter) + } +} + +// ─── Main ──────────────────────────────────────────────────────────────────── + +async function main () { + loadEnv(ENV_FILE, 'tests') + + bridgeAddress = getEnv('BRIDGE_ADDRESS') + issuerAddress = getEnv('ISSUER_ADDRESS') + + console.log('[tests] Connecting to TFChain and Stellar...') + api = await ApiPromise.create({ provider: new WsProvider(TFCHAIN_URL) }) + horizon = new StellarSdk.Horizon.Server(HORIZON_URL) + + try { + const keyring = new Keyring({ type: 'sr25519' }) + alice = keyring.addFromUri('//Alice') + + console.log('[tests] Starting test suite...\n') + + await test1_normalWithdraw() + await test2_batchWithdraw() + await test3_badDeposit() + await test5_deposit() + await test6_belowMinimum() + await test4_crashRecovery() // kills/restarts bridge + await test8_lostCursor() // kills/restarts bridge with wiped cursor + await test9_expiredBatchRecovery() // kills bridge, 50 swaps, expiry, restart (long) + await test7_cleanState() + + console.log(`\n${'─'.repeat(50)}`) + console.log(`Results: ${counter.passed} passed, ${counter.failed} failed`) + console.log('─'.repeat(50)) + } finally { + await api.disconnect() + } + + process.exit(counter.failed > 0 ? 1 : 0) +} + +main().catch(e => { + console.error(`[tests] FATAL: ${e.message || e}`) + process.exit(1) +}) diff --git a/scripts/package-lock.json b/scripts/package-lock.json new file mode 100644 index 000000000..642bedc17 --- /dev/null +++ b/scripts/package-lock.json @@ -0,0 +1,4690 @@ +{ + "name": "tfchain-js-scripts", + "version": "2.12.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tfchain-js-scripts", + "version": "2.12.0", + "license": "ISC", + "dependencies": { + "@polkadot/api": "^10.7.2", + "@stellar/stellar-sdk": "^12.3.0", + "axios": "^0.25.0", + "bip39": "^3.0.3", + "blake": "^1.0.1", + "bn.js": "^5.1.3", + "ip-regex": "^4.3.0", + "moment": "^2.29.1" + }, + "devDependencies": { + "standard": "^16.0.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", + "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.20", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/api": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-10.8.1.tgz", + "integrity": "sha512-Txx1bXmB4FHghzPZ+OVQk6oYgPE03bhwMNiXzmC8Ia/tw5aoFnko2FFl+Y1pEhhMKDmqfyVe4L+HxPjfEQbsfA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api-augment": "10.8.1", + "@polkadot/api-base": "10.8.1", + "@polkadot/api-derive": "10.8.1", + "@polkadot/keyring": "^12.2.2", + "@polkadot/rpc-augment": "10.8.1", + "@polkadot/rpc-core": "10.8.1", + "@polkadot/rpc-provider": "10.8.1", + "@polkadot/types": "10.8.1", + "@polkadot/types-augment": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/types-create": "10.8.1", + "@polkadot/types-known": "10.8.1", + "@polkadot/util": "^12.2.2", + "@polkadot/util-crypto": "^12.2.2", + "eventemitter3": "^5.0.1", + "rxjs": "^7.8.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/api-augment": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.8.1.tgz", + "integrity": "sha512-KFfF0OESmFI8hFmuKGuU204+S4SORIxniZr88xUnEPyJQr4R6XYnbGSKcLJM5Y2MK8a7JEoKgg+hfnUTK6Se0w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api-base": "10.8.1", + "@polkadot/rpc-augment": "10.8.1", + "@polkadot/types": "10.8.1", + "@polkadot/types-augment": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/util": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/api-base": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.8.1.tgz", + "integrity": "sha512-13BZ04UtiCECQshstL9RBLDJ6nq9HSwWXwMuWZcXUEPSsPhfR3iT0o212dtGrGliakYWgGEU1LGJuGhZ5iK7TA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-core": "10.8.1", + "@polkadot/types": "10.8.1", + "@polkadot/util": "^12.2.2", + "rxjs": "^7.8.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/api-derive": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.8.1.tgz", + "integrity": "sha512-r1SBY9vu6OZMGp8/KZFwOqh7yS8yl0YbNDWuju2BEMWQ4Xx6WOlQjQV8Np9UFtKcnBFQzQjMLWH3vwrfTDgVEQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api": "10.8.1", + "@polkadot/api-augment": "10.8.1", + "@polkadot/api-base": "10.8.1", + "@polkadot/rpc-core": "10.8.1", + "@polkadot/types": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/util": "^12.2.2", + "@polkadot/util-crypto": "^12.2.2", + "rxjs": "^7.8.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/keyring": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.2.2.tgz", + "integrity": "sha512-z8MVdgrhzg/bFiR2i5/W06Ma+IPeisH7EtGuIQ+ZwXiCJlXMAGUy5spfk3fUbXYubCCqNycqFgKTYDM/rDhXSg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "12.2.2", + "@polkadot/util-crypto": "12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "12.2.2", + "@polkadot/util-crypto": "12.2.2" + } + }, + "node_modules/@polkadot/networks": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.2.2.tgz", + "integrity": "sha512-SsZognHwXyD2saJkB35G+28noAZBcNpJAXsTI7QTTDHGiQSDp0mPmrk3Rt7BRAeFn4qdXQuRqQYKYUwBM2i9mQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "12.2.2", + "@substrate/ss58-registry": "^1.40.0", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/rpc-augment": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.8.1.tgz", + "integrity": "sha512-FmXAQLyG8cwBI+MwMxxx4qttolR2gFnYXC7PjYrrjYq4AZrrGWd9SvwXx8aA/NLRJ/PJqvri4dsoKPe7NiE+1A==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-core": "10.8.1", + "@polkadot/types": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/util": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/rpc-core": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.8.1.tgz", + "integrity": "sha512-GTMYBBssiP6wyYvc8hB0glQc4VUneGxiSYjWGijh9NEl/JVBpU01jcK3dfx534AWptctJN1Vk2fWzhaDgnj8zA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-augment": "10.8.1", + "@polkadot/rpc-provider": "10.8.1", + "@polkadot/types": "10.8.1", + "@polkadot/util": "^12.2.2", + "rxjs": "^7.8.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/rpc-provider": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.8.1.tgz", + "integrity": "sha512-yQdUmaWRMSa/qVGBRP1vGjdv4DnlaYOctJfRpz2MWPbEckH5DmPRxV4BAZ9FVa5lATX0Qkmr3uvBt3qApH7xhQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^12.2.2", + "@polkadot/types": "10.8.1", + "@polkadot/types-support": "10.8.1", + "@polkadot/util": "^12.2.2", + "@polkadot/util-crypto": "^12.2.2", + "@polkadot/x-fetch": "^12.2.2", + "@polkadot/x-global": "^12.2.2", + "@polkadot/x-ws": "^12.2.2", + "eventemitter3": "^5.0.1", + "mock-socket": "^9.2.1", + "nock": "^13.3.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@substrate/connect": "0.7.26" + } + }, + "node_modules/@polkadot/types": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-10.8.1.tgz", + "integrity": "sha512-m6UvsvQOZ7sRGbonb6QLs4mZ6TmYKdAXAcHakiJl2xArqsgOghJsKhgaTqcigPkSq4947MXtIkEzdrwFEnkYkQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^12.2.2", + "@polkadot/types-augment": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/types-create": "10.8.1", + "@polkadot/util": "^12.2.2", + "@polkadot/util-crypto": "^12.2.2", + "rxjs": "^7.8.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/types-augment": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.8.1.tgz", + "integrity": "sha512-rVn8aA4u6YPcxGEnBq2rXVmgXM5kSuiTHIjsusb6Sm3PzO//NcC/TW9sbZjlAJApgSoj9iagM7Y85OPGOZlxwg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/util": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/types-codec": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.8.1.tgz", + "integrity": "sha512-8dj4T6GA6JxuwUNShO70omZ4qkChwsJeGAJg5x09UeLEAwBS02BkFSllRUJjGEwnAUb/Iq4s3NBVmYiiZ/wmKg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^12.2.2", + "@polkadot/x-bigint": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/types-create": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.8.1.tgz", + "integrity": "sha512-v2WZHQAjf8TiLipRkR1iPTyWSjGHJJP2SQ5uVO5UJlHilpE8lODqY1rr/9hGN+sbRhU0vEy6ZceDEKuNbtJB3Q==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "10.8.1", + "@polkadot/util": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/types-known": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.8.1.tgz", + "integrity": "sha512-AIeuF7eTIEnUgxa1pU0UMmF/tIXgucAECwU8vzoKeJLrYWA16VYUm0Pst9e3jK3PyLaCneMRyR00Lc7oxVANbw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/networks": "^12.2.2", + "@polkadot/types": "10.8.1", + "@polkadot/types-codec": "10.8.1", + "@polkadot/types-create": "10.8.1", + "@polkadot/util": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/types-support": { + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.8.1.tgz", + "integrity": "sha512-arDVaL70vzVL5JBGWW1qcOASn1cJ/UxNMR3fHchoVkAqS20VIrehE8MF4zXMdjcP0Ak3+6E0FaSmHMTKlmEJsg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/util": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.2.2.tgz", + "integrity": "sha512-u/v5Z2+iUwX/CXEMVZgJmwqqx1kT5Zfxsio3vpuYaPCg49xhTKqAcrakgB+1BUHhhyF3Zkb9uG73JWFR0Lkk9w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "12.2.2", + "@polkadot/x-global": "12.2.2", + "@polkadot/x-textdecoder": "12.2.2", + "@polkadot/x-textencoder": "12.2.2", + "@types/bn.js": "^5.1.1", + "bn.js": "^5.2.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/util-crypto": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.2.2.tgz", + "integrity": "sha512-4JfEd/TJaDArp5Jpr3N/aYHp+QR71XzZRKqU4u7WkGKmnGt28Qfh2IWGB/E2MvIFxa6CjIiQMxN2hnkNr49JAQ==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@polkadot/networks": "12.2.2", + "@polkadot/util": "12.2.2", + "@polkadot/wasm-crypto": "^7.2.1", + "@polkadot/wasm-util": "^7.2.1", + "@polkadot/x-bigint": "12.2.2", + "@polkadot/x-randomvalues": "12.2.2", + "@scure/base": "1.1.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "12.2.2" + } + }, + "node_modules/@polkadot/wasm-bridge": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.2.1.tgz", + "integrity": "sha512-uV/LHREDBGBbHrrv7HTki+Klw0PYZzFomagFWII4lp6Toj/VCvRh5WMzooVC+g/XsBGosAwrvBhoModabyHx+A==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-util": "7.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.2.1.tgz", + "integrity": "sha512-SA2+33S9TAwGhniKgztVN6pxUKpGfN4Tre/eUZGUfpgRkT92wIUT2GpGWQE+fCCqGQgADrNiBcwt6XwdPqMQ4Q==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-bridge": "7.2.1", + "@polkadot/wasm-crypto-asmjs": "7.2.1", + "@polkadot/wasm-crypto-init": "7.2.1", + "@polkadot/wasm-crypto-wasm": "7.2.1", + "@polkadot/wasm-util": "7.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-asmjs": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.1.tgz", + "integrity": "sha512-z/d21bmxyVfkzGsKef/FWswKX02x5lK97f4NPBZ9XBeiFkmzlXhdSnu58/+b1sKsRAGdW/Rn/rTNRDhW0GqCAg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-init": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.1.tgz", + "integrity": "sha512-GcEXtwN9LcSf32V9zSaYjHImFw16hCyo2Xzg4GLLDPPeaAAfbFr2oQMgwyDbvBrBjLKHVHjsPZyGhXae831amw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-bridge": "7.2.1", + "@polkadot/wasm-crypto-asmjs": "7.2.1", + "@polkadot/wasm-crypto-wasm": "7.2.1", + "@polkadot/wasm-util": "7.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-wasm": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.1.tgz", + "integrity": "sha512-DqyXE4rSD0CVlLIw88B58+HHNyrvm+JAnYyuEDYZwCvzUWOCNos/DDg9wi/K39VAIsCCKDmwKqkkfIofuOj/lA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-util": "7.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/wasm-util": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.2.1.tgz", + "integrity": "sha512-FBSn/3aYJzhN0sYAYhHB8y9JL8mVgxLy4M1kUXYbyo+8GLRQEN5rns8Vcb8TAlIzBWgVTOOptYBvxo0oj0h7Og==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/x-bigint": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.2.2.tgz", + "integrity": "sha512-KSe7WAqwI1tubi0m5CP4oqf8EIjABZXLGkTHXKwjtAAMa9Q7hqFmVG2sXfvC+XSnhto1UKMe52TjuPrYSJI+jg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/x-fetch": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.2.2.tgz", + "integrity": "sha512-A3ttQp9oE6QH9VsggdQsBsgc9zyalxHoVXhZsn6yqcjzc9AoaY5QevezxVy88ZQpRp3bsYVn0RqyBV7eFq8WPw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "12.2.2", + "node-fetch": "^3.3.1", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/x-global": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.2.2.tgz", + "integrity": "sha512-hLVoKR9fGhZdy/eK/LHTyh4jJ3V+3VfcxbCey0k2t1Byrwbmsi6wL3NUQk6i3NviswR9OSCic9mhgDQPRBXZEg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/x-randomvalues": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.2.2.tgz", + "integrity": "sha512-eExiOT/up5ZzwHJkFpGhQ6sCdPSJnn6PJsQnyJMEdgPaUES70u/wWMLGFNiy3U8rRRVSsZi6rc9Unsr02LczzA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@polkadot/util": "12.2.2", + "@polkadot/wasm-util": "*" + } + }, + "node_modules/@polkadot/x-textdecoder": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.2.2.tgz", + "integrity": "sha512-Rsvsc7ZLBKT1rls8gdbvzLLEs2sGUA8cDiTaQUkCHJN3ja/37Bppz1wNPcEIMsJ2pyL6bwq86HB0xmC28QVdqA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/x-textencoder": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.2.2.tgz", + "integrity": "sha512-g6bX4DTBmkr3QLNeihlrHYvaZCKu1kFiK+BDQXVzBg+oHpzxz5wSVhzsG3GEVoVszXMiugWpSn03wCIvaRFMoQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "12.2.2", + "tslib": "^2.5.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@polkadot/x-ws": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.2.2.tgz", + "integrity": "sha512-kZtdfRHsgpJ+HV/jY8mQG4BFpCIz6NxZlrRKzWdaIacPVeXHkV3nfk7i9ghK+MP/nWC0AKuq06yysp9ZwWMCug==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "12.2.2", + "tslib": "^2.5.3", + "ws": "^8.13.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@stellar/js-xdr": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.1.2.tgz", + "integrity": "sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==", + "license": "Apache-2.0" + }, + "node_modules/@stellar/stellar-base": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-12.1.1.tgz", + "integrity": "sha512-gOBSOFDepihslcInlqnxKZdIW9dMUO1tpOm3AtJR33K2OvpXG6SaVHCzAmCFArcCqI9zXTEiSoh70T48TmiHJA==", + "license": "Apache-2.0", + "dependencies": { + "@stellar/js-xdr": "^3.1.2", + "base32.js": "^0.1.0", + "bignumber.js": "^9.1.2", + "buffer": "^6.0.3", + "sha.js": "^2.3.6", + "tweetnacl": "^1.0.3" + }, + "optionalDependencies": { + "sodium-native": "^4.1.1" + } + }, + "node_modules/@stellar/stellar-sdk": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-12.3.0.tgz", + "integrity": "sha512-F2DYFop/M5ffXF0lvV5Ezjk+VWNKg0QDX8gNhwehVU3y5LYA3WAY6VcCarMGPaG9Wdgoeh1IXXzOautpqpsltw==", + "license": "Apache-2.0", + "dependencies": { + "@stellar/stellar-base": "^12.1.1", + "axios": "^1.7.7", + "bignumber.js": "^9.1.2", + "eventsource": "^2.0.2", + "randombytes": "^2.1.0", + "toml": "^3.0.0", + "urijs": "^1.19.1" + } + }, + "node_modules/@stellar/stellar-sdk/node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@substrate/connect": { + "version": "0.7.26", + "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.7.26.tgz", + "integrity": "sha512-uuGSiroGuKWj1+38n1kY5HReer5iL9bRwPCzuoLtqAOmI1fGI0hsSI2LlNQMAbfRgr7VRHXOk5MTuQf5ulsFRw==", + "deprecated": "versions below 1.x are no longer maintained", + "license": "GPL-3.0-only", + "optional": true, + "dependencies": { + "@substrate/connect-extension-protocol": "^1.0.1", + "eventemitter3": "^4.0.7", + "smoldot": "1.0.4" + } + }, + "node_modules/@substrate/connect-extension-protocol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.1.tgz", + "integrity": "sha512-161JhCC1csjH3GE5mPLEd7HbWtwNSPJBg3p1Ksz9SFlTzj/bgEwudiRN2y5i0MoLGCIJRYKyKGMxVnd29PzNjg==", + "license": "GPL-3.0-only", + "optional": true + }, + "node_modules/@substrate/connect/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT", + "optional": true + }, + "node_modules/@substrate/ss58-registry": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.40.0.tgz", + "integrity": "sha512-QuU2nBql3J4KCnOWtWDw4n1K4JU0T79j54ZZvm/9nhsX6AIar13FyhsaBfs6QkJ2ixTQAnd7TocJIoJRWbqMZA==", + "license": "Apache-2.0" + }, + "node_modules/@types/bn.js": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.7" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-addon-resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.10.0.tgz", + "integrity": "sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-module-resolve": "^1.10.0", + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-module-resolve": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.1.tgz", + "integrity": "sha512-hbmAPyFpEq8FoZMd5sFO3u6MC5feluWoGE8YKlA8fCrl6mNtx68Wjg4DTiDJcqRJaovTvOYKfYngoBUnbaT7eg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-semver": "^1.0.0" + }, + "peerDependencies": { + "bare-url": "*" + }, + "peerDependenciesMeta": { + "bare-url": { + "optional": true + } + } + }, + "node_modules/bare-semver": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.2.tgz", + "integrity": "sha512-ESVaN2nzWhcI5tf3Zzcq9aqCZ676VWzqw07eEZ0qxAcEOAFYBa0pWq8sK34OQeHLY3JsfKXZS9mDyzyxGjeLzA==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/base32.js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", + "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bip39": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", + "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "license": "ISC", + "dependencies": { + "@noble/hashes": "^1.2.0" + } + }, + "node_modules/blake": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blake/-/blake-1.0.1.tgz", + "integrity": "sha512-vX8JQdac+BNxW4clj/rJk0ooLBXTdt462V2QSz5GMNJ8RhYK48n7cW/UyUvuXGMiqctsd7i1xIio4vI8O/j+Fw==", + "license": "MIT", + "dependencies": { + "cop": "^0.3.6", + "event-stream": "^3.3.1", + "fstream": "^1.0.7", + "lru-cache": "^2.6.5", + "mkdirp": "^0.5.1", + "popfun": "^1.0.0", + "prettydate": "0.0.1" + }, + "bin": { + "blake": "bin/cli.js" + }, + "engines": { + "node": ">0.10" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/cop": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cop/-/cop-0.3.6.tgz", + "integrity": "sha512-JB+js3riedeJxEmea7HZbV0xI4+j0/WHVYststvqtOgcEWg+bHNuYY9o1DJCeQEUY6XusaQe9CWHZP3z/zhJOA==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.21.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", + "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.0", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", + "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.3.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.20", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peerDependencies": { + "eslint": "^7.12.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1 || ^5.0.0" + } + }, + "node_modules/eslint-config-standard-jsx": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-10.0.0.tgz", + "integrity": "sha512-hLeA2f5e06W1xyr/93/QJulN/rLbUVUmqTlexv9PRKHFwEC9ffJcH2LvJhMoEqYQBEYafedgGZXH2W8NUpt5lA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peerDependencies": { + "eslint": "^7.12.1", + "eslint-plugin-react": "^7.21.5" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.6.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", + "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.3.tgz", + "integrity": "sha512-ZMbFvZ1WAYSZKY662MBVEWR45VaBT6KSJCiupjrNlcdakB90juaZeDCbJq19e73JZQubqFtgETohwgAt8u5P6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", + "doctrine": "^2.1.0", + "estraverse": "^5.2.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.hasown": "^1.0.0", + "object.values": "^1.1.4", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-stream": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", + "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==", + "license": "ISC" + }, + "node_modules/map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mock-socket": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.2.1.tgz", + "integrity": "sha512-aw9F9T9G2zpGipLLhSNh6ZpgUyUl4frcVmRN08uE1NWPWg43Wx6+sGPDbQ7E5iFZZDJW5b5bypMeAEHqTbIFag==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nock": { + "version": "13.3.1", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.1.tgz", + "integrity": "sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.21", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", + "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)", + "optional": true + }, + "node_modules/parent-module": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/popfun": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/popfun/-/popfun-1.0.0.tgz", + "integrity": "sha512-8TOxvFAIyxvxNn8ca7RXtPJi7bPrBH77H8+yRWKgvV/5SJUAu5XXCDGtTf7UrezQq+WkZJgI9fXv/irfoPSQgg==", + "license": "MIT", + "engines": { + "node": ">0.10" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettydate": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/prettydate/-/prettydate-0.0.1.tgz", + "integrity": "sha512-kkTd6fDCxmiTyod7+rW9LXnvkw3G6CrSYcVokhlJ9mr+Zb4DcbcgIlVIhj9I3Mg9AhZDIlkk1MdAJTBP6jwUhw==", + "engines": { + "node": "*" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-addon": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.2.0.tgz", + "integrity": "sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-addon-resolve": "^1.3.0" + }, + "engines": { + "bare": ">=1.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/smoldot": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-1.0.4.tgz", + "integrity": "sha512-N3TazI1C4GGrseFH/piWyZCCCRJTRx2QhDfrUKRT4SzILlW5m8ayZ3QTKICcz1C/536T9cbHHJyP7afxI6Mi1A==", + "license": "GPL-3.0-or-later WITH Classpath-exception-2.0", + "optional": true, + "dependencies": { + "pako": "^2.0.4", + "ws": "^8.8.1" + } + }, + "node_modules/sodium-native": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.3.tgz", + "integrity": "sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==", + "license": "MIT", + "optional": true, + "dependencies": { + "require-addon": "^1.1.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/standard": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/standard/-/standard-16.0.4.tgz", + "integrity": "sha512-2AGI874RNClW4xUdM+bg1LRXVlYLzTNEkHmTG5mhyn45OhbgwA+6znowkOGYy+WMb5HRyELvtNy39kcdMQMcYQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "eslint": "~7.18.0", + "eslint-config-standard": "16.0.3", + "eslint-config-standard-jsx": "10.0.0", + "eslint-plugin-import": "~2.24.2", + "eslint-plugin-node": "~11.1.0", + "eslint-plugin-promise": "~5.1.0", + "eslint-plugin-react": "~7.25.1", + "standard-engine": "^14.0.1" + }, + "bin": { + "standard": "bin/cmd.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/standard-engine": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-14.0.1.tgz", + "integrity": "sha512-7FEzDwmHDOGva7r9ifOzD3BGdTbA7ujJ50afLVdW/tK14zQEptJjbFuUfn50irqdHDcTbNh0DTIoMPynMCXb0Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "get-stdin": "^8.0.0", + "minimist": "^1.2.5", + "pkg-conf": "^3.1.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8.10" + } + }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "license": "0BSD" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", + "license": "MIT" + }, + "node_modules/v8-compile-cache": { + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/scripts/package.json b/scripts/package.json index 92b88f48d..0d79b89f9 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@polkadot/api": "^10.7.2", + "@stellar/stellar-sdk": "^12.3.0", "axios": "^0.25.0", "bip39": "^3.0.3", "blake": "^1.0.1", diff --git a/scripts/wait_for_node.js b/scripts/wait_for_node.js new file mode 100644 index 000000000..1bce165ed --- /dev/null +++ b/scripts/wait_for_node.js @@ -0,0 +1,55 @@ +#!/usr/bin/env node +/** + * wait_for_node.js + * + * Polls a WebSocket endpoint until it accepts connections, then exits 0. + * Used by Make targets to block until TFChain is ready before running setup. + * + * Usage: + * node scripts/wait_for_node.js + * TFCHAIN_URL=ws://localhost:9944 WAIT_TIMEOUT_MS=30000 node scripts/wait_for_node.js + */ + +'use strict' + +const { ApiPromise, WsProvider } = require('@polkadot/api') + +const url = process.env.TFCHAIN_URL || 'ws://localhost:9944' +const timeoutMs = parseInt(process.env.WAIT_TIMEOUT_MS || '60000') +const intervalMs = 1500 + +async function tryConnect () { + return new Promise((resolve) => { + const provider = new WsProvider(url, false) + const timer = setTimeout(() => { provider.disconnect(); resolve(false) }, 4000) + provider.on('connected', async () => { + clearTimeout(timer) + try { + const api = await ApiPromise.create({ provider, noInitWarn: true }) + await api.disconnect() + resolve(true) + } catch { + resolve(false) + } + }) + provider.on('error', () => { clearTimeout(timer); resolve(false) }) + provider.connect() + }) +} + +async function main () { + const deadline = Date.now() + timeoutMs + process.stdout.write(`[wait] Waiting for TFChain at ${url}`) + while (Date.now() < deadline) { + if (await tryConnect()) { + console.log(' ready.') + process.exit(0) + } + process.stdout.write('.') + await new Promise(r => setTimeout(r, intervalMs)) + } + console.log('\n[wait] Timed out waiting for TFChain.') + process.exit(1) +} + +main() diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 8b74be261..255fbaabd 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -4,19 +4,19 @@ "@babel/code-frame@^7.0.0": version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz" integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== dependencies: "@babel/highlight" "^7.22.5" "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== "@babel/highlight@^7.22.5": version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz" integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== dependencies: "@babel/helper-validator-identifier" "^7.22.5" @@ -25,7 +25,7 @@ "@eslint/eslintrc@^0.3.0": version "0.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz" integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== dependencies: ajv "^6.12.4" @@ -41,19 +41,19 @@ "@noble/curves@1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz" integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== dependencies: "@noble/hashes" "1.3.1" -"@noble/hashes@1.3.1", "@noble/hashes@^1.2.0": +"@noble/hashes@^1.2.0", "@noble/hashes@1.3.1": version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== "@polkadot/api-augment@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-10.8.1.tgz#585b93ef9d09c114b57a8794574a429386c94660" + resolved "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.8.1.tgz" integrity sha512-KFfF0OESmFI8hFmuKGuU204+S4SORIxniZr88xUnEPyJQr4R6XYnbGSKcLJM5Y2MK8a7JEoKgg+hfnUTK6Se0w== dependencies: "@polkadot/api-base" "10.8.1" @@ -66,7 +66,7 @@ "@polkadot/api-base@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-10.8.1.tgz#c6df0ff420c1af48ec58c823681d6c342d7b56f5" + resolved "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.8.1.tgz" integrity sha512-13BZ04UtiCECQshstL9RBLDJ6nq9HSwWXwMuWZcXUEPSsPhfR3iT0o212dtGrGliakYWgGEU1LGJuGhZ5iK7TA== dependencies: "@polkadot/rpc-core" "10.8.1" @@ -77,7 +77,7 @@ "@polkadot/api-derive@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-10.8.1.tgz#eab3fa9ef975bccad5ab0d5275699f42b51725c7" + resolved "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.8.1.tgz" integrity sha512-r1SBY9vu6OZMGp8/KZFwOqh7yS8yl0YbNDWuju2BEMWQ4Xx6WOlQjQV8Np9UFtKcnBFQzQjMLWH3vwrfTDgVEQ== dependencies: "@polkadot/api" "10.8.1" @@ -91,9 +91,9 @@ rxjs "^7.8.1" tslib "^2.5.3" -"@polkadot/api@10.8.1", "@polkadot/api@^10.7.2": +"@polkadot/api@^10.7.2", "@polkadot/api@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-10.8.1.tgz#ecf4e8a7167d67ba1392ba0b93133c701e088280" + resolved "https://registry.npmjs.org/@polkadot/api/-/api-10.8.1.tgz" integrity sha512-Txx1bXmB4FHghzPZ+OVQk6oYgPE03bhwMNiXzmC8Ia/tw5aoFnko2FFl+Y1pEhhMKDmqfyVe4L+HxPjfEQbsfA== dependencies: "@polkadot/api-augment" "10.8.1" @@ -116,16 +116,16 @@ "@polkadot/keyring@^12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-12.2.2.tgz#4efb5333c78222a91949b699d4a65b338c79eede" + resolved "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.2.2.tgz" integrity sha512-z8MVdgrhzg/bFiR2i5/W06Ma+IPeisH7EtGuIQ+ZwXiCJlXMAGUy5spfk3fUbXYubCCqNycqFgKTYDM/rDhXSg== dependencies: "@polkadot/util" "12.2.2" "@polkadot/util-crypto" "12.2.2" tslib "^2.5.3" -"@polkadot/networks@12.2.2", "@polkadot/networks@^12.2.2": +"@polkadot/networks@^12.2.2", "@polkadot/networks@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-12.2.2.tgz#14b34210ea2dfc3b27897b579eb93c5f0a8f2a1c" + resolved "https://registry.npmjs.org/@polkadot/networks/-/networks-12.2.2.tgz" integrity sha512-SsZognHwXyD2saJkB35G+28noAZBcNpJAXsTI7QTTDHGiQSDp0mPmrk3Rt7BRAeFn4qdXQuRqQYKYUwBM2i9mQ== dependencies: "@polkadot/util" "12.2.2" @@ -134,7 +134,7 @@ "@polkadot/rpc-augment@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-10.8.1.tgz#19bbfdf78ca5b6d493aee7b954bb4a526be6ebe7" + resolved "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.8.1.tgz" integrity sha512-FmXAQLyG8cwBI+MwMxxx4qttolR2gFnYXC7PjYrrjYq4AZrrGWd9SvwXx8aA/NLRJ/PJqvri4dsoKPe7NiE+1A== dependencies: "@polkadot/rpc-core" "10.8.1" @@ -145,7 +145,7 @@ "@polkadot/rpc-core@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-10.8.1.tgz#1bc8f7f840164bf3f03fe71851071c7f19f4f166" + resolved "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.8.1.tgz" integrity sha512-GTMYBBssiP6wyYvc8hB0glQc4VUneGxiSYjWGijh9NEl/JVBpU01jcK3dfx534AWptctJN1Vk2fWzhaDgnj8zA== dependencies: "@polkadot/rpc-augment" "10.8.1" @@ -157,7 +157,7 @@ "@polkadot/rpc-provider@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-10.8.1.tgz#7455b284934151bcc20e89d9605cb09186cea74a" + resolved "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.8.1.tgz" integrity sha512-yQdUmaWRMSa/qVGBRP1vGjdv4DnlaYOctJfRpz2MWPbEckH5DmPRxV4BAZ9FVa5lATX0Qkmr3uvBt3qApH7xhQ== dependencies: "@polkadot/keyring" "^12.2.2" @@ -177,7 +177,7 @@ "@polkadot/types-augment@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-10.8.1.tgz#e774f3ba399f9f8961a5f557fb5a9c7c5901625a" + resolved "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.8.1.tgz" integrity sha512-rVn8aA4u6YPcxGEnBq2rXVmgXM5kSuiTHIjsusb6Sm3PzO//NcC/TW9sbZjlAJApgSoj9iagM7Y85OPGOZlxwg== dependencies: "@polkadot/types" "10.8.1" @@ -187,7 +187,7 @@ "@polkadot/types-codec@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-10.8.1.tgz#65f886fd2b717e2e12b319a395f9887edd1f9094" + resolved "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.8.1.tgz" integrity sha512-8dj4T6GA6JxuwUNShO70omZ4qkChwsJeGAJg5x09UeLEAwBS02BkFSllRUJjGEwnAUb/Iq4s3NBVmYiiZ/wmKg== dependencies: "@polkadot/util" "^12.2.2" @@ -196,7 +196,7 @@ "@polkadot/types-create@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-10.8.1.tgz#f5974a00918e2c4b7fca29c18abd3410536393ad" + resolved "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.8.1.tgz" integrity sha512-v2WZHQAjf8TiLipRkR1iPTyWSjGHJJP2SQ5uVO5UJlHilpE8lODqY1rr/9hGN+sbRhU0vEy6ZceDEKuNbtJB3Q== dependencies: "@polkadot/types-codec" "10.8.1" @@ -205,7 +205,7 @@ "@polkadot/types-known@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-10.8.1.tgz#f630d3354cbe80149360edb37c569c5042eced12" + resolved "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.8.1.tgz" integrity sha512-AIeuF7eTIEnUgxa1pU0UMmF/tIXgucAECwU8vzoKeJLrYWA16VYUm0Pst9e3jK3PyLaCneMRyR00Lc7oxVANbw== dependencies: "@polkadot/networks" "^12.2.2" @@ -217,7 +217,7 @@ "@polkadot/types-support@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-10.8.1.tgz#b299f829374ce77fdfbe1d1b8faa14ba02969783" + resolved "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.8.1.tgz" integrity sha512-arDVaL70vzVL5JBGWW1qcOASn1cJ/UxNMR3fHchoVkAqS20VIrehE8MF4zXMdjcP0Ak3+6E0FaSmHMTKlmEJsg== dependencies: "@polkadot/util" "^12.2.2" @@ -225,7 +225,7 @@ "@polkadot/types@10.8.1": version "10.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-10.8.1.tgz#83c01c347189ff97b98b34a5a4aba27c715539eb" + resolved "https://registry.npmjs.org/@polkadot/types/-/types-10.8.1.tgz" integrity sha512-m6UvsvQOZ7sRGbonb6QLs4mZ6TmYKdAXAcHakiJl2xArqsgOghJsKhgaTqcigPkSq4947MXtIkEzdrwFEnkYkQ== dependencies: "@polkadot/keyring" "^12.2.2" @@ -237,9 +237,9 @@ rxjs "^7.8.1" tslib "^2.5.3" -"@polkadot/util-crypto@12.2.2", "@polkadot/util-crypto@^12.2.2": +"@polkadot/util-crypto@^12.2.2", "@polkadot/util-crypto@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-12.2.2.tgz#7e6ab56482d3dfb8704a724d695028677799c685" + resolved "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.2.2.tgz" integrity sha512-4JfEd/TJaDArp5Jpr3N/aYHp+QR71XzZRKqU4u7WkGKmnGt28Qfh2IWGB/E2MvIFxa6CjIiQMxN2hnkNr49JAQ== dependencies: "@noble/curves" "1.1.0" @@ -253,9 +253,9 @@ "@scure/base" "1.1.1" tslib "^2.5.3" -"@polkadot/util@12.2.2", "@polkadot/util@^12.2.2": +"@polkadot/util@*", "@polkadot/util@^12.2.2", "@polkadot/util@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-12.2.2.tgz#f586fd62c330a09bb026b1584be1bb07c8b27b6b" + resolved "https://registry.npmjs.org/@polkadot/util/-/util-12.2.2.tgz" integrity sha512-u/v5Z2+iUwX/CXEMVZgJmwqqx1kT5Zfxsio3vpuYaPCg49xhTKqAcrakgB+1BUHhhyF3Zkb9uG73JWFR0Lkk9w== dependencies: "@polkadot/x-bigint" "12.2.2" @@ -268,7 +268,7 @@ "@polkadot/wasm-bridge@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-7.2.1.tgz#8464a96552207d2b49c6f32137b24132534b91ee" + resolved "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.2.1.tgz" integrity sha512-uV/LHREDBGBbHrrv7HTki+Klw0PYZzFomagFWII4lp6Toj/VCvRh5WMzooVC+g/XsBGosAwrvBhoModabyHx+A== dependencies: "@polkadot/wasm-util" "7.2.1" @@ -276,14 +276,14 @@ "@polkadot/wasm-crypto-asmjs@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.1.tgz#3e7a91e2905ab7354bc37b82f3e151a62bb024db" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.1.tgz" integrity sha512-z/d21bmxyVfkzGsKef/FWswKX02x5lK97f4NPBZ9XBeiFkmzlXhdSnu58/+b1sKsRAGdW/Rn/rTNRDhW0GqCAg== dependencies: tslib "^2.5.0" "@polkadot/wasm-crypto-init@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.1.tgz#9dbba41ed7d382575240f1483cf5a139ff2787bd" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.1.tgz" integrity sha512-GcEXtwN9LcSf32V9zSaYjHImFw16hCyo2Xzg4GLLDPPeaAAfbFr2oQMgwyDbvBrBjLKHVHjsPZyGhXae831amw== dependencies: "@polkadot/wasm-bridge" "7.2.1" @@ -294,7 +294,7 @@ "@polkadot/wasm-crypto-wasm@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.1.tgz#d2486322c725f6e5d2cc2d6abcb77ecbbaedc738" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.1.tgz" integrity sha512-DqyXE4rSD0CVlLIw88B58+HHNyrvm+JAnYyuEDYZwCvzUWOCNos/DDg9wi/K39VAIsCCKDmwKqkkfIofuOj/lA== dependencies: "@polkadot/wasm-util" "7.2.1" @@ -302,7 +302,7 @@ "@polkadot/wasm-crypto@^7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-7.2.1.tgz#db671dcb73f1646dc13478b5ffc3be18c64babe1" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.2.1.tgz" integrity sha512-SA2+33S9TAwGhniKgztVN6pxUKpGfN4Tre/eUZGUfpgRkT92wIUT2GpGWQE+fCCqGQgADrNiBcwt6XwdPqMQ4Q== dependencies: "@polkadot/wasm-bridge" "7.2.1" @@ -312,16 +312,16 @@ "@polkadot/wasm-util" "7.2.1" tslib "^2.5.0" -"@polkadot/wasm-util@7.2.1", "@polkadot/wasm-util@^7.2.1": +"@polkadot/wasm-util@*", "@polkadot/wasm-util@^7.2.1", "@polkadot/wasm-util@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-util/-/wasm-util-7.2.1.tgz#fda233120ec02f77f0d14e4d3c7ad9ce06535fb8" + resolved "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.2.1.tgz" integrity sha512-FBSn/3aYJzhN0sYAYhHB8y9JL8mVgxLy4M1kUXYbyo+8GLRQEN5rns8Vcb8TAlIzBWgVTOOptYBvxo0oj0h7Og== dependencies: tslib "^2.5.0" -"@polkadot/x-bigint@12.2.2", "@polkadot/x-bigint@^12.2.2": +"@polkadot/x-bigint@^12.2.2", "@polkadot/x-bigint@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-12.2.2.tgz#18ff80c306b486fb926702ba9bb56291fb69d4f1" + resolved "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.2.2.tgz" integrity sha512-KSe7WAqwI1tubi0m5CP4oqf8EIjABZXLGkTHXKwjtAAMa9Q7hqFmVG2sXfvC+XSnhto1UKMe52TjuPrYSJI+jg== dependencies: "@polkadot/x-global" "12.2.2" @@ -329,23 +329,23 @@ "@polkadot/x-fetch@^12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-12.2.2.tgz#452b096a3233308a1cbbeae867c26a374b62b9e8" + resolved "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.2.2.tgz" integrity sha512-A3ttQp9oE6QH9VsggdQsBsgc9zyalxHoVXhZsn6yqcjzc9AoaY5QevezxVy88ZQpRp3bsYVn0RqyBV7eFq8WPw== dependencies: "@polkadot/x-global" "12.2.2" node-fetch "^3.3.1" tslib "^2.5.3" -"@polkadot/x-global@12.2.2", "@polkadot/x-global@^12.2.2": +"@polkadot/x-global@^12.2.2", "@polkadot/x-global@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-12.2.2.tgz#dda816c00738b72209637e623b50ecad5ce234bf" + resolved "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.2.2.tgz" integrity sha512-hLVoKR9fGhZdy/eK/LHTyh4jJ3V+3VfcxbCey0k2t1Byrwbmsi6wL3NUQk6i3NviswR9OSCic9mhgDQPRBXZEg== dependencies: tslib "^2.5.3" -"@polkadot/x-randomvalues@12.2.2": +"@polkadot/x-randomvalues@*", "@polkadot/x-randomvalues@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-12.2.2.tgz#c249d990f3033b0e9ea4a7964419f04d47b0d228" + resolved "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.2.2.tgz" integrity sha512-eExiOT/up5ZzwHJkFpGhQ6sCdPSJnn6PJsQnyJMEdgPaUES70u/wWMLGFNiy3U8rRRVSsZi6rc9Unsr02LczzA== dependencies: "@polkadot/x-global" "12.2.2" @@ -353,7 +353,7 @@ "@polkadot/x-textdecoder@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-12.2.2.tgz#9e3c7b17f6a8e032aa3ab906fcff3037aeecaa4c" + resolved "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.2.2.tgz" integrity sha512-Rsvsc7ZLBKT1rls8gdbvzLLEs2sGUA8cDiTaQUkCHJN3ja/37Bppz1wNPcEIMsJ2pyL6bwq86HB0xmC28QVdqA== dependencies: "@polkadot/x-global" "12.2.2" @@ -361,7 +361,7 @@ "@polkadot/x-textencoder@12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-12.2.2.tgz#6a40a953774093a070f2819959f054f258c001af" + resolved "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.2.2.tgz" integrity sha512-g6bX4DTBmkr3QLNeihlrHYvaZCKu1kFiK+BDQXVzBg+oHpzxz5wSVhzsG3GEVoVszXMiugWpSn03wCIvaRFMoQ== dependencies: "@polkadot/x-global" "12.2.2" @@ -369,7 +369,7 @@ "@polkadot/x-ws@^12.2.2": version "12.2.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-12.2.2.tgz#41d7645507137e5f13abb9536c18c840f7e86324" + resolved "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.2.2.tgz" integrity sha512-kZtdfRHsgpJ+HV/jY8mQG4BFpCIz6NxZlrRKzWdaIacPVeXHkV3nfk7i9ghK+MP/nWC0AKuq06yysp9ZwWMCug== dependencies: "@polkadot/x-global" "12.2.2" @@ -378,17 +378,49 @@ "@scure/base@1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== +"@stellar/js-xdr@^3.1.2": + version "3.1.2" + resolved "https://registry.npmjs.org/@stellar/js-xdr/-/js-xdr-3.1.2.tgz" + integrity sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ== + +"@stellar/stellar-base@^12.1.1": + version "12.1.1" + resolved "https://registry.npmjs.org/@stellar/stellar-base/-/stellar-base-12.1.1.tgz" + integrity sha512-gOBSOFDepihslcInlqnxKZdIW9dMUO1tpOm3AtJR33K2OvpXG6SaVHCzAmCFArcCqI9zXTEiSoh70T48TmiHJA== + dependencies: + "@stellar/js-xdr" "^3.1.2" + base32.js "^0.1.0" + bignumber.js "^9.1.2" + buffer "^6.0.3" + sha.js "^2.3.6" + tweetnacl "^1.0.3" + optionalDependencies: + sodium-native "^4.1.1" + +"@stellar/stellar-sdk@^12.3.0": + version "12.3.0" + resolved "https://registry.npmjs.org/@stellar/stellar-sdk/-/stellar-sdk-12.3.0.tgz" + integrity sha512-F2DYFop/M5ffXF0lvV5Ezjk+VWNKg0QDX8gNhwehVU3y5LYA3WAY6VcCarMGPaG9Wdgoeh1IXXzOautpqpsltw== + dependencies: + "@stellar/stellar-base" "^12.1.1" + axios "^1.7.7" + bignumber.js "^9.1.2" + eventsource "^2.0.2" + randombytes "^2.1.0" + toml "^3.0.0" + urijs "^1.19.1" + "@substrate/connect-extension-protocol@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.1.tgz#fa5738039586c648013caa6a0c95c43265dbe77d" + resolved "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.1.tgz" integrity sha512-161JhCC1csjH3GE5mPLEd7HbWtwNSPJBg3p1Ksz9SFlTzj/bgEwudiRN2y5i0MoLGCIJRYKyKGMxVnd29PzNjg== "@substrate/connect@0.7.26": version "0.7.26" - resolved "https://registry.yarnpkg.com/@substrate/connect/-/connect-0.7.26.tgz#a0ee5180c9cb2f29250d1219a32f7b7e7dea1196" + resolved "https://registry.npmjs.org/@substrate/connect/-/connect-0.7.26.tgz" integrity sha512-uuGSiroGuKWj1+38n1kY5HReer5iL9bRwPCzuoLtqAOmI1fGI0hsSI2LlNQMAbfRgr7VRHXOk5MTuQf5ulsFRw== dependencies: "@substrate/connect-extension-protocol" "^1.0.1" @@ -397,39 +429,39 @@ "@substrate/ss58-registry@^1.40.0": version "1.40.0" - resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.40.0.tgz#2223409c496271df786c1ca8496898896595441e" + resolved "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.40.0.tgz" integrity sha512-QuU2nBql3J4KCnOWtWDw4n1K4JU0T79j54ZZvm/9nhsX6AIar13FyhsaBfs6QkJ2ixTQAnd7TocJIoJRWbqMZA== "@types/bn.js@^5.1.1": version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz" integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== dependencies: "@types/node" "*" "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/node@*": version "20.2.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb" + resolved "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz" integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ== acorn-jsx@^5.3.1: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^7.4.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^7.4.0: version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -439,7 +471,7 @@ ajv@^6.10.0, ajv@^6.12.4: ajv@^8.0.1: version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" @@ -449,38 +481,38 @@ ajv@^8.0.1: ansi-colors@^4.1.1: version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + 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.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + 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.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" array-buffer-byte-length@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== dependencies: call-bind "^1.0.2" @@ -488,7 +520,7 @@ array-buffer-byte-length@^1.0.0: array-includes@^3.1.3, array-includes@^3.1.5: version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz" integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== dependencies: call-bind "^1.0.2" @@ -499,7 +531,7 @@ array-includes@^3.1.3, array-includes@^3.1.5: array.prototype.flat@^1.2.4: version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz" integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== dependencies: call-bind "^1.0.2" @@ -509,7 +541,7 @@ array.prototype.flat@^1.2.4: array.prototype.flatmap@^1.2.4: version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz" integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== dependencies: call-bind "^1.0.2" @@ -519,36 +551,87 @@ array.prototype.flatmap@^1.2.4: astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +available-typed-arrays@^1.0.5, available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" axios@^0.25.0: version "0.25.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" + resolved "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz" integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g== dependencies: follow-redirects "^1.14.7" +axios@^1.7.7: + version "1.13.6" + resolved "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz" + integrity sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ== + dependencies: + follow-redirects "^1.15.11" + form-data "^4.0.5" + proxy-from-env "^1.1.0" + balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bare-addon-resolve@^1.3.0: + version "1.10.0" + resolved "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.10.0.tgz" + integrity sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA== + dependencies: + bare-module-resolve "^1.10.0" + bare-semver "^1.0.0" + +bare-module-resolve@^1.10.0: + version "1.12.1" + resolved "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.1.tgz" + integrity sha512-hbmAPyFpEq8FoZMd5sFO3u6MC5feluWoGE8YKlA8fCrl6mNtx68Wjg4DTiDJcqRJaovTvOYKfYngoBUnbaT7eg== + dependencies: + bare-semver "^1.0.0" + +bare-semver@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.2.tgz" + integrity sha512-ESVaN2nzWhcI5tf3Zzcq9aqCZ676VWzqw07eEZ0qxAcEOAFYBa0pWq8sK34OQeHLY3JsfKXZS9mDyzyxGjeLzA== + +base32.js@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz" + integrity sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bignumber.js@^9.1.2: + version "9.3.1" + resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz" + integrity sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ== + bip39@^3.0.3: version "3.1.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" + resolved "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz" integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== dependencies: "@noble/hashes" "^1.2.0" blake@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/blake/-/blake-1.0.1.tgz#6c8cff58e5217c86329a49c61e72cda3eb83862b" + resolved "https://registry.npmjs.org/blake/-/blake-1.0.1.tgz" integrity sha512-vX8JQdac+BNxW4clj/rJk0ooLBXTdt462V2QSz5GMNJ8RhYK48n7cW/UyUvuXGMiqctsd7i1xIio4vI8O/j+Fw== dependencies: cop "^0.3.6" @@ -561,33 +644,59 @@ blake@^1.0.1: bn.js@^5.1.3, bn.js@^5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + 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" -call-bind@^1.0.0, call-bind@^1.0.2: +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== + dependencies: + call-bind-apply-helpers "^1.0.0" + es-define-property "^1.0.0" + get-intrinsic "^1.2.4" + set-function-length "^1.2.2" + +call-bound@^1.0.3, call-bound@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== chalk@^2.0.0: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + 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" @@ -596,7 +705,7 @@ chalk@^2.0.0: chalk@^4.0.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -604,41 +713,48 @@ chalk@^4.0.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + 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.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + 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.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-name@1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + 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.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== cop@^0.3.6: version "0.3.6" - resolved "https://registry.yarnpkg.com/cop/-/cop-0.3.6.tgz#8f1485eb26b5481a45ef0f058e69699e16cbbeac" + resolved "https://registry.npmjs.org/cop/-/cop-0.3.6.tgz" integrity sha512-JB+js3riedeJxEmea7HZbV0xI4+j0/WHVYststvqtOgcEWg+bHNuYY9o1DJCeQEUY6XusaQe9CWHZP3z/zhJOA== cross-spawn@^7.0.2: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -647,84 +763,107 @@ cross-spawn@^7.0.2: data-uri-to-buffer@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz" integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== debug@^2.6.9: version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.2.7: version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + 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.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + doctrine@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== enquirer@^2.3.5: version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + 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" es-abstract@^1.19.0, es-abstract@^1.20.4: version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz" integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== dependencies: array-buffer-byte-length "^1.0.0" @@ -762,25 +901,43 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: unbox-primitive "^1.0.2" which-typed-array "^1.1.9" -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== +es-define-property@^1.0.0, es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.1, es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" es-shim-unscopables@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== dependencies: has "^1.0.3" es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" @@ -789,22 +946,22 @@ es-to-primitive@^1.2.1: escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== eslint-config-standard-jsx@10.0.0: version "10.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-10.0.0.tgz#dc24992661325a2e480e2c3091d669f19034e18d" + resolved "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-10.0.0.tgz" integrity sha512-hLeA2f5e06W1xyr/93/QJulN/rLbUVUmqTlexv9PRKHFwEC9ffJcH2LvJhMoEqYQBEYafedgGZXH2W8NUpt5lA== eslint-config-standard@16.0.3: version "16.0.3" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" + resolved "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz" integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== eslint-import-resolver-node@^0.3.6: version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz" integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== dependencies: debug "^3.2.7" @@ -813,22 +970,22 @@ eslint-import-resolver-node@^0.3.6: eslint-module-utils@^2.6.2: version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" eslint-plugin-es@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz" integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== dependencies: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@~2.24.2: +eslint-plugin-import@^2.22.1, eslint-plugin-import@~2.24.2: version "2.24.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz#2c8cd2e341f3885918ee27d18479910ade7bb4da" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz" integrity sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q== dependencies: array-includes "^3.1.3" @@ -847,9 +1004,9 @@ eslint-plugin-import@~2.24.2: resolve "^1.20.0" tsconfig-paths "^3.11.0" -eslint-plugin-node@~11.1.0: +eslint-plugin-node@^11.1.0, eslint-plugin-node@~11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz" integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== dependencies: eslint-plugin-es "^3.0.0" @@ -859,14 +1016,14 @@ eslint-plugin-node@~11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-promise@~5.1.0: +"eslint-plugin-promise@^4.2.1 || ^5.0.0", eslint-plugin-promise@~5.1.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz#9674d11c056d1bafac38e4a3a9060be740988d90" + resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz" integrity sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA== -eslint-plugin-react@~7.25.1: +eslint-plugin-react@^7.21.5, eslint-plugin-react@~7.25.1: version "7.25.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.25.3.tgz#3333a974772745ddb3aecea84621019b635766bc" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.25.3.tgz" integrity sha512-ZMbFvZ1WAYSZKY662MBVEWR45VaBT6KSJCiupjrNlcdakB90juaZeDCbJq19e73JZQubqFtgETohwgAt8u5P6w== dependencies: array-includes "^3.1.3" @@ -885,7 +1042,7 @@ eslint-plugin-react@~7.25.1: eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -893,24 +1050,29 @@ eslint-scope@^5.1.1: eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.1.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@~7.18.0: +"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0", "eslint@^3 || ^4 || ^5 || ^6 || ^7", eslint@^7.0.0, eslint@^7.12.1, eslint@>=4.19.1, eslint@>=5.16.0, eslint@~7.18.0: version "7.18.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.18.0.tgz#7fdcd2f3715a41fe6295a16234bd69aed2c75e67" + resolved "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz" integrity sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ== dependencies: "@babel/code-frame" "^7.0.0" @@ -953,7 +1115,7 @@ eslint@~7.18.0: espree@^7.3.0, espree@^7.3.1: version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" @@ -962,41 +1124,41 @@ espree@^7.3.0, espree@^7.3.1: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.2.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + 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.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + 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.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + 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.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + 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.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== event-stream@^3.3.1: version "3.3.5" - resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.5.tgz#e5dd8989543630d94c6cf4d657120341fa31636b" + resolved "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz" integrity sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g== dependencies: duplexer "^0.1.1" @@ -1009,32 +1171,37 @@ event-stream@^3.3.1: eventemitter3@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== eventemitter3@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== +eventsource@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz" + integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== + fast-deep-equal@^3.1.1: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + 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.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fetch-blob@^3.1.2, fetch-blob@^3.1.4: version "3.2.0" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + resolved "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz" integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== dependencies: node-domexception "^1.0.0" @@ -1042,28 +1209,28 @@ fetch-blob@^3.1.2, fetch-blob@^3.1.4: file-entry-cache@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + 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" find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== dependencies: locate-path "^2.0.0" find-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: locate-path "^3.0.0" flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" @@ -1071,41 +1238,52 @@ flat-cache@^3.0.4: flatted@^3.1.0: version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -follow-redirects@^1.14.7: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +follow-redirects@^1.14.7, follow-redirects@^1.15.11: + version "1.15.11" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz" + integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== + +for-each@^0.3.3, for-each@^0.3.5: + version "0.3.5" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz" + integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== + dependencies: + is-callable "^1.2.7" -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== +form-data@^4.0.5: + version "4.0.5" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz" + integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== dependencies: - is-callable "^1.1.3" + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + hasown "^2.0.2" + mime-types "^2.1.12" formdata-polyfill@^4.0.10: version "4.0.10" - resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + resolved "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz" integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== dependencies: fetch-blob "^3.1.2" from@^0.1.7: version "0.1.7" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + resolved "https://registry.npmjs.org/from/-/from-0.1.7.tgz" integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fstream@^1.0.7: version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz" integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" @@ -1113,14 +1291,14 @@ fstream@^1.0.7: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== function.prototype.name@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== dependencies: call-bind "^1.0.2" @@ -1130,32 +1308,46 @@ function.prototype.name@^1.1.5: functional-red-black-tree@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.4, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" get-stdin@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz" integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== get-symbol-description@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: call-bind "^1.0.2" @@ -1163,14 +1355,14 @@ get-symbol-description@^1.0.0: glob-parent@^5.0.0: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + 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@^7.1.3: version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -1182,94 +1374,104 @@ glob@^7.1.3: globals@^12.1.0: version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + resolved "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz" integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== dependencies: type-fest "^0.8.1" globalthis@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== dependencies: define-properties "^1.1.3" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" +gopd@^1.0.1, gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== graceful-fs@^4.1.15, graceful-fs@^4.1.2: version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + 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.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: - get-intrinsic "^1.1.1" + es-define-property "^1.0.0" has-proto@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.0.2, has-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: - has-symbols "^1.0.2" + has-symbols "^1.0.3" has@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.1: version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + 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.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -1277,25 +1479,25 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + 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.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + 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, inherits@~2.0.0: +inherits@^2.0.4, inherits@~2.0.0, inherits@2: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== internal-slot@^1.0.3, internal-slot@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: get-intrinsic "^1.2.0" @@ -1304,12 +1506,12 @@ internal-slot@^1.0.3, internal-slot@^1.0.5: ip-regex@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz" integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== dependencies: call-bind "^1.0.2" @@ -1318,75 +1520,75 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: +is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.11.0, is-core-module@^2.6.0, is-core-module@^2.9.0: version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz" integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" is-date-object@^1.0.1: version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-negative-zero@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" is-regex@^1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -1394,56 +1596,57 @@ is-regex@^1.1.4: is-shared-array-buffer@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== dependencies: call-bind "^1.0.2" is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== +is-typed-array@^1.1.10, is-typed-array@^1.1.14, is-typed-array@^1.1.9: + version "1.1.15" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz" + integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.16" is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -1451,39 +1654,39 @@ js-yaml@^3.13.1: json-parse-better-errors@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stringify-safe@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.3.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== dependencies: array-includes "^3.1.5" @@ -1491,7 +1694,7 @@ json5@^1.0.2: levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + 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" @@ -1499,7 +1702,7 @@ levn@^0.4.1: load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== dependencies: graceful-fs "^4.1.2" @@ -1509,7 +1712,7 @@ load-json-file@^4.0.0: load-json-file@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-5.3.0.tgz#4d3c1e01fa1c03ea78a60ac7af932c9ce53403f3" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz" integrity sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw== dependencies: graceful-fs "^4.1.15" @@ -1520,7 +1723,7 @@ load-json-file@^5.2.0: locate-path@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== dependencies: p-locate "^2.0.0" @@ -1528,7 +1731,7 @@ locate-path@^2.0.0: locate-path@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: p-locate "^3.0.0" @@ -1536,90 +1739,102 @@ locate-path@^3.0.0: lodash.truncate@^4.4.2: version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loose-envify@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lru-cache@^2.6.5: version "2.7.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz" integrity sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ== lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" map-stream@0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + resolved "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz" integrity sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ== +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"mkdirp@>=0.5 0", mkdirp@^0.5.1: +mkdirp@^0.5.1, "mkdirp@>=0.5 0": version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" mock-socket@^9.2.1: version "9.2.1" - resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.2.1.tgz#cc9c0810aa4d0afe02d721dcb2b7e657c00e2282" + resolved "https://registry.npmjs.org/mock-socket/-/mock-socket-9.2.1.tgz" integrity sha512-aw9F9T9G2zpGipLLhSNh6ZpgUyUl4frcVmRN08uE1NWPWg43Wx6+sGPDbQ7E5iFZZDJW5b5bypMeAEHqTbIFag== moment@^2.29.1: version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz" integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: +ms@^2.1.1, ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== nock@^13.3.1: version "13.3.1" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.3.1.tgz#f22d4d661f7a05ebd9368edae1b5dc0a62d758fc" + resolved "https://registry.npmjs.org/nock/-/nock-13.3.1.tgz" integrity sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw== dependencies: debug "^4.1.0" @@ -1629,12 +1844,12 @@ nock@^13.3.1: node-domexception@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== node-fetch@^3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz" integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== dependencies: data-uri-to-buffer "^4.0.0" @@ -1643,7 +1858,7 @@ node-fetch@^3.3.1: normalize-package-data@^2.3.2: version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -1653,22 +1868,22 @@ normalize-package-data@^2.3.2: object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-inspect@^1.12.3, object-inspect@^1.9.0: version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object.assign@^4.1.3, object.assign@^4.1.4: version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== dependencies: call-bind "^1.0.2" @@ -1678,7 +1893,7 @@ object.assign@^4.1.3, object.assign@^4.1.4: object.entries@^1.1.4: version "1.1.6" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz" integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== dependencies: call-bind "^1.0.2" @@ -1687,7 +1902,7 @@ object.entries@^1.1.4: object.fromentries@^2.0.4: version "2.0.6" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz" integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== dependencies: call-bind "^1.0.2" @@ -1696,7 +1911,7 @@ object.fromentries@^2.0.4: object.hasown@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" + resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz" integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== dependencies: define-properties "^1.1.4" @@ -1704,7 +1919,7 @@ object.hasown@^1.0.0: object.values@^1.1.4: version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz" integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== dependencies: call-bind "^1.0.2" @@ -1713,14 +1928,14 @@ object.values@^1.1.4: once@^1.3.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + 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.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -1732,57 +1947,57 @@ optionator@^0.9.1: p-limit@^1.1.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-limit@^2.0.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-locate@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== dependencies: p-limit "^1.1.0" p-locate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: p-limit "^2.0.0" p-try@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@^2.0.4: version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + resolved "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz" integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + 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@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" @@ -1790,51 +2005,51 @@ parse-json@^4.0.0: path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + 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.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" pause-stream@^0.0.11: version "0.0.11" - resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + resolved "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz" integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A== dependencies: through "~2.3" pify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== pify@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pkg-conf@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-3.1.0.tgz#d9f9c75ea1bae0e77938cde045b276dac7cc69ae" + resolved "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz" integrity sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ== dependencies: find-up "^3.0.0" @@ -1842,34 +2057,39 @@ pkg-conf@^3.1.0: pkg-up@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz" integrity sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg== dependencies: find-up "^2.1.0" popfun@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/popfun/-/popfun-1.0.0.tgz#49528e6c1b49a5efb7f41cf2131bc95cea4bccb4" + resolved "https://registry.npmjs.org/popfun/-/popfun-1.0.0.tgz" integrity sha512-8TOxvFAIyxvxNn8ca7RXtPJi7bPrBH77H8+yRWKgvV/5SJUAu5XXCDGtTf7UrezQq+WkZJgI9fXv/irfoPSQgg== +possible-typed-array-names@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz" + integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== + prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettydate@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/prettydate/-/prettydate-0.0.1.tgz#cbe3624713cff4801f4aa0531ac3f9f224d33aa5" + resolved "https://registry.npmjs.org/prettydate/-/prettydate-0.0.1.tgz" integrity sha512-kkTd6fDCxmiTyod7+rW9LXnvkw3G6CrSYcVokhlJ9mr+Zb4DcbcgIlVIhj9I3Mg9AhZDIlkk1MdAJTBP6jwUhw== progress@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== prop-types@^15.7.2: version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== dependencies: loose-envify "^1.4.0" @@ -1878,22 +2098,34 @@ prop-types@^15.7.2: propagate@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" + resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz" integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + react-is@^16.13.1: version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== read-pkg-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz" integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== dependencies: find-up "^2.0.0" @@ -1901,7 +2133,7 @@ read-pkg-up@^3.0.0: read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== dependencies: load-json-file "^4.0.0" @@ -1910,7 +2142,7 @@ read-pkg@^3.0.0: regexp.prototype.flags@^1.4.3: version "1.5.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== dependencies: call-bind "^1.0.2" @@ -1919,22 +2151,29 @@ regexp.prototype.flags@^1.4.3: regexpp@^3.0.0, regexpp@^3.1.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +require-addon@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/require-addon/-/require-addon-1.2.0.tgz" + integrity sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA== + dependencies: + bare-addon-resolve "^1.3.0" + require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve@^1.10.0, resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.1: version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== dependencies: is-core-module "^2.11.0" @@ -1943,75 +2182,101 @@ resolve@^1.10.0, resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.1: resolve@^2.0.0-next.3: version "2.0.0-next.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== dependencies: is-core-module "^2.9.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -rimraf@2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" +rimraf@2: + version "2.7.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rxjs@^7.8.1: version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" +safe-buffer@^5.1.0, safe-buffer@^5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex-test@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== dependencies: call-bind "^1.0.2" get-intrinsic "^1.1.3" is-regex "^1.1.4" -"semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.1.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.2.1: version "7.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz" integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== dependencies: lru-cache "^6.0.0" +"semver@2 || 3 || 4 || 5": + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +set-function-length@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +sha.js@^2.3.6: + version "2.4.12" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz" + integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + to-buffer "^1.2.0" + shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + 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.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -2020,7 +2285,7 @@ side-channel@^1.0.4: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -2029,15 +2294,22 @@ slice-ansi@^4.0.0: smoldot@1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/smoldot/-/smoldot-1.0.4.tgz#e4c38cedad68d699a11b5b9ce72bb75c891bfd98" + resolved "https://registry.npmjs.org/smoldot/-/smoldot-1.0.4.tgz" integrity sha512-N3TazI1C4GGrseFH/piWyZCCCRJTRx2QhDfrUKRT4SzILlW5m8ayZ3QTKICcz1C/536T9cbHHJyP7afxI6Mi1A== dependencies: pako "^2.0.4" ws "^8.8.1" +sodium-native@^4.1.1: + version "4.3.3" + resolved "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.3.tgz" + integrity sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw== + dependencies: + require-addon "^1.1.0" + spdx-correct@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" @@ -2045,12 +2317,12 @@ spdx-correct@^3.0.0: spdx-exceptions@^2.1.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" @@ -2058,24 +2330,24 @@ spdx-expression-parse@^3.0.0: spdx-license-ids@^3.0.0: version "3.0.13" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== split@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + resolved "https://registry.npmjs.org/split/-/split-1.0.1.tgz" integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== dependencies: through "2" sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== standard-engine@^14.0.1: version "14.0.1" - resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-14.0.1.tgz#fe568e138c3d9768fc59ff81001f7049908a8156" + resolved "https://registry.npmjs.org/standard-engine/-/standard-engine-14.0.1.tgz" integrity sha512-7FEzDwmHDOGva7r9ifOzD3BGdTbA7ujJ50afLVdW/tK14zQEptJjbFuUfn50irqdHDcTbNh0DTIoMPynMCXb0Q== dependencies: get-stdin "^8.0.0" @@ -2085,7 +2357,7 @@ standard-engine@^14.0.1: standard@^16.0.3: version "16.0.4" - resolved "https://registry.yarnpkg.com/standard/-/standard-16.0.4.tgz#779113ba41dd218ab545e7b4eb2405561f6eb370" + resolved "https://registry.npmjs.org/standard/-/standard-16.0.4.tgz" integrity sha512-2AGI874RNClW4xUdM+bg1LRXVlYLzTNEkHmTG5mhyn45OhbgwA+6znowkOGYy+WMb5HRyELvtNy39kcdMQMcYQ== dependencies: eslint "~7.18.0" @@ -2099,7 +2371,7 @@ standard@^16.0.3: stream-combiner@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + resolved "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz" integrity sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ== dependencies: duplexer "~0.1.1" @@ -2107,7 +2379,7 @@ stream-combiner@^0.2.2: string-width@^4.2.3: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -2116,7 +2388,7 @@ string-width@^4.2.3: string.prototype.matchall@^4.0.5: version "4.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz" integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== dependencies: call-bind "^1.0.2" @@ -2130,7 +2402,7 @@ string.prototype.matchall@^4.0.5: string.prototype.trim@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz" integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== dependencies: call-bind "^1.0.2" @@ -2139,7 +2411,7 @@ string.prototype.trim@^1.2.7: string.prototype.trimend@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== dependencies: call-bind "^1.0.2" @@ -2148,7 +2420,7 @@ string.prototype.trimend@^1.0.6: string.prototype.trimstart@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz" integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== dependencies: call-bind "^1.0.2" @@ -2157,43 +2429,43 @@ string.prototype.trimstart@^1.0.6: strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + 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.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + 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.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + 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" supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== table@^6.0.4: version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + resolved "https://registry.npmjs.org/table/-/table-6.8.1.tgz" integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== dependencies: ajv "^8.0.1" @@ -2204,17 +2476,31 @@ table@^6.0.4: text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -through@2, through@^2.3.8, through@~2.3, through@~2.3.4: +through@^2.3.8, through@~2.3, through@~2.3.4, through@2: version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +to-buffer@^1.2.0: + version "1.2.2" + resolved "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz" + integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== + dependencies: + isarray "^2.0.5" + safe-buffer "^5.2.1" + typed-array-buffer "^1.0.3" + +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + tsconfig-paths@^3.11.0: version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz" integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" @@ -2224,29 +2510,43 @@ tsconfig-paths@^3.11.0: tslib@^2.1.0, tslib@^2.5.0, tslib@^2.5.3: version "2.5.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + 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.3.0: version "0.3.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz" integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== type-fest@^0.8.1: version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typed-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz" + integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + is-typed-array "^1.1.14" + typed-array-length@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== dependencies: call-bind "^1.0.2" @@ -2255,7 +2555,7 @@ typed-array-length@^1.0.4: unbox-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: call-bind "^1.0.2" @@ -2265,19 +2565,24 @@ unbox-primitive@^1.0.2: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" +urijs@^1.19.1: + version "1.19.11" + resolved "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz" + integrity sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ== + v8-compile-cache@^2.0.3: version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -2285,12 +2590,12 @@ validate-npm-package-license@^3.0.1: web-streams-polyfill@^3.0.3: version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz" integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -2299,46 +2604,47 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.16, which-typed-array@^1.1.9: + version "1.1.20" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz" + integrity sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" + available-typed-arrays "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.4" + for-each "^0.3.5" + get-proto "^1.0.1" + gopd "^1.2.0" + has-tostringtag "^1.0.2" which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + 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.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + 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.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== ws@^8.13.0, ws@^8.8.1: version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== xdg-basedir@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==