From 4ecbcd7b1e32340f93f780f12b01ed0ca8c23538 Mon Sep 17 00:00:00 2001 From: Ty J Everett Date: Fri, 24 Jul 2026 18:28:04 -0700 Subject: [PATCH 1/6] chore: modernize, harden, and release the TypeScript stack --- conformance/runner/package.json | 3 +- conformance/runner/ts/package.json | 2 +- docs-site/package.json | 30 +- .../assets/asyncapi/authsocket/index.html | 2045 +-- .../public/assets/asyncapi/brc29/index.html | 966 +- .../public/assets/asyncapi/brc31/index.html | 1945 +-- .../public/assets/asyncapi/gasp/index.html | 1560 +-- docs-site/src/components/CodeBlock.tsx | 20 +- docs/about/contributing.md | 7 +- docs/about/versioning.md | 13 +- docs/packages/helpers/amountinator.md | 6 +- docs/packages/helpers/did-client.md | 6 +- docs/packages/helpers/did.md | 6 +- docs/packages/helpers/fund-wallet.md | 6 +- docs/packages/helpers/simple.md | 6 +- docs/packages/helpers/templates.md | 6 +- docs/packages/helpers/wallet-helper.md | 6 +- docs/packages/messaging/authsocket-client.md | 6 +- docs/packages/messaging/authsocket.md | 6 +- docs/packages/messaging/message-box-client.md | 6 +- docs/packages/messaging/paymail.md | 6 +- docs/packages/middleware/402-pay.md | 6 +- .../middleware/auth-express-middleware.md | 6 +- .../middleware/payment-express-middleware.md | 6 +- docs/packages/network/teranode-listener.md | 6 +- docs/packages/overlays/gasp.md | 6 +- .../overlays/overlay-discovery-services.md | 6 +- docs/packages/overlays/overlay-express.md | 6 +- docs/packages/overlays/overlay-topics.md | 6 +- docs/packages/overlays/overlay.md | 11 +- docs/packages/sdk/bsv-sdk.md | 6 +- .../packages/wallet/btms-permission-module.md | 6 +- docs/packages/wallet/btms.md | 6 +- docs/packages/wallet/wallet-relay.md | 6 +- docs/packages/wallet/wallet-toolbox.md | 6 +- docs/reference/dependency-policy.md | 86 + docs/reference/index.md | 20 +- docs/reference/release-2026-07-25.md | 87 + docs/specs/overlay-http.md | 9 +- package.json | 7 +- packages/helpers/amountinator/AGENTS.md | 4 +- packages/helpers/amountinator/package.json | 10 +- .../src/utils/currencyConverter.ts | 3 +- .../tests/currencyConverterCache.test.ts | 12 +- packages/helpers/bsv-wallet-helper/AGENTS.md | 2 +- .../helpers/bsv-wallet-helper/BASELINE.md | 4 +- .../helpers/bsv-wallet-helper/package.json | 22 +- packages/helpers/create-bsv-app/package.json | 50 +- packages/helpers/did-client/AGENTS.md | 2 +- packages/helpers/did-client/BASELINE.md | 4 +- packages/helpers/did-client/eslint.config.js | 39 - packages/helpers/did-client/package.json | 24 +- .../helpers/did-client/tsconfig.eslint.json | 19 - packages/helpers/did/package.json | 20 +- packages/helpers/fund-wallet/AGENTS.md | 2 +- packages/helpers/fund-wallet/BASELINE.md | 2 +- packages/helpers/fund-wallet/package.json | 14 +- packages/helpers/simple/BASELINE.md | 4 +- packages/helpers/simple/package.json | 24 +- packages/helpers/ts-templates/AGENTS.md | 2 +- packages/helpers/ts-templates/CONTRIBUTING.md | 2 +- packages/helpers/ts-templates/package.json | 13 +- .../messaging/authsocket-client/BASELINE.md | 4 +- .../messaging/authsocket-client/package.json | 18 +- packages/messaging/authsocket/BASELINE.md | 4 +- packages/messaging/authsocket/package.json | 22 +- .../messaging/message-box-client/AGENTS.md | 2 +- .../messaging/message-box-client/BASELINE.md | 4 +- .../message-box-client/eslint.config.js | 39 - .../messaging/message-box-client/package.json | 37 +- .../message-box-client/tsconfig.eslint.json | 19 - packages/messaging/ts-paymail/AGENTS.md | 2 +- packages/messaging/ts-paymail/BASELINE.md | 4 +- packages/messaging/ts-paymail/CONTRIBUTING.md | 2 +- .../ts-paymail/docs/examples/package.json | 12 +- packages/messaging/ts-paymail/package.json | 22 +- packages/middleware/402-pay/package.json | 6 +- .../auth-express-middleware/AGENTS.md | 2 +- .../auth-express-middleware/BASELINE.md | 8 +- .../auth-express-middleware/package.json | 16 +- .../src/__tests/ExpressTransport.test.ts | 13 + .../auth-express-middleware/src/index.ts | 20 +- packages/middleware/auth/package.json | 21 +- .../payment-express-middleware/AGENTS.md | 2 +- .../payment-express-middleware/BASELINE.md | 4 +- .../payment-express-middleware/package.json | 14 +- packages/network/ts-p2p/CONTRIBUTING.md | 2 +- packages/network/ts-p2p/package.json | 34 +- packages/overlays/btms-backend/AGENTS.md | 2 +- packages/overlays/btms-backend/BASELINE.md | 4 +- packages/overlays/btms-backend/package.json | 18 +- packages/overlays/gasp-core/AGENTS.md | 2 +- packages/overlays/gasp-core/BASELINE.md | 4 +- packages/overlays/gasp-core/package.json | 13 +- .../overlay-discovery-services/AGENTS.md | 2 +- .../overlay-discovery-services/BASELINE.md | 4 +- .../overlay-discovery-services/package.json | 18 +- packages/overlays/overlay-express/AGENTS.md | 2 +- packages/overlays/overlay-express/BASELINE.md | 4 +- .../overlays/overlay-express/package.json | 32 +- .../overlay-express/src/OverlayExpress.ts | 22 +- .../src/__tests__/OverlayExpress.test.ts | 88 +- .../__tests__/OverlayProviders.live.test.ts | 8 +- .../overlay-express/src/generalGuide.md.ts | 2 +- packages/overlays/overlay/AGENTS.md | 7 +- packages/overlays/overlay/BASELINE.md | 8 +- packages/overlays/overlay/CONTRIBUTING.md | 2 +- packages/overlays/overlay/README.md | 5 +- packages/overlays/overlay/package.json | 20 +- packages/overlays/overlay/src/Engine.ts | 31 +- .../overlay/src/GASP/OverlayGASPStorage.ts | 3 +- .../overlay/src/__tests/BASMChain.test.ts | 47 +- .../overlay/src/__tests/Engine.test.ts | 48 +- packages/overlays/overlay/tsconfig.base.json | 1 + packages/overlays/topics/AGENTS.md | 2 +- packages/overlays/topics/BASELINE.md | 2 +- packages/overlays/topics/package.json | 16 +- packages/sdk/BASELINE.md | 8 +- packages/sdk/CONTRIBUTING.md | 2 +- packages/sdk/eslint.config.js | 43 - packages/sdk/package.json | 26 +- packages/sdk/src/auth/utils/createNonce.ts | 7 +- packages/sdk/src/auth/utils/verifyNonce.ts | 6 +- .../sdk/src/overlay-tools/SHIPBroadcaster.ts | 6 +- .../__tests/SHIPBroadcaster.test.ts | 27 +- packages/sdk/src/script/templates/PushDrop.ts | 2 +- .../script/templates/__tests/PushDrop.test.ts | 12 + packages/sdk/src/transaction/Transaction.ts | 6 +- .../__tests/Transaction.additional.test.ts | 24 + packages/sdk/src/wallet/ProtoWallet.ts | 2 +- .../src/wallet/__tests/ProtoWallet.test.ts | 32 +- packages/sdk/tsconfig.eslint.json | 19 - packages/verifast/package.json | 19 +- .../btms-permission-module/package.json | 8 +- packages/wallet/btms/AGENTS.md | 2 +- packages/wallet/btms/BASELINE.md | 4 +- packages/wallet/btms/package.json | 12 +- packages/wallet/ts-wallet-relay/package.json | 22 +- .../wallet-toolbox-examples/BASELINE.md | 2 +- .../wallet-toolbox-examples/package.json | 22 +- packages/wallet/wallet-toolbox/BASELINE.md | 22 +- .../wallet/wallet-toolbox/CONTRIBUTING.md | 2 +- .../wallet/wallet-toolbox/client/package.json | 11 +- .../wallet/wallet-toolbox/mobile/package.json | 11 +- packages/wallet/wallet-toolbox/package.json | 36 +- ...alletPermissionsManager.denialcode.test.ts | 10 +- ...WalletPermissionsManager.mintdedup.test.ts | 32 +- .../wallet/wallet-toolbox/src/index.client.ts | 1 + .../remoting/__test/StorageClient.test.ts | 25 + .../src/wab-client/WABTransport.ts | 2 +- .../wallet/wallet-toolbox/tsconfig.all.json | 1 + .../wallet-toolbox/tsconfig.client.json | 1 + packages/wallet/wallet-toolbox/tsconfig.json | 8 +- .../wallet-toolbox/tsconfig.mobile.json | 1 + pnpm-lock.yaml | 10323 +++------------- pnpm-workspace.yaml | 39 +- scripts/check-versions.mjs | 16 +- scripts/generate-asyncapi-html.mjs | 299 +- scripts/sync-versions.mjs | 53 +- specs/reliability/message-box-server.md | 4 +- specs/reliability/overlay-express.md | 4 +- specs/reliability/ts-sdk.md | 4 +- specs/reliability/wallet-toolbox.md | 2 +- 163 files changed, 6762 insertions(+), 12441 deletions(-) create mode 100644 docs/reference/dependency-policy.md create mode 100644 docs/reference/release-2026-07-25.md delete mode 100644 packages/helpers/did-client/eslint.config.js delete mode 100644 packages/helpers/did-client/tsconfig.eslint.json delete mode 100644 packages/messaging/message-box-client/eslint.config.js delete mode 100644 packages/messaging/message-box-client/tsconfig.eslint.json create mode 100644 packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts delete mode 100644 packages/sdk/eslint.config.js delete mode 100644 packages/sdk/tsconfig.eslint.json diff --git a/conformance/runner/package.json b/conformance/runner/package.json index aef15e88b..768717214 100644 --- a/conformance/runner/package.json +++ b/conformance/runner/package.json @@ -11,10 +11,9 @@ "build": "echo 'no build step'" }, "dependencies": { - "ajv": "^8.17.1" + "ajv": "^8.20.0" }, "devDependencies": { - "ts-standard": "^12.0.0", "typescript": "^6.0.3" } } diff --git a/conformance/runner/ts/package.json b/conformance/runner/ts/package.json index a23599cd5..efa0e75d4 100644 --- a/conformance/runner/ts/package.json +++ b/conformance/runner/ts/package.json @@ -9,7 +9,7 @@ "@bsv/sdk": "workspace:^", "@jest/globals": "^30.4.1", "jest": "^30.4.2", - "ts-jest": "^29.4.11", + "ts-jest": "^29.4.12", "typescript": "^6.0.3" } } diff --git a/docs-site/package.json b/docs-site/package.json index fc2e9e41a..529d9b3b0 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -10,29 +10,29 @@ "validate": "node scripts/validate-frontmatter.mjs && node scripts/check-links.mjs" }, "dependencies": { - "@mdx-js/react": "^3.1.0", - "react": "^19.2.7", - "react-dom": "^19.2.7", - "react-router-dom": "^6.28.0" + "@mdx-js/react": "^3.1.1", + "react": "^19.2.8", + "react-dom": "^19.2.8", + "react-router-dom": "^6.30.4" }, "devDependencies": { - "@mdx-js/rollup": "^3.1.0", - "@shikijs/rehype": "^4.2.0", + "@mdx-js/rollup": "^3.1.1", + "@shikijs/rehype": "^4.3.1", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^6.0.2", - "ajv": "^8.17.0", + "@vitejs/plugin-react": "^6.0.4", + "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "gray-matter": "^4.0.3", - "mermaid": "^11.0.0", - "pagefind": "^1.1.0", - "rehype-autolink-headings": "^7.0.0", + "mermaid": "^11.16.0", + "pagefind": "^1.5.2", + "rehype-autolink-headings": "^7.1.0", "rehype-slug": "^6.0.0", "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "remark-mdx-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.1", + "remark-mdx-frontmatter": "^5.2.0", "typescript": "^6.0.3", - "vite": "^8.0.16", - "vite-react-ssg": "^0.9.0" + "vite": "^8.1.5", + "vite-react-ssg": "^0.9.2" } } diff --git a/docs-site/public/assets/asyncapi/authsocket/index.html b/docs-site/public/assets/asyncapi/authsocket/index.html index 8c146b83e..6df0e2af0 100644 --- a/docs-site/public/assets/asyncapi/authsocket/index.html +++ b/docs-site/public/assets/asyncapi/authsocket/index.html @@ -1,994 +1,1069 @@ - - - - - - AuthSocket WebSocket Protocol 1.0.0 documentation - - - - + + + + + + + AuthSocket WebSocket Protocol · AsyncAPI + - - -
AuthSocket WebSocket Protocol 1.0.0

AsyncAPI 3.0 specification for the AuthSocketServer / AuthSocket -WebSocket channel used by the BSV MessageBox Server.

-

Transport layer

-

AuthSocketServer wraps Socket.IO and sits on top of an HTTP server. + +

+
AsyncAPI 3.1.0 · specs/messaging/authsocket-asyncapi.yaml
+

AuthSocket WebSocket Protocol

v1.0.0
+
AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket` +WebSocket channel used by the BSV MessageBox Server. + +## Transport layer + +`AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server. All Socket.IO events are standard Socket.IO framing; this spec describes -the application-level event names and payload shapes that flow over the -Socket.IO connection.

-

BRC-103 mutual authentication

-

Every Socket.IO connection undergoes BRC-103 (Peer) handshake before +the *application-level* event names and payload shapes that flow over the +Socket.IO connection. + +## BRC-103 mutual authentication + +Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before application events are exchanged. The handshake is carried on the -authMessage event using the AuthMessage envelope defined in the -@bsv/sdk Transport interface.

-

Once the handshake succeeds the peer's identityKey (compressed secp256k1 +**`authMessage`** event using the `AuthMessage` envelope defined in the +`@bsv/sdk` `Transport` interface. + +Once the handshake succeeds the peer's `identityKey` (compressed secp256k1 public key, 66-char hex) is known server-side and stored in memory for the -lifetime of the connection.

-

Application events

-

After authentication the server emits and listens for the events described +lifetime of the connection. + +## Application events + +After authentication the server emits and listens for the events described below. All application payloads are serialized as JSON inside the -BRC-103 general message (Peer.toPeer). The transport layer -(SocketServerTransport) wraps them in an { eventName, data } envelope -before signing.

-

Source of truth:

-
    -
  • packages/messaging/authsocket/src/AuthSocketServer.ts
  • -
  • packages/messaging/authsocket/src/SocketServerTransport.ts
  • -
  • packages/messaging/message-box-server/src/index.ts
  • -
-

Servers

  • wss://messagebox.babbage.systems/wssproduction

    Production MessageBox WebSocket endpoint (Socket.IO over WSS).

    -
  • ws://localhost:{port}/wslocal

    Local development Socket.IO server.

    -
    object
    string
    required

    HTTP port the MessageBox Server listens on.

    -

Operations

  • RECEIVE authMessage

    Low-level Socket.IO event used by SocketServerTransport to carry -BRC-103 AuthMessage frames. This event is NOT an application event; -it is emitted and received transparently by the Peer class from -@bsv/sdk. Application developers do not interact with this channel -directly — they use the typed events below.

    -

    See packages/messaging/authsocket/src/SocketServerTransport.ts.

    -

    Server receives an AuthMessage frame from the client during BRC-103 handshake.

    Operation IDreceiveAuthMessage

    Available only on servers:

    Accepts the following message:

    BRC-103 auth frame (both directions — client and server).

    Message IDauthMessageFrame
    object

    BRC-103 auth envelope as defined in @bsv/sdk. Carried on the -low-level authMessage Socket.IO event. Not an application-level event.

    -

    Examples

  • SEND authMessage

    Low-level Socket.IO event used by SocketServerTransport to carry -BRC-103 AuthMessage frames. This event is NOT an application event; -it is emitted and received transparently by the Peer class from -@bsv/sdk. Application developers do not interact with this channel -directly — they use the typed events below.

    -

    See packages/messaging/authsocket/src/SocketServerTransport.ts.

    -

    Server sends an AuthMessage frame to the client during BRC-103 handshake.

    Operation IDsendAuthMessage

    Available only on servers:

    Accepts the following message:

    BRC-103 auth frame (both directions — client and server).

    Message IDauthMessageFrame
    object

    BRC-103 auth envelope as defined in @bsv/sdk. Carried on the -low-level authMessage Socket.IO event. Not an application-level event.

    -

    Examples

  • RECEIVE authenticated

    Fallback authentication event. The client emits this when its identity +BRC-103 `general` message (`Peer.toPeer`). The transport layer +(`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope +before signing. + +Source of truth: +- `packages/messaging/authsocket/src/AuthSocketServer.ts` +- `packages/messaging/authsocket/src/SocketServerTransport.ts` +- `packages/messaging/message-box-server/src/index.ts` +

    +
    2Servers16Channels17Operations0Messages18Schemas
    + + +
    +
    +

    Servers

    2
    +
    +

    production

    +

    wss://messagebox.babbage.systems/

    +
    Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    +
    host
    messagebox.babbage.systems
    pathname
    /
    protocol
    wss
    description
    Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    +
    +

    local

    +

    ws://localhost:{port}/

    +
    Local development Socket.IO server.
    +
    host
    localhost:{port}
    pathname
    /
    protocol
    ws
    description
    Local development Socket.IO server.
    variables
    1 field
    port
    2 fields
    default
    5001
    description
    HTTP port the MessageBox Server listens on.
    +
    +
    +

    Channels

    16
    +
    +

    authMessage

    +

    authMessage

    +
    Low-level Socket.IO event used by `SocketServerTransport` to carry +BRC-103 `AuthMessage` frames. This event is NOT an application event; +it is emitted and received transparently by the `Peer` class from +`@bsv/sdk`. Application developers do not interact with this channel +directly — they use the typed events below. + +See `packages/messaging/authsocket/src/SocketServerTransport.ts`. +
    +
    address
    authMessage
    description
    Low-level Socket.IO event used by `SocketServerTransport` to carry +BRC-103 `AuthMessage` frames. This event is NOT an application event; +it is emitted and received transparently by the `Peer` class from +`@bsv/sdk`. Application developers do not interact with this channel +directly — they use the typed events below. + +See `packages/messaging/authsocket/src/SocketServerTransport.ts`. +
    messages
    1 field
    authMessageFrame
    3 fields
    name
    authMessageFrame
    summary
    BRC-103 auth frame (both directions — client and server).
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage
    +
    +

    authenticated

    +

    authenticated

    +
    Fallback authentication event. The client emits this when its identity +key was not included in the Socket.IO handshake. The server validates +the key, updates its in-memory `authenticatedSockets` map, and emits +`authenticationSuccess` or `authenticationFailed` in response. +
    +
    address
    authenticated
    description
    Fallback authentication event. The client emits this when its identity key was not included in the Socket.IO handshake. The server validates -the key, updates its in-memory authenticatedSockets map, and emits -authenticationSuccess or authenticationFailed in response.

    -

    Server receives the client's identity key on the 'authenticated' event.

    Operation IDreceiveAuthenticated

    Available only on servers:

    Accepts the following message:

    Client sends its identity key for post-connection auth.

    Message IDauthenticateMessage
    object

    Sent by the client on the authenticated event when the identity key +the key, updates its in-memory `authenticatedSockets` map, and emits +`authenticationSuccess` or `authenticationFailed` in response. +

    messages
    1 field
    authenticateMessage
    3 fields
    name
    authenticateMessage
    summary
    Client sends its identity key for post-connection auth.
    payload
    1 field
    $ref
    #/components/schemas/AuthenticatePayload
    +
    +

    authenticationSuccess

    +

    authenticationSuccess

    +
    Emitted by the server after successful identity key validation.
    +
    address
    authenticationSuccess
    description
    Emitted by the server after successful identity key validation.
    messages
    1 field
    authSuccessMessage
    2 fields
    name
    authSuccessMessage
    payload
    1 field
    $ref
    #/components/schemas/AuthSuccessPayload
    +
    +

    authenticationFailed

    +

    authenticationFailed

    +
    Emitted by the server when identity key validation fails.
    +
    address
    authenticationFailed
    description
    Emitted by the server when identity key validation fails.
    messages
    1 field
    authFailedMessage
    2 fields
    name
    authFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/AuthFailedPayload
    +
    +

    joinRoom

    +

    joinRoom

    +
    Client requests to subscribe to a room. Only authenticated sockets may +join rooms. The server responds with `joinedRoom` on success or +`joinFailed` on error. + +Room ID convention: `<recipientIdentityKey>-<messageBoxType>`. +
    +
    address
    joinRoom
    description
    Client requests to subscribe to a room. Only authenticated sockets may +join rooms. The server responds with `joinedRoom` on success or +`joinFailed` on error. + +Room ID convention: `<recipientIdentityKey>-<messageBoxType>`. +
    messages
    1 field
    joinRoomMessage
    3 fields
    name
    joinRoomMessage
    summary
    Room ID string to join.
    payload
    1 field
    $ref
    #/components/schemas/JoinRoomPayload
    +
    +

    joinedRoom

    +

    joinedRoom

    +
    Server confirms the client has joined the specified room.
    +
    address
    joinedRoom
    description
    Server confirms the client has joined the specified room.
    messages
    1 field
    joinedRoomMessage
    2 fields
    name
    joinedRoomMessage
    payload
    1 field
    $ref
    #/components/schemas/JoinedRoomPayload
    +
    +

    joinFailed

    +

    joinFailed

    +
    Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    +
    address
    joinFailed
    description
    Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    messages
    1 field
    joinFailedMessage
    2 fields
    name
    joinFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/JoinFailedPayload
    +
    +

    leaveRoom

    +

    leaveRoom

    +
    Client requests to leave a room.
    +
    address
    leaveRoom
    description
    Client requests to leave a room.
    messages
    1 field
    leaveRoomMessage
    3 fields
    name
    leaveRoomMessage
    summary
    Room ID string to leave.
    payload
    1 field
    $ref
    #/components/schemas/LeaveRoomPayload
    +
    +

    leftRoom

    +

    leftRoom

    +
    Server confirms the client has left the room.
    +
    address
    leftRoom
    description
    Server confirms the client has left the room.
    messages
    1 field
    leftRoomMessage
    2 fields
    name
    leftRoomMessage
    payload
    1 field
    $ref
    #/components/schemas/LeftRoomPayload
    +
    +

    leaveFailed

    +

    leaveFailed

    +
    Emitted when `leaveRoom` fails.
    +
    address
    leaveFailed
    description
    Emitted when `leaveRoom` fails.
    messages
    1 field
    leaveFailedMessage
    2 fields
    name
    leaveFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/LeaveFailedPayload
    +
    +

    sendMessage

    +

    sendMessage

    +
    Client sends a message to a recipient via WebSocket. The server: +1. Validates the sender is authenticated. +2. Validates `roomId` and `message`. +3. Creates the message box if it does not exist. +4. Inserts the message into the database (with ON CONFLICT IGNORE dedup). +5. Emits `sendMessageAck-{roomId}` back to the sender. +6. Broadcasts `sendMessage-{roomId}` to all connections in the room. +
    +
    address
    sendMessage
    description
    Client sends a message to a recipient via WebSocket. The server: +1. Validates the sender is authenticated. +2. Validates `roomId` and `message`. +3. Creates the message box if it does not exist. +4. Inserts the message into the database (with ON CONFLICT IGNORE dedup). +5. Emits `sendMessageAck-{roomId}` back to the sender. +6. Broadcasts `sendMessage-{roomId}` to all connections in the room. +
    messages
    1 field
    sendMessageMessage
    2 fields
    name
    sendMessageMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessagePayload
    +
    +

    sendMessageAck

    +

    sendMessageAck-{roomId}

    +
    Per-room acknowledgement emitted to the sender only after the message +is stored. The event name is `sendMessageAck-<roomId>` where `roomId` +matches the value in the originating `sendMessage` payload. +
    +
    address
    sendMessageAck-{roomId}
    description
    Per-room acknowledgement emitted to the sender only after the message +is stored. The event name is `sendMessageAck-<roomId>` where `roomId` +matches the value in the originating `sendMessage` payload. +
    parameters
    1 field
    roomId
    1 field
    description
    The room ID from the originating sendMessage request.
    messages
    1 field
    sendMessageAckMessage
    2 fields
    name
    sendMessageAckMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessageAckPayload
    +
    +

    sendMessageBroadcast

    +

    sendMessage-{roomId}

    +
    Broadcast emitted to all connections subscribed to `roomId` after a +successful `sendMessage`. The event name is `sendMessage-<roomId>`. +
    +
    address
    sendMessage-{roomId}
    description
    Broadcast emitted to all connections subscribed to `roomId` after a +successful `sendMessage`. The event name is `sendMessage-<roomId>`. +
    parameters
    1 field
    roomId
    1 field
    description
    The target room ID.
    messages
    1 field
    sendMessageBroadcastMessage
    2 fields
    name
    sendMessageBroadcastMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessageBroadcastPayload
    +
    +

    messageFailed

    +

    messageFailed

    +
    Emitted to the sender when `sendMessage` processing fails.
    +
    address
    messageFailed
    description
    Emitted to the sender when `sendMessage` processing fails.
    messages
    1 field
    messageFailedMessage
    2 fields
    name
    messageFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/MessageFailedPayload
    +
    +

    paymentFailed

    +

    paymentFailed

    +
    Emitted to unauthenticated sockets that attempt to send a message +(same event name reused from older payment-gate logic). +
    +
    address
    paymentFailed
    description
    Emitted to unauthenticated sockets that attempt to send a message +(same event name reused from older payment-gate logic). +
    messages
    1 field
    paymentFailedMessage
    2 fields
    name
    paymentFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/PaymentFailedPayload
    +
    +

    disconnect

    +

    disconnect

    +
    Standard Socket.IO disconnect event. The server removes the socket from +the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`. +
    +
    address
    disconnect
    description
    Standard Socket.IO disconnect event. The server removes the socket from +the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`. +
    messages
    1 field
    disconnectMessage
    2 fields
    name
    disconnectMessage
    payload
    1 field
    $ref
    #/components/schemas/DisconnectPayload
    +
    +
+

Operations

17
+
+

receiveAuthMessage

+ receive +
Server receives an AuthMessage frame from the client during BRC-103 handshake.
+
action
receive
channel
1 field
$ref
#/channels/authMessage
summary
Server receives an AuthMessage frame from the client during BRC-103 handshake.
messages
1 item
  1. $ref
    #/channels/authMessage/messages/authMessageFrame
+
+

sendAuthMessage

+ send +
Server sends an AuthMessage frame to the client during BRC-103 handshake.
+
action
send
channel
1 field
$ref
#/channels/authMessage
summary
Server sends an AuthMessage frame to the client during BRC-103 handshake.
messages
1 item
  1. $ref
    #/channels/authMessage/messages/authMessageFrame
+
+

receiveAuthenticated

+ receive +
Server receives the client's identity key on the 'authenticated' event.
+
action
receive
channel
1 field
$ref
#/channels/authenticated
summary
Server receives the client's identity key on the 'authenticated' event.
messages
1 item
  1. $ref
    #/channels/authenticated/messages/authenticateMessage
+
+

sendAuthenticationSuccess

+ send +
Server confirms successful identity key validation.
+
action
send
channel
1 field
$ref
#/channels/authenticationSuccess
summary
Server confirms successful identity key validation.
messages
1 item
  1. $ref
    #/channels/authenticationSuccess/messages/authSuccessMessage
+
+

sendAuthenticationFailed

+ send +
Server rejects an invalid identity key.
+
action
send
channel
1 field
$ref
#/channels/authenticationFailed
summary
Server rejects an invalid identity key.
messages
1 item
  1. $ref
    #/channels/authenticationFailed/messages/authFailedMessage
+
+

receiveJoinRoom

+ receive +
Server receives a room join request.
+
action
receive
channel
1 field
$ref
#/channels/joinRoom
summary
Server receives a room join request.
messages
1 item
  1. $ref
    #/channels/joinRoom/messages/joinRoomMessage
+
+

sendJoinedRoom

+ send +
Server confirms room join.
+
action
send
channel
1 field
$ref
#/channels/joinedRoom
summary
Server confirms room join.
messages
1 item
  1. $ref
    #/channels/joinedRoom/messages/joinedRoomMessage
+
+

sendJoinFailed

+ send +
Server signals room join failure.
+
action
send
channel
1 field
$ref
#/channels/joinFailed
summary
Server signals room join failure.
messages
1 item
  1. $ref
    #/channels/joinFailed/messages/joinFailedMessage
+
+

receiveLeaveRoom

+ receive +
Server receives a room leave request.
+
action
receive
channel
1 field
$ref
#/channels/leaveRoom
summary
Server receives a room leave request.
messages
1 item
  1. $ref
    #/channels/leaveRoom/messages/leaveRoomMessage
+
+

sendLeftRoom

+ send +
Server confirms room leave.
+
action
send
channel
1 field
$ref
#/channels/leftRoom
summary
Server confirms room leave.
messages
1 item
  1. $ref
    #/channels/leftRoom/messages/leftRoomMessage
+
+

sendLeaveFailed

+ send +
Server signals room leave failure.
+
action
send
channel
1 field
$ref
#/channels/leaveFailed
summary
Server signals room leave failure.
messages
1 item
  1. $ref
    #/channels/leaveFailed/messages/leaveFailedMessage
+
+

receiveSendMessage

+ receive +
Server receives a message from the client to deliver to a recipient.
+
action
receive
channel
1 field
$ref
#/channels/sendMessage
summary
Server receives a message from the client to deliver to a recipient.
messages
1 item
  1. $ref
    #/channels/sendMessage/messages/sendMessageMessage
+
+

sendSendMessageAck

+ send +
Server acknowledges delivery of a message to the sender.
+
action
send
channel
1 field
$ref
#/channels/sendMessageAck
summary
Server acknowledges delivery of a message to the sender.
messages
1 item
  1. $ref
    #/channels/sendMessageAck/messages/sendMessageAckMessage
+
+

sendSendMessageBroadcast

+ send +
Server broadcasts a new message to all room subscribers.
+
action
send
channel
1 field
$ref
#/channels/sendMessageBroadcast
summary
Server broadcasts a new message to all room subscribers.
messages
1 item
  1. $ref
    #/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage
+
+

sendMessageFailed

+ send +
Server signals message delivery failure.
+
action
send
channel
1 field
$ref
#/channels/messageFailed
summary
Server signals message delivery failure.
messages
1 item
  1. $ref
    #/channels/messageFailed/messages/messageFailedMessage
+
+

sendPaymentFailed

+ send +
Server signals auth/payment gate rejection.
+
action
send
channel
1 field
$ref
#/channels/paymentFailed
summary
Server signals auth/payment gate rejection.
messages
1 item
  1. $ref
    #/channels/paymentFailed/messages/paymentFailedMessage
+
+

receiveDisconnect

+ receive +
Client disconnects; server cleans up in-memory state.
+
action
receive
channel
1 field
$ref
#/channels/disconnect
summary
Client disconnects; server cleans up in-memory state.
messages
1 item
  1. $ref
    #/channels/disconnect/messages/disconnectMessage
+
+
+

Schemas

18
+
+

PubKeyHex

+ +
Compressed secp256k1 public key, 66 hex characters.
+
type
string
pattern
^0[23][0-9a-fA-F]{64}$
description
Compressed secp256k1 public key, 66 hex characters.
+
+

AuthMessage

+ +
BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the +low-level `authMessage` Socket.IO event. Not an application-level event. +
+
type
object
description
BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the +low-level `authMessage` Socket.IO event. Not an application-level event. +
required
3 items
  1. messageType
  2. version
  3. identityKey
properties
9 fields
messageType
3 fields
type
string
enum
3 items
  1. initialRequest
  2. initialResponse
  3. general
description
- `initialRequest` — first handshake message from initiating peer +- `initialResponse` — server's challenge response (includes nonce, signature) +- `general` — signed application payload after handshake +
version
2 fields
type
string
description
Auth protocol version string.
identityKey
1 field
$ref
#/components/schemas/PubKeyHex
nonce
2 fields
type
string
description
Fresh random nonce (base64) generated by the sender.
yourNonce
2 fields
type
string
description
Echo of the peer's nonce from the previous message.
initialNonce
2 fields
type
string
description
Present in `initialRequest`; absent in subsequent messages.
payload
3 fields
type
array
items
1 field
type
integer
description
Signed application payload (byte array). Empty for handshake messages.
signature
3 fields
type
array
items
1 field
type
integer
description
DER-encoded ECDSA signature over the payload.
requestedCertificates
3 fields
type
object
description
Optional certificate request set (BRC-52 format).
additionalProperties
true
+
+

EventEnvelope

+ +
Application-level wrapper JSON-encoded inside the BRC-103 `general` +message payload. The `SocketServerTransport` encodes/decodes this +transparently; application code only sees `eventName` and `data`. +
+
type
object
description
Application-level wrapper JSON-encoded inside the BRC-103 `general` +message payload. The `SocketServerTransport` encodes/decodes this +transparently; application code only sees `eventName` and `data`. +
required
2 items
  1. eventName
  2. data
properties
2 fields
eventName
2 fields
type
string
description
The Socket.IO event name.
data
1 field
description
The event-specific payload.
+
+

AuthenticatePayload

+ +
Sent by the client on the `authenticated` event when the identity key was not available at connection time (fallback path). The server validates -the key and responds with authenticationSuccess or authenticationFailed.

-

Examples

  • SEND authenticationSuccess

    Emitted by the server after successful identity key validation.

    -

    Server confirms successful identity key validation.

    Operation IDsendAuthenticationSuccess

    Available only on servers:

    Accepts the following message:

    Message IDauthSuccessMessage
    object

    Examples

  • SEND authenticationFailed

    Emitted by the server when identity key validation fails.

    -

    Server rejects an invalid identity key.

    Operation IDsendAuthenticationFailed

    Available only on servers:

    Accepts the following message:

    Message IDauthFailedMessage
    object

    Examples

  • RECEIVE joinRoom

    Client requests to subscribe to a room. Only authenticated sockets may -join rooms. The server responds with joinedRoom on success or -joinFailed on error.

    -

    Room ID convention: <recipientIdentityKey>-<messageBoxType>.

    -

    Server receives a room join request.

    Operation IDreceiveJoinRoom

    Available only on servers:

    Accepts the following message:

    Room ID string to join.

    Message IDjoinRoomMessage
    Payloadstring

    The room ID string sent by the client on the joinRoom event. -Room IDs use the convention <recipientKey>-<messageBoxType>. -Example: 028d37b9...-payment_inbox.

    -

    Examples

  • SEND joinedRoom

    Server confirms the client has joined the specified room.

    -

    Server confirms room join.

    Operation IDsendJoinedRoom

    Available only on servers:

    Accepts the following message:

    Message IDjoinedRoomMessage
    object

    Examples

  • SEND joinFailed

    Emitted when joinRoom fails (unauthenticated or invalid roomId).

    -

    Server signals room join failure.

    Operation IDsendJoinFailed

    Available only on servers:

    Accepts the following message:

    Message IDjoinFailedMessage
    object

    Examples

  • RECEIVE leaveRoom

    Client requests to leave a room.

    -

    Server receives a room leave request.

    Operation IDreceiveLeaveRoom

    Available only on servers:

    Accepts the following message:

    Room ID string to leave.

    Message IDleaveRoomMessage
    Payloadstring

    The room ID string sent by the client on the leaveRoom event.

    -

    Examples

  • SEND leftRoom

    Server confirms the client has left the room.

    -

    Server confirms room leave.

    Operation IDsendLeftRoom

    Available only on servers:

    Accepts the following message:

    Message IDleftRoomMessage
    object

    Examples

  • SEND leaveFailed

    Emitted when leaveRoom fails.

    -

    Server signals room leave failure.

    Operation IDsendLeaveFailed

    Available only on servers:

    Accepts the following message:

    Message IDleaveFailedMessage
    object

    Examples

  • RECEIVE sendMessage

    Client sends a message to a recipient via WebSocket. The server:

    -
      -
    1. Validates the sender is authenticated.
    2. -
    3. Validates roomId and message.
    4. -
    5. Creates the message box if it does not exist.
    6. -
    7. Inserts the message into the database (with ON CONFLICT IGNORE dedup).
    8. -
    9. Emits sendMessageAck-{roomId} back to the sender.
    10. -
    11. Broadcasts sendMessage-{roomId} to all connections in the room.
    12. -
    -

    Server receives a message from the client to deliver to a recipient.

    Operation IDreceiveSendMessage

    Available only on servers:

    Accepts the following message:

    Message IDsendMessageMessage
    object

    Payload for the client-to-server sendMessage event.

    -

    Examples

  • SEND sendMessageAck-{roomId}

    Per-room acknowledgement emitted to the sender only after the message -is stored. The event name is sendMessageAck-<roomId> where roomId -matches the value in the originating sendMessage payload.

    -

    Server acknowledges delivery of a message to the sender.

    Operation IDsendSendMessageAck

    Available only on servers:

    object
    roomIdstring
    required

    The room ID from the originating sendMessage request.

    -

    Accepts the following message:

    Message IDsendMessageAckMessage
    object

    Acknowledgement emitted by the server on sendMessageAck-{roomId} after -a successful sendMessage. Note: the event name is dynamic and includes -the room ID used in the originating request.

    -

    Examples

  • SEND sendMessage-{roomId}

    Broadcast emitted to all connections subscribed to roomId after a -successful sendMessage. The event name is sendMessage-<roomId>.

    -

    Server broadcasts a new message to all room subscribers.

    Operation IDsendSendMessageBroadcast

    Available only on servers:

    object
    roomIdstring
    required

    The target room ID.

    -

    Accepts the following message:

    Message IDsendMessageBroadcastMessage
    object

    Broadcast emitted by the server on sendMessage-{roomId} to all -connections in the room (including the sender). Note: the event name -is dynamic.

    -

    Examples

  • SEND messageFailed

    Emitted to the sender when sendMessage processing fails.

    -

    Server signals message delivery failure.

    Operation IDsendMessageFailed

    Available only on servers:

    Accepts the following message:

    Message IDmessageFailedMessage
    object

    Examples

  • SEND paymentFailed

    Emitted to unauthenticated sockets that attempt to send a message -(same event name reused from older payment-gate logic).

    -

    Server signals auth/payment gate rejection.

    Operation IDsendPaymentFailed

    Available only on servers:

    Accepts the following message:

    Message IDpaymentFailedMessage
    object

    Examples

  • RECEIVE disconnect

    Standard Socket.IO disconnect event. The server removes the socket from -the authenticatedSockets map and the peers map in AuthSocketServer.

    -

    Client disconnects; server cleans up in-memory state.

    Operation IDreceiveDisconnect

    Available only on servers:

    Accepts the following message:

    Message IDdisconnectMessage
    Payloadstring

    The Socket.IO disconnect reason string (e.g. transport close, -server namespace disconnect).

    -

    Examples

  • Schemas

    - - - - - - \ No newline at end of file +is dynamic. +
    required
    3 items
    1. sender
    2. messageId
    3. body
    properties
    3 fields
    sender
    1 field
    $ref
    #/components/schemas/PubKeyHex
    messageId
    1 field
    type
    string
    body
    1 field
    type
    string
    +
    +

    MessageFailedPayload

    + + +
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string
    +
    +

    PaymentFailedPayload

    + + +
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string
    +
    +

    DisconnectPayload

    + +
    The Socket.IO disconnect reason string (e.g. `transport close`, +`server namespace disconnect`). +
    +
    type
    string
    description
    The Socket.IO disconnect reason string (e.g. `transport close`, +`server namespace disconnect`). +
    +
    + +
    + Raw YAML source +
    asyncapi: "3.1.0"
    +
    +info:
    +  title: AuthSocket WebSocket Protocol
    +  version: "1.0.0"
    +  description: |
    +    AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket`
    +    WebSocket channel used by the BSV MessageBox Server.
    +
    +    ## Transport layer
    +
    +    `AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server.
    +    All Socket.IO events are standard Socket.IO framing; this spec describes
    +    the *application-level* event names and payload shapes that flow over the
    +    Socket.IO connection.
    +
    +    ## BRC-103 mutual authentication
    +
    +    Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before
    +    application events are exchanged. The handshake is carried on the
    +    **`authMessage`** event using the `AuthMessage` envelope defined in the
    +    `@bsv/sdk` `Transport` interface.
    +
    +    Once the handshake succeeds the peer's `identityKey` (compressed secp256k1
    +    public key, 66-char hex) is known server-side and stored in memory for the
    +    lifetime of the connection.
    +
    +    ## Application events
    +
    +    After authentication the server emits and listens for the events described
    +    below. All application payloads are serialized as JSON inside the
    +    BRC-103 `general` message (`Peer.toPeer`). The transport layer
    +    (`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope
    +    before signing.
    +
    +    Source of truth:
    +    - `packages/messaging/authsocket/src/AuthSocketServer.ts`
    +    - `packages/messaging/authsocket/src/SocketServerTransport.ts`
    +    - `packages/messaging/message-box-server/src/index.ts`
    +
    +servers:
    +  production:
    +    host: "messagebox.babbage.systems"
    +    pathname: "/"
    +    protocol: wss
    +    description: Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    +  local:
    +    host: "localhost:{port}"
    +    pathname: "/"
    +    protocol: ws
    +    description: Local development Socket.IO server.
    +    variables:
    +      port:
    +        default: "5001"
    +        description: HTTP port the MessageBox Server listens on.
    +
    +# ---------------------------------------------------------------------------
    +# Components
    +# ---------------------------------------------------------------------------
    +components:
    +  schemas:
    +    PubKeyHex:
    +      type: string
    +      pattern: "^0[23][0-9a-fA-F]{64}$"
    +      description: Compressed secp256k1 public key, 66 hex characters.
    +
    +    AuthMessage:
    +      type: object
    +      description: |
    +        BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the
    +        low-level `authMessage` Socket.IO event. Not an application-level event.
    +      required: [messageType, version, identityKey]
    +      properties:
    +        messageType:
    +          type: string
    +          enum: [initialRequest, initialResponse, general]
    +          description: |
    +            - `initialRequest`  — first handshake message from initiating peer
    +            - `initialResponse` — server's challenge response (includes nonce, signature)
    +            - `general`         — signed application payload after handshake
    +        version:
    +          type: string
    +          description: Auth protocol version string.
    +        identityKey:
    +          $ref: "#/components/schemas/PubKeyHex"
    +        nonce:
    +          type: string
    +          description: Fresh random nonce (base64) generated by the sender.
    +        yourNonce:
    +          type: string
    +          description: Echo of the peer's nonce from the previous message.
    +        initialNonce:
    +          type: string
    +          description: Present in `initialRequest`; absent in subsequent messages.
    +        payload:
    +          type: array
    +          items:
    +            type: integer
    +          description: Signed application payload (byte array). Empty for handshake messages.
    +        signature:
    +          type: array
    +          items:
    +            type: integer
    +          description: DER-encoded ECDSA signature over the payload.
    +        requestedCertificates:
    +          type: object
    +          description: Optional certificate request set (BRC-52 format).
    +          additionalProperties: true
    +
    +    EventEnvelope:
    +      type: object
    +      description: |
    +        Application-level wrapper JSON-encoded inside the BRC-103 `general`
    +        message payload. The `SocketServerTransport` encodes/decodes this
    +        transparently; application code only sees `eventName` and `data`.
    +      required: [eventName, data]
    +      properties:
    +        eventName:
    +          type: string
    +          description: The Socket.IO event name.
    +        data:
    +          description: The event-specific payload.
    +
    +    # ----- Authentication flow -----
    +    AuthenticatePayload:
    +      type: object
    +      description: |
    +        Sent by the client on the `authenticated` event when the identity key
    +        was not available at connection time (fallback path). The server validates
    +        the key and responds with `authenticationSuccess` or `authenticationFailed`.
    +      properties:
    +        identityKey:
    +          $ref: "#/components/schemas/PubKeyHex"
    +
    +    AuthSuccessPayload:
    +      type: object
    +      required: [status]
    +      properties:
    +        status:
    +          type: string
    +          enum: [success]
    +
    +    AuthFailedPayload:
    +      type: object
    +      required: [reason]
    +      properties:
    +        reason:
    +          type: string
    +          description: Human-readable reason for failure.
    +
    +    # ----- Room management -----
    +    JoinRoomPayload:
    +      type: string
    +      description: |
    +        The room ID string sent by the client on the `joinRoom` event.
    +        Room IDs use the convention `<recipientKey>-<messageBoxType>`.
    +        Example: `028d37b9...-payment_inbox`.
    +
    +    JoinedRoomPayload:
    +      type: object
    +      required: [roomId]
    +      properties:
    +        roomId:
    +          type: string
    +
    +    JoinFailedPayload:
    +      type: object
    +      required: [reason]
    +      properties:
    +        reason:
    +          type: string
    +
    +    LeaveRoomPayload:
    +      type: string
    +      description: The room ID string sent by the client on the `leaveRoom` event.
    +
    +    LeftRoomPayload:
    +      type: object
    +      required: [roomId]
    +      properties:
    +        roomId:
    +          type: string
    +
    +    LeaveFailedPayload:
    +      type: object
    +      required: [reason]
    +      properties:
    +        reason:
    +          type: string
    +
    +    # ----- Message sending -----
    +    WsSendMessagePayload:
    +      type: object
    +      description: Payload for the client-to-server `sendMessage` event.
    +      required: [roomId, message]
    +      properties:
    +        roomId:
    +          type: string
    +          description: |
    +            Target room. Format: `<recipientKey>-<messageBoxType>`.
    +            The server extracts the `messageBoxType` by splitting on `-` and
    +            taking the second part; it uses the authenticated sender key from
    +            `authenticatedSockets`.
    +        message:
    +          type: object
    +          required: [messageId, recipient, body]
    +          properties:
    +            messageId:
    +              type: string
    +              description: Unique identifier for this message (deduplication key).
    +            recipient:
    +              $ref: "#/components/schemas/PubKeyHex"
    +            body:
    +              type: string
    +              description: Message body string.
    +
    +    WsSendMessageAckPayload:
    +      type: object
    +      description: |
    +        Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after
    +        a successful `sendMessage`. Note: the event name is dynamic and includes
    +        the room ID used in the originating request.
    +      required: [status, messageId]
    +      properties:
    +        status:
    +          type: string
    +          enum: [success]
    +        messageId:
    +          type: string
    +
    +    WsSendMessageBroadcastPayload:
    +      type: object
    +      description: |
    +        Broadcast emitted by the server on `sendMessage-{roomId}` to all
    +        connections in the room (including the sender). Note: the event name
    +        is dynamic.
    +      required: [sender, messageId, body]
    +      properties:
    +        sender:
    +          $ref: "#/components/schemas/PubKeyHex"
    +        messageId:
    +          type: string
    +        body:
    +          type: string
    +
    +    MessageFailedPayload:
    +      type: object
    +      required: [reason]
    +      properties:
    +        reason:
    +          type: string
    +
    +    PaymentFailedPayload:
    +      type: object
    +      required: [reason]
    +      properties:
    +        reason:
    +          type: string
    +
    +    DisconnectPayload:
    +      type: string
    +      description: |
    +        The Socket.IO disconnect reason string (e.g. `transport close`,
    +        `server namespace disconnect`).
    +
    +# ---------------------------------------------------------------------------
    +# Channels
    +# ---------------------------------------------------------------------------
    +channels:
    +
    +  # -------- Low-level auth handshake (BRC-103 / Peer transport) --------
    +  authMessage:
    +    address: authMessage
    +    description: |
    +      Low-level Socket.IO event used by `SocketServerTransport` to carry
    +      BRC-103 `AuthMessage` frames. This event is NOT an application event;
    +      it is emitted and received transparently by the `Peer` class from
    +      `@bsv/sdk`. Application developers do not interact with this channel
    +      directly — they use the typed events below.
    +
    +      See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
    +    messages:
    +      authMessageFrame:
    +        name: authMessageFrame
    +        summary: BRC-103 auth frame (both directions — client and server).
    +        payload:
    +          $ref: "#/components/schemas/AuthMessage"
    +
    +  # -------- Application authentication --------
    +  authenticated:
    +    address: authenticated
    +    description: |
    +      Fallback authentication event. The client emits this when its identity
    +      key was not included in the Socket.IO handshake. The server validates
    +      the key, updates its in-memory `authenticatedSockets` map, and emits
    +      `authenticationSuccess` or `authenticationFailed` in response.
    +    messages:
    +      authenticateMessage:
    +        name: authenticateMessage
    +        summary: Client sends its identity key for post-connection auth.
    +        payload:
    +          $ref: "#/components/schemas/AuthenticatePayload"
    +
    +  authenticationSuccess:
    +    address: authenticationSuccess
    +    description: Emitted by the server after successful identity key validation.
    +    messages:
    +      authSuccessMessage:
    +        name: authSuccessMessage
    +        payload:
    +          $ref: "#/components/schemas/AuthSuccessPayload"
    +
    +  authenticationFailed:
    +    address: authenticationFailed
    +    description: Emitted by the server when identity key validation fails.
    +    messages:
    +      authFailedMessage:
    +        name: authFailedMessage
    +        payload:
    +          $ref: "#/components/schemas/AuthFailedPayload"
    +
    +  # -------- Room management --------
    +  joinRoom:
    +    address: joinRoom
    +    description: |
    +      Client requests to subscribe to a room. Only authenticated sockets may
    +      join rooms. The server responds with `joinedRoom` on success or
    +      `joinFailed` on error.
    +
    +      Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
    +    messages:
    +      joinRoomMessage:
    +        name: joinRoomMessage
    +        summary: Room ID string to join.
    +        payload:
    +          $ref: "#/components/schemas/JoinRoomPayload"
    +
    +  joinedRoom:
    +    address: joinedRoom
    +    description: Server confirms the client has joined the specified room.
    +    messages:
    +      joinedRoomMessage:
    +        name: joinedRoomMessage
    +        payload:
    +          $ref: "#/components/schemas/JoinedRoomPayload"
    +
    +  joinFailed:
    +    address: joinFailed
    +    description: Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    +    messages:
    +      joinFailedMessage:
    +        name: joinFailedMessage
    +        payload:
    +          $ref: "#/components/schemas/JoinFailedPayload"
    +
    +  leaveRoom:
    +    address: leaveRoom
    +    description: Client requests to leave a room.
    +    messages:
    +      leaveRoomMessage:
    +        name: leaveRoomMessage
    +        summary: Room ID string to leave.
    +        payload:
    +          $ref: "#/components/schemas/LeaveRoomPayload"
    +
    +  leftRoom:
    +    address: leftRoom
    +    description: Server confirms the client has left the room.
    +    messages:
    +      leftRoomMessage:
    +        name: leftRoomMessage
    +        payload:
    +          $ref: "#/components/schemas/LeftRoomPayload"
    +
    +  leaveFailed:
    +    address: leaveFailed
    +    description: Emitted when `leaveRoom` fails.
    +    messages:
    +      leaveFailedMessage:
    +        name: leaveFailedMessage
    +        payload:
    +          $ref: "#/components/schemas/LeaveFailedPayload"
    +
    +  # -------- Message sending --------
    +  sendMessage:
    +    address: sendMessage
    +    description: |
    +      Client sends a message to a recipient via WebSocket. The server:
    +      1. Validates the sender is authenticated.
    +      2. Validates `roomId` and `message`.
    +      3. Creates the message box if it does not exist.
    +      4. Inserts the message into the database (with ON CONFLICT IGNORE dedup).
    +      5. Emits `sendMessageAck-{roomId}` back to the sender.
    +      6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
    +    messages:
    +      sendMessageMessage:
    +        name: sendMessageMessage
    +        payload:
    +          $ref: "#/components/schemas/WsSendMessagePayload"
    +
    +  sendMessageAck:
    +    address: "sendMessageAck-{roomId}"
    +    description: |
    +      Per-room acknowledgement emitted to the sender only after the message
    +      is stored. The event name is `sendMessageAck-<roomId>` where `roomId`
    +      matches the value in the originating `sendMessage` payload.
    +    parameters:
    +      roomId:
    +        description: The room ID from the originating sendMessage request.
    +    messages:
    +      sendMessageAckMessage:
    +        name: sendMessageAckMessage
    +        payload:
    +          $ref: "#/components/schemas/WsSendMessageAckPayload"
    +
    +  sendMessageBroadcast:
    +    address: "sendMessage-{roomId}"
    +    description: |
    +      Broadcast emitted to all connections subscribed to `roomId` after a
    +      successful `sendMessage`. The event name is `sendMessage-<roomId>`.
    +    parameters:
    +      roomId:
    +        description: The target room ID.
    +    messages:
    +      sendMessageBroadcastMessage:
    +        name: sendMessageBroadcastMessage
    +        payload:
    +          $ref: "#/components/schemas/WsSendMessageBroadcastPayload"
    +
    +  messageFailed:
    +    address: messageFailed
    +    description: Emitted to the sender when `sendMessage` processing fails.
    +    messages:
    +      messageFailedMessage:
    +        name: messageFailedMessage
    +        payload:
    +          $ref: "#/components/schemas/MessageFailedPayload"
    +
    +  paymentFailed:
    +    address: paymentFailed
    +    description: |
    +      Emitted to unauthenticated sockets that attempt to send a message
    +      (same event name reused from older payment-gate logic).
    +    messages:
    +      paymentFailedMessage:
    +        name: paymentFailedMessage
    +        payload:
    +          $ref: "#/components/schemas/PaymentFailedPayload"
    +
    +  # -------- Lifecycle --------
    +  disconnect:
    +    address: disconnect
    +    description: |
    +      Standard Socket.IO disconnect event. The server removes the socket from
    +      the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
    +    messages:
    +      disconnectMessage:
    +        name: disconnectMessage
    +        payload:
    +          $ref: "#/components/schemas/DisconnectPayload"
    +
    +# ---------------------------------------------------------------------------
    +# Operations
    +# ---------------------------------------------------------------------------
    +operations:
    +
    +  # --- Auth handshake (transport-level, both directions) ---
    +  receiveAuthMessage:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/authMessage"
    +    summary: Server receives an AuthMessage frame from the client during BRC-103 handshake.
    +    messages:
    +      - $ref: "#/channels/authMessage/messages/authMessageFrame"
    +
    +  sendAuthMessage:
    +    action: send
    +    channel:
    +      $ref: "#/channels/authMessage"
    +    summary: Server sends an AuthMessage frame to the client during BRC-103 handshake.
    +    messages:
    +      - $ref: "#/channels/authMessage/messages/authMessageFrame"
    +
    +  # --- Client authentication ---
    +  receiveAuthenticated:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/authenticated"
    +    summary: Server receives the client's identity key on the 'authenticated' event.
    +    messages:
    +      - $ref: "#/channels/authenticated/messages/authenticateMessage"
    +
    +  sendAuthenticationSuccess:
    +    action: send
    +    channel:
    +      $ref: "#/channels/authenticationSuccess"
    +    summary: Server confirms successful identity key validation.
    +    messages:
    +      - $ref: "#/channels/authenticationSuccess/messages/authSuccessMessage"
    +
    +  sendAuthenticationFailed:
    +    action: send
    +    channel:
    +      $ref: "#/channels/authenticationFailed"
    +    summary: Server rejects an invalid identity key.
    +    messages:
    +      - $ref: "#/channels/authenticationFailed/messages/authFailedMessage"
    +
    +  # --- Room management ---
    +  receiveJoinRoom:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/joinRoom"
    +    summary: Server receives a room join request.
    +    messages:
    +      - $ref: "#/channels/joinRoom/messages/joinRoomMessage"
    +
    +  sendJoinedRoom:
    +    action: send
    +    channel:
    +      $ref: "#/channels/joinedRoom"
    +    summary: Server confirms room join.
    +    messages:
    +      - $ref: "#/channels/joinedRoom/messages/joinedRoomMessage"
    +
    +  sendJoinFailed:
    +    action: send
    +    channel:
    +      $ref: "#/channels/joinFailed"
    +    summary: Server signals room join failure.
    +    messages:
    +      - $ref: "#/channels/joinFailed/messages/joinFailedMessage"
    +
    +  receiveLeaveRoom:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/leaveRoom"
    +    summary: Server receives a room leave request.
    +    messages:
    +      - $ref: "#/channels/leaveRoom/messages/leaveRoomMessage"
    +
    +  sendLeftRoom:
    +    action: send
    +    channel:
    +      $ref: "#/channels/leftRoom"
    +    summary: Server confirms room leave.
    +    messages:
    +      - $ref: "#/channels/leftRoom/messages/leftRoomMessage"
    +
    +  sendLeaveFailed:
    +    action: send
    +    channel:
    +      $ref: "#/channels/leaveFailed"
    +    summary: Server signals room leave failure.
    +    messages:
    +      - $ref: "#/channels/leaveFailed/messages/leaveFailedMessage"
    +
    +  # --- Message sending ---
    +  receiveSendMessage:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/sendMessage"
    +    summary: Server receives a message from the client to deliver to a recipient.
    +    messages:
    +      - $ref: "#/channels/sendMessage/messages/sendMessageMessage"
    +
    +  sendSendMessageAck:
    +    action: send
    +    channel:
    +      $ref: "#/channels/sendMessageAck"
    +    summary: Server acknowledges delivery of a message to the sender.
    +    messages:
    +      - $ref: "#/channels/sendMessageAck/messages/sendMessageAckMessage"
    +
    +  sendSendMessageBroadcast:
    +    action: send
    +    channel:
    +      $ref: "#/channels/sendMessageBroadcast"
    +    summary: Server broadcasts a new message to all room subscribers.
    +    messages:
    +      - $ref: "#/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage"
    +
    +  sendMessageFailed:
    +    action: send
    +    channel:
    +      $ref: "#/channels/messageFailed"
    +    summary: Server signals message delivery failure.
    +    messages:
    +      - $ref: "#/channels/messageFailed/messages/messageFailedMessage"
    +
    +  sendPaymentFailed:
    +    action: send
    +    channel:
    +      $ref: "#/channels/paymentFailed"
    +    summary: Server signals auth/payment gate rejection.
    +    messages:
    +      - $ref: "#/channels/paymentFailed/messages/paymentFailedMessage"
    +
    +  # --- Lifecycle ---
    +  receiveDisconnect:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/disconnect"
    +    summary: Client disconnects; server cleans up in-memory state.
    +    messages:
    +      - $ref: "#/channels/disconnect/messages/disconnectMessage"
    +
    +
    + + + + diff --git a/docs-site/public/assets/asyncapi/brc29/index.html b/docs-site/public/assets/asyncapi/brc29/index.html index ee7f6ffb7..94a49e174 100644 --- a/docs-site/public/assets/asyncapi/brc29/index.html +++ b/docs-site/public/assets/asyncapi/brc29/index.html @@ -1,471 +1,529 @@ - - - - - - BRC-29 Simple Authenticated BSV P2PKH Payment Protocol 1.0.0 documentation - - - - + + + + + + + BRC-29 Simple Authenticated BSV P2PKH Payment Protocol · AsyncAPI + - - -
    BRC-29 Simple Authenticated BSV P2PKH Payment Protocol 1.0.0

    Specifies the peer-to-peer payment flow defined in BRC-29, including + +

    +
    AsyncAPI 3.1.0 · specs/payments/brc29-payment-protocol.yaml
    +

    BRC-29 Simple Authenticated BSV P2PKH Payment Protocol

    v1.0.0
    +
    Specifies the peer-to-peer payment flow defined in BRC-29, including BRC-42 key derivation prefix/suffix negotiation, the current Atomic BEEF -payment message, and the BRC-100 internalizeAction remittance envelope.

    -

    The older BRC-8 extended-envelope format (the transactions array) is +payment message, and the BRC-100 internalizeAction remittance envelope. + +The older BRC-8 extended-envelope format (the `transactions` array) is deprecated for new integrations; only the current BRC-100 / Atomic BEEF -transport is modelled here.

    -

    Source of truth: /docs/BRCs/payments/0029.md

    -

    Operations

    • SEND payment/send

      Logical channel representing a sender delivering a BRC-29 payment message +transport is modelled here. + +Source of truth: /docs/BRCs/payments/0029.md +

      +
      0Servers2Channels2Operations2Messages8Schemas
      + + +
      +
      +

      Channels

      2
      +
      +

      paymentSend

      +

      payment/send

      +
      Logical channel representing a sender delivering a BRC-29 payment message +to a recipient. In practice this is carried over whatever higher-level +transport the application chooses (HTTP POST, WebSocket, BRC-104 message +box, etc.). The channel models the one-way delivery of the payment. +
      +
      address
      payment/send
      description
      Logical channel representing a sender delivering a BRC-29 payment message to a recipient. In practice this is carried over whatever higher-level transport the application chooses (HTTP POST, WebSocket, BRC-104 message -box, etc.). The channel models the one-way delivery of the payment.

      -

      Sender delivers a BRC-29 payment message to the recipient.

      Operation IDsendPayment

      Accepts the following message:

      BRC-29 Payment Message

      Current (BRC-100 / Atomic BEEF) payment message sent from the payer to +box, etc.). The channel models the one-way delivery of the payment. +

      messages
      1 field
      paymentMessage
      1 field
      $ref
      #/components/messages/PaymentMessage
      +
      +

      paymentAcknowledge

      +

      payment/acknowledge

      +
      Logical channel representing the recipient acknowledging acceptance or +rejection of the incoming payment after calling internalizeAction. +
      +
      address
      payment/acknowledge
      description
      Logical channel representing the recipient acknowledging acceptance or +rejection of the incoming payment after calling internalizeAction. +
      messages
      1 field
      paymentAck
      1 field
      $ref
      #/components/messages/PaymentAck
      +
      +
    +

    Operations

    2
    +
    +

    sendPayment

    + send +
    Sender delivers a BRC-29 payment message to the recipient.
    +
    action
    send
    channel
    1 field
    $ref
    #/channels/paymentSend
    summary
    Sender delivers a BRC-29 payment message to the recipient.
    messages
    1 item
    1. $ref
      #/channels/paymentSend/messages/paymentMessage
    +
    +

    receiveAck

    + receive +
    Sender receives payment acceptance or rejection from the recipient.
    +
    action
    receive
    channel
    1 field
    $ref
    #/channels/paymentAcknowledge
    summary
    Sender receives payment acceptance or rejection from the recipient.
    messages
    1 item
    1. $ref
      #/channels/paymentAcknowledge/messages/paymentAck
    +
    +
    +

    Messages

    2
    +
    +

    PaymentMessage

    + +
    Current (BRC-100 / Atomic BEEF) payment message sent from the payer to the payee. Carries one transaction with one or more P2PKH outputs derived via BRC-42 key derivation using the invoice number format `2-3241645161d8-<derivationPrefix> <derivationSuffix>`. -

    Message IDpaymentMessage
    object

    Payment message delivered from sender to recipient. The transaction -field carries a base64-encoded Atomic BEEF blob (BRC-95). For payments -containing multiple outputs each output MUST carry its own -derivationSuffix and outputIndex so the recipient can recover the -correct P2PKH private key for each UTXO.

    -

    Examples

  • RECEIVE payment/acknowledge

    Logical channel representing the recipient acknowledging acceptance or -rejection of the incoming payment after calling internalizeAction.

    -

    Sender receives payment acceptance or rejection from the recipient.

    Operation IDreceiveAck

    Accepts the following message:

    Payment Acknowledgement

    Informal acknowledgement returned by the recipient after calling -BRC-100 internalizeAction. No mandatory wire format is defined by -BRC-29; the shape below is the conventional minimal envelope. -

    Message IDpaymentAck
    object

    Minimal response returned to the sender after the recipient has called -internalizeAction. BRC-29 does not mandate a wire format; this is -the conventional shape used by ts-sdk integrations.

    -

    Examples

  • Messages

    +

    Schemas

    8
    +
    +

    PaymentMessage

    + +
    Payment message delivered from sender to recipient. The `transaction` field carries a base64-encoded Atomic BEEF blob (BRC-95). For payments containing multiple outputs each output MUST carry its own derivationSuffix and outputIndex so the recipient can recover the -correct P2PKH private key for each UTXO.

    -
  • #2Payment Acknowledgement

    Informal acknowledgement returned by the recipient after calling -BRC-100 internalizeAction. No mandatory wire format is defined by -BRC-29; the shape below is the conventional minimal envelope. -

    Message IDPaymentAck
    object

    Minimal response returned to the sender after the recipient has called -internalizeAction. BRC-29 does not mandate a wire format; this is -the conventional shape used by ts-sdk integrations.

    -
  • Schemas

    - - - - - - \ No newline at end of file +correct P2PKH private key for each UTXO. +
    required
    3 items
    1. derivationPrefix
    2. derivationSuffix
    3. transaction
    properties
    5 fields
    derivationPrefix
    3 fields
    type
    string
    description
    Payment-wide random nonce (base64-encoded, BRC-29 §3). +Uniquely identifies this payment across all outputs. +
    example
    3q2+7w==
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific random nonce (base64-encoded). +Uniquely identifies a single output within this payment. +For multi-output payments, use the `outputs` array instead. +
    example
    iMba2Q==
    transaction
    3 fields
    type
    string
    description
    Base64-encoded Atomic BEEF (BRC-95) containing the signed BSV +transaction with one or more P2PKH outputs for the recipient. +
    example
    <base64-encoded-BEEF>
    outputs
    3 fields
    type
    array
    description
    Present when multiple outputs belong to the same payment. Each +element describes one P2PKH output intended for the recipient. +When this array is absent, `derivationSuffix` at the top level +refers to output index 0. +
    items
    1 field
    $ref
    #/components/schemas/PaymentOutputDescriptor
    senderIdentityKey
    3 fields
    type
    string
    description
    Hex-encoded compressed secp256k1 identity public key of the sender. +SHOULD be included so the recipient can verify key derivation and +include it in the internalizeAction remittance. +
    example
    02abc123...
    +
    +

    PaymentOutputDescriptor

    + +
    Describes one P2PKH output within a multi-output BRC-29 payment.
    +
    type
    object
    description
    Describes one P2PKH output within a multi-output BRC-29 payment.
    required
    2 items
    1. outputIndex
    2. derivationSuffix
    properties
    2 fields
    outputIndex
    3 fields
    type
    integer
    minimum
    0
    description
    Zero-based output index within the transaction.
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific nonce for this output (base64-encoded).
    example
    X9k4LA==
    +
    +

    Brc42InvoiceNumber

    + +
    BRC-42 invoice number used to derive the recipient's P2PKH key for each +output. Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>` +where: + - `2` = security level (BRC-43) + - `3241645161d8` = BRC-29 magic number + - derivationPrefix / derivationSuffix are the values from the message +
    +
    type
    string
    description
    BRC-42 invoice number used to derive the recipient's P2PKH key for each +output. Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>` +where: + - `2` = security level (BRC-43) + - `3241645161d8` = BRC-29 magic number + - derivationPrefix / derivationSuffix are the values from the message +
    pattern
    ^2-3241645161d8-[A-Za-z0-9+/=]+ [A-Za-z0-9+/=]+$
    example
    2-3241645161d8-3q2+7w== iMba2Q==
    +
    +

    PaymentRemittance

    + +
    Remittance object passed to BRC-100 `internalizeAction` for each +payment output. The recipient's wallet uses these fields to derive +the private key and credit the UTXO. +
    +
    type
    object
    description
    Remittance object passed to BRC-100 `internalizeAction` for each +payment output. The recipient's wallet uses these fields to derive +the private key and credit the UTXO. +
    required
    3 items
    1. derivationPrefix
    2. derivationSuffix
    3. senderIdentityKey
    properties
    3 fields
    derivationPrefix
    3 fields
    type
    string
    description
    Payment-wide derivation prefix (base64-encoded).
    example
    3q2+7w==
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific derivation suffix (base64-encoded).
    example
    iMba2Q==
    senderIdentityKey
    3 fields
    type
    string
    description
    Hex-encoded compressed secp256k1 identity public key of the sender.
    example
    02abc123...
    +
    +

    InternalizeActionArgs

    + +
    Arguments passed to the BRC-100 `internalizeAction` wallet method by +the recipient when processing an incoming BRC-29 payment. +
    +
    type
    object
    description
    Arguments passed to the BRC-100 `internalizeAction` wallet method by +the recipient when processing an incoming BRC-29 payment. +
    required
    3 items
    1. tx
    2. outputs
    3. description
    properties
    3 fields
    tx
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    Raw Atomic BEEF bytes of the payment transaction.
    outputs
    4 fields
    type
    array
    minItems
    1
    items
    1 field
    $ref
    #/components/schemas/InternalizeOutput
    description
    One entry per P2PKH output intended for this recipient.
    description
    3 fields
    type
    string
    description
    Human-readable description of the payment.
    example
    Incoming BRC-29 payment
    +
    +

    InternalizeOutput

    + + +
    type
    object
    required
    3 items
    1. outputIndex
    2. protocol
    3. paymentRemittance
    properties
    3 fields
    outputIndex
    3 fields
    type
    integer
    minimum
    0
    description
    Zero-based output index within the transaction.
    protocol
    3 fields
    type
    string
    enum
    1 item
    1. wallet payment
    description
    Protocol identifier understood by BRC-100 wallets.
    paymentRemittance
    1 field
    $ref
    #/components/schemas/PaymentRemittance
    +
    +

    PaymentAck

    + +
    Minimal response returned to the sender after the recipient has called +`internalizeAction`. BRC-29 does not mandate a wire format; this is +the conventional shape used by ts-sdk integrations. +
    +
    type
    object
    description
    Minimal response returned to the sender after the recipient has called +`internalizeAction`. BRC-29 does not mandate a wire format; this is +the conventional shape used by ts-sdk integrations. +
    required
    1 item
    1. accepted
    properties
    3 fields
    accepted
    2 fields
    type
    boolean
    description
    true if internalizeAction succeeded and the payment was credited.
    txid
    3 fields
    type
    string
    description
    Txid of the accepted transaction (hex, 64 characters).
    pattern
    ^[0-9a-fA-F]{64}$
    error
    2 fields
    type
    string
    description
    Human-readable error message if `accepted` is false. Only present +on rejection. +
    +
    +

    LegacyPaymentEnvelope

    + +
    **Deprecated.** The original BRC-8 extended-envelope format. New +integrations MUST NOT use this format; use `PaymentMessage` instead. +Documented here only for backwards-compatibility reference. +
    +
    type
    object
    deprecated
    true
    description
    **Deprecated.** The original BRC-8 extended-envelope format. New +integrations MUST NOT use this format; use `PaymentMessage` instead. +Documented here only for backwards-compatibility reference. +
    required
    4 items
    1. protocol
    2. senderIdentityKey
    3. derivationPrefix
    4. transactions
    properties
    4 fields
    protocol
    2 fields
    type
    string
    enum
    1 item
    1. 3241645161d8
    senderIdentityKey
    2 fields
    type
    string
    description
    Hex-encoded sender identity public key.
    derivationPrefix
    2 fields
    type
    string
    description
    Payment-wide derivation prefix.
    transactions
    3 fields
    type
    array
    description
    Array of extended BRC-8 transaction envelopes.
    items
    2 fields
    type
    object
    description
    Extended BRC-8 transaction envelope (schema omitted — deprecated).
    +
    + +
    + Raw YAML source +
    asyncapi: "3.1.0"
    +
    +info:
    +  title: BRC-29 Simple Authenticated BSV P2PKH Payment Protocol
    +  version: "1.0.0"
    +  description: |
    +    Specifies the peer-to-peer payment flow defined in BRC-29, including
    +    BRC-42 key derivation prefix/suffix negotiation, the current Atomic BEEF
    +    payment message, and the BRC-100 internalizeAction remittance envelope.
    +
    +    The older BRC-8 extended-envelope format (the `transactions` array) is
    +    deprecated for new integrations; only the current BRC-100 / Atomic BEEF
    +    transport is modelled here.
    +
    +    Source of truth: /docs/BRCs/payments/0029.md
    +  license:
    +    name: Open BSV Licence
    +
    +defaultContentType: application/json
    +
    +# ---------------------------------------------------------------------------
    +# Channels
    +# ---------------------------------------------------------------------------
    +channels:
    +  paymentSend:
    +    address: payment/send
    +    description: |
    +      Logical channel representing a sender delivering a BRC-29 payment message
    +      to a recipient.  In practice this is carried over whatever higher-level
    +      transport the application chooses (HTTP POST, WebSocket, BRC-104 message
    +      box, etc.).  The channel models the one-way delivery of the payment.
    +    messages:
    +      paymentMessage:
    +        $ref: "#/components/messages/PaymentMessage"
    +
    +  paymentAcknowledge:
    +    address: payment/acknowledge
    +    description: |
    +      Logical channel representing the recipient acknowledging acceptance or
    +      rejection of the incoming payment after calling internalizeAction.
    +    messages:
    +      paymentAck:
    +        $ref: "#/components/messages/PaymentAck"
    +
    +# ---------------------------------------------------------------------------
    +# Operations
    +# ---------------------------------------------------------------------------
    +operations:
    +  sendPayment:
    +    action: send
    +    channel:
    +      $ref: "#/channels/paymentSend"
    +    summary: Sender delivers a BRC-29 payment message to the recipient.
    +    messages:
    +      - $ref: "#/channels/paymentSend/messages/paymentMessage"
    +
    +  receiveAck:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/paymentAcknowledge"
    +    summary: Sender receives payment acceptance or rejection from the recipient.
    +    messages:
    +      - $ref: "#/channels/paymentAcknowledge/messages/paymentAck"
    +
    +# ---------------------------------------------------------------------------
    +# Components
    +# ---------------------------------------------------------------------------
    +components:
    +  messages:
    +    PaymentMessage:
    +      name: PaymentMessage
    +      title: BRC-29 Payment Message
    +      summary: |
    +        Current (BRC-100 / Atomic BEEF) payment message sent from the payer to
    +        the payee.  Carries one transaction with one or more P2PKH outputs
    +        derived via BRC-42 key derivation using the invoice number format
    +        `2-3241645161d8-<derivationPrefix> <derivationSuffix>`.
    +      payload:
    +        $ref: "#/components/schemas/PaymentMessage"
    +
    +    PaymentAck:
    +      name: PaymentAck
    +      title: Payment Acknowledgement
    +      summary: |
    +        Informal acknowledgement returned by the recipient after calling
    +        BRC-100 internalizeAction.  No mandatory wire format is defined by
    +        BRC-29; the shape below is the conventional minimal envelope.
    +      payload:
    +        $ref: "#/components/schemas/PaymentAck"
    +
    +  schemas:
    +    # -----------------------------------------------------------------------
    +    # PaymentMessage — single-output form (multi-output uses array variant)
    +    # -----------------------------------------------------------------------
    +    PaymentMessage:
    +      type: object
    +      description: |
    +        Payment message delivered from sender to recipient.  The `transaction`
    +        field carries a base64-encoded Atomic BEEF blob (BRC-95).  For payments
    +        containing multiple outputs each output MUST carry its own
    +        derivationSuffix and outputIndex so the recipient can recover the
    +        correct P2PKH private key for each UTXO.
    +      required:
    +        - derivationPrefix
    +        - derivationSuffix
    +        - transaction
    +      properties:
    +        derivationPrefix:
    +          type: string
    +          description: |
    +            Payment-wide random nonce (base64-encoded, BRC-29 §3).
    +            Uniquely identifies this payment across all outputs.
    +          example: "3q2+7w=="
    +        derivationSuffix:
    +          type: string
    +          description: |
    +            UTXO-specific random nonce (base64-encoded).
    +            Uniquely identifies a single output within this payment.
    +            For multi-output payments, use the `outputs` array instead.
    +          example: "iMba2Q=="
    +        transaction:
    +          type: string
    +          description: |
    +            Base64-encoded Atomic BEEF (BRC-95) containing the signed BSV
    +            transaction with one or more P2PKH outputs for the recipient.
    +          example: "<base64-encoded-BEEF>"
    +        outputs:
    +          type: array
    +          description: |
    +            Present when multiple outputs belong to the same payment.  Each
    +            element describes one P2PKH output intended for the recipient.
    +            When this array is absent, `derivationSuffix` at the top level
    +            refers to output index 0.
    +          items:
    +            $ref: "#/components/schemas/PaymentOutputDescriptor"
    +        senderIdentityKey:
    +          type: string
    +          description: |
    +            Hex-encoded compressed secp256k1 identity public key of the sender.
    +            SHOULD be included so the recipient can verify key derivation and
    +            include it in the internalizeAction remittance.
    +          example: "02abc123..."
    +
    +    PaymentOutputDescriptor:
    +      type: object
    +      description: Describes one P2PKH output within a multi-output BRC-29 payment.
    +      required:
    +        - outputIndex
    +        - derivationSuffix
    +      properties:
    +        outputIndex:
    +          type: integer
    +          minimum: 0
    +          description: Zero-based output index within the transaction.
    +        derivationSuffix:
    +          type: string
    +          description: UTXO-specific nonce for this output (base64-encoded).
    +          example: "X9k4LA=="
    +
    +    # -----------------------------------------------------------------------
    +    # Key-derivation invoice number (informational)
    +    # -----------------------------------------------------------------------
    +    Brc42InvoiceNumber:
    +      type: string
    +      description: |
    +        BRC-42 invoice number used to derive the recipient's P2PKH key for each
    +        output.  Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>`
    +        where:
    +          - `2`             = security level (BRC-43)
    +          - `3241645161d8`  = BRC-29 magic number
    +          - derivationPrefix / derivationSuffix are the values from the message
    +      pattern: "^2-3241645161d8-[A-Za-z0-9+/=]+ [A-Za-z0-9+/=]+$"
    +      example: "2-3241645161d8-3q2+7w== iMba2Q=="
    +
    +    # -----------------------------------------------------------------------
    +    # internalizeAction remittance (as passed by the recipient's wallet)
    +    # -----------------------------------------------------------------------
    +    PaymentRemittance:
    +      type: object
    +      description: |
    +        Remittance object passed to BRC-100 `internalizeAction` for each
    +        payment output.  The recipient's wallet uses these fields to derive
    +        the private key and credit the UTXO.
    +      required:
    +        - derivationPrefix
    +        - derivationSuffix
    +        - senderIdentityKey
    +      properties:
    +        derivationPrefix:
    +          type: string
    +          description: Payment-wide derivation prefix (base64-encoded).
    +          example: "3q2+7w=="
    +        derivationSuffix:
    +          type: string
    +          description: UTXO-specific derivation suffix (base64-encoded).
    +          example: "iMba2Q=="
    +        senderIdentityKey:
    +          type: string
    +          description: Hex-encoded compressed secp256k1 identity public key of the sender.
    +          example: "02abc123..."
    +
    +    # -----------------------------------------------------------------------
    +    # Full internalizeAction args shape (BRC-100)
    +    # -----------------------------------------------------------------------
    +    InternalizeActionArgs:
    +      type: object
    +      description: |
    +        Arguments passed to the BRC-100 `internalizeAction` wallet method by
    +        the recipient when processing an incoming BRC-29 payment.
    +      required:
    +        - tx
    +        - outputs
    +        - description
    +      properties:
    +        tx:
    +          type: array
    +          items:
    +            type: integer
    +            minimum: 0
    +            maximum: 255
    +          description: Raw Atomic BEEF bytes of the payment transaction.
    +        outputs:
    +          type: array
    +          minItems: 1
    +          items:
    +            $ref: "#/components/schemas/InternalizeOutput"
    +          description: One entry per P2PKH output intended for this recipient.
    +        description:
    +          type: string
    +          description: Human-readable description of the payment.
    +          example: "Incoming BRC-29 payment"
    +
    +    InternalizeOutput:
    +      type: object
    +      required:
    +        - outputIndex
    +        - protocol
    +        - paymentRemittance
    +      properties:
    +        outputIndex:
    +          type: integer
    +          minimum: 0
    +          description: Zero-based output index within the transaction.
    +        protocol:
    +          type: string
    +          enum:
    +            - "wallet payment"
    +          description: Protocol identifier understood by BRC-100 wallets.
    +        paymentRemittance:
    +          $ref: "#/components/schemas/PaymentRemittance"
    +
    +    # -----------------------------------------------------------------------
    +    # Acknowledgement
    +    # -----------------------------------------------------------------------
    +    PaymentAck:
    +      type: object
    +      description: |
    +        Minimal response returned to the sender after the recipient has called
    +        `internalizeAction`.  BRC-29 does not mandate a wire format; this is
    +        the conventional shape used by ts-sdk integrations.
    +      required:
    +        - accepted
    +      properties:
    +        accepted:
    +          type: boolean
    +          description: true if internalizeAction succeeded and the payment was credited.
    +        txid:
    +          type: string
    +          description: Txid of the accepted transaction (hex, 64 characters).
    +          pattern: "^[0-9a-fA-F]{64}$"
    +        error:
    +          type: string
    +          description: |
    +            Human-readable error message if `accepted` is false.  Only present
    +            on rejection.
    +
    +    # -----------------------------------------------------------------------
    +    # Legacy (deprecated) payment envelope — documented for compatibility only
    +    # -----------------------------------------------------------------------
    +    LegacyPaymentEnvelope:
    +      type: object
    +      deprecated: true
    +      description: |
    +        **Deprecated.** The original BRC-8 extended-envelope format.  New
    +        integrations MUST NOT use this format; use `PaymentMessage` instead.
    +        Documented here only for backwards-compatibility reference.
    +      required:
    +        - protocol
    +        - senderIdentityKey
    +        - derivationPrefix
    +        - transactions
    +      properties:
    +        protocol:
    +          type: string
    +          enum:
    +            - "3241645161d8"
    +        senderIdentityKey:
    +          type: string
    +          description: Hex-encoded sender identity public key.
    +        derivationPrefix:
    +          type: string
    +          description: Payment-wide derivation prefix.
    +        transactions:
    +          type: array
    +          description: Array of extended BRC-8 transaction envelopes.
    +          items:
    +            type: object
    +            description: Extended BRC-8 transaction envelope (schema omitted — deprecated).
    +
    +
    + + + + diff --git a/docs-site/public/assets/asyncapi/brc31/index.html b/docs-site/public/assets/asyncapi/brc31/index.html index 45c1a2cb7..32d18a4fb 100644 --- a/docs-site/public/assets/asyncapi/brc31/index.html +++ b/docs-site/public/assets/asyncapi/brc31/index.html @@ -1,902 +1,1075 @@ - - - - - - BRC-103 Mutual Authentication Handshake 1.0.0 documentation - - - - + + + + + + + BRC-103 Mutual Authentication Handshake · AsyncAPI + - - -
    BRC-103 Mutual Authentication Handshake 1.0.0

    AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual -authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as -implemented in:

    -
      -
    • packages/middleware/auth-express-middleware/src/index.ts -(ExpressTransport, createAuthMiddleware) — BRC-104 HTTP transport -(https://bsv.brc.dev/peer-to-peer/0104)
    • -
    • packages/messaging/authsocket/src/SocketServerTransport.ts -(SocketServerTransport) — Socket.IO transport
    • -
    • @bsv/sdk Peer and Transport interfaces
    • -
    -

    Note: this file replaces the earlier brc31-handshake.yaml. BRC-31 was + +

    +
    AsyncAPI 3.1.0 · specs/auth/brc103-mutual-auth.yaml
    +

    BRC-103 Mutual Authentication Handshake

    v1.0.0
    +
    AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual +authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as +implemented in: + +- `packages/middleware/auth-express-middleware/src/index.ts` + (`ExpressTransport`, `createAuthMiddleware`) — BRC-104 HTTP transport + (https://bsv.brc.dev/peer-to-peer/0104) +- `packages/messaging/authsocket/src/SocketServerTransport.ts` + (`SocketServerTransport`) — Socket.IO transport +- `@bsv/sdk` `Peer` and `Transport` interfaces + +Note: this file replaces the earlier `brc31-handshake.yaml`. BRC-31 was the legacy identifier; the protocol is now standardised as BRC-103 with -BRC-104 covering the HTTP binding.

    -

    Protocol overview

    -

    BRC-103 mutual authentication uses ECDH-derived key pairs to create a +BRC-104 covering the HTTP binding. + +## Protocol overview + +BRC-103 mutual authentication uses ECDH-derived key pairs to create a shared, forward-secret session between two parties. Neither party trusts -the other's identity until the signed handshake is verified.

    -

    Two-phase handshake

    -

    Phase 1 — Non-general (initial exchange)

    -

    Carried over the special endpoint POST /.well-known/auth for HTTP -transports, or the authMessage Socket.IO event for WebSocket transports.

    -
      -
    1. Client → Server initialRequest -Client generates a fresh nonce, signs it with its identity key, and -sends the auth message. Headers on the HTTP path:

      -
      x-bsv-auth-version: <version>
      -x-bsv-auth-identity-key: <clientPubKeyHex>
      -x-bsv-auth-nonce: <base64Nonce>
      -
      -

      Body (HTTP): the AuthMessage JSON object.

      -
    2. -
    3. Server → Client initialResponse -Server validates the client's nonce/signature, generates its own nonce, -signs the response, and returns the AuthMessage. HTTP response headers:

      -
      x-bsv-auth-version: <version>
      -x-bsv-auth-message-type: initialResponse
      -x-bsv-auth-identity-key: <serverPubKeyHex>
      -x-bsv-auth-nonce: <base64ServerNonce>
      -x-bsv-auth-your-nonce: <base64ClientNonce>
      -x-bsv-auth-signature: <hexDERSignature>
      -x-bsv-auth-requested-certificates: <JSON> (optional)
      -
      -
    4. -
    -

    Phase 2 — General (authenticated request/response)

    -

    Once the session is established all subsequent HTTP requests carry:

    -
    x-bsv-auth-version: <version>
    +the other's identity until the signed handshake is verified.
    +
    +### Two-phase handshake
    +
    +**Phase 1 — Non-general (initial exchange)**
    +
    +Carried over the special endpoint `POST /.well-known/auth` for HTTP
    +transports, or the `authMessage` Socket.IO event for WebSocket transports.
    +
    +1. **Client → Server** `initialRequest`
    +   Client generates a fresh nonce, signs it with its identity key, and
    +   sends the auth message. Headers on the HTTP path:
    +   ```
    +   x-bsv-auth-version: <version>
    +   x-bsv-auth-identity-key: <clientPubKeyHex>
    +   x-bsv-auth-nonce: <base64Nonce>
    +   ```
    +   Body (HTTP): the `AuthMessage` JSON object.
    +
    +2. **Server → Client** `initialResponse`
    +   Server validates the client's nonce/signature, generates its own nonce,
    +   signs the response, and returns the `AuthMessage`. HTTP response headers:
    +   ```
    +   x-bsv-auth-version: <version>
    +   x-bsv-auth-message-type: initialResponse
    +   x-bsv-auth-identity-key: <serverPubKeyHex>
    +   x-bsv-auth-nonce: <base64ServerNonce>
    +   x-bsv-auth-your-nonce: <base64ClientNonce>
    +   x-bsv-auth-signature: <hexDERSignature>
    +   x-bsv-auth-requested-certificates: <JSON> (optional)
    +   ```
    +
    +**Phase 2 — General (authenticated request/response)**
    +
    +Once the session is established all subsequent HTTP requests carry:
    +```
    +x-bsv-auth-version: <version>
     x-bsv-auth-identity-key: <clientPubKeyHex>
     x-bsv-auth-nonce: <base64Nonce>
     x-bsv-auth-your-nonce: <base64ServerNonce>
     x-bsv-auth-request-id: <base64RequestId>
     x-bsv-auth-signature: <hexDERSignature>
    -
    -

    The signed payload includes: requestId || method || pathname || search || headers (sorted) || body.

    -

    The server responds with:

    -
    x-bsv-auth-version: <version>
    +```
    +
    +The signed payload includes: `requestId || method || pathname || search
    +|| headers (sorted) || body`.
    +
    +The server responds with:
    +```
    +x-bsv-auth-version: <version>
     x-bsv-auth-identity-key: <serverPubKeyHex>
     x-bsv-auth-nonce: <base64Nonce>
     x-bsv-auth-your-nonce: <base64ClientNonce>
     x-bsv-auth-request-id: <base64RequestId>
     x-bsv-auth-signature: <hexDERSignature>
    -
    -

    The signed response payload includes: requestId || statusCode || headers (sorted) || body.

    -

    Certificate flow (optional)

    -

    If the server declares certificatesToRequest, it embeds the request set -in the x-bsv-auth-requested-certificates header of the initialResponse. -The client then provides certificates in a follow-up /.well-known/auth -call before the next() middleware proceeds. The server waits up to -30 seconds; timeout returns 408.

    -

    Unauthenticated pass-through

    -

    If allowUnauthenticated: true is set in middleware options, requests -without auth headers proceed with req.auth.identityKey = 'unknown'.

    -

    Implementation-specific notes

    -
      -
    • ExpressTransport intercepts res.status, res.json, res.send, -res.set, res.end, res.sendFile, and res.text to buffer the -response until after Peer.toPeer signs and re-emits it. Original -methods are saved as res.__status, res.__json, etc.
    • -
    • The RequestId is a 32-byte random value encoded as base64.
    • -
    • Nonces are single-use; the SessionManager stores seen nonces to -prevent replay. Deployments that run multiple server instances should -use a shared AsyncSessionManager store so every instance can resolve -the same nonce/session state during the handshake.
    • -
    -

    Servers

    • https://{host}/.well-known/authhttpshttpServer

      HTTP endpoint for BRC-103 non-general (initial handshake) messages. -General (authenticated) messages use normal application paths.

      -
      object
      string
      required

    Operations

    • SEND /.well-known/auth

      HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. -The client POSTs an AuthMessage JSON body; the server replies with an -AuthMessage JSON body and the x-bsv-auth-* response headers.

      -

      In Socket.IO transports the same exchange happens over the authMessage -Socket.IO event (see authsocket-asyncapi.yaml) rather than this HTTP -endpoint.

      -

      Client initiates BRC-103 handshake (Phase 1, step 1).

      Client POSTs an initialRequest AuthMessage to /.well-known/auth. -The body is a JSON-serialized AuthMessage with messageType: initialRequest.

      -
      Operation IDsendInitialRequest

      Available only on servers:

      Accepts the following message:

      Client initiates the BRC-103 handshake.

      Message IDinitialRequest

      The client generates a nonce, signs it, and sends the -initialRequest AuthMessage as the POST body.

      -
      object

      The core BRC-103 message envelope. Transported over HTTP bodies -(at /.well-known/auth) or Socket.IO authMessage events.

      -
      object

      HTTP request headers sent by the client when initiating the BRC-103 -handshake at POST /.well-known/auth.

      -

      Examples

    • RECEIVE /.well-known/auth

      HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. -The client POSTs an AuthMessage JSON body; the server replies with an -AuthMessage JSON body and the x-bsv-auth-* response headers.

      -

      In Socket.IO transports the same exchange happens over the authMessage -Socket.IO event (see authsocket-asyncapi.yaml) rather than this HTTP -endpoint.

      -

      Client receives the server's Phase 1 challenge response.

      Server replies with initialResponse. If requestedCertificates is -non-empty the client must send a follow-up request with the required -certificates before proceeding to Phase 2.

      -
      Operation IDreceiveInitialResponse

      Available only on servers:

      Accepts the following message:

      Server completes Phase 1 of the BRC-103 handshake.

      Message IDinitialResponse

      The server validates the client's nonce/signature, generates its own -nonce, signs the response, and replies. The body is an AuthMessage -JSON object. Response headers carry the x-bsv-auth-* fields.

      -

      If certificatesToRequest is configured, the -x-bsv-auth-requested-certificates header contains the JSON-encoded +``` + +The signed response payload includes: `requestId || statusCode || +headers (sorted) || body`. + +### Certificate flow (optional) + +If the server declares `certificatesToRequest`, it embeds the request set +in the `x-bsv-auth-requested-certificates` header of the `initialResponse`. +The client then provides certificates in a follow-up `/.well-known/auth` +call before the `next()` middleware proceeds. The server waits up to +30 seconds; timeout returns 408. + +### Unauthenticated pass-through + +If `allowUnauthenticated: true` is set in middleware options, requests +without auth headers proceed with `req.auth.identityKey = 'unknown'`. + +## Implementation-specific notes + +- `ExpressTransport` intercepts `res.status`, `res.json`, `res.send`, + `res.set`, `res.end`, `res.sendFile`, and `res.text` to buffer the + response until after `Peer.toPeer` signs and re-emits it. Original + methods are saved as `res.__status`, `res.__json`, etc. +- The `RequestId` is a 32-byte random value encoded as base64. +- Nonces are single-use; the `SessionManager` stores seen nonces to + prevent replay. Deployments that run multiple server instances should + use a shared `AsyncSessionManager` store so every instance can resolve + the same nonce/session state during the handshake. +

      +
      1Servers4Channels5Operations0Messages14Schemas
      + + +
      +
      +

      Servers

      1
      +
      +

      httpServer

      +

      https://{host}/.well-known/auth

      +
      HTTP endpoint for BRC-103 non-general (initial handshake) messages. +General (authenticated) messages use normal application paths. +
      +
      host
      {host}
      pathname
      /.well-known/auth
      protocol
      https
      description
      HTTP endpoint for BRC-103 non-general (initial handshake) messages. +General (authenticated) messages use normal application paths. +
      variables
      1 field
      host
      1 field
      default
      messagebox.babbage.systems
      +
      +
      +

      Channels

      4
      +
      +

      wellKnownAuth

      +

      /.well-known/auth

      +
      HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. +The client POSTs an `AuthMessage` JSON body; the server replies with an +`AuthMessage` JSON body and the `x-bsv-auth-*` response headers. + +In Socket.IO transports the same exchange happens over the `authMessage` +Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP +endpoint. +
      +
      address
      /.well-known/auth
      description
      HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. +The client POSTs an `AuthMessage` JSON body; the server replies with an +`AuthMessage` JSON body and the `x-bsv-auth-*` response headers. + +In Socket.IO transports the same exchange happens over the `authMessage` +Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP +endpoint. +
      messages
      2 fields
      initialRequest
      6 fields
      name
      initialRequest
      summary
      Client initiates the BRC-103 handshake.
      description
      The client generates a nonce, signs it, and sends the +`initialRequest` AuthMessage as the POST body. +
      headers
      1 field
      $ref
      #/components/schemas/InitialRequestHeaders
      payload
      1 field
      $ref
      #/components/schemas/AuthMessage
      examples
      1 item
      1. name
        example-initial-request
        payload
        7 fields
        messageType
        initialRequest
        version
        0.1
        identityKey
        028d37b941208cd6b8a4c28288eda5f2f16c2b3ab0fcb6d13c18b47fe37b971fc1
        nonce
        dGVzdE5vbmNlMTIzNA==
        initialNonce
        dGVzdE5vbmNlMTIzNA==
        payload
        0 itemsempty list
        signature
        0 itemsempty list
      initialResponse
      5 fields
      name
      initialResponse
      summary
      Server completes Phase 1 of the BRC-103 handshake.
      description
      The server validates the client's nonce/signature, generates its own +nonce, signs the response, and replies. The body is an `AuthMessage` +JSON object. Response headers carry the `x-bsv-auth-*` fields. + +If `certificatesToRequest` is configured, the +`x-bsv-auth-requested-certificates` header contains the JSON-encoded request set. The client must supply certificates in a follow-up -POST before the session is fully established.

      -
      object

      The core BRC-103 message envelope. Transported over HTTP bodies -(at /.well-known/auth) or Socket.IO authMessage events.

      -
      object

      HTTP response headers set by the server completing Phase 1 of the -BRC-103 handshake.

      -

      Examples

    • SEND {applicationPath}

      Every authenticated application HTTP request (Phase 2). The path is -the actual application endpoint (e.g. /sendMessage, /listMessages). -The auth headers are attached alongside any application-specific headers.

      -

      Client sends an authenticated application request (Phase 2).

      Any application HTTP request after the handshake. The client attaches -x-bsv-auth-* headers and a fresh signed payload covering the full -request. The server uses buildAuthMessageFromRequest to reconstruct -and verify the payload.

      -
      Operation IDsendGeneralRequest

      Available only on servers:

      object
      applicationPathstring
      required

      The application route path (e.g. /sendMessage).

      -

      Accepts the following message:

      Authenticated application request.

      Message IDgeneralRequestMessage

      The client sends application-level request headers and body, augmented -with x-bsv-auth-* mutual-auth headers. The x-bsv-auth-signature +POST before the session is fully established. +

      headers
      1 field
      $ref
      #/components/schemas/InitialResponseHeaders
      payload
      1 field
      $ref
      #/components/schemas/AuthMessage
      +
      +

      generalRequest

      +

      {applicationPath}

      +
      Every authenticated application HTTP request (Phase 2). The path is +the actual application endpoint (e.g. `/sendMessage`, `/listMessages`). +The auth headers are attached alongside any application-specific headers. +
      +
      address
      {applicationPath}
      description
      Every authenticated application HTTP request (Phase 2). The path is +the actual application endpoint (e.g. `/sendMessage`, `/listMessages`). +The auth headers are attached alongside any application-specific headers. +
      parameters
      1 field
      applicationPath
      1 field
      description
      The application route path (e.g. /sendMessage).
      messages
      1 field
      generalRequestMessage
      5 fields
      name
      generalRequestMessage
      summary
      Authenticated application request.
      description
      The client sends application-level request headers and body, augmented +with `x-bsv-auth-*` mutual-auth headers. The `x-bsv-auth-signature` covers the entire request (method, path, query string, signed headers, -and body) as described in RequestAuthPayload.

      -
      Payloadany

      Application-defined request body (any content type).

      -
      object

      HTTP request headers sent by the client for every authenticated -application request (Phase 2).

      -

      Examples

    • RECEIVE {applicationPath}

      Every authenticated application HTTP response (Phase 2). The server -signs the response status code, relevant headers, and body before sending.

      -

      Client receives the server's authenticated application response (Phase 2).

      The server's response includes x-bsv-auth-* headers and a signature +and body) as described in `RequestAuthPayload`. +

      headers
      1 field
      $ref
      #/components/schemas/GeneralRequestHeaders
      payload
      1 field
      description
      Application-defined request body (any content type).
      +
      +

      generalResponse

      +

      {applicationPath}

      +
      Every authenticated application HTTP response (Phase 2). The server +signs the response status code, relevant headers, and body before sending. +
      +
      address
      {applicationPath}
      description
      Every authenticated application HTTP response (Phase 2). The server +signs the response status code, relevant headers, and body before sending. +
      parameters
      1 field
      applicationPath
      1 field
      description
      The application route path.
      messages
      1 field
      generalResponseMessage
      5 fields
      name
      generalResponseMessage
      summary
      Authenticated application response.
      description
      The server buffers the handler's response via `ResponseWriterWrapper`, +calls `Peer.toPeer` to sign it, and flushes the signed response +including `x-bsv-auth-*` response headers. The `x-bsv-auth-signature` +covers `requestId || statusCode || signed response headers || body`. +
      headers
      1 field
      $ref
      #/components/schemas/GeneralResponseHeaders
      payload
      1 field
      description
      Application-defined response body.
      +
      +

      authError

      +

      {applicationPath}

      +
      Error responses emitted by the auth middleware when authentication fails. +
      +
      address
      {applicationPath}
      description
      Error responses emitted by the auth middleware when authentication fails. +
      parameters
      1 field
      applicationPath
      1 field
      description
      The path at which the error was encountered.
      messages
      3 fields
      unauthorized
      3 fields
      name
      unauthorized
      summary
      401 — mutual auth failed (no or bad auth headers).
      payload
      1 field
      $ref
      #/components/schemas/AuthError401
      certificateTimeout
      3 fields
      name
      certificateTimeout
      summary
      408 — server waited 30 s for client certificates and timed out.
      payload
      1 field
      $ref
      #/components/schemas/AuthError408
      signingFailed
      3 fields
      name
      signingFailed
      summary
      500 — server failed to sign its response payload.
      payload
      1 field
      $ref
      #/components/schemas/AuthError500
      +
      +
    +

    Operations

    5
    +
    +

    sendInitialRequest

    + send +
    Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`. +The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`. +
    +
    action
    send
    channel
    1 field
    $ref
    #/channels/wellKnownAuth
    summary
    Client initiates BRC-103 handshake (Phase 1, step 1).
    description
    Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`. +The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`. +
    messages
    1 item
    1. $ref
      #/channels/wellKnownAuth/messages/initialRequest
    +
    +

    receiveInitialResponse

    + receive +
    Server replies with `initialResponse`. If `requestedCertificates` is +non-empty the client must send a follow-up request with the required +certificates before proceeding to Phase 2. +
    +
    action
    receive
    channel
    1 field
    $ref
    #/channels/wellKnownAuth
    summary
    Client receives the server's Phase 1 challenge response.
    description
    Server replies with `initialResponse`. If `requestedCertificates` is +non-empty the client must send a follow-up request with the required +certificates before proceeding to Phase 2. +
    messages
    1 item
    1. $ref
      #/channels/wellKnownAuth/messages/initialResponse
    +
    +

    sendGeneralRequest

    + send +
    Any application HTTP request after the handshake. The client attaches +`x-bsv-auth-*` headers and a fresh signed payload covering the full +request. The server uses `buildAuthMessageFromRequest` to reconstruct +and verify the payload. +
    +
    action
    send
    channel
    1 field
    $ref
    #/channels/generalRequest
    summary
    Client sends an authenticated application request (Phase 2).
    description
    Any application HTTP request after the handshake. The client attaches +`x-bsv-auth-*` headers and a fresh signed payload covering the full +request. The server uses `buildAuthMessageFromRequest` to reconstruct +and verify the payload. +
    messages
    1 item
    1. $ref
      #/channels/generalRequest/messages/generalRequestMessage
    +
    +

    receiveGeneralResponse

    + receive +
    The server's response includes `x-bsv-auth-*` headers and a signature +over the response payload. The client can verify the response origin +using `buildResponsePayload` semantics. +
    +
    action
    receive
    channel
    1 field
    $ref
    #/channels/generalResponse
    summary
    Client receives the server's authenticated application response (Phase 2).
    description
    The server's response includes `x-bsv-auth-*` headers and a signature over the response payload. The client can verify the response origin -using buildResponsePayload semantics.

    -
    Operation IDreceiveGeneralResponse

    Available only on servers:

    object
    applicationPathstring
    required

    The application route path.

    -

    Accepts the following message:

    Authenticated application response.

    Message IDgeneralResponseMessage

    The server buffers the handler's response via ResponseWriterWrapper, -calls Peer.toPeer to sign it, and flushes the signed response -including x-bsv-auth-* response headers. The x-bsv-auth-signature -covers requestId || statusCode || signed response headers || body.

    -
    Payloadany

    Application-defined response body.

    -
    object

    HTTP response headers set by the server on every authenticated -application response (Phase 2).

    -

    Examples

  • RECEIVE {applicationPath}

    Error responses emitted by the auth middleware when authentication fails.

    -

    Client receives an auth error from the middleware.

    Operation IDreceiveAuthError

    Available only on servers:

    object
    applicationPathstring
    required

    The path at which the error was encountered.

    -

    Accepts one of the following messages:

    • #0

      401 — mutual auth failed (no or bad auth headers).

      Message IDunauthorized
      object

      Returned when mutual authentication fails (no or bad auth headers).

      -

      Examples

    • #1

      408 — server waited 30 s for client certificates and timed out.

      Message IDcertificateTimeout
      object

      Returned when the server is waiting for client certificates -and the 30-second timeout elapses.

      -

      Examples

    • #2

      500 — server failed to sign its response payload.

      Message IDsigningFailed
      object

      Returned when the server fails to sign its response payload -(ERR_RESPONSE_SIGNING_FAILED).

      -

      Examples

  • Schemas

    • string

      Compressed secp256k1 public key, 66 hex characters.

      -
    • Base64Stringstring

      Base64-encoded binary data.

      -
    • string

      Hex-encoded binary data.

      -
    • string
        -
      • initialRequest — first message from the initiating party
      • -
      • initialResponse — response from the receiving party completing Phase 1
      • -
      • general — signed application message (Phase 2)
      • -
      -
    • object

      The core BRC-103 message envelope. Transported over HTTP bodies -(at /.well-known/auth) or Socket.IO authMessage events.

      -
    • object

      HTTP request headers sent by the client when initiating the BRC-103 -handshake at POST /.well-known/auth.

      -
    • object

      HTTP response headers set by the server completing Phase 1 of the -BRC-103 handshake.

      -
    • object

      HTTP request headers sent by the client for every authenticated -application request (Phase 2).

      -
    • object

      HTTP response headers set by the server on every authenticated -application response (Phase 2).

      -
    • object

      Returned when mutual authentication fails (no or bad auth headers).

      -
    • object

      Returned when the server is waiting for client certificates -and the 30-second timeout elapses.

      -
    • object

      Returned when the server fails to sign its response payload -(ERR_RESPONSE_SIGNING_FAILED).

      -
    • object

      Informational schema: the signed payload for a general REQUEST. -Assembled by buildAuthMessageFromRequest in ExpressTransport.

      -

      Wire encoding (binary, concatenated):

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      FieldEncoding
      requestId32 raw bytes (decoded from base64)
      methodVarInt(len) + UTF-8 bytes
      pathnameVarInt(len) + UTF-8 bytes
      searchVarInt(len) + UTF-8 bytes, or VarInt(-1)
      nHeadersVarInt
      headers (sorted)VarInt(keyLen)+key + VarInt(valLen)+val
      bodyLengthVarInt(len) or VarInt(-1)
      bodyraw bytes
      -

      Only these headers are included (sorted, lowercase):

      -
        -
      • Headers starting with x-bsv- (but NOT x-bsv-auth-*)
      • -
      • content-type (normalized: type only, no parameters)
      • -
      • authorization
      • -
      -
    • object

      Informational schema: the signed payload for a general RESPONSE. -Assembled by buildResponsePayload in ExpressTransport.

      -

      Wire encoding (binary, concatenated):

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      FieldEncoding
      requestId32 raw bytes (decoded from base64)
      statusCodeVarInt
      nHeadersVarInt
      headers (sorted)VarInt(keyLen)+key + VarInt(valLen)+val
      bodyLengthVarInt(len) or VarInt(-1)
      bodyraw bytes
      -

      Only these response headers are included (sorted, lowercase):

      -
        -
      • Headers starting with x-bsv- (but NOT x-bsv-auth-*)
      • -
      • authorization
      • -
      -
    - - - - - - \ No newline at end of file +using `buildResponsePayload` semantics. +
    messages
    1 item
    1. $ref
      #/channels/generalResponse/messages/generalResponseMessage
    +
    +

    receiveAuthError

    + receive +
    Client receives an auth error from the middleware.
    +
    action
    receive
    channel
    1 field
    $ref
    #/channels/authError
    summary
    Client receives an auth error from the middleware.
    messages
    3 items
    1. $ref
      #/channels/authError/messages/unauthorized
    2. $ref
      #/channels/authError/messages/certificateTimeout
    3. $ref
      #/channels/authError/messages/signingFailed
    +
    +
    +

    Schemas

    14
    +
    +

    PubKeyHex

    + +
    Compressed secp256k1 public key, 66 hex characters.
    +
    type
    string
    pattern
    ^0[23][0-9a-fA-F]{64}$
    description
    Compressed secp256k1 public key, 66 hex characters.
    +
    +

    Base64String

    + +
    Base64-encoded binary data.
    +
    type
    string
    description
    Base64-encoded binary data.
    +
    +

    HexString

    + +
    Hex-encoded binary data.
    +
    type
    string
    pattern
    ^[0-9a-fA-F]+$
    description
    Hex-encoded binary data.
    +
    +

    AuthMessageType

    + +
    - `initialRequest` — first message from the initiating party +- `initialResponse` — response from the receiving party completing Phase 1 +- `general` — signed application message (Phase 2) +
    +
    type
    string
    enum
    3 items
    1. initialRequest
    2. initialResponse
    3. general
    description
    - `initialRequest` — first message from the initiating party +- `initialResponse` — response from the receiving party completing Phase 1 +- `general` — signed application message (Phase 2) +
    +
    +

    AuthMessage

    + +
    The core BRC-103 message envelope. Transported over HTTP bodies +(at `/.well-known/auth`) or Socket.IO `authMessage` events. +
    +
    type
    object
    description
    The core BRC-103 message envelope. Transported over HTTP bodies +(at `/.well-known/auth`) or Socket.IO `authMessage` events. +
    required
    3 items
    1. messageType
    2. version
    3. identityKey
    properties
    9 fields
    messageType
    1 field
    $ref
    #/components/schemas/AuthMessageType
    version
    2 fields
    type
    string
    description
    Auth protocol version (e.g. "0.1").
    identityKey
    2 fields
    $ref
    #/components/schemas/PubKeyHex
    description
    Public identity key of the sender of this message.
    nonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Fresh single-use random value generated by the sender. +Stored in the `SessionManager` to prevent replay. Multi-instance +deployments should store it in a shared `AsyncSessionManager` +implementation. +
    yourNonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Echo of the peer's nonce from the previous message.
    initialNonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Present in `initialRequest` only. The very first nonce from the +initiating party before a session key is established. +
    payload
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    For `general` messages: the signed application payload. +Encoding: `requestId(32) || VarInt(statusCode) || VarInt(nHeaders) +|| [header pairs] || VarInt(bodyLength) || body`. +For handshake messages: empty or absent. +
    signature
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    DER-encoded ECDSA signature over the payload.
    requestedCertificates
    3 fields
    type
    object
    description
    BRC-52 certificate request set. Present in `initialResponse` when +the server requires certificates from the client. +
    additionalProperties
    true
    +
    +

    InitialRequestHeaders

    + +
    HTTP request headers sent by the client when initiating the BRC-103 +handshake at POST `/.well-known/auth`. +
    +
    type
    object
    description
    HTTP request headers sent by the client when initiating the BRC-103 +handshake at POST `/.well-known/auth`. +
    required
    3 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    properties
    3 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    +
    +

    InitialResponseHeaders

    + +
    HTTP response headers set by the server completing Phase 1 of the +BRC-103 handshake. +
    +
    type
    object
    description
    HTTP response headers set by the server completing Phase 1 of the +BRC-103 handshake. +
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-message-type
    3. x-bsv-auth-identity-key
    4. x-bsv-auth-nonce
    5. x-bsv-auth-your-nonce
    6. x-bsv-auth-signature
    properties
    7 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-message-type
    2 fields
    type
    string
    enum
    1 item
    1. initialResponse
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-signature
    1 field
    $ref
    #/components/schemas/HexString
    x-bsv-auth-requested-certificates
    2 fields
    type
    string
    description
    JSON-encoded BRC-52 certificate request set (optional).
    +
    +

    GeneralRequestHeaders

    + +
    HTTP request headers sent by the client for every authenticated +application request (Phase 2). +
    +
    type
    object
    description
    HTTP request headers sent by the client for every authenticated +application request (Phase 2). +
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    4. x-bsv-auth-your-nonce
    5. x-bsv-auth-request-id
    6. x-bsv-auth-signature
    properties
    6 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-request-id
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    32-byte random value, base64-encoded.
    x-bsv-auth-signature
    2 fields
    $ref
    #/components/schemas/HexString
    description
    ECDSA signature over: +`requestId(32B) || VarInt(method.length) || method +|| VarInt(pathname.length) || pathname +|| VarInt(search.length) || search (or -1 if empty) +|| VarInt(nHeaders) || [sorted header pairs] +|| VarInt(bodyLength) || body (or -1 if empty)`. +
    +
    +

    GeneralResponseHeaders

    + +
    HTTP response headers set by the server on every authenticated +application response (Phase 2). +
    +
    type
    object
    description
    HTTP response headers set by the server on every authenticated +application response (Phase 2). +
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    4. x-bsv-auth-your-nonce
    5. x-bsv-auth-request-id
    6. x-bsv-auth-signature
    properties
    6 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-request-id
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-signature
    2 fields
    $ref
    #/components/schemas/HexString
    description
    ECDSA signature over: +`requestId(32B) || VarInt(statusCode) +|| VarInt(nHeaders) || [sorted non-auth x-bsv header pairs] +|| VarInt(bodyLength) || body (or -1 if empty)`. +
    +
    +

    AuthError401

    + +
    Returned when mutual authentication fails (no or bad auth headers).
    +
    type
    object
    description
    Returned when mutual authentication fails (no or bad auth headers).
    required
    3 items
    1. status
    2. code
    3. message
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    2 items
    1. UNAUTHORIZED
    2. ERR_AUTH_FAILED
    message
    1 field
    type
    string
    +
    +

    AuthError408

    + +
    Returned when the server is waiting for client certificates +and the 30-second timeout elapses. +
    +
    type
    object
    description
    Returned when the server is waiting for client certificates +and the 30-second timeout elapses. +
    required
    3 items
    1. status
    2. code
    3. message
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    1 item
    1. CERTIFICATE_TIMEOUT
    message
    1 field
    type
    string
    +
    +

    AuthError500

    + +
    Returned when the server fails to sign its response payload +(`ERR_RESPONSE_SIGNING_FAILED`). +
    +
    type
    object
    description
    Returned when the server fails to sign its response payload +(`ERR_RESPONSE_SIGNING_FAILED`). +
    required
    3 items
    1. status
    2. code
    3. description
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    2 items
    1. ERR_RESPONSE_SIGNING_FAILED
    2. ERR_INTERNAL_SERVER_ERROR
    description
    1 field
    type
    string
    +
    +

    RequestAuthPayload

    + +
    Informational schema: the signed payload for a `general` REQUEST. +Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`. + +Wire encoding (binary, concatenated): +| Field | Encoding | +|------------------|------------------------------------------| +| requestId | 32 raw bytes (decoded from base64) | +| method | VarInt(len) + UTF-8 bytes | +| pathname | VarInt(len) + UTF-8 bytes | +| search | VarInt(len) + UTF-8 bytes, or VarInt(-1) | +| nHeaders | VarInt | +| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | +| bodyLength | VarInt(len) or VarInt(-1) | +| body | raw bytes | + +Only these headers are included (sorted, lowercase): +- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) +- `content-type` (normalized: type only, no parameters) +- `authorization` +
    +
    type
    object
    description
    Informational schema: the signed payload for a `general` REQUEST. +Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`. + +Wire encoding (binary, concatenated): +| Field | Encoding | +|------------------|------------------------------------------| +| requestId | 32 raw bytes (decoded from base64) | +| method | VarInt(len) + UTF-8 bytes | +| pathname | VarInt(len) + UTF-8 bytes | +| search | VarInt(len) + UTF-8 bytes, or VarInt(-1) | +| nHeaders | VarInt | +| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | +| bodyLength | VarInt(len) or VarInt(-1) | +| body | raw bytes | + +Only these headers are included (sorted, lowercase): +- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) +- `content-type` (normalized: type only, no parameters) +- `authorization` +
    +
    +

    ResponseAuthPayload

    + +
    Informational schema: the signed payload for a `general` RESPONSE. +Assembled by `buildResponsePayload` in `ExpressTransport`. + +Wire encoding (binary, concatenated): +| Field | Encoding | +|------------------|------------------------------------------| +| requestId | 32 raw bytes (decoded from base64) | +| statusCode | VarInt | +| nHeaders | VarInt | +| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | +| bodyLength | VarInt(len) or VarInt(-1) | +| body | raw bytes | + +Only these response headers are included (sorted, lowercase): +- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) +- `authorization` +
    +
    type
    object
    description
    Informational schema: the signed payload for a `general` RESPONSE. +Assembled by `buildResponsePayload` in `ExpressTransport`. + +Wire encoding (binary, concatenated): +| Field | Encoding | +|------------------|------------------------------------------| +| requestId | 32 raw bytes (decoded from base64) | +| statusCode | VarInt | +| nHeaders | VarInt | +| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | +| bodyLength | VarInt(len) or VarInt(-1) | +| body | raw bytes | + +Only these response headers are included (sorted, lowercase): +- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) +- `authorization` +
    +
    +
    +
    + Raw YAML source +
    asyncapi: "3.1.0"
    +
    +info:
    +  title: BRC-103 Mutual Authentication Handshake
    +  version: "1.0.0"
    +  description: |
    +    AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual
    +    authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as
    +    implemented in:
    +
    +    - `packages/middleware/auth-express-middleware/src/index.ts`
    +      (`ExpressTransport`, `createAuthMiddleware`) — BRC-104 HTTP transport
    +      (https://bsv.brc.dev/peer-to-peer/0104)
    +    - `packages/messaging/authsocket/src/SocketServerTransport.ts`
    +      (`SocketServerTransport`) — Socket.IO transport
    +    - `@bsv/sdk` `Peer` and `Transport` interfaces
    +
    +    Note: this file replaces the earlier `brc31-handshake.yaml`. BRC-31 was
    +    the legacy identifier; the protocol is now standardised as BRC-103 with
    +    BRC-104 covering the HTTP binding.
    +
    +    ## Protocol overview
    +
    +    BRC-103 mutual authentication uses ECDH-derived key pairs to create a
    +    shared, forward-secret session between two parties. Neither party trusts
    +    the other's identity until the signed handshake is verified.
    +
    +    ### Two-phase handshake
    +
    +    **Phase 1 — Non-general (initial exchange)**
    +
    +    Carried over the special endpoint `POST /.well-known/auth` for HTTP
    +    transports, or the `authMessage` Socket.IO event for WebSocket transports.
    +
    +    1. **Client → Server** `initialRequest`
    +       Client generates a fresh nonce, signs it with its identity key, and
    +       sends the auth message. Headers on the HTTP path:
    +       ```
    +       x-bsv-auth-version: <version>
    +       x-bsv-auth-identity-key: <clientPubKeyHex>
    +       x-bsv-auth-nonce: <base64Nonce>
    +       ```
    +       Body (HTTP): the `AuthMessage` JSON object.
    +
    +    2. **Server → Client** `initialResponse`
    +       Server validates the client's nonce/signature, generates its own nonce,
    +       signs the response, and returns the `AuthMessage`. HTTP response headers:
    +       ```
    +       x-bsv-auth-version: <version>
    +       x-bsv-auth-message-type: initialResponse
    +       x-bsv-auth-identity-key: <serverPubKeyHex>
    +       x-bsv-auth-nonce: <base64ServerNonce>
    +       x-bsv-auth-your-nonce: <base64ClientNonce>
    +       x-bsv-auth-signature: <hexDERSignature>
    +       x-bsv-auth-requested-certificates: <JSON> (optional)
    +       ```
    +
    +    **Phase 2 — General (authenticated request/response)**
    +
    +    Once the session is established all subsequent HTTP requests carry:
    +    ```
    +    x-bsv-auth-version: <version>
    +    x-bsv-auth-identity-key: <clientPubKeyHex>
    +    x-bsv-auth-nonce: <base64Nonce>
    +    x-bsv-auth-your-nonce: <base64ServerNonce>
    +    x-bsv-auth-request-id: <base64RequestId>
    +    x-bsv-auth-signature: <hexDERSignature>
    +    ```
    +
    +    The signed payload includes: `requestId || method || pathname || search
    +    || headers (sorted) || body`.
    +
    +    The server responds with:
    +    ```
    +    x-bsv-auth-version: <version>
    +    x-bsv-auth-identity-key: <serverPubKeyHex>
    +    x-bsv-auth-nonce: <base64Nonce>
    +    x-bsv-auth-your-nonce: <base64ClientNonce>
    +    x-bsv-auth-request-id: <base64RequestId>
    +    x-bsv-auth-signature: <hexDERSignature>
    +    ```
    +
    +    The signed response payload includes: `requestId || statusCode ||
    +    headers (sorted) || body`.
    +
    +    ### Certificate flow (optional)
    +
    +    If the server declares `certificatesToRequest`, it embeds the request set
    +    in the `x-bsv-auth-requested-certificates` header of the `initialResponse`.
    +    The client then provides certificates in a follow-up `/.well-known/auth`
    +    call before the `next()` middleware proceeds. The server waits up to
    +    30 seconds; timeout returns 408.
    +
    +    ### Unauthenticated pass-through
    +
    +    If `allowUnauthenticated: true` is set in middleware options, requests
    +    without auth headers proceed with `req.auth.identityKey = 'unknown'`.
    +
    +    ## Implementation-specific notes
    +
    +    - `ExpressTransport` intercepts `res.status`, `res.json`, `res.send`,
    +      `res.set`, `res.end`, `res.sendFile`, and `res.text` to buffer the
    +      response until after `Peer.toPeer` signs and re-emits it. Original
    +      methods are saved as `res.__status`, `res.__json`, etc.
    +    - The `RequestId` is a 32-byte random value encoded as base64.
    +    - Nonces are single-use; the `SessionManager` stores seen nonces to
    +      prevent replay. Deployments that run multiple server instances should
    +      use a shared `AsyncSessionManager` store so every instance can resolve
    +      the same nonce/session state during the handshake.
    +
    +servers:
    +  httpServer:
    +    host: "{host}"
    +    pathname: "/.well-known/auth"
    +    protocol: https
    +    description: |
    +      HTTP endpoint for BRC-103 non-general (initial handshake) messages.
    +      General (authenticated) messages use normal application paths.
    +    variables:
    +      host:
    +        default: messagebox.babbage.systems
    +
    +# ---------------------------------------------------------------------------
    +# Components
    +# ---------------------------------------------------------------------------
    +components:
    +  schemas:
    +    PubKeyHex:
    +      type: string
    +      pattern: "^0[23][0-9a-fA-F]{64}$"
    +      description: Compressed secp256k1 public key, 66 hex characters.
    +
    +    Base64String:
    +      type: string
    +      description: Base64-encoded binary data.
    +
    +    HexString:
    +      type: string
    +      pattern: "^[0-9a-fA-F]+$"
    +      description: Hex-encoded binary data.
    +
    +    AuthMessageType:
    +      type: string
    +      enum: [initialRequest, initialResponse, general]
    +      description: |
    +        - `initialRequest`  — first message from the initiating party
    +        - `initialResponse` — response from the receiving party completing Phase 1
    +        - `general`         — signed application message (Phase 2)
    +
    +    AuthMessage:
    +      type: object
    +      description: |
    +        The core BRC-103 message envelope. Transported over HTTP bodies
    +        (at `/.well-known/auth`) or Socket.IO `authMessage` events.
    +      required: [messageType, version, identityKey]
    +      properties:
    +        messageType:
    +          $ref: "#/components/schemas/AuthMessageType"
    +        version:
    +          type: string
    +          description: Auth protocol version (e.g. "0.1").
    +        identityKey:
    +          $ref: "#/components/schemas/PubKeyHex"
    +          description: Public identity key of the sender of this message.
    +        nonce:
    +          $ref: "#/components/schemas/Base64String"
    +          description: |
    +            Fresh single-use random value generated by the sender.
    +            Stored in the `SessionManager` to prevent replay. Multi-instance
    +            deployments should store it in a shared `AsyncSessionManager`
    +            implementation.
    +        yourNonce:
    +          $ref: "#/components/schemas/Base64String"
    +          description: Echo of the peer's nonce from the previous message.
    +        initialNonce:
    +          $ref: "#/components/schemas/Base64String"
    +          description: |
    +            Present in `initialRequest` only. The very first nonce from the
    +            initiating party before a session key is established.
    +        payload:
    +          type: array
    +          items:
    +            type: integer
    +            minimum: 0
    +            maximum: 255
    +          description: |
    +            For `general` messages: the signed application payload.
    +            Encoding: `requestId(32) || VarInt(statusCode) || VarInt(nHeaders)
    +            || [header pairs] || VarInt(bodyLength) || body`.
    +            For handshake messages: empty or absent.
    +        signature:
    +          type: array
    +          items:
    +            type: integer
    +            minimum: 0
    +            maximum: 255
    +          description: DER-encoded ECDSA signature over the payload.
    +        requestedCertificates:
    +          type: object
    +          description: |
    +            BRC-52 certificate request set. Present in `initialResponse` when
    +            the server requires certificates from the client.
    +          additionalProperties: true
    +
    +    # -------------------------------------------------------------------------
    +    # HTTP header shapes (informational — not AsyncAPI schema objects)
    +    # -------------------------------------------------------------------------
    +    InitialRequestHeaders:
    +      type: object
    +      description: |
    +        HTTP request headers sent by the client when initiating the BRC-103
    +        handshake at POST `/.well-known/auth`.
    +      required:
    +        - x-bsv-auth-version
    +        - x-bsv-auth-identity-key
    +        - x-bsv-auth-nonce
    +      properties:
    +        x-bsv-auth-version:
    +          type: string
    +        x-bsv-auth-identity-key:
    +          $ref: "#/components/schemas/PubKeyHex"
    +        x-bsv-auth-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +
    +    InitialResponseHeaders:
    +      type: object
    +      description: |
    +        HTTP response headers set by the server completing Phase 1 of the
    +        BRC-103 handshake.
    +      required:
    +        - x-bsv-auth-version
    +        - x-bsv-auth-message-type
    +        - x-bsv-auth-identity-key
    +        - x-bsv-auth-nonce
    +        - x-bsv-auth-your-nonce
    +        - x-bsv-auth-signature
    +      properties:
    +        x-bsv-auth-version:
    +          type: string
    +        x-bsv-auth-message-type:
    +          type: string
    +          enum: [initialResponse]
    +        x-bsv-auth-identity-key:
    +          $ref: "#/components/schemas/PubKeyHex"
    +        x-bsv-auth-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-your-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-signature:
    +          $ref: "#/components/schemas/HexString"
    +        x-bsv-auth-requested-certificates:
    +          type: string
    +          description: JSON-encoded BRC-52 certificate request set (optional).
    +
    +    GeneralRequestHeaders:
    +      type: object
    +      description: |
    +        HTTP request headers sent by the client for every authenticated
    +        application request (Phase 2).
    +      required:
    +        - x-bsv-auth-version
    +        - x-bsv-auth-identity-key
    +        - x-bsv-auth-nonce
    +        - x-bsv-auth-your-nonce
    +        - x-bsv-auth-request-id
    +        - x-bsv-auth-signature
    +      properties:
    +        x-bsv-auth-version:
    +          type: string
    +        x-bsv-auth-identity-key:
    +          $ref: "#/components/schemas/PubKeyHex"
    +        x-bsv-auth-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-your-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-request-id:
    +          $ref: "#/components/schemas/Base64String"
    +          description: 32-byte random value, base64-encoded.
    +        x-bsv-auth-signature:
    +          $ref: "#/components/schemas/HexString"
    +          description: |
    +            ECDSA signature over:
    +            `requestId(32B) || VarInt(method.length) || method
    +            || VarInt(pathname.length) || pathname
    +            || VarInt(search.length) || search (or -1 if empty)
    +            || VarInt(nHeaders) || [sorted header pairs]
    +            || VarInt(bodyLength) || body (or -1 if empty)`.
    +
    +    GeneralResponseHeaders:
    +      type: object
    +      description: |
    +        HTTP response headers set by the server on every authenticated
    +        application response (Phase 2).
    +      required:
    +        - x-bsv-auth-version
    +        - x-bsv-auth-identity-key
    +        - x-bsv-auth-nonce
    +        - x-bsv-auth-your-nonce
    +        - x-bsv-auth-request-id
    +        - x-bsv-auth-signature
    +      properties:
    +        x-bsv-auth-version:
    +          type: string
    +        x-bsv-auth-identity-key:
    +          $ref: "#/components/schemas/PubKeyHex"
    +        x-bsv-auth-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-your-nonce:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-request-id:
    +          $ref: "#/components/schemas/Base64String"
    +        x-bsv-auth-signature:
    +          $ref: "#/components/schemas/HexString"
    +          description: |
    +            ECDSA signature over:
    +            `requestId(32B) || VarInt(statusCode)
    +            || VarInt(nHeaders) || [sorted non-auth x-bsv header pairs]
    +            || VarInt(bodyLength) || body (or -1 if empty)`.
    +
    +    # -------------------------------------------------------------------------
    +    # Error shapes
    +    # -------------------------------------------------------------------------
    +    AuthError401:
    +      type: object
    +      description: Returned when mutual authentication fails (no or bad auth headers).
    +      required: [status, code, message]
    +      properties:
    +        status:
    +          type: string
    +          enum: [error]
    +        code:
    +          type: string
    +          enum: [UNAUTHORIZED, ERR_AUTH_FAILED]
    +        message:
    +          type: string
    +
    +    AuthError408:
    +      type: object
    +      description: |
    +        Returned when the server is waiting for client certificates
    +        and the 30-second timeout elapses.
    +      required: [status, code, message]
    +      properties:
    +        status:
    +          type: string
    +          enum: [error]
    +        code:
    +          type: string
    +          enum: [CERTIFICATE_TIMEOUT]
    +        message:
    +          type: string
    +
    +    AuthError500:
    +      type: object
    +      description: |
    +        Returned when the server fails to sign its response payload
    +        (`ERR_RESPONSE_SIGNING_FAILED`).
    +      required: [status, code, description]
    +      properties:
    +        status:
    +          type: string
    +          enum: [error]
    +        code:
    +          type: string
    +          enum: [ERR_RESPONSE_SIGNING_FAILED, ERR_INTERNAL_SERVER_ERROR]
    +        description:
    +          type: string
    +
    +    RequestAuthPayload:
    +      type: object
    +      description: |
    +        Informational schema: the signed payload for a `general` REQUEST.
    +        Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`.
    +
    +        Wire encoding (binary, concatenated):
    +        | Field            | Encoding                                 |
    +        |------------------|------------------------------------------|
    +        | requestId        | 32 raw bytes (decoded from base64)       |
    +        | method           | VarInt(len) + UTF-8 bytes                |
    +        | pathname         | VarInt(len) + UTF-8 bytes                |
    +        | search           | VarInt(len) + UTF-8 bytes, or VarInt(-1) |
    +        | nHeaders         | VarInt                                   |
    +        | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val  |
    +        | bodyLength       | VarInt(len) or VarInt(-1)                |
    +        | body             | raw bytes                                |
    +
    +        Only these headers are included (sorted, lowercase):
    +        - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`)
    +        - `content-type` (normalized: type only, no parameters)
    +        - `authorization`
    +
    +    ResponseAuthPayload:
    +      type: object
    +      description: |
    +        Informational schema: the signed payload for a `general` RESPONSE.
    +        Assembled by `buildResponsePayload` in `ExpressTransport`.
    +
    +        Wire encoding (binary, concatenated):
    +        | Field            | Encoding                                 |
    +        |------------------|------------------------------------------|
    +        | requestId        | 32 raw bytes (decoded from base64)       |
    +        | statusCode       | VarInt                                   |
    +        | nHeaders         | VarInt                                   |
    +        | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val  |
    +        | bodyLength       | VarInt(len) or VarInt(-1)                |
    +        | body             | raw bytes                                |
    +
    +        Only these response headers are included (sorted, lowercase):
    +        - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`)
    +        - `authorization`
    +
    +# ---------------------------------------------------------------------------
    +# Channels
    +# ---------------------------------------------------------------------------
    +channels:
    +
    +  wellKnownAuth:
    +    address: "/.well-known/auth"
    +    description: |
    +      HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages.
    +      The client POSTs an `AuthMessage` JSON body; the server replies with an
    +      `AuthMessage` JSON body and the `x-bsv-auth-*` response headers.
    +
    +      In Socket.IO transports the same exchange happens over the `authMessage`
    +      Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP
    +      endpoint.
    +    messages:
    +      initialRequest:
    +        name: initialRequest
    +        summary: Client initiates the BRC-103 handshake.
    +        description: |
    +          The client generates a nonce, signs it, and sends the
    +          `initialRequest` AuthMessage as the POST body.
    +        headers:
    +          $ref: "#/components/schemas/InitialRequestHeaders"
    +        payload:
    +          $ref: "#/components/schemas/AuthMessage"
    +        examples:
    +          - name: example-initial-request
    +            payload:
    +              messageType: initialRequest
    +              version: "0.1"
    +              identityKey: "028d37b941208cd6b8a4c28288eda5f2f16c2b3ab0fcb6d13c18b47fe37b971fc1"
    +              nonce: "dGVzdE5vbmNlMTIzNA=="
    +              initialNonce: "dGVzdE5vbmNlMTIzNA=="
    +              payload: []
    +              signature: []
    +
    +      initialResponse:
    +        name: initialResponse
    +        summary: Server completes Phase 1 of the BRC-103 handshake.
    +        description: |
    +          The server validates the client's nonce/signature, generates its own
    +          nonce, signs the response, and replies. The body is an `AuthMessage`
    +          JSON object. Response headers carry the `x-bsv-auth-*` fields.
    +
    +          If `certificatesToRequest` is configured, the
    +          `x-bsv-auth-requested-certificates` header contains the JSON-encoded
    +          request set. The client must supply certificates in a follow-up
    +          POST before the session is fully established.
    +        headers:
    +          $ref: "#/components/schemas/InitialResponseHeaders"
    +        payload:
    +          $ref: "#/components/schemas/AuthMessage"
    +
    +  generalRequest:
    +    address: "{applicationPath}"
    +    description: |
    +      Every authenticated application HTTP request (Phase 2). The path is
    +      the actual application endpoint (e.g. `/sendMessage`, `/listMessages`).
    +      The auth headers are attached alongside any application-specific headers.
    +    parameters:
    +      applicationPath:
    +        description: The application route path (e.g. /sendMessage).
    +    messages:
    +      generalRequestMessage:
    +        name: generalRequestMessage
    +        summary: Authenticated application request.
    +        description: |
    +          The client sends application-level request headers and body, augmented
    +          with `x-bsv-auth-*` mutual-auth headers. The `x-bsv-auth-signature`
    +          covers the entire request (method, path, query string, signed headers,
    +          and body) as described in `RequestAuthPayload`.
    +        headers:
    +          $ref: "#/components/schemas/GeneralRequestHeaders"
    +        payload:
    +          description: Application-defined request body (any content type).
    +
    +  generalResponse:
    +    address: "{applicationPath}"
    +    description: |
    +      Every authenticated application HTTP response (Phase 2). The server
    +      signs the response status code, relevant headers, and body before sending.
    +    parameters:
    +      applicationPath:
    +        description: The application route path.
    +    messages:
    +      generalResponseMessage:
    +        name: generalResponseMessage
    +        summary: Authenticated application response.
    +        description: |
    +          The server buffers the handler's response via `ResponseWriterWrapper`,
    +          calls `Peer.toPeer` to sign it, and flushes the signed response
    +          including `x-bsv-auth-*` response headers. The `x-bsv-auth-signature`
    +          covers `requestId || statusCode || signed response headers || body`.
    +        headers:
    +          $ref: "#/components/schemas/GeneralResponseHeaders"
    +        payload:
    +          description: Application-defined response body.
    +
    +  authError:
    +    address: "{applicationPath}"
    +    description: |
    +      Error responses emitted by the auth middleware when authentication fails.
    +    parameters:
    +      applicationPath:
    +        description: The path at which the error was encountered.
    +    messages:
    +      unauthorized:
    +        name: unauthorized
    +        summary: 401 — mutual auth failed (no or bad auth headers).
    +        payload:
    +          $ref: "#/components/schemas/AuthError401"
    +
    +      certificateTimeout:
    +        name: certificateTimeout
    +        summary: 408 — server waited 30 s for client certificates and timed out.
    +        payload:
    +          $ref: "#/components/schemas/AuthError408"
    +
    +      signingFailed:
    +        name: signingFailed
    +        summary: 500 — server failed to sign its response payload.
    +        payload:
    +          $ref: "#/components/schemas/AuthError500"
    +
    +# ---------------------------------------------------------------------------
    +# Operations
    +# ---------------------------------------------------------------------------
    +operations:
    +
    +  sendInitialRequest:
    +    action: send
    +    channel:
    +      $ref: "#/channels/wellKnownAuth"
    +    summary: Client initiates BRC-103 handshake (Phase 1, step 1).
    +    description: |
    +      Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`.
    +      The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`.
    +    messages:
    +      - $ref: "#/channels/wellKnownAuth/messages/initialRequest"
    +
    +  receiveInitialResponse:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/wellKnownAuth"
    +    summary: Client receives the server's Phase 1 challenge response.
    +    description: |
    +      Server replies with `initialResponse`. If `requestedCertificates` is
    +      non-empty the client must send a follow-up request with the required
    +      certificates before proceeding to Phase 2.
    +    messages:
    +      - $ref: "#/channels/wellKnownAuth/messages/initialResponse"
    +
    +  sendGeneralRequest:
    +    action: send
    +    channel:
    +      $ref: "#/channels/generalRequest"
    +    summary: Client sends an authenticated application request (Phase 2).
    +    description: |
    +      Any application HTTP request after the handshake. The client attaches
    +      `x-bsv-auth-*` headers and a fresh signed payload covering the full
    +      request. The server uses `buildAuthMessageFromRequest` to reconstruct
    +      and verify the payload.
    +    messages:
    +      - $ref: "#/channels/generalRequest/messages/generalRequestMessage"
    +
    +  receiveGeneralResponse:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/generalResponse"
    +    summary: Client receives the server's authenticated application response (Phase 2).
    +    description: |
    +      The server's response includes `x-bsv-auth-*` headers and a signature
    +      over the response payload. The client can verify the response origin
    +      using `buildResponsePayload` semantics.
    +    messages:
    +      - $ref: "#/channels/generalResponse/messages/generalResponseMessage"
    +
    +  receiveAuthError:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/authError"
    +    summary: Client receives an auth error from the middleware.
    +    messages:
    +      - $ref: "#/channels/authError/messages/unauthorized"
    +      - $ref: "#/channels/authError/messages/certificateTimeout"
    +      - $ref: "#/channels/authError/messages/signingFailed"
    +
    +
    + + + + diff --git a/docs-site/public/assets/asyncapi/gasp/index.html b/docs-site/public/assets/asyncapi/gasp/index.html index b134c1cf5..7f67491f4 100644 --- a/docs-site/public/assets/asyncapi/gasp/index.html +++ b/docs-site/public/assets/asyncapi/gasp/index.html @@ -1,70 +1,46 @@ - - - - - - GASP — Graph Aware Sync Protocol 1.0.0 documentation - - - - + + + + + + + GASP — Graph Aware Sync Protocol · AsyncAPI + - - -
    GASP — Graph Aware Sync Protocol 1.0.0

    AsyncAPI specification for GASP (Graph Aware Sync Protocol), the + +

    +
    AsyncAPI 3.1.0 · specs/sync/gasp-asyncapi.yaml
    +

    GASP — Graph Aware Sync Protocol

    v1.0.0
    +
    AsyncAPI specification for GASP (Graph Aware Sync Protocol), the cross-node UTXO synchronisation protocol implemented in -gasp-core (@bsv/gasp-core).

    -

    GASP is a bidirectional gossip/sync protocol between overlay nodes. -Two parties exchange UTXO lists (the "initial exchange") and then +`gasp-core` (`@bsv/gasp-core`). + +GASP is a bidirectional gossip/sync protocol between overlay nodes. +Two parties exchange UTXO lists (the "initial exchange") and then walk the transaction graph in a request/response pattern to transfer -any UTXOs the counterparty does not yet hold.

    -

    Protocol flow (normal, bidirectional)

    -
    Initiator                                   Responder
    +any UTXOs the counterparty does not yet hold.
    +
    +## Protocol flow (normal, bidirectional)
    +
    +```
    +Initiator                                   Responder
        |                                             |
        |-- GASPInitialRequest ---------------------->|
        |<- GASPInitialResponse -----------------------|
    @@ -79,694 +55,808 @@ 

    Protocol flow (normal, bidirectional |-- GASPNodeResponse ------------------------>| | (repeat until graph is complete) | | -

    -

    Source of truth: /ts/gasp-core/src/GASP.ts

    -

    Operations

    • SEND gasp/initialRequest

      Initiator sends its sync parameters. The responder replies on the -gasp/initialResponse channel.

      -

      Initiator sends sync parameters to the responder.

      Operation IDsendInitialRequest

      Accepts the following message:

      GASP Initial Request

      First message in a GASP sync session. The initiator declares its +``` + +Source of truth: /ts/gasp-core/src/GASP.ts +

      +
      0Servers7Channels7Operations6Messages8Schemas
      + + +
      +
      +

      Channels

      7
      +
      +

      gaspInitialRequest

      +

      gasp/initialRequest

      +
      Initiator sends its sync parameters. The responder replies on the +`gasp/initialResponse` channel. +
      +
      address
      gasp/initialRequest
      description
      Initiator sends its sync parameters. The responder replies on the +`gasp/initialResponse` channel. +
      messages
      1 field
      GASPInitialRequest
      1 field
      $ref
      #/components/messages/GASPInitialRequest
      +
      +

      gaspInitialResponse

      +

      gasp/initialResponse

      +
      Responder sends back its list of known UTXOs and the timestamp from +which it wants to receive UTXOs from the initiator. +
      +
      address
      gasp/initialResponse
      description
      Responder sends back its list of known UTXOs and the timestamp from +which it wants to receive UTXOs from the initiator. +
      messages
      1 field
      GASPInitialResponse
      1 field
      $ref
      #/components/messages/GASPInitialResponse
      +
      +

      gaspInitialReply

      +

      gasp/initialReply

      +
      Initiator (if operating in bidirectional mode) sends the set of UTXOs +it holds that the responder does not. Absent in unidirectional mode. +
      +
      address
      gasp/initialReply
      description
      Initiator (if operating in bidirectional mode) sends the set of UTXOs +it holds that the responder does not. Absent in unidirectional mode. +
      messages
      1 field
      GASPInitialReply
      1 field
      $ref
      #/components/messages/GASPInitialReply
      +
      +

      gaspRequestNode

      +

      gasp/requestNode

      +
      Either party requests a specific graph node (transaction + output) from +the other. Used when walking the transaction graph to hydrate UTXOs. +
      +
      address
      gasp/requestNode
      description
      Either party requests a specific graph node (transaction + output) from +the other. Used when walking the transaction graph to hydrate UTXOs. +
      messages
      1 field
      GASPNodeRequest
      1 field
      $ref
      #/components/messages/GASPNodeRequest
      +
      +

      gaspNode

      +

      gasp/node

      +
      The responding party delivers the requested GASPNode (raw transaction, +optional BUMP proof, optional metadata). +
      +
      address
      gasp/node
      description
      The responding party delivers the requested GASPNode (raw transaction, +optional BUMP proof, optional metadata). +
      messages
      1 field
      GASPNode
      1 field
      $ref
      #/components/messages/GASPNode
      +
      +

      gaspSubmitNode

      +

      gasp/submitNode

      +
      A party submits a node it is trying to push to the counterparty. +The counterparty appends it to the temporary graph and may respond +with a list of additional inputs it still needs. +
      +
      address
      gasp/submitNode
      description
      A party submits a node it is trying to push to the counterparty. +The counterparty appends it to the temporary graph and may respond +with a list of additional inputs it still needs. +
      messages
      1 field
      GASPNode
      1 field
      $ref
      #/components/messages/GASPNode
      +
      +

      gaspNodeResponse

      +

      gasp/nodeResponse

      +
      Response to a submitted node; specifies which additional input transactions +(if any) the recipient still needs to complete the graph. An empty / null +response means the graph is complete. +
      +
      address
      gasp/nodeResponse
      description
      Response to a submitted node; specifies which additional input transactions +(if any) the recipient still needs to complete the graph. An empty / null +response means the graph is complete. +
      messages
      1 field
      GASPNodeResponse
      1 field
      $ref
      #/components/messages/GASPNodeResponse
      +
      +
      +

      Operations

      7
      +
      +

      sendInitialRequest

      + send +
      Initiator sends sync parameters to the responder.
      +
      action
      send
      channel
      1 field
      $ref
      #/channels/gaspInitialRequest
      summary
      Initiator sends sync parameters to the responder.
      messages
      1 item
      1. $ref
        #/channels/gaspInitialRequest/messages/GASPInitialRequest
      +
      +

      receiveInitialResponse

      + receive +
      Initiator receives the responder's UTXO list and since timestamp.
      +
      action
      receive
      channel
      1 field
      $ref
      #/channels/gaspInitialResponse
      summary
      Initiator receives the responder's UTXO list and since timestamp.
      messages
      1 item
      1. $ref
        #/channels/gaspInitialResponse/messages/GASPInitialResponse
      +
      +

      sendInitialReply

      + send +
      Initiator (bidirectional mode only) sends UTXOs the responder is missing. +
      +
      action
      send
      channel
      1 field
      $ref
      #/channels/gaspInitialReply
      summary
      Initiator (bidirectional mode only) sends UTXOs the responder is missing. +
      messages
      1 item
      1. $ref
        #/channels/gaspInitialReply/messages/GASPInitialReply
      +
      +

      requestNode

      + send +
      Request a specific transaction node from the counterparty.
      +
      action
      send
      channel
      1 field
      $ref
      #/channels/gaspRequestNode
      summary
      Request a specific transaction node from the counterparty.
      messages
      1 item
      1. $ref
        #/channels/gaspRequestNode/messages/GASPNodeRequest
      +
      +

      deliverNode

      + receive +
      Receive a requested graph node from the counterparty.
      +
      action
      receive
      channel
      1 field
      $ref
      #/channels/gaspNode
      summary
      Receive a requested graph node from the counterparty.
      messages
      1 item
      1. $ref
        #/channels/gaspNode/messages/GASPNode
      +
      +

      submitNode

      + send +
      Push a graph node to the counterparty for ingestion.
      +
      action
      send
      channel
      1 field
      $ref
      #/channels/gaspSubmitNode
      summary
      Push a graph node to the counterparty for ingestion.
      messages
      1 item
      1. $ref
        #/channels/gaspSubmitNode/messages/GASPNode
      +
      +

      receiveNodeResponse

      + receive +
      Receive the counterparty's response to a submitted node, listing any +additional input transactions needed to complete the graph. +
      +
      action
      receive
      channel
      1 field
      $ref
      #/channels/gaspNodeResponse
      summary
      Receive the counterparty's response to a submitted node, listing any +additional input transactions needed to complete the graph. +
      messages
      1 item
      1. $ref
        #/channels/gaspNodeResponse/messages/GASPNodeResponse
      +
      +
      +

      Messages

      6
      +
      +

      GASPInitialRequest

      + +
      First message in a GASP sync session. The initiator declares its protocol version, the timestamp of the last sync with this party, and an optional page size limit. -

      Message IDGASPInitialRequest
      object

      Parameters sent by the initiator to start a GASP sync session. -Version mismatch (current version is 1) causes the responder to throw -GASPVersionMismatchError and abort the session.

      -

      Examples

    • RECEIVE gasp/initialResponse

      Responder sends back its list of known UTXOs and the timestamp from -which it wants to receive UTXOs from the initiator.

      -

      Initiator receives the responder's UTXO list and since timestamp.

      Operation IDreceiveInitialResponse

      Accepts the following message:

      GASP Initial Response

      Responder's reply to GASPInitialRequest. Contains the list of UTXOs +

      +
      name
      GASPInitialRequest
      title
      GASP Initial Request
      summary
      First message in a GASP sync session. The initiator declares its +protocol version, the timestamp of the last sync with this party, and +an optional page size limit. +
      payload
      1 field
      $ref
      #/components/schemas/GASPInitialRequest
      +
      +

      GASPInitialResponse

      + +
      Responder's reply to GASPInitialRequest. Contains the list of UTXOs +the responder has seen since `request.since`, plus the timestamp from +which the responder wants UTXOs back from the initiator. +
      +
      name
      GASPInitialResponse
      title
      GASP Initial Response
      summary
      Responder's reply to GASPInitialRequest. Contains the list of UTXOs the responder has seen since `request.since`, plus the timestamp from which the responder wants UTXOs back from the initiator. -

      Message IDGASPInitialResponse
      object

      Responder's answer to GASPInitialRequest. UTXOList contains all -UTXOs the responder has seen since request.since; unconfirmed -(non-timestamped) UTXOs are always included regardless of timestamp.

      -

      Examples

    • SEND gasp/initialReply

      Initiator (if operating in bidirectional mode) sends the set of UTXOs -it holds that the responder does not. Absent in unidirectional mode.

      -

      Initiator (bidirectional mode only) sends UTXOs the responder is missing. -

      Operation IDsendInitialReply

      Accepts the following message:

      GASP Initial Reply

      Initiator's follow-up (bidirectional mode). UTXOs the initiator holds +

      payload
      1 field
      $ref
      #/components/schemas/GASPInitialResponse
      +
      +

      GASPInitialReply

      + +
      Initiator's follow-up (bidirectional mode). UTXOs the initiator holds that were not in the Initial Response — i.e. UTXOs the responder needs. -

      Message IDGASPInitialReply
      object

      Sent by the initiator in bidirectional mode. Contains UTXOs the -initiator holds that are newer than response.since AND were not -already present in the Initial Response (so the responder can ingest -them).

      -

      Examples

    • SEND gasp/requestNode

      Either party requests a specific graph node (transaction + output) from -the other. Used when walking the transaction graph to hydrate UTXOs.

      -

      Request a specific transaction node from the counterparty.

      Operation IDrequestNode

      Accepts the following message:

      GASP Node Request

      Request for a specific transaction node identified by graphID, txid, +

      +
      name
      GASPInitialReply
      title
      GASP Initial Reply
      summary
      Initiator's follow-up (bidirectional mode). UTXOs the initiator holds +that were not in the Initial Response — i.e. UTXOs the responder needs. +
      payload
      1 field
      $ref
      #/components/schemas/GASPInitialReply
      +
      +

      GASPNodeRequest

      + +
      Request for a specific transaction node identified by graphID, txid, +outputIndex, and whether transaction/output metadata should be included. +
      +
      name
      GASPNodeRequest
      title
      GASP Node Request
      summary
      Request for a specific transaction node identified by graphID, txid, outputIndex, and whether transaction/output metadata should be included. -

      Message IDGASPNodeRequest
      object

      Request for a specific graph node. graphID is the 36-byte outpoint -string (<txid>.<vout>) identifying the tip of the graph being walked.

      -

      Examples

    • RECEIVE gasp/node

      The responding party delivers the requested GASPNode (raw transaction, -optional BUMP proof, optional metadata).

      -

      Receive a requested graph node from the counterparty.

      Operation IDdeliverNode

      Accepts the following message:

      GASP Node

      A transaction node: the raw transaction, the output index, an optional +

      payload
      1 field
      $ref
      #/components/schemas/GASPNodeRequest
      +
      +

      GASPNode

      + +
      A transaction node: the raw transaction, the output index, an optional BUMP merkle proof, optional metadata strings, and a mapping of input outpoints to metadata hashes so the receiver can request ancestors. -

      Message IDGASPNode
      object

      A fully-hydrated graph node. rawTx is the complete serialised -Bitcoin transaction in hex. proof is a hex-encoded BUMP (BRC-74) -merkle proof, only present for confirmed transactions. inputs maps -each input outpoint (<txid>.<vout>) to the hash of its metadata, -allowing the recipient to detect when it needs updated metadata.

      -

      Examples

    • SEND gasp/submitNode

      A party submits a node it is trying to push to the counterparty. -The counterparty appends it to the temporary graph and may respond -with a list of additional inputs it still needs.

      -

      Push a graph node to the counterparty for ingestion.

      Operation IDsubmitNode

      Accepts the following message:

      GASP Node

      A transaction node: the raw transaction, the output index, an optional +

      +
      name
      GASPNode
      title
      GASP Node
      summary
      A transaction node: the raw transaction, the output index, an optional BUMP merkle proof, optional metadata strings, and a mapping of input outpoints to metadata hashes so the receiver can request ancestors. -

      Message IDGASPNode
      object

      A fully-hydrated graph node. rawTx is the complete serialised -Bitcoin transaction in hex. proof is a hex-encoded BUMP (BRC-74) -merkle proof, only present for confirmed transactions. inputs maps -each input outpoint (<txid>.<vout>) to the hash of its metadata, -allowing the recipient to detect when it needs updated metadata.

      -

      Examples

    • RECEIVE gasp/nodeResponse

      Response to a submitted node; specifies which additional input transactions -(if any) the recipient still needs to complete the graph. An empty / null -response means the graph is complete.

      -

      Receive the counterparty's response to a submitted node, listing any -additional input transactions needed to complete the graph. -

      Operation IDreceiveNodeResponse

      Accepts the following message:

      GASP Node Response

      Response to a submitted GASPNode. Lists the input outpoints (in +

      payload
      1 field
      $ref
      #/components/schemas/GASPNode
      +
      +

      GASPNodeResponse

      + +
      Response to a submitted GASPNode. Lists the input outpoints (in 36-byte `<txid>.<vout>` format) that the recipient still needs to complete the graph. A null / absent response means no further inputs are required and the graph is complete. -

      Message IDGASPNodeResponse
      object

      Response to a submitted GASPNode. requestedInputs lists outpoints -the recipient still needs in order to complete the graph and whether -metadata is required for each. If null or omitted, the graph is -complete and will be validated and finalised.

      -

      Examples

    Messages

    • #1GASP Initial Request

      First message in a GASP sync session. The initiator declares its -protocol version, the timestamp of the last sync with this party, and -an optional page size limit. -

      Message IDGASPInitialRequest
      object

      Parameters sent by the initiator to start a GASP sync session. -Version mismatch (current version is 1) causes the responder to throw -GASPVersionMismatchError and abort the session.

      -
    • #2GASP Initial Response

      Responder's reply to GASPInitialRequest. Contains the list of UTXOs -the responder has seen since `request.since`, plus the timestamp from -which the responder wants UTXOs back from the initiator. -

      Message IDGASPInitialResponse
      object

      Responder's answer to GASPInitialRequest. UTXOList contains all -UTXOs the responder has seen since request.since; unconfirmed -(non-timestamped) UTXOs are always included regardless of timestamp.

      -
    • #3GASP Initial Reply

      Initiator's follow-up (bidirectional mode). UTXOs the initiator holds -that were not in the Initial Response — i.e. UTXOs the responder needs. -

      Message IDGASPInitialReply
      object

      Sent by the initiator in bidirectional mode. Contains UTXOs the -initiator holds that are newer than response.since AND were not -already present in the Initial Response (so the responder can ingest -them).

      -
    • #4GASP Node Request

      Request for a specific transaction node identified by graphID, txid, -outputIndex, and whether transaction/output metadata should be included. -

      Message IDGASPNodeRequest
      object

      Request for a specific graph node. graphID is the 36-byte outpoint -string (<txid>.<vout>) identifying the tip of the graph being walked.

      -
    • #5GASP Node

      A transaction node: the raw transaction, the output index, an optional -BUMP merkle proof, optional metadata strings, and a mapping of input -outpoints to metadata hashes so the receiver can request ancestors. -

      Message IDGASPNode
      object

      A fully-hydrated graph node. rawTx is the complete serialised -Bitcoin transaction in hex. proof is a hex-encoded BUMP (BRC-74) -merkle proof, only present for confirmed transactions. inputs maps -each input outpoint (<txid>.<vout>) to the hash of its metadata, -allowing the recipient to detect when it needs updated metadata.

      -
    • #6GASP Node Response

      Response to a submitted GASPNode. Lists the input outpoints (in +

      +
      name
      GASPNodeResponse
      title
      GASP Node Response
      summary
      Response to a submitted GASPNode. Lists the input outpoints (in 36-byte `<txid>.<vout>` format) that the recipient still needs to complete the graph. A null / absent response means no further inputs are required and the graph is complete. -

      Message IDGASPNodeResponse
      object

      Response to a submitted GASPNode. requestedInputs lists outpoints -the recipient still needs in order to complete the graph and whether -metadata is required for each. If null or omitted, the graph is -complete and will be validated and finalised.

      -

    Schemas

    • object

      Parameters sent by the initiator to start a GASP sync session. +

      payload
      1 field
      $ref
      #/components/schemas/GASPNodeResponse
      +
      +
    +

    Schemas

    8
    +
    +

    GASPInitialRequest

    + +
    Parameters sent by the initiator to start a GASP sync session. Version mismatch (current version is 1) causes the responder to throw -GASPVersionMismatchError and abort the session.

    -
  • object

    Responder's answer to GASPInitialRequest. UTXOList contains all -UTXOs the responder has seen since request.since; unconfirmed -(non-timestamped) UTXOs are always included regardless of timestamp.

    -
  • object

    Sent by the initiator in bidirectional mode. Contains UTXOs the -initiator holds that are newer than response.since AND were not +GASPVersionMismatchError and abort the session. +

    +
    type
    object
    description
    Parameters sent by the initiator to start a GASP sync session. +Version mismatch (current version is 1) causes the responder to throw +GASPVersionMismatchError and abort the session. +
    required
    2 items
    1. version
    2. since
    properties
    3 fields
    version
    4 fields
    type
    integer
    description
    GASP protocol version. Currently always 1.
    enum
    1 item
    1. 1
    example
    1
    since
    4 fields
    type
    integer
    minimum
    0
    description
    UNIX timestamp (seconds since epoch) of the last successful sync +with this counterparty. Use 0 to request all UTXOs. +Must be a non-negative integer. +
    example
    1714000000
    limit
    4 fields
    type
    integer
    minimum
    1
    description
    Optional maximum number of UTXOs the responder should return per +page. When the response contains exactly `limit` items the +initiator MUST send another GASPInitialRequest to fetch the next +page. Absent means "return all". +
    example
    1000
    +
    +

    GASPInitialResponse

    + +
    Responder's answer to GASPInitialRequest. `UTXOList` contains all +UTXOs the responder has seen since `request.since`; unconfirmed +(non-timestamped) UTXOs are always included regardless of timestamp. +
    +
    type
    object
    description
    Responder's answer to GASPInitialRequest. `UTXOList` contains all +UTXOs the responder has seen since `request.since`; unconfirmed +(non-timestamped) UTXOs are always included regardless of timestamp. +
    required
    2 items
    1. UTXOList
    2. since
    properties
    2 fields
    UTXOList
    3 fields
    type
    array
    description
    UTXOs the responder knows about (after `request.since`). The +initiator will request any of these it does not already hold. +
    items
    1 field
    $ref
    #/components/schemas/GASPOutput
    since
    4 fields
    type
    integer
    minimum
    0
    description
    Timestamp from which the responder wants to receive UTXOs back +from the initiator (used in the GASPInitialReply filter step). +
    example
    1714001000
    +
    +

    GASPInitialReply

    + +
    Sent by the initiator in bidirectional mode. Contains UTXOs the +initiator holds that are newer than `response.since` AND were not +already present in the Initial Response (so the responder can ingest +them). +
    +
    type
    object
    description
    Sent by the initiator in bidirectional mode. Contains UTXOs the +initiator holds that are newer than `response.since` AND were not already present in the Initial Response (so the responder can ingest -them).

    -
  • object

    Minimal outpoint descriptor used in the initial exchange phases. -score is a sortable timestamp (seconds since epoch) assigned when -the UTXO was first confirmed; unconfirmed UTXOs may have score 0.

    -
  • object

    Request for a specific graph node. graphID is the 36-byte outpoint -string (<txid>.<vout>) identifying the tip of the graph being walked.

    -
  • object

    A fully-hydrated graph node. rawTx is the complete serialised -Bitcoin transaction in hex. proof is a hex-encoded BUMP (BRC-74) -merkle proof, only present for confirmed transactions. inputs maps -each input outpoint (<txid>.<vout>) to the hash of its metadata, -allowing the recipient to detect when it needs updated metadata.

    -
  • object

    Response to a submitted GASPNode. requestedInputs lists outpoints +them). +

    required
    1 item
    1. UTXOList
    properties
    1 field
    UTXOList
    3 fields
    type
    array
    description
    UTXOs the responder needs from the initiator.
    items
    1 field
    $ref
    #/components/schemas/GASPOutput
    +
    +

    GASPOutput

    + +
    Minimal outpoint descriptor used in the initial exchange phases. +`score` is a sortable timestamp (seconds since epoch) assigned when +the UTXO was first confirmed; unconfirmed UTXOs may have score 0. +
    +
    type
    object
    description
    Minimal outpoint descriptor used in the initial exchange phases. +`score` is a sortable timestamp (seconds since epoch) assigned when +the UTXO was first confirmed; unconfirmed UTXOs may have score 0. +
    required
    3 items
    1. txid
    2. outputIndex
    3. score
    properties
    3 fields
    txid
    4 fields
    type
    string
    pattern
    ^[0-9a-fA-F]{64}$
    description
    Transaction ID (hex, 64 characters).
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    Output index (vout) within the transaction.
    example
    0
    score
    3 fields
    type
    number
    description
    Sortable confirmation timestamp (UNIX seconds). 0 for unconfirmed +outputs. Used to filter UTXOs by the `since` parameters. +
    example
    1714000000
    +
    +

    GASPNodeRequest

    + +
    Request for a specific graph node. `graphID` is the 36-byte outpoint +string (`<txid>.<vout>`) identifying the tip of the graph being walked. +
    +
    type
    object
    description
    Request for a specific graph node. `graphID` is the 36-byte outpoint +string (`<txid>.<vout>`) identifying the tip of the graph being walked. +
    required
    4 items
    1. graphID
    2. txid
    3. outputIndex
    4. metadata
    properties
    4 fields
    graphID
    3 fields
    type
    string
    description
    Graph identifier — the 36-byte outpoint string (`<txid>.<vout>`) +of the UTXO at the tip of this sync graph. +
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0
    txid
    4 fields
    type
    string
    pattern
    ^[0-9a-fA-F]{64}$
    description
    Transaction ID of the node being requested.
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    Output index within the requested transaction.
    example
    0
    metadata
    3 fields
    type
    boolean
    description
    Whether the responder should include transaction and output metadata +in the returned GASPNode. +
    example
    true
    +
    +

    GASPNode

    + +
    A fully-hydrated graph node. `rawTx` is the complete serialised +Bitcoin transaction in hex. `proof` is a hex-encoded BUMP (BRC-74) +merkle proof, only present for confirmed transactions. `inputs` maps +each input outpoint (`<txid>.<vout>`) to the hash of its metadata, +allowing the recipient to detect when it needs updated metadata. +
    +
    type
    object
    description
    A fully-hydrated graph node. `rawTx` is the complete serialised +Bitcoin transaction in hex. `proof` is a hex-encoded BUMP (BRC-74) +merkle proof, only present for confirmed transactions. `inputs` maps +each input outpoint (`<txid>.<vout>`) to the hash of its metadata, +allowing the recipient to detect when it needs updated metadata. +
    required
    3 items
    1. graphID
    2. rawTx
    3. outputIndex
    properties
    7 fields
    graphID
    3 fields
    type
    string
    description
    Outpoint string (`<txid>.<vout>`) of the UTXO at the graph tip. +
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0
    rawTx
    3 fields
    type
    string
    description
    Complete Bitcoin transaction serialised as a lowercase hex string.
    example
    0100000001...
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    The output index within rawTx that this node represents.
    example
    0
    proof
    2 fields
    type
    string
    description
    Hex-encoded BUMP merkle proof for the transaction. Present only +when the transaction is confirmed in a block. +
    txMetadata
    2 fields
    type
    string
    description
    Opaque string of transaction-level metadata. Present only when +the request set `metadata: true`. +
    outputMetadata
    2 fields
    type
    string
    description
    Opaque string of output-level metadata. Present only when the +request set `metadata: true`. +
    inputs
    3 fields
    type
    object
    description
    Mapping of input outpoints (`<txid>.<vout>`) to an object +containing the hash of their metadata. Present only when +`metadata: true` was requested. +
    additionalProperties
    3 fields
    type
    object
    required
    1 item
    1. hash
    properties
    1 field
    hash
    2 fields
    type
    string
    description
    Hash of the input's metadata (hex or base64).
    +
    +

    GASPNodeResponse

    + +
    Response to a submitted GASPNode. `requestedInputs` lists outpoints the recipient still needs in order to complete the graph and whether metadata is required for each. If null or omitted, the graph is -complete and will be validated and finalised.

    -
  • object

    Thrown (and serialised into the response) when the responder's GASP -version differs from the version declared in GASPInitialRequest.

    -
  • - - - - - - \ No newline at end of file +complete and will be validated and finalised. + +
    type
    object
    description
    Response to a submitted GASPNode. `requestedInputs` lists outpoints +the recipient still needs in order to complete the graph and whether +metadata is required for each. If null or omitted, the graph is +complete and will be validated and finalised. +
    properties
    1 field
    requestedInputs
    3 fields
    type
    object
    description
    Mapping of input outpoints (`<txid>.<vout>`) to their metadata +requirement. An empty object or absent field signals completion. +
    additionalProperties
    3 fields
    type
    object
    required
    1 item
    1. metadata
    properties
    1 field
    metadata
    2 fields
    type
    boolean
    description
    Whether the submitter should include metadata for this input.
    +
    +

    GASPVersionMismatchError

    + +
    Thrown (and serialised into the response) when the responder's GASP +version differs from the version declared in GASPInitialRequest. +
    +
    type
    object
    description
    Thrown (and serialised into the response) when the responder's GASP +version differs from the version declared in GASPInitialRequest. +
    required
    4 items
    1. code
    2. message
    3. currentVersion
    4. foreignVersion
    properties
    4 fields
    code
    2 fields
    type
    string
    enum
    1 item
    1. ERR_GASP_VERSION_MISMATCH
    message
    2 fields
    type
    string
    example
    GASP version mismatch. Current version: 1, foreign version: 2
    currentVersion
    3 fields
    type
    integer
    description
    The responder's supported GASP version.
    example
    1
    foreignVersion
    3 fields
    type
    integer
    description
    The version declared by the initiator.
    example
    2
    +
    + +
    + Raw YAML source +
    asyncapi: "3.1.0"
    +
    +info:
    +  title: GASP — Graph Aware Sync Protocol
    +  version: "1.0.0"
    +  description: |
    +    AsyncAPI specification for GASP (Graph Aware Sync Protocol), the
    +    cross-node UTXO synchronisation protocol implemented in
    +    `gasp-core` (`@bsv/gasp-core`).
    +
    +    GASP is a bidirectional gossip/sync protocol between overlay nodes.
    +    Two parties exchange UTXO lists (the "initial exchange") and then
    +    walk the transaction graph in a request/response pattern to transfer
    +    any UTXOs the counterparty does not yet hold.
    +
    +    ## Protocol flow (normal, bidirectional)
    +
    +    ```
    +    Initiator                                   Responder
    +       |                                             |
    +       |-- GASPInitialRequest ---------------------->|
    +       |<- GASPInitialResponse -----------------------|
    +       |-- GASPInitialReply ------------------------->|   (if not unidirectional)
    +       |                                             |
    +       |  [for each UTXO the counterparty is missing]
    +       |-- requestNode(graphID, txid, vout, meta) -->|
    +       |<- GASPNode ---------------------------------|
    +       |                                             |
    +       |  [responder may request further inputs]
    +       |<- submitNode(GASPNode) ---------------------|
    +       |-- GASPNodeResponse ------------------------>|
    +       |          (repeat until graph is complete)
    +       |                                             |
    +    ```
    +
    +    Source of truth: /ts/gasp-core/src/GASP.ts
    +  license:
    +    name: Open BSV Licence
    +
    +defaultContentType: application/json
    +
    +# ---------------------------------------------------------------------------
    +# Channels
    +# ---------------------------------------------------------------------------
    +channels:
    +  gaspInitialRequest:
    +    address: gasp/initialRequest
    +    description: |
    +      Initiator sends its sync parameters.  The responder replies on the
    +      `gasp/initialResponse` channel.
    +    messages:
    +      GASPInitialRequest:
    +        $ref: "#/components/messages/GASPInitialRequest"
    +
    +  gaspInitialResponse:
    +    address: gasp/initialResponse
    +    description: |
    +      Responder sends back its list of known UTXOs and the timestamp from
    +      which it wants to receive UTXOs from the initiator.
    +    messages:
    +      GASPInitialResponse:
    +        $ref: "#/components/messages/GASPInitialResponse"
    +
    +  gaspInitialReply:
    +    address: gasp/initialReply
    +    description: |
    +      Initiator (if operating in bidirectional mode) sends the set of UTXOs
    +      it holds that the responder does not.  Absent in unidirectional mode.
    +    messages:
    +      GASPInitialReply:
    +        $ref: "#/components/messages/GASPInitialReply"
    +
    +  gaspRequestNode:
    +    address: gasp/requestNode
    +    description: |
    +      Either party requests a specific graph node (transaction + output) from
    +      the other.  Used when walking the transaction graph to hydrate UTXOs.
    +    messages:
    +      GASPNodeRequest:
    +        $ref: "#/components/messages/GASPNodeRequest"
    +
    +  gaspNode:
    +    address: gasp/node
    +    description: |
    +      The responding party delivers the requested GASPNode (raw transaction,
    +      optional BUMP proof, optional metadata).
    +    messages:
    +      GASPNode:
    +        $ref: "#/components/messages/GASPNode"
    +
    +  gaspSubmitNode:
    +    address: gasp/submitNode
    +    description: |
    +      A party submits a node it is trying to push to the counterparty.
    +      The counterparty appends it to the temporary graph and may respond
    +      with a list of additional inputs it still needs.
    +    messages:
    +      GASPNode:
    +        $ref: "#/components/messages/GASPNode"
    +
    +  gaspNodeResponse:
    +    address: gasp/nodeResponse
    +    description: |
    +      Response to a submitted node; specifies which additional input transactions
    +      (if any) the recipient still needs to complete the graph.  An empty / null
    +      response means the graph is complete.
    +    messages:
    +      GASPNodeResponse:
    +        $ref: "#/components/messages/GASPNodeResponse"
    +
    +# ---------------------------------------------------------------------------
    +# Operations
    +# ---------------------------------------------------------------------------
    +operations:
    +  sendInitialRequest:
    +    action: send
    +    channel:
    +      $ref: "#/channels/gaspInitialRequest"
    +    summary: Initiator sends sync parameters to the responder.
    +    messages:
    +      - $ref: "#/channels/gaspInitialRequest/messages/GASPInitialRequest"
    +
    +  receiveInitialResponse:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/gaspInitialResponse"
    +    summary: Initiator receives the responder's UTXO list and since timestamp.
    +    messages:
    +      - $ref: "#/channels/gaspInitialResponse/messages/GASPInitialResponse"
    +
    +  sendInitialReply:
    +    action: send
    +    channel:
    +      $ref: "#/channels/gaspInitialReply"
    +    summary: |
    +      Initiator (bidirectional mode only) sends UTXOs the responder is missing.
    +    messages:
    +      - $ref: "#/channels/gaspInitialReply/messages/GASPInitialReply"
    +
    +  requestNode:
    +    action: send
    +    channel:
    +      $ref: "#/channels/gaspRequestNode"
    +    summary: Request a specific transaction node from the counterparty.
    +    messages:
    +      - $ref: "#/channels/gaspRequestNode/messages/GASPNodeRequest"
    +
    +  deliverNode:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/gaspNode"
    +    summary: Receive a requested graph node from the counterparty.
    +    messages:
    +      - $ref: "#/channels/gaspNode/messages/GASPNode"
    +
    +  submitNode:
    +    action: send
    +    channel:
    +      $ref: "#/channels/gaspSubmitNode"
    +    summary: Push a graph node to the counterparty for ingestion.
    +    messages:
    +      - $ref: "#/channels/gaspSubmitNode/messages/GASPNode"
    +
    +  receiveNodeResponse:
    +    action: receive
    +    channel:
    +      $ref: "#/channels/gaspNodeResponse"
    +    summary: |
    +      Receive the counterparty's response to a submitted node, listing any
    +      additional input transactions needed to complete the graph.
    +    messages:
    +      - $ref: "#/channels/gaspNodeResponse/messages/GASPNodeResponse"
    +
    +# ---------------------------------------------------------------------------
    +# Components
    +# ---------------------------------------------------------------------------
    +components:
    +  messages:
    +    GASPInitialRequest:
    +      name: GASPInitialRequest
    +      title: GASP Initial Request
    +      summary: |
    +        First message in a GASP sync session.  The initiator declares its
    +        protocol version, the timestamp of the last sync with this party, and
    +        an optional page size limit.
    +      payload:
    +        $ref: "#/components/schemas/GASPInitialRequest"
    +
    +    GASPInitialResponse:
    +      name: GASPInitialResponse
    +      title: GASP Initial Response
    +      summary: |
    +        Responder's reply to GASPInitialRequest.  Contains the list of UTXOs
    +        the responder has seen since `request.since`, plus the timestamp from
    +        which the responder wants UTXOs back from the initiator.
    +      payload:
    +        $ref: "#/components/schemas/GASPInitialResponse"
    +
    +    GASPInitialReply:
    +      name: GASPInitialReply
    +      title: GASP Initial Reply
    +      summary: |
    +        Initiator's follow-up (bidirectional mode).  UTXOs the initiator holds
    +        that were not in the Initial Response — i.e. UTXOs the responder needs.
    +      payload:
    +        $ref: "#/components/schemas/GASPInitialReply"
    +
    +    GASPNodeRequest:
    +      name: GASPNodeRequest
    +      title: GASP Node Request
    +      summary: |
    +        Request for a specific transaction node identified by graphID, txid,
    +        outputIndex, and whether transaction/output metadata should be included.
    +      payload:
    +        $ref: "#/components/schemas/GASPNodeRequest"
    +
    +    GASPNode:
    +      name: GASPNode
    +      title: GASP Node
    +      summary: |
    +        A transaction node: the raw transaction, the output index, an optional
    +        BUMP merkle proof, optional metadata strings, and a mapping of input
    +        outpoints to metadata hashes so the receiver can request ancestors.
    +      payload:
    +        $ref: "#/components/schemas/GASPNode"
    +
    +    GASPNodeResponse:
    +      name: GASPNodeResponse
    +      title: GASP Node Response
    +      summary: |
    +        Response to a submitted GASPNode.  Lists the input outpoints (in
    +        36-byte `<txid>.<vout>` format) that the recipient still needs to
    +        complete the graph.  A null / absent response means no further inputs
    +        are required and the graph is complete.
    +      payload:
    +        $ref: "#/components/schemas/GASPNodeResponse"
    +
    +  schemas:
    +    # -----------------------------------------------------------------------
    +    GASPInitialRequest:
    +      type: object
    +      description: |
    +        Parameters sent by the initiator to start a GASP sync session.
    +        Version mismatch (current version is 1) causes the responder to throw
    +        GASPVersionMismatchError and abort the session.
    +      required:
    +        - version
    +        - since
    +      properties:
    +        version:
    +          type: integer
    +          description: GASP protocol version.  Currently always 1.
    +          enum: [1]
    +          example: 1
    +        since:
    +          type: integer
    +          minimum: 0
    +          description: |
    +            UNIX timestamp (seconds since epoch) of the last successful sync
    +            with this counterparty.  Use 0 to request all UTXOs.
    +            Must be a non-negative integer.
    +          example: 1714000000
    +        limit:
    +          type: integer
    +          minimum: 1
    +          description: |
    +            Optional maximum number of UTXOs the responder should return per
    +            page.  When the response contains exactly `limit` items the
    +            initiator MUST send another GASPInitialRequest to fetch the next
    +            page.  Absent means "return all".
    +          example: 1000
    +
    +    GASPInitialResponse:
    +      type: object
    +      description: |
    +        Responder's answer to GASPInitialRequest.  `UTXOList` contains all
    +        UTXOs the responder has seen since `request.since`; unconfirmed
    +        (non-timestamped) UTXOs are always included regardless of timestamp.
    +      required:
    +        - UTXOList
    +        - since
    +      properties:
    +        UTXOList:
    +          type: array
    +          description: |
    +            UTXOs the responder knows about (after `request.since`).  The
    +            initiator will request any of these it does not already hold.
    +          items:
    +            $ref: "#/components/schemas/GASPOutput"
    +        since:
    +          type: integer
    +          minimum: 0
    +          description: |
    +            Timestamp from which the responder wants to receive UTXOs back
    +            from the initiator (used in the GASPInitialReply filter step).
    +          example: 1714001000
    +
    +    GASPInitialReply:
    +      type: object
    +      description: |
    +        Sent by the initiator in bidirectional mode.  Contains UTXOs the
    +        initiator holds that are newer than `response.since` AND were not
    +        already present in the Initial Response (so the responder can ingest
    +        them).
    +      required:
    +        - UTXOList
    +      properties:
    +        UTXOList:
    +          type: array
    +          description: UTXOs the responder needs from the initiator.
    +          items:
    +            $ref: "#/components/schemas/GASPOutput"
    +
    +    GASPOutput:
    +      type: object
    +      description: |
    +        Minimal outpoint descriptor used in the initial exchange phases.
    +        `score` is a sortable timestamp (seconds since epoch) assigned when
    +        the UTXO was first confirmed; unconfirmed UTXOs may have score 0.
    +      required:
    +        - txid
    +        - outputIndex
    +        - score
    +      properties:
    +        txid:
    +          type: string
    +          pattern: "^[0-9a-fA-F]{64}$"
    +          description: Transaction ID (hex, 64 characters).
    +          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
    +        outputIndex:
    +          type: integer
    +          minimum: 0
    +          description: Output index (vout) within the transaction.
    +          example: 0
    +        score:
    +          type: number
    +          description: |
    +            Sortable confirmation timestamp (UNIX seconds).  0 for unconfirmed
    +            outputs.  Used to filter UTXOs by the `since` parameters.
    +          example: 1714000000
    +
    +    GASPNodeRequest:
    +      type: object
    +      description: |
    +        Request for a specific graph node.  `graphID` is the 36-byte outpoint
    +        string (`<txid>.<vout>`) identifying the tip of the graph being walked.
    +      required:
    +        - graphID
    +        - txid
    +        - outputIndex
    +        - metadata
    +      properties:
    +        graphID:
    +          type: string
    +          description: |
    +            Graph identifier — the 36-byte outpoint string (`<txid>.<vout>`)
    +            of the UTXO at the tip of this sync graph.
    +          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0"
    +        txid:
    +          type: string
    +          pattern: "^[0-9a-fA-F]{64}$"
    +          description: Transaction ID of the node being requested.
    +          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
    +        outputIndex:
    +          type: integer
    +          minimum: 0
    +          description: Output index within the requested transaction.
    +          example: 0
    +        metadata:
    +          type: boolean
    +          description: |
    +            Whether the responder should include transaction and output metadata
    +            in the returned GASPNode.
    +          example: true
    +
    +    GASPNode:
    +      type: object
    +      description: |
    +        A fully-hydrated graph node.  `rawTx` is the complete serialised
    +        Bitcoin transaction in hex.  `proof` is a hex-encoded BUMP (BRC-74)
    +        merkle proof, only present for confirmed transactions.  `inputs` maps
    +        each input outpoint (`<txid>.<vout>`) to the hash of its metadata,
    +        allowing the recipient to detect when it needs updated metadata.
    +      required:
    +        - graphID
    +        - rawTx
    +        - outputIndex
    +      properties:
    +        graphID:
    +          type: string
    +          description: |
    +            Outpoint string (`<txid>.<vout>`) of the UTXO at the graph tip.
    +          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0"
    +        rawTx:
    +          type: string
    +          description: Complete Bitcoin transaction serialised as a lowercase hex string.
    +          example: "0100000001..."
    +        outputIndex:
    +          type: integer
    +          minimum: 0
    +          description: The output index within rawTx that this node represents.
    +          example: 0
    +        proof:
    +          type: string
    +          description: |
    +            Hex-encoded BUMP merkle proof for the transaction.  Present only
    +            when the transaction is confirmed in a block.
    +        txMetadata:
    +          type: string
    +          description: |
    +            Opaque string of transaction-level metadata.  Present only when
    +            the request set `metadata: true`.
    +        outputMetadata:
    +          type: string
    +          description: |
    +            Opaque string of output-level metadata.  Present only when the
    +            request set `metadata: true`.
    +        inputs:
    +          type: object
    +          description: |
    +            Mapping of input outpoints (`<txid>.<vout>`) to an object
    +            containing the hash of their metadata.  Present only when
    +            `metadata: true` was requested.
    +          additionalProperties:
    +            type: object
    +            required:
    +              - hash
    +            properties:
    +              hash:
    +                type: string
    +                description: Hash of the input's metadata (hex or base64).
    +
    +    GASPNodeResponse:
    +      type: object
    +      description: |
    +        Response to a submitted GASPNode.  `requestedInputs` lists outpoints
    +        the recipient still needs in order to complete the graph and whether
    +        metadata is required for each.  If null or omitted, the graph is
    +        complete and will be validated and finalised.
    +      properties:
    +        requestedInputs:
    +          type: object
    +          description: |
    +            Mapping of input outpoints (`<txid>.<vout>`) to their metadata
    +            requirement.  An empty object or absent field signals completion.
    +          additionalProperties:
    +            type: object
    +            required:
    +              - metadata
    +            properties:
    +              metadata:
    +                type: boolean
    +                description: Whether the submitter should include metadata for this input.
    +
    +  # -----------------------------------------------------------------------
    +  # Error shapes
    +  # -----------------------------------------------------------------------
    +    GASPVersionMismatchError:
    +      type: object
    +      description: |
    +        Thrown (and serialised into the response) when the responder's GASP
    +        version differs from the version declared in GASPInitialRequest.
    +      required:
    +        - code
    +        - message
    +        - currentVersion
    +        - foreignVersion
    +      properties:
    +        code:
    +          type: string
    +          enum:
    +            - "ERR_GASP_VERSION_MISMATCH"
    +        message:
    +          type: string
    +          example: "GASP version mismatch. Current version: 1, foreign version: 2"
    +        currentVersion:
    +          type: integer
    +          description: The responder's supported GASP version.
    +          example: 1
    +        foreignVersion:
    +          type: integer
    +          description: The version declared by the initiator.
    +          example: 2
    +
    +
    + + + + diff --git a/docs-site/src/components/CodeBlock.tsx b/docs-site/src/components/CodeBlock.tsx index 43c1adcd8..d252c423d 100644 --- a/docs-site/src/components/CodeBlock.tsx +++ b/docs-site/src/components/CodeBlock.tsx @@ -1,4 +1,4 @@ -import { lazy, Suspense, useState, type ReactNode } from 'react' +import { isValidElement, lazy, Suspense, useState, type ReactNode } from 'react' import '../styles/code.css' const Mermaid = lazy(() => import('./Mermaid')) @@ -8,15 +8,21 @@ interface Props { [key: string]: unknown } +function textContent(node: ReactNode): string { + if (node === null || node === undefined || typeof node === 'boolean') return '' + if (typeof node === 'string' || typeof node === 'number') return String(node) + if (Array.isArray(node)) return node.map(textContent).join('') + if (isValidElement<{ children?: ReactNode }>(node)) return textContent(node.props.children) + return '' +} + export default function CodeBlock({ children, ...rest }: Readonly) { const [copied, setCopied] = useState(false) - const codeEl = - typeof children === 'object' && children !== null && 'props' in (children as object) - ? (children as { props: { children?: string; className?: string } }).props - : null - - const rawCode = codeEl?.children ?? '' + const codeEl = isValidElement<{ children?: ReactNode; className?: string }>(children) + ? children.props + : undefined + const rawCode = textContent(codeEl?.children ?? children) // Shiki strips language-xxx from but we inject data-language on
     via transformer
       const lang = (rest['data-language'] as string | undefined)
         ?? codeEl?.className?.replace('language-', '')
    diff --git a/docs/about/contributing.md b/docs/about/contributing.md
    index 95728be79..ad45b0642 100644
    --- a/docs/about/contributing.md
    +++ b/docs/about/contributing.md
    @@ -113,11 +113,12 @@ pnpm test --coverage
     # Check linting
     pnpm lint
     
    -# Fix linting issues
    -pnpm lint --fix
    +# Fix linting issues in a package
    +pnpm --filter @bsv/sdk exec oxlint --fix src
     ```
     
    -Uses **ts-standard** for consistent code style.
    +Uses **Oxlint** for fast, consistent TypeScript checks. Errors fail CI; warnings
    +remain visible while the inherited warning backlog is reduced.
     
     ### Build Packages
     
    diff --git a/docs/about/versioning.md b/docs/about/versioning.md
    index fa7380ab4..6f259b24a 100644
    --- a/docs/about/versioning.md
    +++ b/docs/about/versioning.md
    @@ -121,7 +121,8 @@ Features may be deprecated before removal:
     
     ## Dependencies
     
    -ts-stack pins dependencies to minor versions:
    +ts-stack declares compatible public semver ranges and keeps internal workspace
    +links canonical:
     
     ```json
     {
    @@ -132,9 +133,13 @@ ts-stack pins dependencies to minor versions:
     }
     ```
     
    -This allows:
    -- Patch updates automatically (bug fixes)
    -- Requires manual update for minor/major (new features/breaking changes)
    +This allows compatible minor and patch updates while reserving major upgrades
    +for explicit migrations. Runtime, development, and optional references to other
    +workspace packages use `workspace:^`; published peer dependencies use a broad
    +public range such as `^2`.
    +
    +See [Dependency and Release Policy](../reference/dependency-policy.md) for the
    +audit gate, supply-chain controls, residual advisory policy, and release flow.
     
     ## Publishing
     
    diff --git a/docs/packages/helpers/amountinator.md b/docs/packages/helpers/amountinator.md
    index 202c31dc0..2749e8c9b 100644
    --- a/docs/packages/helpers/amountinator.md
    +++ b/docs/packages/helpers/amountinator.md
    @@ -3,11 +3,11 @@ id: pkg-amountinator
     title: "@bsv/amountinator"
     kind: package
     domain: helpers
    -version: "2.0.1"
    +version: "2.1.1"
     source_repo: "bsv-blockchain/amountinator"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/amountinator"
     repo: "https://github.com/bsv-blockchain/amountinator"
    diff --git a/docs/packages/helpers/did-client.md b/docs/packages/helpers/did-client.md
    index 2ce3ff854..696b91077 100644
    --- a/docs/packages/helpers/did-client.md
    +++ b/docs/packages/helpers/did-client.md
    @@ -3,11 +3,11 @@ id: pkg-did-client
     title: "@bsv/did-client"
     kind: package
     domain: helpers
    -version: "1.1.2"
    +version: "1.2.1"
     source_repo: "bsv-blockchain/did-client"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/did-client"
     repo: "https://github.com/bsv-blockchain/did-client"
    diff --git a/docs/packages/helpers/did.md b/docs/packages/helpers/did.md
    index bc5fe9cc3..379593431 100644
    --- a/docs/packages/helpers/did.md
    +++ b/docs/packages/helpers/did.md
    @@ -3,11 +3,11 @@ id: pkg-did
     title: "@bsv/did"
     kind: package
     domain: helpers
    -version: "0.1.0"
    +version: "0.2.1"
     source_repo: "bsv-blockchain/ts-stack"
     source_commit: "unknown"
    -last_updated: "2026-05-07"
    -last_verified: "2026-05-07"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/did"
     repo: "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/did"
    diff --git a/docs/packages/helpers/fund-wallet.md b/docs/packages/helpers/fund-wallet.md
    index bb1b1642b..002228983 100644
    --- a/docs/packages/helpers/fund-wallet.md
    +++ b/docs/packages/helpers/fund-wallet.md
    @@ -3,11 +3,11 @@ id: pkg-fund-wallet
     title: "@bsv/fund-wallet"
     kind: package
     domain: helpers
    -version: "1.3.1"
    +version: "1.4.1"
     source_repo: "bsv-blockchain/fund-wallet"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/fund-wallet"
     repo: "https://github.com/bsv-blockchain/fund-wallet"
    diff --git a/docs/packages/helpers/simple.md b/docs/packages/helpers/simple.md
    index 615d5593d..9036e179e 100644
    --- a/docs/packages/helpers/simple.md
    +++ b/docs/packages/helpers/simple.md
    @@ -3,11 +3,11 @@ id: pkg-simple
     title: "@bsv/simple"
     kind: package
     domain: helpers
    -version: "0.3.0"
    +version: "0.4.1"
     source_repo: "bsv-blockchain/simple"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/simple"
     repo: "https://github.com/bsv-blockchain/simple"
    diff --git a/docs/packages/helpers/templates.md b/docs/packages/helpers/templates.md
    index 767927a9e..1d87e40c4 100644
    --- a/docs/packages/helpers/templates.md
    +++ b/docs/packages/helpers/templates.md
    @@ -3,11 +3,11 @@ id: pkg-templates
     title: "@bsv/templates"
     kind: package
     domain: helpers
    -version: "1.4.0"
    +version: "1.9.1"
     source_repo: "bsv-blockchain/templates"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/templates"
     repo: "https://github.com/bsv-blockchain/templates"
    diff --git a/docs/packages/helpers/wallet-helper.md b/docs/packages/helpers/wallet-helper.md
    index df1b3364c..23d5abb58 100644
    --- a/docs/packages/helpers/wallet-helper.md
    +++ b/docs/packages/helpers/wallet-helper.md
    @@ -3,11 +3,11 @@ id: pkg-wallet-helper
     title: "@bsv/wallet-helper"
     kind: package
     domain: helpers
    -version: "0.0.6"
    +version: "0.1.1"
     source_repo: "bsv-blockchain/wallet-helper"
     source_commit: "unknown"
    -last_updated: "2026-04-30"
    -last_verified: "2026-04-30"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/wallet-helper"
     repo: "https://github.com/bsv-blockchain/wallet-helper"
    diff --git a/docs/packages/messaging/authsocket-client.md b/docs/packages/messaging/authsocket-client.md
    index e7edab166..2a4a16e33 100644
    --- a/docs/packages/messaging/authsocket-client.md
    +++ b/docs/packages/messaging/authsocket-client.md
    @@ -3,11 +3,11 @@ id: pkg-authsocket-client
     title: "@bsv/authsocket-client"
     kind: package
     domain: messaging
    -version: "2.0.2"
    +version: "2.1.1"
     source_repo: "bsv-blockchain/authsocket-client"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/authsocket-client"
     repo: "https://github.com/bsv-blockchain/authsocket-client"
    diff --git a/docs/packages/messaging/authsocket.md b/docs/packages/messaging/authsocket.md
    index 4020b3fe9..44674023f 100644
    --- a/docs/packages/messaging/authsocket.md
    +++ b/docs/packages/messaging/authsocket.md
    @@ -3,11 +3,11 @@ id: pkg-authsocket
     title: "@bsv/authsocket"
     kind: package
     domain: messaging
    -version: "2.0.1"
    +version: "2.1.1"
     source_repo: "bsv-blockchain/authsocket"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/authsocket"
     repo: "https://github.com/bsv-blockchain/authsocket"
    diff --git a/docs/packages/messaging/message-box-client.md b/docs/packages/messaging/message-box-client.md
    index 1204c16a5..ffd0912b8 100644
    --- a/docs/packages/messaging/message-box-client.md
    +++ b/docs/packages/messaging/message-box-client.md
    @@ -3,11 +3,11 @@ id: pkg-message-box-client
     title: "@bsv/message-box-client"
     kind: package
     domain: messaging
    -version: "2.1.1"
    +version: "2.2.2"
     source_repo: "bsv-blockchain/message-box-client"
     source_commit: "unknown"
    -last_updated: "2026-04-30"
    -last_verified: "2026-04-30"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/message-box-client"
     repo: "https://github.com/bsv-blockchain/message-box-client"
    diff --git a/docs/packages/messaging/paymail.md b/docs/packages/messaging/paymail.md
    index 5104f58e4..aad8b70d1 100644
    --- a/docs/packages/messaging/paymail.md
    +++ b/docs/packages/messaging/paymail.md
    @@ -3,11 +3,11 @@ id: pkg-paymail
     title: "@bsv/paymail"
     kind: package
     domain: messaging
    -version: "2.3.0"
    +version: "2.4.1"
     source_repo: "bsv-blockchain/paymail"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/paymail"
     repo: "https://github.com/bsv-blockchain/paymail"
    diff --git a/docs/packages/middleware/402-pay.md b/docs/packages/middleware/402-pay.md
    index 62bd78dd2..cda2d2816 100644
    --- a/docs/packages/middleware/402-pay.md
    +++ b/docs/packages/middleware/402-pay.md
    @@ -3,11 +3,11 @@ id: pkg-402-pay
     title: "@bsv/402-pay"
     kind: package
     domain: middleware
    -version: "0.1.3"
    +version: "0.2.1"
     source_repo: "bsv-blockchain/402-pay"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/402-pay"
     repo: "https://github.com/bsv-blockchain/402-pay"
    diff --git a/docs/packages/middleware/auth-express-middleware.md b/docs/packages/middleware/auth-express-middleware.md
    index 7d0eed6f5..fc963abea 100644
    --- a/docs/packages/middleware/auth-express-middleware.md
    +++ b/docs/packages/middleware/auth-express-middleware.md
    @@ -3,11 +3,11 @@ id: pkg-auth-express-middleware
     title: "@bsv/auth-express-middleware"
     kind: package
     domain: middleware
    -version: "2.0.5"
    +version: "2.1.2"
     source_repo: "bsv-blockchain/auth-express-middleware"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/auth-express-middleware"
     repo: "https://github.com/bsv-blockchain/auth-express-middleware"
    diff --git a/docs/packages/middleware/payment-express-middleware.md b/docs/packages/middleware/payment-express-middleware.md
    index f0c20670a..c7c1ffb5c 100644
    --- a/docs/packages/middleware/payment-express-middleware.md
    +++ b/docs/packages/middleware/payment-express-middleware.md
    @@ -3,11 +3,11 @@ id: pkg-payment-express-middleware
     title: "@bsv/payment-express-middleware"
     kind: package
     domain: middleware
    -version: "2.0.2"
    +version: "2.1.1"
     source_repo: "bsv-blockchain/payment-express-middleware"
     source_commit: "unknown"
    -last_updated: "2026-04-30"
    -last_verified: "2026-04-30"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/payment-express-middleware"
     repo: "https://github.com/bsv-blockchain/payment-express-middleware"
    diff --git a/docs/packages/network/teranode-listener.md b/docs/packages/network/teranode-listener.md
    index 704884152..91d277ff7 100644
    --- a/docs/packages/network/teranode-listener.md
    +++ b/docs/packages/network/teranode-listener.md
    @@ -4,9 +4,9 @@ title: "@bsv/teranode-listener"
     kind: package
     domain: network
     npm: "@bsv/teranode-listener"
    -version: "1.0.3"
    -last_updated: "2026-04-29"
    -last_verified: "2026-04-29"
    +version: "1.1.1"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["network", "broadcast", "teranode", "p2p", "libp2p"]
     ---
    diff --git a/docs/packages/overlays/gasp.md b/docs/packages/overlays/gasp.md
    index d50f2f6be..a03947828 100644
    --- a/docs/packages/overlays/gasp.md
    +++ b/docs/packages/overlays/gasp.md
    @@ -3,11 +3,11 @@ id: pkg-gasp
     title: "@bsv/gasp"
     kind: package
     domain: overlays
    -version: "1.2.2"
    +version: "1.3.1"
     source_repo: "bsv-blockchain/gasp"
     source_commit: "unknown"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     npm: "https://www.npmjs.com/package/@bsv/gasp"
     repo: "https://github.com/bsv-blockchain/gasp"
    diff --git a/docs/packages/overlays/overlay-discovery-services.md b/docs/packages/overlays/overlay-discovery-services.md
    index dd005ae5a..f1da329f2 100644
    --- a/docs/packages/overlays/overlay-discovery-services.md
    +++ b/docs/packages/overlays/overlay-discovery-services.md
    @@ -4,9 +4,9 @@ title: "@bsv/overlay-discovery-services"
     kind: package
     domain: overlays
     npm: "@bsv/overlay-discovery-services"
    -version: "1.0.0"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +version: "2.1.1"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["overlay", "discovery"]
     ---
    diff --git a/docs/packages/overlays/overlay-express.md b/docs/packages/overlays/overlay-express.md
    index 82be69eed..54e4887ca 100644
    --- a/docs/packages/overlays/overlay-express.md
    +++ b/docs/packages/overlays/overlay-express.md
    @@ -4,9 +4,9 @@ title: "@bsv/overlay-express"
     kind: package
     domain: overlays
     npm: "@bsv/overlay-express"
    -version: "1.0.0"
    -last_updated: "2026-06-27"
    -last_verified: "2026-06-27"
    +version: "2.4.2"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["overlay", "express", "http"]
     ---
    diff --git a/docs/packages/overlays/overlay-topics.md b/docs/packages/overlays/overlay-topics.md
    index ba3e7c43b..d99bb6dc1 100644
    --- a/docs/packages/overlays/overlay-topics.md
    +++ b/docs/packages/overlays/overlay-topics.md
    @@ -4,9 +4,9 @@ title: "@bsv/overlay-topics"
     kind: package
     domain: overlays
     npm: "@bsv/overlay-topics"
    -version: "1.0.0"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +version: "1.6.1"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["overlay", "topics", "uhrp"]
     ---
    diff --git a/docs/packages/overlays/overlay.md b/docs/packages/overlays/overlay.md
    index 18cb14b96..5b3ae1758 100644
    --- a/docs/packages/overlays/overlay.md
    +++ b/docs/packages/overlays/overlay.md
    @@ -4,9 +4,9 @@ title: "@bsv/overlay"
     kind: package
     domain: overlays
     npm: "@bsv/overlay"
    -version: "1.0.0"
    -last_updated: "2026-06-27"
    -last_verified: "2026-06-27"
    +version: "2.2.1"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["overlay", "framework"]
     ---
    @@ -48,7 +48,10 @@ const engine = new Engine(
     )
     
     // Submit transactions with topics
    -const topics = JSON.parse(req.headers['x-topics'] ?? '[]')
    +const topicsHeader = req.headers['x-topics'] ?? ''
    +const topics = topicsHeader.trim().startsWith('[')
    +  ? JSON.parse(topicsHeader)
    +  : topicsHeader.split(',').map(topic => topic.trim())
     const taggedBEEF = { beef: Array.from(req.body), topics }
     await engine.submit(taggedBEEF, (steak) => res.status(200).json(steak))
     
    diff --git a/docs/packages/sdk/bsv-sdk.md b/docs/packages/sdk/bsv-sdk.md
    index 33c02b4ed..0094efcaf 100644
    --- a/docs/packages/sdk/bsv-sdk.md
    +++ b/docs/packages/sdk/bsv-sdk.md
    @@ -3,10 +3,10 @@ id: bsv-sdk
     title: "@bsv/sdk"
     kind: package
     domain: sdk
    -version: "2.0.14"
    +version: "2.2.0"
     npm: "@bsv/sdk"
    -last_updated: "2026-04-30"
    -last_verified: "2026-04-30"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     status: stable
     tags: ["sdk", "crypto", "transactions"]
    diff --git a/docs/packages/wallet/btms-permission-module.md b/docs/packages/wallet/btms-permission-module.md
    index 998bdc2c9..b22c5d47e 100644
    --- a/docs/packages/wallet/btms-permission-module.md
    +++ b/docs/packages/wallet/btms-permission-module.md
    @@ -4,9 +4,9 @@ title: "@bsv/btms-permission-module"
     kind: package
     domain: wallet
     npm: "@bsv/btms-permission-module"
    -version: "1.0.1"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +version: "1.1.1"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["tokens", "permissions"]
     github_repo: "https://github.com/bsv-blockchain/ts-stack"
    diff --git a/docs/packages/wallet/btms.md b/docs/packages/wallet/btms.md
    index fc46bc986..c378698c9 100644
    --- a/docs/packages/wallet/btms.md
    +++ b/docs/packages/wallet/btms.md
    @@ -4,9 +4,9 @@ title: "@bsv/btms"
     kind: package
     domain: wallet
     npm: "@bsv/btms"
    -version: "1.0.1"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +version: "1.1.1"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["tokens", "protocol"]
     github_repo: "https://github.com/bsv-blockchain/ts-stack"
    diff --git a/docs/packages/wallet/wallet-relay.md b/docs/packages/wallet/wallet-relay.md
    index 613c9d025..db4ad7e2c 100644
    --- a/docs/packages/wallet/wallet-relay.md
    +++ b/docs/packages/wallet/wallet-relay.md
    @@ -4,9 +4,9 @@ title: "@bsv/wallet-relay"
     kind: package
     domain: wallet
     npm: "@bsv/wallet-relay"
    -version: "0.1.0"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +version: "0.2.2"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["wallet", "relay"]
     github_repo: "https://github.com/bsv-blockchain/ts-stack"
    diff --git a/docs/packages/wallet/wallet-toolbox.md b/docs/packages/wallet/wallet-toolbox.md
    index 44efcecdf..0b675c49d 100644
    --- a/docs/packages/wallet/wallet-toolbox.md
    +++ b/docs/packages/wallet/wallet-toolbox.md
    @@ -4,9 +4,9 @@ title: "@bsv/wallet-toolbox"
     kind: package
     domain: wallet
     npm: "@bsv/wallet-toolbox"
    -version: "2.1.22"
    -last_updated: "2026-04-30"
    -last_verified: "2026-04-30"
    +version: "2.4.4"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["wallet", "brc100"]
     github_repo: "https://github.com/bsv-blockchain/ts-stack"
    diff --git a/docs/reference/dependency-policy.md b/docs/reference/dependency-policy.md
    new file mode 100644
    index 000000000..ed3cc99c8
    --- /dev/null
    +++ b/docs/reference/dependency-policy.md
    @@ -0,0 +1,86 @@
    +---
    +id: dependency-release-policy
    +title: "Dependency and Release Policy"
    +kind: reference
    +version: "1.0.0"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
    +review_cadence_days: 30
    +status: stable
    +tags: [reference, dependencies, security, releases]
    +---
    +
    +# Dependency and Release Policy
    +
    +This workspace keeps application code, published npm packages, and infrastructure
    +images on one reviewed dependency baseline.
    +
    +## Supported toolchain
    +
    +- Node.js 24.11 or newer
    +- pnpm 10
    +- TypeScript 6
    +- Oxlint for TypeScript linting
    +
    +CI, conformance, documentation, and release workflows run on Node.js 24. Package
    +lint errors fail the build. Existing warnings remain visible and are reduced
    +progressively; a package may opt into stricter warning enforcement once its
    +warning baseline reaches zero.
    +
    +## Supply-chain controls
    +
    +`pnpm-workspace.yaml` is the source of truth for installation controls:
    +
    +- dependency build scripts are denied unless explicitly listed in `allowBuilds`;
    +- ordinary releases must age for 24 hours before installation;
    +- first-party `@bsv/*` packages are exempt so coordinated releases can complete;
    +- registry provenance downgrades are rejected for recent packages; and
    +- `pnpm audit --audit-level=high` blocks high and critical advisories in CI and
    +  release jobs.
    +
    +The workspace carries one audited dependency override. Jest 30 still reaches
    +unpatched `brace-expansion` 1.x/2.x releases through its current `glob` and
    +`test-exclude` graph, so those versions are raised to 5.0.8. This final
    +substitution is verified by every Jest suite and is removed when Jest accepts
    +the patched major. Any future temporary override must likewise name its upstream
    +removal condition in `pnpm-workspace.yaml` and verify the affected path.
    +
    +The former AsyncAPI generator override was eliminated by replacing that
    +dependency with a deterministic
    +renderer built on the maintained `yaml` parser. This removes the legacy parser,
    +`brace-expansion`, and `jsonpath-plus` chains instead of masking them with
    +transitive substitutions.
    +
    +## Known upstream advisory holds
    +
    +The verified 2026-07-24 audit contains no high or critical findings. The
    +remaining findings are not runtime paths in published BSV libraries:
    +
    +| Scope | Severity | Reason for hold |
    +| --- | --- | --- |
    +| Jest notifier: `uuid` 8 | Moderate | Test notification path only; no caller supplies a UUID output buffer. |
    +| Docs site: React Router 6 | Moderate | Static, repository-authored site. Router 7 is incompatible with the current SSG adapter and currently introduces a high-severity React Server Components advisory into the audit. |
    +| `ts-jest` build helper: `esbuild` | Low | Development dependency; the advisory requires a Windows development server, which this workflow does not run. |
    +| Express: `body-parser` 2.2 | Low | The paymail service does not configure an invalid body-size limit. |
    +
    +Do not hide these with broad overrides. Re-evaluate them when Jest, `ts-jest`,
    +Express, or the docs SSG adapter publishes a compatible fix.
    +
    +## Update and release flow
    +
    +1. Refresh direct dependencies within their declared semver ranges.
    +2. Remove obsolete or unused packages before considering overrides.
    +3. Run the frozen install, version checks, audit, lint, build, tests,
    +   conformance, and documentation build.
    +4. Review Dependabot changes as grouped maintenance work. Do not merge a bot PR
    +   merely because its diff is generated: check runtime relevance, changelogs,
    +   peer compatibility, audit impact, and full CI.
    +5. Patch-bump every publishable workspace package whose source or published
    +   manifest changed.
    +6. Publish through the OIDC release workflow. Never publish from a workstation.
    +7. Merge the generated version-sync PR, then release any infra images whose
    +   first-party dependency ranges changed.
    +
    +Breaking major upgrades are handled as focused migrations with an explicit
    +compatibility and rollback plan. They are not forced into the workspace through
    +transitive overrides.
    diff --git a/docs/reference/index.md b/docs/reference/index.md
    index c3c98cb7b..cb3a88fee 100644
    --- a/docs/reference/index.md
    +++ b/docs/reference/index.md
    @@ -3,8 +3,8 @@ id: reference-overview
     title: "Reference"
     kind: meta
     version: "n/a"
    -last_updated: "2026-04-29"
    -last_verified: "2026-04-29"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     review_cadence_days: 30
     status: stable
     tags: [reference, api, index]
    @@ -17,11 +17,13 @@ Quick reference material for API details and protocol indices.
     ## Contents
     
     - **[BRC Standards Index](./brc-index.md)** — All BRC standards with links to implementations
    +- **[Dependency and release policy](./dependency-policy.md)** — Runtime baseline, supply-chain controls, advisory handling, and release rules
    +- **[July 2026 modernization release](./release-2026-07-25.md)** — Package versions, compatibility notes, and verification scope
     - **TypeDoc API docs** — Per-package generated reference (see links below)
     
     ## Packages by Domain
     
    -All 27 packages in the monorepo, with published npm names.
    +All 30 public packages in the monorepo, with published npm names.
     
     ### SDK
     
    @@ -34,10 +36,11 @@ All 27 packages in the monorepo, with published npm names.
     | Package | npm | Purpose |
     |---------|-----|---------|
     | wallet-toolbox | `@bsv/wallet-toolbox` | Modular toolkit for building BRC-100-compliant wallets |
    +| wallet-toolbox-client | `@bsv/wallet-toolbox-client` | Browser and remote client surfaces for wallet-toolbox |
    +| wallet-toolbox-mobile | `@bsv/wallet-toolbox-mobile` | Mobile wallet-toolbox entry point |
     | btms | `@bsv/btms` | UTXO-based token client (BTMS) |
     | btms-permission-module | `@bsv/btms-permission-module` | Permission hooks for BTMS token operations |
     | ts-wallet-relay | `@bsv/wallet-relay` | ECDH-encrypted WebSocket tunnel between desktop and mobile wallets |
    -| wallet-toolbox-examples | `@bsv/wallet-toolbox-examples` | Reference wallet implementations using wallet-toolbox |
     
     ### Overlays
     
    @@ -48,7 +51,6 @@ All 27 packages in the monorepo, with published npm names.
     | overlay-topics | `@bsv/overlay-topics` | Built-in Topic Managers and Lookup Services (UHRP, BTMS) |
     | overlay-discovery-services | `@bsv/overlay-discovery-services` | SHIP/SLAP discovery for overlay networks |
     | gasp-core | `@bsv/gasp` | Graph-Aware Sync Protocol for inter-node synchronization |
    -| btms-backend | `@bsv/btms-backend` | Overlay-server-side shell for BTMS; core logic now in `@bsv/overlay-topics` |
     
     ### Messaging
     
    @@ -64,6 +66,7 @@ All 27 packages in the monorepo, with published npm names.
     | Package | npm | Purpose |
     |---------|-----|---------|
     | auth-express-middleware | `@bsv/auth-express-middleware` | BRC-31 mutual-auth middleware for Express |
    +| auth | `@bsv/auth` | Framework-neutral authenticated request helpers |
     | payment-express-middleware | `@bsv/payment-express-middleware` | BRC-121 payment-gated middleware for Express |
     | 402-pay | `@bsv/402-pay` | BRC-121 HTTP 402 client |
     
    @@ -78,6 +81,7 @@ All 27 packages in the monorepo, with published npm names.
     | amountinator | `@bsv/amountinator` | BSV amount formatting and conversion |
     | fund-wallet | `@bsv/fund-wallet` | CLI tool for funding wallets on testnet |
     | ts-templates | `@bsv/templates` | Low-level script templates |
    +| create-bsv-app | `create-bsv-app` | Starter application generator |
     
     ### Network
     
    @@ -85,6 +89,12 @@ All 27 packages in the monorepo, with published npm names.
     |---------|-----|---------|
     | ts-p2p | `@bsv/teranode-listener` | BSV peer-to-peer node listener |
     
    +### Verification
    +
    +| Package | npm | Purpose |
    +|---------|-----|---------|
    +| verifast | `@bsv/verifast` | High-performance script verification backend |
    +
     ## Quick Navigation
     
     - [Specifications](../specs/) — Protocol details and machine-readable contracts
    diff --git a/docs/reference/release-2026-07-25.md b/docs/reference/release-2026-07-25.md
    new file mode 100644
    index 000000000..536e0c653
    --- /dev/null
    +++ b/docs/reference/release-2026-07-25.md
    @@ -0,0 +1,87 @@
    +---
    +id: release-2026-07-25
    +title: "July 2026 Stack Modernization Release"
    +kind: reference
    +version: "1.0.0"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
    +review_cadence_days: 30
    +status: stable
    +tags: [reference, release, compatibility, security]
    +---
    +
    +# July 2026 Stack Modernization Release
    +
    +This release reconciles the TypeScript stack onto one Node.js 24, pnpm 10,
    +TypeScript 6, and Oxlint baseline. It removes stale first-party registry pins,
    +refreshes compatible direct dependencies, replaces the legacy AsyncAPI
    +generator, reduces the workspace to one audited Jest security override, and
    +publishes every changed public package through the protected OIDC workflow.
    +
    +## Compatibility and security highlights
    +
    +- `@bsv/sdk` now preserves `OP_16` PushDrop fields, emits canonical
    +  comma-separated `X-Topics`, uses the configured HTTP client for SHIP
    +  submissions, produces fixed-width cross-SDK Schnorr linkage proofs, and can
    +  preserve already-signed inputs.
    +- Overlay HTTP accepts canonical comma-separated topics and the legacy JSON
    +  array during migration. Empty payloads receive stable validation errors.
    +- Overlay proof refresh persists updated Merkle paths through recursive source
    +  transactions.
    +- Remote wallet basket queries remain scoped to the authenticated user.
    +- Internal workspace dependencies use `workspace:^`; public SDK peer ranges
    +  remain broad enough to prevent duplicate nominal SDK types.
    +- The client and mobile wallet-toolbox packages own their build artifacts, so
    +  recursive workspace builds order every consumer correctly from a clean checkout.
    +- AsyncAPI reference pages are rendered deterministically with `yaml` and no
    +  remote assets or legacy generator/parser chain.
    +- The frozen audit has no high or critical findings. Accepted moderate and low
    +  upstream holds are listed in
    +  [Dependency and Release Policy](./dependency-policy.md).
    +
    +## Public package manifest
    +
    +| Domain | Package | Version |
    +| --- | --- | --- |
    +| SDK | `@bsv/sdk` | `2.2.0` |
    +| Wallet | `@bsv/wallet-toolbox` | `2.4.4` |
    +| Wallet | `@bsv/wallet-toolbox-client` | `2.4.4` |
    +| Wallet | `@bsv/wallet-toolbox-mobile` | `2.4.4` |
    +| Wallet | `@bsv/btms` | `1.1.1` |
    +| Wallet | `@bsv/btms-permission-module` | `1.1.1` |
    +| Wallet | `@bsv/wallet-relay` | `0.2.2` |
    +| Overlay | `@bsv/overlay` | `2.2.1` |
    +| Overlay | `@bsv/overlay-express` | `2.4.2` |
    +| Overlay | `@bsv/overlay-topics` | `1.6.1` |
    +| Overlay | `@bsv/overlay-discovery-services` | `2.1.1` |
    +| Overlay | `@bsv/gasp` | `1.3.1` |
    +| Messaging | `@bsv/authsocket` | `2.1.1` |
    +| Messaging | `@bsv/authsocket-client` | `2.1.1` |
    +| Messaging | `@bsv/message-box-client` | `2.2.2` |
    +| Messaging | `@bsv/paymail` | `2.4.1` |
    +| Middleware | `@bsv/auth` | `0.1.1` |
    +| Middleware | `@bsv/auth-express-middleware` | `2.1.2` |
    +| Middleware | `@bsv/payment-express-middleware` | `2.1.1` |
    +| Middleware | `@bsv/402-pay` | `0.2.1` |
    +| Helpers | `@bsv/amountinator` | `2.1.1` |
    +| Helpers | `@bsv/did` | `0.2.1` |
    +| Helpers | `@bsv/did-client` | `1.2.1` |
    +| Helpers | `@bsv/fund-wallet` | `1.4.1` |
    +| Helpers | `@bsv/simple` | `0.4.1` |
    +| Helpers | `@bsv/templates` | `1.9.1` |
    +| Helpers | `@bsv/wallet-helper` | `0.1.1` |
    +| Helpers | `create-bsv-app` | `1.0.2` |
    +| Network | `@bsv/teranode-listener` | `1.1.1` |
    +| Verification | `@bsv/verifast` | `0.3.0` |
    +
    +## Consumer baseline
    +
    +Applications should use Node.js 24.11 or newer and install the latest package
    +versions normally. Libraries that expose SDK types should declare `@bsv/sdk` as
    +a peer dependency instead of bundling another runtime copy. Overlay deployments
    +should accept both `X-Topics` formats during the transition and emit the
    +comma-separated canonical form.
    +
    +The release is validated by the frozen install, audit gate, full workspace
    +build, package test suites, 6,650 conformance vectors, docs render/link check,
    +dependency review, CodeQL, Socket, and the repository merge gate.
    diff --git a/docs/specs/overlay-http.md b/docs/specs/overlay-http.md
    index 35343b039..d35c0a1f0 100644
    --- a/docs/specs/overlay-http.md
    +++ b/docs/specs/overlay-http.md
    @@ -3,8 +3,8 @@ id: spec-overlay-http
     title: Overlay HTTP API
     kind: spec
     version: "1.0.0"
    -last_updated: "2026-04-28"
    -last_verified: "2026-04-28"
    +last_updated: "2026-07-24"
    +last_verified: "2026-07-24"
     status: stable
     tags: ["spec", "overlay"]
     ---
    @@ -36,7 +36,8 @@ tags: ["spec", "overlay"]
     
     1. **Client → Overlay** `POST /submit`
        - Raw BEEF transaction (BRC-62) in request body
    -   - `x-topics` header: JSON array of topic names (e.g., `["tm_ship", "tm_identity"]`)
    +   - `x-topics` header: OpenAPI simple-style, comma-separated topic names (e.g., `tm_ship,tm_identity`)
    +   - During migration, the TypeScript server also accepts the legacy JSON array form
        - Optional `x-includes-off-chain-values` for metadata
     
     2. **Overlay Engine**
    @@ -113,7 +114,7 @@ const response = await fetch('https://overlay.example.com/submit', {
       method: 'POST',
       headers: {
         'content-type': 'application/octet-stream',
    -    'x-topics': JSON.stringify(topics)
    +    'x-topics': topics.join(',')
       },
       body: new Uint8Array(action.tx)
     })
    diff --git a/package.json b/package.json
    index 5b41c9076..cbd1d10ab 100644
    --- a/package.json
    +++ b/package.json
    @@ -17,12 +17,11 @@
         "docs:preview": "pnpm --filter docs-site preview"
       },
       "devDependencies": {
    -    "@asyncapi/generator": "^3.3.0",
    -    "@asyncapi/html-template": "^3.5.6"
    +    "yaml": "^2.9.0"
       },
       "engines": {
    -    "node": ">=22",
    -    "pnpm": ">=9"
    +    "node": ">=24.11",
    +    "pnpm": ">=10"
       },
       "packageManager": "pnpm@10.33.2"
     }
    diff --git a/packages/helpers/amountinator/AGENTS.md b/packages/helpers/amountinator/AGENTS.md
    index 4701aad2e..408a00c6c 100644
    --- a/packages/helpers/amountinator/AGENTS.md
    +++ b/packages/helpers/amountinator/AGENTS.md
    @@ -79,8 +79,8 @@ const amount = await staticConverter.convertAmount('100')
     ## Dependencies
     
     **Runtime:**
    -- `@bsv/sdk` ^2.0.14
    -- `@bsv/wallet-toolbox-client` ^2.1.18 (Services, WalletSettingsManager)
    +- `@bsv/sdk` ^2.1.6
    +- `@bsv/wallet-toolbox-client` ^2.4.4 (Services, WalletSettingsManager)
     
     **Dev:**
     - TypeScript, Jest, ts-jest
    diff --git a/packages/helpers/amountinator/package.json b/packages/helpers/amountinator/package.json
    index 9b3fa8423..a5e4e1696 100644
    --- a/packages/helpers/amountinator/package.json
    +++ b/packages/helpers/amountinator/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/amountinator",
    -  "version": "2.1.0",
    +  "version": "2.1.1",
       "description": "Currency amount conversion",
       "author": "Peer-to-peer Privacy Systems Research, LLC & BSV Association",
       "license": "Open BSV License",
    @@ -28,15 +28,15 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/amountinator#readme",
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    +    "ts-jest": "^29.4.12",
         "ts-node": "^10.9.2",
    -    "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "typescript": "^6.0.3"
       },
       "dependencies": {
    -    "@bsv/wallet-toolbox-client": "^2.3.3"
    +    "@bsv/wallet-toolbox-client": "workspace:^"
       },
       "keywords": [
         "bsv",
    diff --git a/packages/helpers/amountinator/src/utils/currencyConverter.ts b/packages/helpers/amountinator/src/utils/currencyConverter.ts
    index dda074e4e..9fc7b1339 100644
    --- a/packages/helpers/amountinator/src/utils/currencyConverter.ts
    +++ b/packages/helpers/amountinator/src/utils/currencyConverter.ts
    @@ -7,8 +7,7 @@ import {
       SUPPORTED_FIAT_CURRENCY_CODES,
       SupportedCurrencyCode
     } from '../types'
    -import { Services } from '@bsv/wallet-toolbox-client'
    -import { WalletSettingsManager } from '@bsv/wallet-toolbox-client/out/src/WalletSettingsManager'
    +import { Services, WalletSettingsManager } from '@bsv/wallet-toolbox-client'
     const DEFAULT_REFRESH_INTERVAL = 5 * 60 * 1000
     
     /**
    diff --git a/packages/helpers/amountinator/tests/currencyConverterCache.test.ts b/packages/helpers/amountinator/tests/currencyConverterCache.test.ts
    index 043e55ae4..a60da74aa 100644
    --- a/packages/helpers/amountinator/tests/currencyConverterCache.test.ts
    +++ b/packages/helpers/amountinator/tests/currencyConverterCache.test.ts
    @@ -7,18 +7,12 @@ jest.mock('@bsv/wallet-toolbox-client', () => ({
         Services: jest.fn().mockImplementation(() => ({
             getBsvExchangeRate: getBsvExchangeRateMock,
             getFiatExchangeRates: getFiatExchangeRatesMock
    +    })),
    +    WalletSettingsManager: jest.fn().mockImplementation(() => ({
    +        get: jest.fn().mockResolvedValue({ currency: 'USD' })
         }))
     }))
     
    -jest.mock(
    -    '@bsv/wallet-toolbox-client/out/src/WalletSettingsManager',
    -    () => ({
    -        WalletSettingsManager: jest.fn().mockImplementation(() => ({
    -            get: jest.fn().mockResolvedValue({ currency: 'USD' })
    -        }))
    -    })
    -)
    -
     describe('CurrencyConverter cache behaviour', () => {
         let cc: CurrencyConverter
     
    diff --git a/packages/helpers/bsv-wallet-helper/AGENTS.md b/packages/helpers/bsv-wallet-helper/AGENTS.md
    index b364911a4..1a87d29a7 100644
    --- a/packages/helpers/bsv-wallet-helper/AGENTS.md
    +++ b/packages/helpers/bsv-wallet-helper/AGENTS.md
    @@ -128,7 +128,7 @@ console.log('Would send:', preview.estimatedFee)
     - `@bsv/wallet-toolbox-client` ^2.1.18
     
     **Dev:**
    -- TypeScript, Jest, ts-jest, ts-standard
    +- TypeScript, Jest, ts-jest, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/helpers/bsv-wallet-helper/BASELINE.md b/packages/helpers/bsv-wallet-helper/BASELINE.md
    index 25e0e2842..48884b95d 100644
    --- a/packages/helpers/bsv-wallet-helper/BASELINE.md
    +++ b/packages/helpers/bsv-wallet-helper/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/helpers/bsv-wallet-helper/package.json b/packages/helpers/bsv-wallet-helper/package.json
    index 60e9f73d7..dc012d82d 100644
    --- a/packages/helpers/bsv-wallet-helper/package.json
    +++ b/packages/helpers/bsv-wallet-helper/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/wallet-helper",
    -  "version": "0.1.0",
    +  "version": "0.1.1",
       "description": "",
       "main": "dist/index.js",
       "module": "dist/index.mjs",
    @@ -22,8 +22,8 @@
       },
       "scripts": {
         "test": "jest --runInBand",
    -    "lint:ci-disabled": "ts-standard src/**/*.ts",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint:ci-disabled": "oxlint src",
    +    "lint": "oxlint src",
         "test:watch": "jest --watch",
         "test:coverage-disabled": "jest --coverage",
         "build": "tsup && tsc --emitDeclarationOnly"
    @@ -33,25 +33,19 @@
       "license": "ISC",
       "type": "commonjs",
       "dependencies": {
    -    "@bsv/wallet-toolbox-client": "^2.3.3"
    +    "@bsv/wallet-toolbox-client": "workspace:^"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    +    "ts-jest": "^29.4.12",
         "tslib": "^2.8.1",
         "tsup": "^8.5.1",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    -  },
    -  "ts-standard": {
    -    "project": "tsconfig.eslint.json",
    -    "ignore": [
    -      "dist"
    -    ]
    +    "oxlint": "^1.75.0"
       },
       "bugs": {
         "url": "https://github.com/bsv-blockchain/ts-stack/issues"
    diff --git a/packages/helpers/create-bsv-app/package.json b/packages/helpers/create-bsv-app/package.json
    index 4d12f677f..897223096 100644
    --- a/packages/helpers/create-bsv-app/package.json
    +++ b/packages/helpers/create-bsv-app/package.json
    @@ -1,31 +1,43 @@
     {
       "name": "create-bsv-app",
    -  "version": "1.0.1",
    +  "version": "1.0.2",
       "description": "The unified CLI and starter catalogue for creating BSV applications",
       "type": "module",
       "main": "dist/index.js",
    -  "bin": { "create-bsv-app": "dist/index.js" },
    -  "files": ["dist", ".claude", "LICENSE.txt"],
    +  "bin": {
    +    "create-bsv-app": "dist/index.js"
    +  },
    +  "files": [
    +    "dist",
    +    ".claude",
    +    "LICENSE.txt"
    +  ],
       "scripts": {
         "build": "tsc",
         "test": "jest",
    -    "lint": "ts-standard --fix src/**/*.ts",
    -    "lint:ci": "ts-standard src/**/*.ts",
    +    "lint": "oxlint src",
    +    "lint:ci": "oxlint src",
         "clean": "rm -rf dist coverage",
         "dev": "node dist/index.js"
       },
    -  "dependencies": { "@clack/prompts": "^0.7.0" },
    +  "dependencies": {
    +    "@clack/prompts": "^0.7.0"
    +  },
       "devDependencies": {
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "typescript": "^6.0.3"
    +    "ts-jest": "^29.4.12",
    +    "typescript": "^6.0.3",
    +    "oxlint": "^1.75.0"
    +  },
    +  "publishConfig": {
    +    "access": "public"
    +  },
    +  "engines": {
    +    "node": ">=22"
       },
    -  "publishConfig": { "access": "public" },
    -  "engines": { "node": ">=22" },
       "author": "BSV Association",
       "license": "SEE LICENSE IN LICENSE.txt",
       "repository": {
    @@ -33,11 +45,11 @@
         "url": "git+https://github.com/bsv-blockchain/ts-stack.git",
         "directory": "packages/helpers/create-bsv-app"
       },
    -  "keywords": ["bsv", "bitcoin", "scaffolding", "starter", "wallet"],
    -  "ts-standard": {
    -    "project": "tsconfig.eslint.json",
    -    "ignore": [
    -      "dist"
    -    ]
    -  }
    +  "keywords": [
    +    "bsv",
    +    "bitcoin",
    +    "scaffolding",
    +    "starter",
    +    "wallet"
    +  ]
     }
    diff --git a/packages/helpers/did-client/AGENTS.md b/packages/helpers/did-client/AGENTS.md
    index a55ae94e6..37b1105ba 100644
    --- a/packages/helpers/did-client/AGENTS.md
    +++ b/packages/helpers/did-client/AGENTS.md
    @@ -116,7 +116,7 @@ const page1 = await didClient.findDID({
     - `@bsv/wallet-toolbox-client` ^2.1.18 (implied via @bsv/sdk)
     
     **Dev:**
    -- TypeScript, Jest, ts-jest, ts-standard, webpack
    +- TypeScript, Jest, ts-jest, Oxlint, webpack
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/helpers/did-client/BASELINE.md b/packages/helpers/did-client/BASELINE.md
    index f72593b52..47a97d88c 100644
    --- a/packages/helpers/did-client/BASELINE.md
    +++ b/packages/helpers/did-client/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/helpers/did-client/eslint.config.js b/packages/helpers/did-client/eslint.config.js
    deleted file mode 100644
    index 05f7ba868..000000000
    --- a/packages/helpers/did-client/eslint.config.js
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -import globals from 'globals'
    -import pluginJs from '@eslint/js'
    -import tseslint from 'typescript-eslint'
    -import tsStandard from 'ts-standard'
    -import pluginJest from 'eslint-plugin-jest'
    -
    -export default [
    -  tsStandard,
    -  {
    -    ignorePatterns: ['src/primitives/Point.ts'],
    -    files: ['src/**/*.ts', '**/*.{js,mjs,cjs,ts,jsx,tsx}'],
    -    languageOptions: {
    -      globals: {
    -        ...globals.browser,
    -        process: 'readonly',
    -        ...globals.jest
    -      },
    -      parser: tseslint.parser,
    -      parserOptions: {
    -        project: './tsconfig.json',
    -        tsconfigRootDir: process.cwd()
    -      }
    -    },
    -    plugins: {
    -      '@typescript-eslint': tseslint.plugin,
    -      jest: pluginJest
    -    },
    -    rules: {
    -      ...tseslint.configs.recommended.rules,
    -      ...pluginJs.configs.recommended.rules,
    -
    -      'jest/no-disabled-tests': 'warn',
    -      'jest/no-focused-tests': 'error',
    -      'jest/no-identical-title': 'error',
    -      'jest/prefer-to-have-length': 'warn',
    -      'jest/valid-expect': 'error'
    -    }
    -  }
    -]
    diff --git a/packages/helpers/did-client/package.json b/packages/helpers/did-client/package.json
    index 6a37703eb..52ad12172 100644
    --- a/packages/helpers/did-client/package.json
    +++ b/packages/helpers/did-client/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/did-client",
    -  "version": "1.2.0",
    +  "version": "1.2.1",
       "description": "Discover DID records with ease",
       "publishConfig": {
         "access": "public"
    @@ -20,8 +20,8 @@
         "test": "npm run build && jest --passWithNoTests",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint:ci": "ts-standard src/**/*.ts",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint:ci": "oxlint src",
    +    "lint": "oxlint src",
         "build": "npm run build:ts && npm run build:umd",
         "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "build:umd": "webpack --config webpack.config.js",
    @@ -32,27 +32,23 @@
       "author": "Peer-to-peer Privacy Systems Research, LLC",
       "license": "Open BSV License",
       "devDependencies": {
    -    "@eslint/js": "^10.0.1",
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    -    "eslint": "^10.5.0",
    -    "globals": "^17.6.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
         "jest-environment-jsdom": "^30.4.1",
    -    "ts-jest": "^29.4.11",
    +    "ts-jest": "^29.4.12",
         "ts-loader": "^9.6.2",
    -    "ts-standard": "^12.0.2",
         "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "typescript-eslint": "^8.61.0",
    -    "webpack": "^5.107.2",
    -    "webpack-cli": "^7.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "webpack": "^5.109.0",
    +    "webpack-cli": "^7.2.1",
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
    -    "@bsv/wallet-toolbox-client": "^2.3.3"
    +    "@bsv/wallet-toolbox-client": "workspace:^"
       },
       "overrides": {
         "typescript": "^6.0.3"
    diff --git a/packages/helpers/did-client/tsconfig.eslint.json b/packages/helpers/did-client/tsconfig.eslint.json
    deleted file mode 100644
    index 71a60eb9c..000000000
    --- a/packages/helpers/did-client/tsconfig.eslint.json
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -{
    -  "extends": "./tsconfig.json",
    -  "compilerOptions": {
    -    "types": [
    -      "@types/node"
    -    ],
    -    "noEmit": true,
    -    "strict": true,
    -    "strictNullChecks": true
    -  },
    -  "include": [
    -    "./src/**/*.{ts,tsx,js,jsx}",
    -    "./eslint.config.js",
    -    "./jest.config.js",
    -    "./**/*.js", 
    -    "./**/*.ts",
    -    "./*.ts"
    -  ]
    -}  
    diff --git a/packages/helpers/did/package.json b/packages/helpers/did/package.json
    index 146478368..117e368c3 100644
    --- a/packages/helpers/did/package.json
    +++ b/packages/helpers/did/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/did",
    -  "version": "0.2.0",
    +  "version": "0.2.1",
       "description": "SD-JWT VC and did:key helpers for BSV SDK identities",
       "publishConfig": {
         "access": "public"
    @@ -32,33 +32,27 @@
         "test": "npm run build && jest --passWithNoTests",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint:ci": "ts-standard src/**/*.ts tests/**/*.ts",
    -    "lint": "ts-standard --fix src/**/*.ts tests/**/*.ts",
    +    "lint:ci": "oxlint src tests",
    +    "lint": "oxlint src tests",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build"
       },
    -  "ts-standard": {
    -    "project": "tsconfig.eslint.json",
    -    "ignore": [
    -      "dist"
    -    ]
    -  },
       "author": "Peer-to-peer Privacy Systems Research, LLC & BSV Association",
       "license": "Open BSV License",
       "dependencies": {
         "qrcode": "^1.5.4"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "@types/qrcode": "^1.5.6",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    +    "ts-jest": "^29.4.12",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "repository": {
         "type": "git",
    diff --git a/packages/helpers/fund-wallet/AGENTS.md b/packages/helpers/fund-wallet/AGENTS.md
    index 59fd5fd0f..58bab8905 100644
    --- a/packages/helpers/fund-wallet/AGENTS.md
    +++ b/packages/helpers/fund-wallet/AGENTS.md
    @@ -64,7 +64,7 @@ npx fund-wallet
     - `@bsv/wallet-toolbox` ^2.1.22 (ServerWallet for local funding)
     - `chalk` ^5.4.1 (colored CLI output)
     - `dotenv` ^16.5.0 (environment variable loading)
    -- `readline` ^1.3.0 (interactive prompts)
    +- Node.js built-ins `node:crypto` and `node:readline`
     
     **Dev:**
     - TypeScript, @types/node
    diff --git a/packages/helpers/fund-wallet/BASELINE.md b/packages/helpers/fund-wallet/BASELINE.md
    index 90df63b52..a6c1d9c85 100644
    --- a/packages/helpers/fund-wallet/BASELINE.md
    +++ b/packages/helpers/fund-wallet/BASELINE.md
    @@ -39,7 +39,7 @@
     ## Dependencies
     | Type | Count | Packages |
     |------|-------|---------|
    -| Production | 6 | @bsv/sdk, @bsv/wallet-toolbox, chalk, crypto, dotenv, readline |
    +| Production | 4 | @bsv/sdk, @bsv/wallet-toolbox, chalk, dotenv |
     
     ## Known Issues & Incidents
     - No tests configured.
    diff --git a/packages/helpers/fund-wallet/package.json b/packages/helpers/fund-wallet/package.json
    index 1ffb315db..360039909 100644
    --- a/packages/helpers/fund-wallet/package.json
    +++ b/packages/helpers/fund-wallet/package.json
    @@ -1,7 +1,7 @@
     {
       "name": "@bsv/fund-wallet",
       "private": false,
    -  "version": "1.4.0",
    +  "version": "1.4.1",
       "description": "fund a metanet wallet",
       "license": "ISC",
       "author": "deggen",
    @@ -21,16 +21,14 @@
         "test": "exit 0"
       },
       "dependencies": {
    -    "@bsv/wallet-toolbox": "^2.3.3",
    +    "@bsv/wallet-toolbox": "workspace:^",
         "chalk": "^5.6.2",
    -    "crypto": "^1.0.1",
    -    "dotenv": "^17.4.2",
    -    "readline": "^1.3.0"
    +    "dotenv": "^17.4.2"
       },
       "devDependencies": {
    -    "@types/node": "^26.0.0",
    -    "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "@bsv/sdk": "workspace:^",
    +    "@types/node": "^26.1.1",
    +    "typescript": "^6.0.3"
       },
       "files": [
         "dist"
    diff --git a/packages/helpers/simple/BASELINE.md b/packages/helpers/simple/BASELINE.md
    index f433ddfcb..8f4356ae1 100644
    --- a/packages/helpers/simple/BASELINE.md
    +++ b/packages/helpers/simple/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/helpers/simple/package.json b/packages/helpers/simple/package.json
    index 74b74ada6..2dd323c9b 100644
    --- a/packages/helpers/simple/package.json
    +++ b/packages/helpers/simple/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/simple",
    -  "version": "0.4.0",
    +  "version": "0.4.1",
       "description": "Simplified, modular helper library for BSV blockchain development",
       "main": "dist/index.js",
       "types": "dist/index.d.ts",
    @@ -28,8 +28,8 @@
         "dev": "tsc --watch",
         "test": "jest",
         "test:coverage": "jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    -    "lint:ci": "ts-standard src/**/*.ts",
    +    "lint": "oxlint src",
    +    "lint:ci": "oxlint src",
         "prepublishOnly": "npm run build"
       },
       "keywords": [
    @@ -45,28 +45,22 @@
       "author": "",
       "license": "MIT",
       "dependencies": {
    -    "@bsv/message-box-client": "^2.2.0",
    -    "@bsv/wallet-toolbox": "^2.3.3",
    -    "@bsv/wallet-toolbox-client": "^2.3.3"
    +    "@bsv/message-box-client": "workspace:^",
    +    "@bsv/wallet-toolbox": "workspace:^",
    +    "@bsv/wallet-toolbox-client": "workspace:^"
       },
       "overrides": {
         "minimatch": "^10.2.1"
       },
    -  "ts-standard": {
    -    "project": "tsconfig.eslint.json",
    -    "ignore": [
    -      "dist"
    -    ]
    -  },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "dotenv": "^17.4.2",
         "jest": "^30.4.2",
         "ts-jest": "^29.4.12",
    -    "ts-standard": "^12.0.2",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "files": [
         "dist",
    diff --git a/packages/helpers/ts-templates/AGENTS.md b/packages/helpers/ts-templates/AGENTS.md
    index 707e37f63..791091c1b 100644
    --- a/packages/helpers/ts-templates/AGENTS.md
    +++ b/packages/helpers/ts-templates/AGENTS.md
    @@ -104,7 +104,7 @@ const unlockingScript2 = await multiSigUnlocker.sign(tx3, 0)
     - `@bsv/sdk` ^2.0.14 (Transaction, Script, OP, LockingScript, etc.)
     
     **Dev:**
    -- TypeScript, Jest, ts-jest, ts-standard
    +- TypeScript, Jest, ts-jest, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/helpers/ts-templates/CONTRIBUTING.md b/packages/helpers/ts-templates/CONTRIBUTING.md
    index 6df10bd19..95a3a7c5e 100644
    --- a/packages/helpers/ts-templates/CONTRIBUTING.md
    +++ b/packages/helpers/ts-templates/CONTRIBUTING.md
    @@ -64,7 +64,7 @@ Thank you for considering contributing to the BSV Blockchain Script Templates Pr
     
     ## Coding Conventions
     
    -- **Code Style**: We use `ts-standard` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
    +- **Code Style**: We use `Oxlint` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
       
     - **Minimal Runtime Dependencies**: Code should not depend on external systems where possible, with a strong preference for maintaining things internally. The one exception is the `@bsv/sdk` library dependency.
       
    diff --git a/packages/helpers/ts-templates/package.json b/packages/helpers/ts-templates/package.json
    index 6325c0b9b..9b98c42ca 100644
    --- a/packages/helpers/ts-templates/package.json
    +++ b/packages/helpers/ts-templates/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/templates",
    -  "version": "1.9.0",
    +  "version": "1.9.1",
       "type": "module",
       "description": "BSV Blockchain Script Templates",
       "main": "dist/cjs/mod.js",
    @@ -28,7 +28,7 @@
         "test": "npm run build && jest --passWithNoTests",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix 'src/**/*.ts'",
    +    "lint": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build"
    @@ -53,16 +53,15 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/ts-templates#readme",
       "devDependencies": {
    -    "@bsv/wallet-toolbox": "^2.3.3",
    +    "@bsv/sdk": "workspace:^",
    +    "@bsv/wallet-toolbox": "workspace:^",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    +    "ts-jest": "^29.4.12",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
    -  "dependencies": {},
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
       },
    diff --git a/packages/messaging/authsocket-client/BASELINE.md b/packages/messaging/authsocket-client/BASELINE.md
    index caeedcaa0..b45e7b00a 100644
    --- a/packages/messaging/authsocket-client/BASELINE.md
    +++ b/packages/messaging/authsocket-client/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/messaging/authsocket-client/package.json b/packages/messaging/authsocket-client/package.json
    index bfb0a382d..b3f56cf39 100644
    --- a/packages/messaging/authsocket-client/package.json
    +++ b/packages/messaging/authsocket-client/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/authsocket-client",
    -  "version": "2.1.0",
    +  "version": "2.1.1",
       "publishConfig": {
         "access": "public"
       },
    @@ -26,7 +26,7 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "npm run build:ts",
         "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "build:umd": "webpack --config webpack.config.js",
    @@ -53,21 +53,21 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/messaging/authsocket-client#readme",
       "dependencies": {
    -    "socket.io-client": "^4.8.1"
    +    "socket.io-client": "^4.8.3"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
         "jest-environment-jsdom": "^30.4.1",
    -    "ts-jest": "^29.4.11",
    +    "ts-jest": "^29.4.12",
         "ts-loader": "^9.6.2",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.5",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "webpack": "^5.107.2",
    -    "webpack-cli": "^7.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "webpack": "^5.109.0",
    +    "webpack-cli": "^7.2.1",
    +    "oxlint": "^1.75.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/messaging/authsocket/BASELINE.md b/packages/messaging/authsocket/BASELINE.md
    index 85e32ebc4..c3d496f01 100644
    --- a/packages/messaging/authsocket/BASELINE.md
    +++ b/packages/messaging/authsocket/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/messaging/authsocket/package.json b/packages/messaging/authsocket/package.json
    index 73a2dac09..b58ed403c 100644
    --- a/packages/messaging/authsocket/package.json
    +++ b/packages/messaging/authsocket/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/authsocket",
    -  "version": "2.1.0",
    +  "version": "2.1.1",
       "publishConfig": {
         "access": "public"
       },
    @@ -28,7 +28,7 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "npm run build:ts",
         "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "build:umd": "webpack --config webpack.config.js",
    @@ -55,23 +55,23 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/messaging/authsocket#readme",
       "dependencies": {
    -    "socket.io": "^4.8.1"
    +    "socket.io": "^4.8.3"
       },
       "devDependencies": {
    -    "@bsv/authsocket-client": "^2.1.0",
    -    "@bsv/message-box-client": "^2.2.0",
    +    "@bsv/authsocket-client": "workspace:^",
    +    "@bsv/message-box-client": "workspace:^",
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
         "jest-environment-jsdom": "^30.4.1",
    -    "ts-jest": "^29.4.11",
    +    "ts-jest": "^29.4.12",
         "ts-loader": "^9.6.2",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.5",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "webpack": "^5.107.2",
    -    "webpack-cli": "^7.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "webpack": "^5.109.0",
    +    "webpack-cli": "^7.2.1",
    +    "oxlint": "^1.75.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/messaging/message-box-client/AGENTS.md b/packages/messaging/message-box-client/AGENTS.md
    index 4d998f591..89b9e57c9 100644
    --- a/packages/messaging/message-box-client/AGENTS.md
    +++ b/packages/messaging/message-box-client/AGENTS.md
    @@ -128,7 +128,7 @@ expect(token).toHaveProperty('amount', 5)
     
     - `@bsv/authsocket-client` ^2.0.2 — WebSocket auth
     - `@bsv/sdk` ^2.0.14 — Wallet, crypto, auth
    -- Dev: jest, ts-jest, ts-standard, webpack, supertest
    +- Dev: jest, ts-jest, Oxlint, webpack, supertest
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/messaging/message-box-client/BASELINE.md b/packages/messaging/message-box-client/BASELINE.md
    index f1776906f..f44b4fe13 100644
    --- a/packages/messaging/message-box-client/BASELINE.md
    +++ b/packages/messaging/message-box-client/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix .` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint .` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/messaging/message-box-client/eslint.config.js b/packages/messaging/message-box-client/eslint.config.js
    deleted file mode 100644
    index 05f7ba868..000000000
    --- a/packages/messaging/message-box-client/eslint.config.js
    +++ /dev/null
    @@ -1,39 +0,0 @@
    -import globals from 'globals'
    -import pluginJs from '@eslint/js'
    -import tseslint from 'typescript-eslint'
    -import tsStandard from 'ts-standard'
    -import pluginJest from 'eslint-plugin-jest'
    -
    -export default [
    -  tsStandard,
    -  {
    -    ignorePatterns: ['src/primitives/Point.ts'],
    -    files: ['src/**/*.ts', '**/*.{js,mjs,cjs,ts,jsx,tsx}'],
    -    languageOptions: {
    -      globals: {
    -        ...globals.browser,
    -        process: 'readonly',
    -        ...globals.jest
    -      },
    -      parser: tseslint.parser,
    -      parserOptions: {
    -        project: './tsconfig.json',
    -        tsconfigRootDir: process.cwd()
    -      }
    -    },
    -    plugins: {
    -      '@typescript-eslint': tseslint.plugin,
    -      jest: pluginJest
    -    },
    -    rules: {
    -      ...tseslint.configs.recommended.rules,
    -      ...pluginJs.configs.recommended.rules,
    -
    -      'jest/no-disabled-tests': 'warn',
    -      'jest/no-focused-tests': 'error',
    -      'jest/no-identical-title': 'error',
    -      'jest/prefer-to-have-length': 'warn',
    -      'jest/valid-expect': 'error'
    -    }
    -  }
    -]
    diff --git a/packages/messaging/message-box-client/package.json b/packages/messaging/message-box-client/package.json
    index 4dfbd714e..edf2a1ebf 100644
    --- a/packages/messaging/message-box-client/package.json
    +++ b/packages/messaging/message-box-client/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/message-box-client",
    -  "version": "2.2.1",
    +  "version": "2.2.2",
       "publishConfig": {
         "access": "public"
       },
    @@ -32,7 +32,7 @@
         "test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.integration.ts --watchman=false",
         "test:coverage": "jest --coverage --coverageReporters=text --coverageReporters=html",
         "test:watch": "jest --watch",
    -    "lint": "ts-standard --fix .",
    +    "lint": "oxlint src",
         "clean": "rimraf dist node_modules && npm install"
       },
       "keywords": [
    @@ -55,36 +55,29 @@
       "author": "BSV Blockchain Association",
       "license": "SEE LICENSE IN LICENSE.txt",
       "devDependencies": {
    -    "@bsv/auth-express-middleware": "^2.1.0",
    -    "@bsv/payment-express-middleware": "^2.1.0",
    -    "@eslint/js": "^10.0.1",
    +    "@bsv/auth-express-middleware": "workspace:^",
    +    "@bsv/payment-express-middleware": "workspace:^",
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    -    "@types/supertest": "^7.2.0",
    -    "@typescript-eslint/eslint-plugin": "^8.61.0",
    -    "@typescript-eslint/parser": "^8.61.0",
    +    "@types/node": "^26.1.1",
    +    "@types/supertest": "^7.2.1",
         "ejs": "^6.0.1",
    -    "eslint": "^10.5.0",
    -    "eslint-plugin-react": "^7.37.4",
    -    "globals": "^17.6.0",
         "jest": "^30.4.2",
    -    "jest-fetch-mock": "^3.0.3",
    -    "ts-jest": "^29.4.11",
    +    "jest-fetch-mock": "^3.2.0",
    +    "ts-jest": "^29.4.12",
         "ts-node": "^10.9.2",
    -    "ts-standard": "^12.0.2",
         "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "typescript-eslint": "^8.61.0",
    -    "webpack": "^5.107.2",
    -    "webpack-bundle-analyzer": "^5.3.0",
    -    "webpack-cli": "^7.0.3",
    -    "webpack-dev-server": "^5.2.5",
    +    "webpack": "^5.109.0",
    +    "webpack-bundle-analyzer": "^5.3.1",
    +    "webpack-cli": "^7.2.1",
    +    "webpack-dev-server": "^5.2.6",
         "webpack-merge": "^6.0.1",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
    -    "@bsv/authsocket-client": "^2.1.0"
    +    "@bsv/authsocket-client": "workspace:^"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/messaging/message-box-client/tsconfig.eslint.json b/packages/messaging/message-box-client/tsconfig.eslint.json
    deleted file mode 100644
    index 71a60eb9c..000000000
    --- a/packages/messaging/message-box-client/tsconfig.eslint.json
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -{
    -  "extends": "./tsconfig.json",
    -  "compilerOptions": {
    -    "types": [
    -      "@types/node"
    -    ],
    -    "noEmit": true,
    -    "strict": true,
    -    "strictNullChecks": true
    -  },
    -  "include": [
    -    "./src/**/*.{ts,tsx,js,jsx}",
    -    "./eslint.config.js",
    -    "./jest.config.js",
    -    "./**/*.js", 
    -    "./**/*.ts",
    -    "./*.ts"
    -  ]
    -}  
    diff --git a/packages/messaging/ts-paymail/AGENTS.md b/packages/messaging/ts-paymail/AGENTS.md
    index 6b3aa4eb9..56f4233cf 100644
    --- a/packages/messaging/ts-paymail/AGENTS.md
    +++ b/packages/messaging/ts-paymail/AGENTS.md
    @@ -119,7 +119,7 @@ expect(publicProfile).toHaveProperty('avatar')
     - `express` ^5.1.0 — web framework (server only)
     - `joi` ^18.0.1 — schema validation
     - `cross-fetch` or `node-fetch` ^3 — HTTP client
    -- Dev: jest, ts-jest, TypeScript, ts-standard
    +- Dev: jest, ts-jest, TypeScript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/messaging/ts-paymail/BASELINE.md b/packages/messaging/ts-paymail/BASELINE.md
    index ab4ea57e5..074617304 100644
    --- a/packages/messaging/ts-paymail/BASELINE.md
    +++ b/packages/messaging/ts-paymail/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix 'src/**/*.ts'` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/messaging/ts-paymail/CONTRIBUTING.md b/packages/messaging/ts-paymail/CONTRIBUTING.md
    index 768daf51d..78f63394f 100644
    --- a/packages/messaging/ts-paymail/CONTRIBUTING.md
    +++ b/packages/messaging/ts-paymail/CONTRIBUTING.md
    @@ -66,7 +66,7 @@ Thank you for considering contributing in the BSV Blockchain ecosystem! This doc
     
     > ADAPT TO YOUR PROJECT
     
    -- **Code Style**: We use `ts-standard` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
    +- **Code Style**: We use `Oxlint` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
     
     - **Testing**: Always include tests for new code or changes. We aim for industry-standard levels of test coverage.
       
    diff --git a/packages/messaging/ts-paymail/docs/examples/package.json b/packages/messaging/ts-paymail/docs/examples/package.json
    index 797586456..7412da73b 100644
    --- a/packages/messaging/ts-paymail/docs/examples/package.json
    +++ b/packages/messaging/ts-paymail/docs/examples/package.json
    @@ -7,7 +7,7 @@
       "scripts": {
         "test": "echo \"Error: no test specified\" && exit 1",
         "build": "tsc -p tsconfig.json",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "server": "npm run build && node dist/cjs/src/server.js",
         "client": "npm run build && node dist/cjs/src/client.js",
         "getProfile": "npm run build && node dist/cjs/src/client/getProfile.js",
    @@ -19,14 +19,14 @@
       "license": "ISC",
       "dependencies": {
         "@bsv/paymail": "workspace:^",
    -    "@bsv/sdk": "^2.1.6",
    +    "@bsv/sdk": "workspace:^",
         "express": "^5.2.1",
    -    "jwt-simple": "^0.5.6",
    -    "ts-standard": "^12.0.2"
    +    "jwt-simple": "^0.5.6"
       },
       "devDependencies": {
    -    "@types/node": "^26.0.0",
    -    "typescript": "^6.0.3"
    +    "@types/node": "^26.1.1",
    +    "typescript": "^6.0.3",
    +    "oxlint": "^1.75.0"
       },
       "repository": {
         "type": "git",
    diff --git a/packages/messaging/ts-paymail/package.json b/packages/messaging/ts-paymail/package.json
    index 8cf94b447..764908c41 100644
    --- a/packages/messaging/ts-paymail/package.json
    +++ b/packages/messaging/ts-paymail/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/paymail",
    -  "version": "2.4.0",
    +  "version": "2.4.1",
       "description": "BSV Paymail library",
       "publishConfig": {
         "access": "public"
    @@ -71,9 +71,9 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix 'src/**/*.ts'",
    -    "ex-lint": "ts-standard --fix 'docs/examples/**/*.ts'",
    -    "docs-lint": "ts-standard --fix 'docs/**/*.ts'",
    +    "lint": "oxlint src",
    +    "ex-lint": "oxlint docs/examples",
    +    "docs-lint": "oxlint docs",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -108,19 +108,19 @@
         "express": "^5.2.1",
         "jest": "^30.4.2",
         "joi": "^18.2.3",
    -    "node-fetch": "^3",
    -    "supertest": "^7.1.4",
    -    "ts-jest": "^29.4.11",
    +    "node-fetch": "^3.3.2",
    +    "supertest": "^7.2.2",
    +    "ts-jest": "^29.4.12",
         "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
    -    "@types/body-parser": "^1.19.5",
    -    "@types/node": "^26.0.0",
    -    "ts-standard": "^12.0.2",
    -    "@bsv/sdk": "workspace:^"
    +    "@types/body-parser": "^1.19.6",
    +    "@types/node": "^26.1.1",
    +    "oxlint": "^1.75.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/middleware/402-pay/package.json b/packages/middleware/402-pay/package.json
    index 90a8a99d8..d65a0ab76 100644
    --- a/packages/middleware/402-pay/package.json
    +++ b/packages/middleware/402-pay/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/402-pay",
    -  "version": "0.2.0",
    +  "version": "0.2.1",
       "description": "BRC-121 Simple 402 Payments — server middleware and client for BSV micropayments over HTTP",
       "type": "module",
       "main": "dist/index.js",
    @@ -49,9 +49,9 @@
       },
       "devDependencies": {
         "@bsv/sdk": "workspace:^",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "typescript": "^6.0.3",
    -    "vitest": "^4.1.9"
    +    "vitest": "^4.1.10"
       },
       "bugs": {
         "url": "https://github.com/bsv-blockchain/ts-stack/issues"
    diff --git a/packages/middleware/auth-express-middleware/AGENTS.md b/packages/middleware/auth-express-middleware/AGENTS.md
    index d0f6815c5..635e7cfbe 100644
    --- a/packages/middleware/auth-express-middleware/AGENTS.md
    +++ b/packages/middleware/auth-express-middleware/AGENTS.md
    @@ -119,7 +119,7 @@ expect(jsonResponse).toBeDefined()
     
     - `@bsv/sdk` ^2.0.14 — BRC-103 `Peer`, `Transport`, `SessionManager`, `Utils`, wallet interfaces
     - `express` ^5.1.0 — Web framework
    -- Dev: jest, ts-jest, TypeScript, ts-standard
    +- Dev: jest, ts-jest, TypeScript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/middleware/auth-express-middleware/BASELINE.md b/packages/middleware/auth-express-middleware/BASELINE.md
    index 5ac15b759..fd971ee29 100644
    --- a/packages/middleware/auth-express-middleware/BASELINE.md
    +++ b/packages/middleware/auth-express-middleware/BASELINE.md
    @@ -38,9 +38,9 @@
     
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard src/**/*.ts` |
    -| Fix command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
    +| Fix command | `oxlint src` |
     | Status | Not yet verified clean in ts-stack CI |
     
     ## Dependencies
    @@ -48,7 +48,7 @@
     | Type | Count | Packages |
     |------|-------|---------|
     | Production | 2 | @bsv/sdk, express |
    -| Dev | — | typescript, jest, ts-standard, ts2md, … |
    +| Dev | — | typescript, jest, Oxlint, ts2md, … |
     
     ## Known Issues & Incidents
     
    diff --git a/packages/middleware/auth-express-middleware/package.json b/packages/middleware/auth-express-middleware/package.json
    index 7ccfa0c24..22ae120af 100644
    --- a/packages/middleware/auth-express-middleware/package.json
    +++ b/packages/middleware/auth-express-middleware/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/auth-express-middleware",
    -  "version": "2.1.1",
    +  "version": "2.1.2",
       "description": "BSV Blockchain mutual-authentication express middleware",
       "repository": {
         "type": "git",
    @@ -34,7 +34,7 @@
         "test": "npm run build && jest --runInBand",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -54,17 +54,17 @@
       "author": "BSV Blockchain Association",
       "license": "SEE LICENSE IN LICENSE.txt",
       "devDependencies": {
    -    "@types/body-parser": "^1.19.5",
    -    "@types/express": "^5.0.0",
    +    "@bsv/sdk": "workspace:^",
    +    "@types/body-parser": "^1.19.6",
    +    "@types/express": "^5.0.6",
         "@types/jest": "^30.0.0",
         "@types/mime-types": "^3.0.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
         "express": "^5.2.1",
    diff --git a/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts b/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts
    new file mode 100644
    index 000000000..9ec75b964
    --- /dev/null
    +++ b/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts
    @@ -0,0 +1,13 @@
    +import { ExpressTransport } from '../index'
    +
    +describe('ExpressTransport configuration', () => {
    +  it('exposes allowUnauthenticated and preserves the legacy alias', () => {
    +    const transport = new ExpressTransport(true)
    +
    +    expect(transport.allowUnauthenticated).toBe(true)
    +    expect(transport.allowAuthenticated).toBe(true)
    +
    +    transport.allowAuthenticated = false
    +    expect(transport.allowUnauthenticated).toBe(false)
    +  })
    +})
    diff --git a/packages/middleware/auth-express-middleware/src/index.ts b/packages/middleware/auth-express-middleware/src/index.ts
    index 924617943..7bebab179 100644
    --- a/packages/middleware/auth-express-middleware/src/index.ts
    +++ b/packages/middleware/auth-express-middleware/src/index.ts
    @@ -164,7 +164,7 @@ class ResponseWriterWrapper {
      */
     export class ExpressTransport implements Transport {
       peer?: Peer
    -  allowAuthenticated: boolean
    +  allowUnauthenticated: boolean
       openNonGeneralHandles: Record> = {}
       openGeneralHandles: Record = {}
       openNextHandlers: Record = {}
    @@ -188,11 +188,23 @@ export class ExpressTransport implements Transport {
         logger?: typeof console,
         logLevel?: LogLevel
       ) {
    -    this.allowAuthenticated = allowUnauthenticated
    +    this.allowUnauthenticated = allowUnauthenticated
         this.logger = logger
         this.logLevel = logLevel || 'error' // Default to 'error' if not provided
       }
     
    +  /**
    +   * @deprecated Use `allowUnauthenticated`. This compatibility alias will be
    +   * removed in the next major release.
    +   */
    +  get allowAuthenticated (): boolean {
    +    return this.allowUnauthenticated
    +  }
    +
    +  set allowAuthenticated (value: boolean) {
    +    this.allowUnauthenticated = value
    +  }
    +
       /**
        * Internal logging method, only logs if logger is defined and log level is appropriate.
        *
    @@ -785,9 +797,9 @@ export class ExpressTransport implements Transport {
         this.log(
           'warn',
           'No Auth headers found on request. Checking allowUnauthenticated setting.',
    -      { allowAuthenticated: this.allowAuthenticated }
    +      { allowUnauthenticated: this.allowUnauthenticated }
         )
    -    if (this.allowAuthenticated) {
    +    if (this.allowUnauthenticated) {
           req.auth = { identityKey: 'unknown' }
           next()
         } else {
    diff --git a/packages/middleware/auth/package.json b/packages/middleware/auth/package.json
    index dfa367085..c125153db 100644
    --- a/packages/middleware/auth/package.json
    +++ b/packages/middleware/auth/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/auth",
    -  "version": "0.1.0",
    +  "version": "0.1.1",
       "description": "Signed, expiry-bound, single-use wallet auth proofs for BSV apps.",
       "main": "dist/index.js",
       "module": "dist/index.mjs",
    @@ -22,8 +22,8 @@
       },
       "scripts": {
         "test": "jest --runInBand",
    -    "lint:ci-disabled": "ts-standard src/**/*.ts",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint:ci-disabled": "oxlint src",
    +    "lint": "oxlint src",
         "test:watch": "jest --watch",
         "test:perf": "jest --config jest.perf.config.js --runInBand",
         "test:coverage-disabled": "jest --coverage",
    @@ -39,24 +39,17 @@
       "author": "BSV Blockchain Association",
       "license": "ISC",
       "type": "commonjs",
    -  "dependencies": {},
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    +    "ts-jest": "^29.4.12",
         "tslib": "^2.8.1",
         "tsup": "^8.5.1",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    -  },
    -  "ts-standard": {
    -    "project": "tsconfig.eslint.json",
    -    "ignore": [
    -      "dist"
    -    ]
    +    "oxlint": "^1.75.0"
       },
       "bugs": {
         "url": "https://github.com/bsv-blockchain/ts-stack/issues"
    diff --git a/packages/middleware/payment-express-middleware/AGENTS.md b/packages/middleware/payment-express-middleware/AGENTS.md
    index 03067eef4..6fa1242c4 100644
    --- a/packages/middleware/payment-express-middleware/AGENTS.md
    +++ b/packages/middleware/payment-express-middleware/AGENTS.md
    @@ -94,7 +94,7 @@ const paymentMiddleware = createPaymentMiddleware({
     - `@bsv/sdk` ^2.0.14 — BRC-29 nonce creation/verification, `createNonce()`, `verifyNonce()`, `Utils`, `AtomicBEEF`
     - `@bsv/auth-express-middleware` ^2.0.5 — Auth middleware (peer dependency; must be installed)
     - `express` ^5.1.0 — Web framework
    -- Dev: jest, ts-jest, TypeScript, ts-standard
    +- Dev: jest, ts-jest, TypeScript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/middleware/payment-express-middleware/BASELINE.md b/packages/middleware/payment-express-middleware/BASELINE.md
    index e2e1c9d6f..b56d805ae 100644
    --- a/packages/middleware/payment-express-middleware/BASELINE.md
    +++ b/packages/middleware/payment-express-middleware/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/middleware/payment-express-middleware/package.json b/packages/middleware/payment-express-middleware/package.json
    index 42c51ddcc..d827fda99 100644
    --- a/packages/middleware/payment-express-middleware/package.json
    +++ b/packages/middleware/payment-express-middleware/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/payment-express-middleware",
    -  "version": "2.1.0",
    +  "version": "2.1.1",
       "description": "BSV Blockchain service monetization express middleware",
       "type": "module",
       "main": "dist/cjs/mod.js",
    @@ -21,7 +21,7 @@
         "test": "npm run build && jest --runInBand",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -50,15 +50,15 @@
       "license": "SEE LICENSE IN LICENSE.txt",
       "devDependencies": {
         "@bsv/auth-express-middleware": "workspace:^",
    -    "@types/body-parser": "^1.19.5",
    +    "@bsv/sdk": "workspace:^",
    +    "@types/body-parser": "^1.19.6",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
         "express": "^5.2.1"
    diff --git a/packages/network/ts-p2p/CONTRIBUTING.md b/packages/network/ts-p2p/CONTRIBUTING.md
    index 768daf51d..78f63394f 100644
    --- a/packages/network/ts-p2p/CONTRIBUTING.md
    +++ b/packages/network/ts-p2p/CONTRIBUTING.md
    @@ -66,7 +66,7 @@ Thank you for considering contributing in the BSV Blockchain ecosystem! This doc
     
     > ADAPT TO YOUR PROJECT
     
    -- **Code Style**: We use `ts-standard` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
    +- **Code Style**: We use `Oxlint` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
     
     - **Testing**: Always include tests for new code or changes. We aim for industry-standard levels of test coverage.
       
    diff --git a/packages/network/ts-p2p/package.json b/packages/network/ts-p2p/package.json
    index 9ca77b8e3..0827c5f52 100644
    --- a/packages/network/ts-p2p/package.json
    +++ b/packages/network/ts-p2p/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/teranode-listener",
    -  "version": "1.1.0",
    +  "version": "1.1.1",
       "description": "An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages",
       "type": "module",
       "main": "dist/index.js",
    @@ -17,31 +17,31 @@
         "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"
       },
       "dependencies": {
    -    "@chainsafe/libp2p-gossipsub": "^14.1.1",
    +    "@chainsafe/libp2p-gossipsub": "^14.1.2",
         "@chainsafe/libp2p-noise": "^17.0.0",
         "@chainsafe/libp2p-yamux": "^8.0.1",
    -    "@libp2p/bootstrap": "^12.0.25",
    -    "@libp2p/crypto": "^5.1.20",
    -    "@libp2p/identify": "^4.1.8",
    -    "@libp2p/interface": "^3.2.4",
    -    "@libp2p/kad-dht": "^16.3.3",
    -    "@libp2p/peer-id": "^6.0.11",
    -    "@libp2p/ping": "^3.1.7",
    -    "@libp2p/pnet": "^3.0.23",
    +    "@libp2p/bootstrap": "^12.0.27",
    +    "@libp2p/crypto": "^5.1.21",
    +    "@libp2p/identify": "^4.1.10",
    +    "@libp2p/interface": "^3.2.5",
    +    "@libp2p/kad-dht": "^16.4.0",
    +    "@libp2p/peer-id": "^6.0.12",
    +    "@libp2p/ping": "^3.1.9",
    +    "@libp2p/pnet": "^3.0.25",
         "@libp2p/pubsub-peer-discovery": "^12.0.0",
    -    "@libp2p/tcp": "^11.0.22",
    +    "@libp2p/tcp": "^11.0.24",
         "@multiformats/multiaddr": "^13.0.3",
    -    "libp2p": "^3.3.4"
    +    "libp2p": "^3.3.6"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "tsx": "^4.22.4",
    -    "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "ts-jest": "^29.4.12",
    +    "tsx": "^4.23.1",
    +    "typescript": "^6.0.3"
       },
       "keywords": [
         "teranode",
    diff --git a/packages/overlays/btms-backend/AGENTS.md b/packages/overlays/btms-backend/AGENTS.md
    index e5aa5a790..b13696a89 100644
    --- a/packages/overlays/btms-backend/AGENTS.md
    +++ b/packages/overlays/btms-backend/AGENTS.md
    @@ -103,7 +103,7 @@ const metadata = await manager.getMetaData()
     - `mongodb` — MongoDB driver (for lookup service)
     
     **Dev:**
    -- jest, ts-jest, typescript, ts-standard
    +- jest, ts-jest, typescript, Oxlint
     - mongodb-memory-server — In-memory MongoDB for tests
     
     ## Common pitfalls / gotchas
    diff --git a/packages/overlays/btms-backend/BASELINE.md b/packages/overlays/btms-backend/BASELINE.md
    index a939068c9..f20732eee 100644
    --- a/packages/overlays/btms-backend/BASELINE.md
    +++ b/packages/overlays/btms-backend/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/overlays/btms-backend/package.json b/packages/overlays/btms-backend/package.json
    index 282c9c5a9..800f5aec1 100644
    --- a/packages/overlays/btms-backend/package.json
    +++ b/packages/overlays/btms-backend/package.json
    @@ -27,7 +27,7 @@
         "test:build": "npm run build && jest",
         "test:watch": "jest --watch",
         "test:coverage": "jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "tsc -b",
         "prepublish": "npm run build",
         "doc": "ts2md --inputFilename=mod.ts --outputFilename=API.md --filenameSubstring=API --firstHeadingLevel=1"
    @@ -36,20 +36,20 @@
       "license": "SEE LICENSE IN LICENSE.txt",
       "devDependencies": {
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
         "mongodb-memory-server": "^11.2.0",
    -    "ts-jest": "^29.4.11",
    +    "ts-jest": "^29.4.12",
         "ts-node": "^10.9.2",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
    -    "typescript": "^6.0.3"
    +    "typescript": "^6.0.3",
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
    -    "@bsv/overlay": "^2.1.1",
    -    "@bsv/sdk": "^2.1.6",
    -    "mongodb": "^7.3.0"
    +    "@bsv/overlay": "workspace:^",
    +    "@bsv/sdk": "workspace:^",
    +    "mongodb": "^7.5.0"
       },
       "repository": {
         "type": "git",
    diff --git a/packages/overlays/gasp-core/AGENTS.md b/packages/overlays/gasp-core/AGENTS.md
    index 9cdfb4c3b..457636b3a 100644
    --- a/packages/overlays/gasp-core/AGENTS.md
    +++ b/packages/overlays/gasp-core/AGENTS.md
    @@ -210,7 +210,7 @@ await gaspSequential.sync()
     - `@bsv/sdk` — Transaction, utils for encoding/decoding
     
     **Dev:**
    -- jest, ts-jest, typescript, ts-standard
    +- jest, ts-jest, typescript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/overlays/gasp-core/BASELINE.md b/packages/overlays/gasp-core/BASELINE.md
    index 9a2b75477..44bf0731d 100644
    --- a/packages/overlays/gasp-core/BASELINE.md
    +++ b/packages/overlays/gasp-core/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/overlays/gasp-core/package.json b/packages/overlays/gasp-core/package.json
    index adf1f57b0..d50f34426 100644
    --- a/packages/overlays/gasp-core/package.json
    +++ b/packages/overlays/gasp-core/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/gasp",
    -  "version": "1.3.0",
    +  "version": "1.3.1",
       "type": "module",
       "description": "Graph Aware Sync Protocol",
       "repository": {
    @@ -37,7 +37,7 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -53,16 +53,15 @@
       "author": "BSV Blockchain Association",
       "license": "SEE LICENSE IN LICENSE.txt",
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
    -  "dependencies": {},
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
       },
    diff --git a/packages/overlays/overlay-discovery-services/AGENTS.md b/packages/overlays/overlay-discovery-services/AGENTS.md
    index 687d62610..775842521 100644
    --- a/packages/overlays/overlay-discovery-services/AGENTS.md
    +++ b/packages/overlays/overlay-discovery-services/AGENTS.md
    @@ -109,7 +109,7 @@ const validName = isValidTopicOrServiceName('tm_custom_topic')
     - `mongodb` — MongoDB for lookup service storage (optional, but expected for production)
     
     **Dev:**
    -- jest, ts-jest, typescript, ts-standard
    +- jest, ts-jest, typescript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/overlays/overlay-discovery-services/BASELINE.md b/packages/overlays/overlay-discovery-services/BASELINE.md
    index 3a65d0606..34539278c 100644
    --- a/packages/overlays/overlay-discovery-services/BASELINE.md
    +++ b/packages/overlays/overlay-discovery-services/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/overlays/overlay-discovery-services/package.json b/packages/overlays/overlay-discovery-services/package.json
    index a938ee31b..fe60022e5 100644
    --- a/packages/overlays/overlay-discovery-services/package.json
    +++ b/packages/overlays/overlay-discovery-services/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/overlay-discovery-services",
    -  "version": "2.1.0",
    +  "version": "2.1.1",
       "type": "module",
       "description": "BSV Blockchain Overlay Services Engine",
       "main": "dist/cjs/mod.js",
    @@ -30,7 +30,7 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -55,21 +55,21 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/overlays/overlay-discovery-services#readme",
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
         "mongodb-memory-server": "^11.2.0",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
    -    "@bsv/overlay": "^2.1.1",
    -    "@bsv/wallet-toolbox-client": "^2.3.3",
    -    "mongodb": "^7.3.0"
    +    "@bsv/overlay": "workspace:^",
    +    "@bsv/wallet-toolbox-client": "workspace:^",
    +    "mongodb": "^7.5.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/overlays/overlay-express/AGENTS.md b/packages/overlays/overlay-express/AGENTS.md
    index d45f43d38..84abe88d3 100644
    --- a/packages/overlays/overlay-express/AGENTS.md
    +++ b/packages/overlays/overlay-express/AGENTS.md
    @@ -132,7 +132,7 @@ const token = server.getAdminToken()
     - `chalk` — Colored console output
     
     **Dev:**
    -- jest, ts-jest, typescript, ts-standard
    +- jest, ts-jest, typescript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/overlays/overlay-express/BASELINE.md b/packages/overlays/overlay-express/BASELINE.md
    index eff5dbbf5..fc4912c1d 100644
    --- a/packages/overlays/overlay-express/BASELINE.md
    +++ b/packages/overlays/overlay-express/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/overlays/overlay-express/package.json b/packages/overlays/overlay-express/package.json
    index c143d4362..7e08b7d8e 100644
    --- a/packages/overlays/overlay-express/package.json
    +++ b/packages/overlays/overlay-express/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/overlay-express",
    -  "version": "2.4.1",
    +  "version": "2.4.2",
       "type": "module",
       "description": "BSV Blockchain Overlay Express",
       "main": "dist/cjs/mod.js",
    @@ -29,8 +29,8 @@
         "test": "jest",
         "test:watch": "jest --watch",
         "test:coverage": "jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    -    "lint:ci": "ts-standard src/**/*.ts",
    +    "lint": "oxlint src",
    +    "lint:ci": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -56,29 +56,29 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/overlays/overlay-express#readme",
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
    -    "@types/body-parser": "^1.19.5",
    -    "@types/express": "^5.0.0",
    +    "@types/body-parser": "^1.19.6",
    +    "@types/express": "^5.0.6",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
    -    "@bsv/auth-express-middleware": "^2.1.0",
    -    "@bsv/overlay": "^2.1.1",
    -    "@bsv/overlay-discovery-services": "^2.1.0",
    -    "@bsv/wallet-toolbox-client": "^2.3.3",
    +    "@bsv/auth-express-middleware": "workspace:^",
    +    "@bsv/overlay": "workspace:^",
    +    "@bsv/overlay-discovery-services": "workspace:^",
    +    "@bsv/wallet-toolbox-client": "workspace:^",
         "body-parser": "^2.3.0",
         "chalk": "^5.6.2",
         "express": "^5.2.1",
    -    "knex": "^3.2.10",
    -    "mongodb": "^7.3.0",
    +    "knex": "^3.3.0",
    +    "mongodb": "^7.5.0",
         "uuid": "^14.0.1"
       },
       "peerDependencies": {
    diff --git a/packages/overlays/overlay-express/src/OverlayExpress.ts b/packages/overlays/overlay-express/src/OverlayExpress.ts
    index c6181c496..85c42af3a 100644
    --- a/packages/overlays/overlay-express/src/OverlayExpress.ts
    +++ b/packages/overlays/overlay-express/src/OverlayExpress.ts
    @@ -188,6 +188,18 @@ interface BASMCapableEngine extends Engine {
       revalidateRecentAnchors: (depth?: number) => Promise
     }
     
    +function parseTopicsHeader (header: string): string[] {
    +  const value = header.trim()
    +  const parsed: unknown = value.startsWith('[')
    +    ? JSON.parse(value)
    +    : value.split(',').map(topic => topic.trim())
    +
    +  if (!Array.isArray(parsed) || parsed.some(topic => typeof topic !== 'string' || topic.length === 0)) {
    +    throw new TypeError('Invalid x-topics header: expected a comma-separated list or JSON string array')
    +  }
    +  return parsed
    +}
    +
     /**
      * OverlayExpress class provides an Express-based server for hosting Overlay Services.
      * It allows configuration of various components like databases, topic managers, and lookup services.
    @@ -1474,9 +1486,13 @@ export default class OverlayExpress {
               if (typeof topicsHeader !== 'string') {
                 throw new TypeError('Missing x-topics header')
               }
    -          const topics = JSON.parse(topicsHeader)
    +          const topics = parseTopicsHeader(topicsHeader)
    +          const body = req.body
    +          if (body == null || typeof body[Symbol.iterator] !== 'function' || body.length === 0) {
    +            throw new TypeError('Missing or empty BEEF body')
    +          }
               let offChainValues: number[] | undefined
    -          let beef = Array.from(req.body as number[])
    +          let beef = Array.from(body as number[])
               if (includesOffChain) {
                 const r = new Utils.Reader(beef)
                 const l = r.readVarIntNum()
    @@ -1989,7 +2005,7 @@ export default class OverlayExpress {
         this.app.post('/admin/health-check', checkAdminAuth as any, (req, res) => {
           ; (async () => {
             try {
    -          const { url } = req.body
    +          const url = req.body?.url
               if (typeof url !== 'string' || url.length === 0) {
                 return res.status(400).json({ status: 'error', message: 'url is required' })
               }
    diff --git a/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts b/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts
    index 6e2793da4..2b26d58bb 100644
    --- a/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts
    +++ b/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts
    @@ -784,6 +784,91 @@ describe('OverlayExpress', () => {
           expect(listenSpy).toHaveBeenCalledWith(3000, expect.any(Function))
         })
     
    +    it('accepts canonical and legacy X-Topics formats on /submit', async () => {
    +      const postSpy = jest.spyOn(instance.app, 'post')
    +      jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => {
    +        callback()
    +        return {} as any
    +      })
    +      await instance.start()
    +
    +      const route = postSpy.mock.calls.find(call => call[0] === '/submit')
    +      const handler: any = route === undefined ? undefined : route[route.length - 1]
    +      expect(handler).toBeDefined()
    +
    +      for (const topicsHeader of ['tm_foo,tm_bar', '["tm_foo","tm_bar"]']) {
    +        const res: any = {
    +          status: jest.fn().mockReturnThis(),
    +          json: jest.fn().mockReturnThis()
    +        }
    +        handler?.({
    +          headers: { 'x-topics': topicsHeader },
    +          body: Buffer.from([1, 2, 3])
    +        }, res)
    +        await new Promise(resolve => setImmediate(resolve))
    +      }
    +
    +      expect(mockEngine.submit).toHaveBeenCalledTimes(2)
    +      for (const call of mockEngine.submit.mock.calls) {
    +        expect(call[0]).toEqual({
    +          beef: [1, 2, 3],
    +          topics: ['tm_foo', 'tm_bar'],
    +          offChainValues: undefined
    +        })
    +      }
    +    })
    +
    +    it('returns a clean 400 for an empty /submit body', async () => {
    +      const postSpy = jest.spyOn(instance.app, 'post')
    +      jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => {
    +        callback()
    +        return {} as any
    +      })
    +      const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
    +      await instance.start()
    +
    +      const route = postSpy.mock.calls.find(call => call[0] === '/submit')
    +      const handler: any = route === undefined ? undefined : route[route.length - 1]
    +      const res: any = {
    +        status: jest.fn().mockReturnThis(),
    +        json: jest.fn().mockReturnThis()
    +      }
    +      handler?.({ headers: { 'x-topics': 'tm_foo' }, body: undefined }, res)
    +      await new Promise(resolve => setImmediate(resolve))
    +
    +      expect(res.status).toHaveBeenCalledWith(400)
    +      expect(res.json).toHaveBeenCalledWith({
    +        status: 'error',
    +        message: 'Missing or empty BEEF body'
    +      })
    +      expect(mockEngine.submit).not.toHaveBeenCalled()
    +      consoleError.mockRestore()
    +    })
    +
    +    it('returns a clean 400 when /admin/health-check has no body', async () => {
    +      const postSpy = jest.spyOn(instance.app, 'post')
    +      jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => {
    +        callback()
    +        return {} as any
    +      })
    +      await instance.start()
    +
    +      const route = postSpy.mock.calls.find(call => call[0] === '/admin/health-check')
    +      const handler: any = route === undefined ? undefined : route[route.length - 1]
    +      const res: any = {
    +        status: jest.fn().mockReturnThis(),
    +        json: jest.fn().mockReturnThis()
    +      }
    +      handler?.({ body: undefined }, res)
    +      await new Promise(resolve => setImmediate(resolve))
    +
    +      expect(res.status).toHaveBeenCalledWith(400)
    +      expect(res.json).toHaveBeenCalledWith({
    +        status: 'error',
    +        message: 'url is required'
    +      })
    +    })
    +
         it('should set up CORS middleware', async () => {
           const useSpy = jest.spyOn(instance.app, 'use')
           jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => {
    @@ -1098,7 +1183,8 @@ describe('OverlayExpress', () => {
             revokeAdvertisements: jest.fn(),
             parseAdvertisement: jest.fn()
           }
    -      instance.engine!.advertiser = mockAdvertiser
    +      if (instance.engine === undefined) throw new Error('improper test setup')
    +      instance.engine.advertiser = mockAdvertiser
     
           jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => {
             callback()
    diff --git a/packages/overlays/overlay-express/src/__tests__/OverlayProviders.live.test.ts b/packages/overlays/overlay-express/src/__tests__/OverlayProviders.live.test.ts
    index 11a3cd88c..e888f98c9 100644
    --- a/packages/overlays/overlay-express/src/__tests__/OverlayProviders.live.test.ts
    +++ b/packages/overlays/overlay-express/src/__tests__/OverlayProviders.live.test.ts
    @@ -19,7 +19,8 @@ describeLive('Overlay providers live integration', () => {
         expect(header?.height).toBe(height)
         expect(header?.hash).toMatch(/^[0-9a-f]{64}$/)
         expect(header?.merkleRoot).toMatch(/^[0-9a-f]{64}$/)
    -    await expect(chaintracks.isValidRootForHeight(header!.merkleRoot, height)).resolves.toBe(true)
    +    if (header === undefined) throw new Error('header was not returned')
    +    await expect(chaintracks.isValidRootForHeight(header.merkleRoot, height)).resolves.toBe(true)
       })
     
       test('fetches and validates a real mined mainnet Arcade proof', async () => {
    @@ -34,6 +35,9 @@ describeLive('Overlay providers live integration', () => {
         expect(proof?.txid).toBe(txid)
         expect(proof?.blockHeight).toBeGreaterThan(0)
         expect(proof?.merkleRoot).toMatch(/^[0-9a-f]{64}$/)
    -    await expect(chaintracks.isValidRootForHeight(proof!.merkleRoot, proof!.blockHeight!)).resolves.toBe(true)
    +    if (proof === undefined || proof.blockHeight === undefined) {
    +      throw new Error('complete proof was not returned')
    +    }
    +    await expect(chaintracks.isValidRootForHeight(proof.merkleRoot, proof.blockHeight)).resolves.toBe(true)
       })
     })
    diff --git a/packages/overlays/overlay-express/src/generalGuide.md.ts b/packages/overlays/overlay-express/src/generalGuide.md.ts
    index 72f9e0fc4..96b0d6813 100644
    --- a/packages/overlays/overlay-express/src/generalGuide.md.ts
    +++ b/packages/overlays/overlay-express/src/generalGuide.md.ts
    @@ -10,7 +10,7 @@ A Topic Manager controls addition and removal of transaction outputs to an Overl
     #### Request Headers
     \\\`\\\`\\\`json
     {
    -  "x-topics": "["tm_messagebox"]", // array of topic identifiers as stringified JSON
    +  "x-topics": "tm_messagebox", // comma-separated topic identifiers
       "x-includes-off-chain-values": "false" // string "true" or "false"
     }
     \\\`\\\`\\\`
    diff --git a/packages/overlays/overlay/AGENTS.md b/packages/overlays/overlay/AGENTS.md
    index 4069a8955..84ac35e6e 100644
    --- a/packages/overlays/overlay/AGENTS.md
    +++ b/packages/overlays/overlay/AGENTS.md
    @@ -48,7 +48,10 @@ const engine = new Engine(
     )
     
     // 2. Submitting transactions with topics
    -const topics = JSON.parse(req.headers['x-topics'])
    +const topicsHeader = req.headers['x-topics']
    +const topics = topicsHeader.trim().startsWith('[')
    +  ? JSON.parse(topicsHeader)
    +  : topicsHeader.split(',').map(topic => topic.trim())
     const taggedBEEF = { beef: Array.from(req.body), topics }
     await engine.submit(taggedBEEF, (steak) => res.status(200).json(steak))
     
    @@ -106,7 +109,7 @@ class CustomLookupService implements LookupService {
     - `knex` — SQL query builder (for KnexStorage)
     
     **Dev:**
    -- jest, ts-jest, typescript, ts-standard
    +- jest, ts-jest, typescript, Oxlint
     
     ## Common pitfalls / gotchas
     
    diff --git a/packages/overlays/overlay/BASELINE.md b/packages/overlays/overlay/BASELINE.md
    index ef210964c..48f0cc8ee 100644
    --- a/packages/overlays/overlay/BASELINE.md
    +++ b/packages/overlays/overlay/BASELINE.md
    @@ -38,9 +38,9 @@
     
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard src/**/*.ts` |
    -| Fix command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
    +| Fix command | `oxlint src` |
     | Status | Not yet verified clean in ts-stack CI |
     
     ## Dependencies
    @@ -48,7 +48,7 @@
     | Type | Count | Packages |
     |------|-------|---------|
     | Production | 3 | @bsv/gasp, @bsv/sdk, knex |
    -| Dev | — | typescript, jest, ts-standard, ts2md, … |
    +| Dev | — | typescript, jest, Oxlint, ts2md, … |
     
     ## Known Issues & Incidents
     
    diff --git a/packages/overlays/overlay/CONTRIBUTING.md b/packages/overlays/overlay/CONTRIBUTING.md
    index d99c0ccf2..5adf7fb8c 100644
    --- a/packages/overlays/overlay/CONTRIBUTING.md
    +++ b/packages/overlays/overlay/CONTRIBUTING.md
    @@ -64,7 +64,7 @@ Thank you for considering contributing to the BSV Blockchain Overlay Services En
     
     ## Coding Conventions
     
    -- **Code Style**: We use `ts-standard` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
    +- **Code Style**: We use `Oxlint` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
       
     - **Minimal Runtime Dependencies**: Code should not depend on external systems where possible, with a strong preference for maintaining things internally. The one exception is the `@bsv/sdk` library dependency.
       
    diff --git a/packages/overlays/overlay/README.md b/packages/overlays/overlay/README.md
    index 71ae2da11..b23953ab2 100644
    --- a/packages/overlays/overlay/README.md
    +++ b/packages/overlays/overlay/README.md
    @@ -145,7 +145,10 @@ app.get(`/getDocumentationForLookupServiceProvider`, async (req, res) => {
     app.post(`/submit`, async (req, res) => {
       try {
         // Parse out the topics and construct the tagged BEEF
    -    const topics = JSON.parse(req.headers['x-topics'] as string)
    +    const topicsHeader = req.headers['x-topics'] as string
    +    const topics = topicsHeader.trim().startsWith('[')
    +      ? JSON.parse(topicsHeader)
    +      : topicsHeader.split(',').map(topic => topic.trim())
         const taggedBEEF: TaggedBEEF = {
           beef: Array.from(req.body as number[]),
           topics
    diff --git a/packages/overlays/overlay/package.json b/packages/overlays/overlay/package.json
    index 16ad32b28..d69fbc560 100644
    --- a/packages/overlays/overlay/package.json
    +++ b/packages/overlays/overlay/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/overlay",
    -  "version": "2.2.0",
    +  "version": "2.2.1",
       "type": "module",
       "description": "BSV Blockchain Overlay Services Engine",
       "main": "dist/cjs/mod.js",
    @@ -39,8 +39,8 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    -    "lint:ci": "ts-standard src/**/*.ts",
    +    "lint": "oxlint src",
    +    "lint:ci": "oxlint src",
         "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "dev": "tsc -b -w",
         "prepublish": "npm run build",
    @@ -65,19 +65,19 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/overlays/overlay#readme",
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "dependencies": {
    -    "@bsv/gasp": "^1.3.0",
    -    "knex": "^3.2.10"
    +    "@bsv/gasp": "workspace:^",
    +    "knex": "^3.3.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/overlays/overlay/src/Engine.ts b/packages/overlays/overlay/src/Engine.ts
    index 0fa47d8b0..7f1af77ae 100644
    --- a/packages/overlays/overlay/src/Engine.ts
    +++ b/packages/overlays/overlay/src/Engine.ts
    @@ -919,7 +919,7 @@ export class Engine {
       async lookup(lookupQuestion: LookupQuestion): Promise {
         // Validate a lookup service for the provider is found
         const lookupService = this.lookupServices[lookupQuestion.service]
    -    if (lookupService === undefined || lookupService === null) throw new Error(`Lookup service not found for provider: ${lookupQuestion.service} `)
    +    if (lookupService === undefined || lookupService === null) throw new Error(`Lookup service not found for provider: ${lookupQuestion.service}`)
     
         const lookupResult = await lookupService.lookup(lookupQuestion)
         const hydrationContext = this.createUTXOHistoryHydrationContext()
    @@ -1954,20 +1954,20 @@ export class Engine {
        * @param proof for txid
        */
       private updateInputProofs(tx: Transaction, txid: string, proof: MerklePath): void {
    -    if (tx.merklePath !== undefined) {
    +    if (tx.id('hex') === txid) {
           // Update the merkle path to handle potential reorgs
           tx.merklePath = proof
           return
         }
    -    if (tx.id('hex') === txid) {
    -      tx.merklePath = proof
    -    } else {
    -      for (const input of tx.inputs) {
    -        // All inputs must have sourceTransactions
    -        const stx = input.sourceTransaction
    -        if (typeof stx !== 'object') continue
    -        this.updateInputProofs(stx, txid, proof)
    -      }
    +    // A mined transaction's source graph is no longer part of its BEEF. Do not
    +    // replace an unrelated transaction's proof with the proof for an ancestor.
    +    if (tx.merklePath !== undefined) return
    +
    +    for (const input of tx.inputs) {
    +      // All inputs must have sourceTransactions
    +      const stx = input.sourceTransaction
    +      if (typeof stx !== 'object') continue
    +      this.updateInputProofs(stx, txid, proof)
         }
       }
     
    @@ -1984,13 +1984,8 @@ export class Engine {
         }
     
         const tx = Transaction.fromBEEF(output.beef)
    -    if (tx.merklePath !== undefined) {
    -      // Update the merkle path to handle potential reorgs
    -      tx.merklePath = proof
    -      return
    -    }
    -
    -    // recursively update all sourceTransactions proven by (txid,proof)
    +    // Update this transaction, or recursively update the matching source
    +    // transaction. This also persists replacement proofs after a reorg.
         this.updateInputProofs(tx, txid, proof)
     
         // Update the output's BEEF in the storage DB
    diff --git a/packages/overlays/overlay/src/GASP/OverlayGASPStorage.ts b/packages/overlays/overlay/src/GASP/OverlayGASPStorage.ts
    index af9807035..53eda50b0 100644
    --- a/packages/overlays/overlay/src/GASP/OverlayGASPStorage.ts
    +++ b/packages/overlays/overlay/src/GASP/OverlayGASPStorage.ts
    @@ -145,7 +145,8 @@ export class OverlayGASPStorage implements GASPStorage {
             }
             return await this.stripAlreadyKnownInputs(response)
           } catch (e) {
    -        console.error(`An error occurred when identifying needed inputs for transaction: ${parsedTx.id('hex')}.${tx.outputIndex}: ${e}`)
    +        const message = e instanceof Error ? e.message : String(e)
    +        console.error(`An error occurred when identifying needed inputs for transaction: ${parsedTx.id('hex')}.${tx.outputIndex}: ${message}`)
             // Cut off the graph in case of an error here.
           }
           // By default, if the topic manager isn't able to stipulate needed inputs, only the inputs necessary for SPV are requested.
    diff --git a/packages/overlays/overlay/src/__tests/BASMChain.test.ts b/packages/overlays/overlay/src/__tests/BASMChain.test.ts
    index 90db102ad..109907b6d 100644
    --- a/packages/overlays/overlay/src/__tests/BASMChain.test.ts
    +++ b/packages/overlays/overlay/src/__tests/BASMChain.test.ts
    @@ -28,6 +28,11 @@ interface FakeStore {
       applied?: AppliedRow[]
     }
     
    +function must (value: T | undefined, message: string): T {
    +  if (value === undefined) throw new Error(message)
    +  return value
    +}
    +
     function makeStorage (store: FakeStore): any {
       const key = (topic: string, height: number): string => `${topic}:${height}`
       return {
    @@ -111,11 +116,11 @@ describe('BRC-136 BASM anchor chain continuity', () => {
         const store: FakeStore = { anchors: new Map(), admitted: new Map() }
     
         // Genesis: topic admits two txs at height 100.
    -    store.admitted!.set(100, [
    +    must(store.admitted, 'admitted transaction map').set(100, [
           { txid: TXID_1, blockIndex: 0 },
           { txid: TXID_2, blockIndex: 1 }
         ])
    -    const genesisRoot = computeBasmRoot(store.admitted!.get(100)!)
    +    const genesisRoot = computeBasmRoot(must(must(store.admitted, 'admitted transaction map').get(100), 'genesis admissions'))
         const genesisTac = computeTac(ZERO, blockHashFor(100), genesisRoot)
         store.anchors.set('tm_test:100', {
           topic: 'tm_test',
    @@ -137,7 +142,7 @@ describe('BRC-136 BASM anchor chain continuity', () => {
         // 101..105 are empty anchors (zero root, zero count) chained off genesis.
         let expectedTac = genesisTac
         for (let h = 101; h <= 105; h++) {
    -      const anchor = store.anchors.get(`tm_test:${h}`)!
    +      const anchor = must(store.anchors.get(`tm_test:${h}`), `anchor ${h}`)
           expect(anchor.basmRoot).toBe(ZERO)
           expect(anchor.admittedCount).toBe(0)
           expectedTac = computeTac(expectedTac, blockHashFor(h), ZERO)
    @@ -146,7 +151,7 @@ describe('BRC-136 BASM anchor chain continuity', () => {
     
         // The tip TAC is a cumulative hash that still depends on the genesis block —
         // i.e. it was NOT reset to a per-block value.
    -    const tipTac = store.anchors.get('tm_test:105')!.tac
    +    const tipTac = must(store.anchors.get('tm_test:105'), 'tip anchor').tac
         const resetTac = computeTac(ZERO, blockHashFor(105), ZERO)
         expect(tipTac).not.toBe(resetTac)
       })
    @@ -192,29 +197,29 @@ describe('BRC-136 BASM reorg handling', () => {
         })
     
         // TXID_2 is demoted: no longer proven, block metadata cleared.
    -    const row = store.applied!.find(r => r.txid === TXID_2)!
    +    const row = must(store.applied?.find(r => r.txid === TXID_2), 'orphaned applied row')
         expect(row.proven).toBe(false)
         expect(row.blockHeight).toBeUndefined()
         // It survives as a receipt record (firstSeenHeight retained).
         expect(row.firstSeenHeight).toBe(101)
     
         // Anchor at 101 rebuilt: empty admitted set, canonical hash, recomputed TAC.
    -    const anchor101 = store.anchors.get('tm_test:101')!
    +    const anchor101 = must(store.anchors.get('tm_test:101'), 'anchor 101')
         expect(anchor101.admittedCount).toBe(0)
         expect(anchor101.basmRoot).toBe(ZERO)
         expect(anchor101.blockHash).toBe(H101_NEW)
    -    const tac100 = store.anchors.get('tm_test:100')!.tac
    +    const tac100 = must(store.anchors.get('tm_test:100'), 'anchor 100').tac
         expect(anchor101.tac).toBe(computeTac(tac100, H101_NEW, ZERO))
     
         // Height 100 is untouched.
         const root100 = computeBasmRoot([{ txid: TXID_1, blockIndex: 0 }])
    -    expect(store.anchors.get('tm_test:100')!.basmRoot).toBe(root100)
    +    expect(must(store.anchors.get('tm_test:100'), 'anchor 100').basmRoot).toBe(root100)
       })
     
       it('is idempotent: orphaned hashes matching no proven rows leave the chain unchanged', async () => {
         const store = seedTwoBlockChain()
         const engine = makeEngine(store, { currentHeight: 101 })
    -    const before = store.anchors.get('tm_test:101')!.tac
    +    const before = must(store.anchors.get('tm_test:101'), 'anchor 101').tac
     
         await (engine as any).handleReorg({
           orphanedBlockHashes: ['ffff000000000000000000000000000000000000000000000000000000000000'],
    @@ -222,8 +227,8 @@ describe('BRC-136 BASM reorg handling', () => {
           newTipHeight: 101
         })
     
    -    expect(store.applied!.find(r => r.txid === TXID_2)!.proven).toBe(true)
    -    expect(store.anchors.get('tm_test:101')!.tac).toBe(before)
    +    expect(must(store.applied?.find(r => r.txid === TXID_2), 'applied row 2').proven).toBe(true)
    +    expect(must(store.anchors.get('tm_test:101'), 'anchor 101').tac).toBe(before)
       })
     
       it('re-proving a demoted tx at a new height restores it to the admitted set', async () => {
    @@ -235,10 +240,10 @@ describe('BRC-136 BASM reorg handling', () => {
           rebuildFromHeight: 101,
           newTipHeight: 101
         })
    -    expect(store.anchors.get('tm_test:101')!.basmRoot).toBe(ZERO)
    +    expect(must(store.anchors.get('tm_test:101'), 'anchor 101').basmRoot).toBe(ZERO)
     
         // TXID_2 re-mined into the new canonical block at 101.
    -    const row = store.applied!.find(r => r.txid === TXID_2)!
    +    const row = must(store.applied?.find(r => r.txid === TXID_2), 'applied row 2')
         row.proven = true
         row.blockHeight = 101
         row.blockHash = H101_NEW
    @@ -251,7 +256,7 @@ describe('BRC-136 BASM reorg handling', () => {
           newTipHeight: 101
         })
     
    -    const anchor101 = store.anchors.get('tm_test:101')!
    +    const anchor101 = must(store.anchors.get('tm_test:101'), 'anchor 101')
         expect(anchor101.admittedCount).toBe(1)
         expect(anchor101.basmRoot).toBe(computeBasmRoot([{ txid: TXID_2, blockIndex: 0 }]))
         expect(anchor101.blockHash).toBe(H101_NEW)
    @@ -268,23 +273,23 @@ describe('BRC-136 BASM reorg revalidation sweep', () => {
     
         await (engine as any).revalidateRecentAnchors(3)
     
    -    expect(store.applied!.find(r => r.txid === TXID_2)!.proven).toBe(false)
    -    const anchor101 = store.anchors.get('tm_test:101')!
    +    expect(must(store.applied?.find(r => r.txid === TXID_2), 'applied row 2').proven).toBe(false)
    +    const anchor101 = must(store.anchors.get('tm_test:101'), 'anchor 101')
         expect(anchor101.basmRoot).toBe(ZERO)
         expect(anchor101.blockHash).toBe(H101_NEW)
         // Height 100 still valid and untouched.
    -    expect(store.applied!.find(r => r.txid === TXID_1)!.proven).toBe(true)
    -    expect(store.anchors.get('tm_test:100')!.basmRoot).toBe(computeBasmRoot([{ txid: TXID_1, blockIndex: 0 }]))
    +    expect(must(store.applied?.find(r => r.txid === TXID_1), 'applied row 1').proven).toBe(true)
    +    expect(must(store.anchors.get('tm_test:100'), 'anchor 100').basmRoot).toBe(computeBasmRoot([{ txid: TXID_1, blockIndex: 0 }]))
       })
     
       it('leaves the chain unchanged when every proof in the window still validates', async () => {
         const store = seedTwoBlockChain()
         const engine = makeEngine(store, { currentHeight: 101, isValidRootForHeight: async () => true })
    -    const before = store.anchors.get('tm_test:101')!.tac
    +    const before = must(store.anchors.get('tm_test:101'), 'anchor 101').tac
     
         await (engine as any).revalidateRecentAnchors(3)
     
    -    expect(store.applied!.find(r => r.txid === TXID_2)!.proven).toBe(true)
    -    expect(store.anchors.get('tm_test:101')!.tac).toBe(before)
    +    expect(must(store.applied?.find(r => r.txid === TXID_2), 'applied row 2').proven).toBe(true)
    +    expect(must(store.anchors.get('tm_test:101'), 'anchor 101').tac).toBe(before)
       })
     })
    diff --git a/packages/overlays/overlay/src/__tests/Engine.test.ts b/packages/overlays/overlay/src/__tests/Engine.test.ts
    index accc4a873..cce6b5c74 100644
    --- a/packages/overlays/overlay/src/__tests/Engine.test.ts
    +++ b/packages/overlays/overlay/src/__tests/Engine.test.ts
    @@ -309,6 +309,37 @@ describe('BSV Overlay Services Engine', () => {
         })
       })
       describe('handleNewMerkleProof tests', () => {
    +    it('persists a replacement proof when the stored BEEF is already mined', async () => {
    +      const tx = Transaction.fromHexBEEF(beef37abad0)
    +      const txid = tx.id('hex')
    +      const output: Output = {
    +        txid,
    +        outputIndex: 0,
    +        outputScript: tx.outputs[0].lockingScript.toBinary(),
    +        topic: 'hello',
    +        satoshis: tx.outputs[0].satoshis,
    +        beef: tx.toBEEF(),
    +        spent: false,
    +        outputsConsumed: [],
    +        consumedBy: [],
    +        score: Date.now()
    +      }
    +      const updateTransactionBEEF = jest.fn(async () => undefined)
    +      mockStorageEngine.findOutputsForTransaction = jest.fn(async () => [output])
    +      mockStorageEngine.updateTransactionBEEF = updateTransactionBEEF
    +      const engine = new Engine(
    +        { Hello: mockTopicManager },
    +        { Hello: mockLookupService },
    +        mockStorageEngine,
    +        mockChainTracker
    +      )
    +
    +      if (tx.merklePath === undefined) throw new Error('improper test setup')
    +      await engine.handleNewMerkleProof(txid, tx.merklePath)
    +
    +      expect(updateTransactionBEEF).toHaveBeenCalledWith(txid, tx.toBEEF())
    +    })
    +
         it('0 simple proof', async () => {
           const beef = beef27c8f1
           const txid = txid27c8f
    @@ -423,7 +454,12 @@ describe('BSV Overlay Services Engine', () => {
     
           const mp37abad = Transaction.fromHexBEEF(beef37abad0).merklePath
           await engine.handleNewMerkleProof(txid37abad, mp37abad)
    -      expect(Object.keys(newBEEF).length).toBe(0)
    +      expect(newBEEF[`${txid37abad}`]).toBe(beef37abad0)
    +      expect(newBEEF[`${txid877734}`].length).toBeGreaterThan(beef8777340.length)
    +      expect(newBEEF[`${txid509f5e}`].length).toBeGreaterThan(beef509f5e0.length)
    +      expect(newBEEF[`${txid942620}`].length).toBeGreaterThan(beef9426200.length)
    +      expect(newBEEF[`${txid17d182}`].length).toBeGreaterThan(beef17d1820.length)
    +      expect(Object.keys(newBEEF)).toHaveLength(5)
     
           const mp877734 = Transaction.fromHexBEEF(beef8777340).merklePath
           await engine.handleNewMerkleProof(txid877734, mp877734)
    @@ -431,7 +467,7 @@ describe('BSV Overlay Services Engine', () => {
           expect(newBEEF[`${txid509f5e}`].length).toBeGreaterThan(beef509f5e0.length)
           expect(newBEEF[`${txid942620}`].length).toBeGreaterThan(beef9426200.length)
           expect(newBEEF[`${txid17d182}`].length).toBeGreaterThan(beef17d1820.length)
    -      expect(Object.keys(newBEEF).length).toBe(4)
    +      expect(Object.keys(newBEEF)).toHaveLength(5)
     
           const mp509f5e = Transaction.fromHexBEEF(beef509f5e0).merklePath
           await engine.handleNewMerkleProof(txid509f5e, mp509f5e)
    @@ -439,7 +475,7 @@ describe('BSV Overlay Services Engine', () => {
           expect(newBEEF[`${txid509f5e}`]).toBe(beef509f5e0)
           expect(newBEEF[`${txid942620}`].length).toBeGreaterThan(beef9426200.length)
           expect(newBEEF[`${txid17d182}`].length).toBeGreaterThan(beef17d1820.length)
    -      expect(Object.keys(newBEEF).length).toBe(4)
    +      expect(Object.keys(newBEEF)).toHaveLength(5)
     
           const mp942620 = Transaction.fromHexBEEF(beef9426200).merklePath
           await engine.handleNewMerkleProof(txid942620, mp942620)
    @@ -447,7 +483,7 @@ describe('BSV Overlay Services Engine', () => {
           expect(newBEEF[`${txid509f5e}`]).toBe(beef509f5e0)
           expect(newBEEF[`${txid942620}`]).toBe(beef9426200)
           expect(newBEEF[`${txid17d182}`].length).toBeGreaterThan(beef17d1820.length)
    -      expect(Object.keys(newBEEF).length).toBe(4)
    +      expect(Object.keys(newBEEF)).toHaveLength(5)
     
           const mp17d182 = Transaction.fromHexBEEF(beef17d1820).merklePath
           await engine.handleNewMerkleProof(txid17d182, mp17d182)
    @@ -455,7 +491,7 @@ describe('BSV Overlay Services Engine', () => {
           expect(newBEEF[`${txid509f5e}`]).toBe(beef509f5e0)
           expect(newBEEF[`${txid942620}`]).toBe(beef9426200)
           expect(newBEEF[`${txid17d182}`]).toBe(beef17d1820)
    -      expect(Object.keys(newBEEF).length).toBe(4)
    +      expect(Object.keys(newBEEF)).toHaveLength(5)
         })
       })
     
    @@ -963,7 +999,7 @@ describe('BSV Overlay Services Engine', () => {
             await expect(engine.lookup({
               service: 'HelloWorld',
               query: { name: 'Bob' }
    -        })).rejects.toThrow()
    +        })).rejects.toThrow('Lookup service not found for provider: HelloWorld')
           })
           it('Calls the lookup function from the lookup service', async () => {
             // TODO: Make the default storage engine return something...?
    diff --git a/packages/overlays/overlay/tsconfig.base.json b/packages/overlays/overlay/tsconfig.base.json
    index cca5c16cf..f4582afdf 100644
    --- a/packages/overlays/overlay/tsconfig.base.json
    +++ b/packages/overlays/overlay/tsconfig.base.json
    @@ -1,6 +1,7 @@
     {
       "compilerOptions": {
         "lib": ["dom", "ESNext"],
    +    "types": ["node"],
         "module": "NodeNext",
         "target": "esnext",
         "moduleResolution": "NodeNext",
    diff --git a/packages/overlays/topics/AGENTS.md b/packages/overlays/topics/AGENTS.md
    index 5d41a55c2..53f6a6440 100644
    --- a/packages/overlays/topics/AGENTS.md
    +++ b/packages/overlays/topics/AGENTS.md
    @@ -177,7 +177,7 @@ await server.start()
     - `mongodb` — MongoDB driver (for lookup services)
     
     **Dev:**
    -- jest, ts-jest, typescript, ts-standard
    +- jest, ts-jest, typescript, Oxlint
     - mongodb-memory-server — In-memory MongoDB for tests
     
     ## Common pitfalls / gotchas
    diff --git a/packages/overlays/topics/BASELINE.md b/packages/overlays/topics/BASELINE.md
    index 8673df0f1..bc75e462e 100644
    --- a/packages/overlays/topics/BASELINE.md
    +++ b/packages/overlays/topics/BASELINE.md
    @@ -9,7 +9,7 @@
     | Check | Status |
     |-------|--------|
     | TypeScript | ✅ passes (`tsc --noEmit`) |
    -| Lint | ⚠️ not yet run (ts-standard) |
    +| Lint | ⚠️ not yet run (Oxlint) |
     | Tests | ✅ 189 passing, 1 skipped (19 suites: all 19 topic pairs) |
     
     ## Coverage
    diff --git a/packages/overlays/topics/package.json b/packages/overlays/topics/package.json
    index 4a2f279b8..277f6854d 100644
    --- a/packages/overlays/topics/package.json
    +++ b/packages/overlays/topics/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/overlay-topics",
    -  "version": "1.6.0",
    +  "version": "1.6.1",
       "description": "Canonical BSV overlay topic managers and lookup services",
       "type": "module",
       "main": "./dist/index.js",
    @@ -13,25 +13,25 @@
       },
       "scripts": {
         "build": "tsc",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand",
         "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"
       },
       "dependencies": {
    -    "@bsv/overlay": "^2.1.1",
    +    "@bsv/overlay": "workspace:^",
         "@bsv/templates": "workspace:^",
    -    "mongodb": "^7.3.0"
    +    "mongodb": "^7.5.0"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
         "mongodb-memory-server": "^11.2.0",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.0",
    +    "ts-jest": "^29.4.12",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "license": "Open BSV",
       "author": "BSV Blockchain Association",
    diff --git a/packages/sdk/BASELINE.md b/packages/sdk/BASELINE.md
    index 505408ea5..e586631f4 100644
    --- a/packages/sdk/BASELINE.md
    +++ b/packages/sdk/BASELINE.md
    @@ -40,9 +40,9 @@
     
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard src/**/*.ts` |
    -| Fix command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
    +| Fix command | `oxlint src` |
     | Status | Not yet verified clean in ts-stack CI |
     
     ## Dependencies
    @@ -50,7 +50,7 @@
     | Type | Count | Packages |
     |------|-------|---------|
     | Production | 0 | *(zero — no runtime deps)* |
    -| Dev | — | typescript, jest, ts-standard, rspack, ts2md, … |
    +| Dev | — | typescript, jest, Oxlint, rspack, ts2md, … |
     
     ## Known Issues & Incidents
     
    diff --git a/packages/sdk/CONTRIBUTING.md b/packages/sdk/CONTRIBUTING.md
    index 84ccddeb3..cd4f0083c 100644
    --- a/packages/sdk/CONTRIBUTING.md
    +++ b/packages/sdk/CONTRIBUTING.md
    @@ -64,7 +64,7 @@ Thank you for considering contributing to the BSV Blockchain Libraries Project!
     
     ## Coding Conventions
     
    -- **Code Style**: We use `ts-standard` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
    +- **Code Style**: We use `Oxlint` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
       
     - **No Runtime Dependencies**: All code should be maintained within this library. Do not introduce external dependencies.
       
    diff --git a/packages/sdk/eslint.config.js b/packages/sdk/eslint.config.js
    deleted file mode 100644
    index a0e59df47..000000000
    --- a/packages/sdk/eslint.config.js
    +++ /dev/null
    @@ -1,43 +0,0 @@
    -import globals from 'globals'
    -import pluginJs from '@eslint/js'
    -import tseslint from 'typescript-eslint'
    -import tsStandard from 'ts-standard'
    -import pluginJest from 'eslint-plugin-jest'
    -
    -export default [
    -  tsStandard, // ✅ Ensure ESLint loads ts-standard as a base config
    -
    -  {
    -    // Add ignorePatterns at the top level for ESLint
    -    ignorePatterns: ['src/primitives/Point.ts', 'docs/swagger/*'],
    -
    -    files: ['src/**/*.ts', '**/*.{js,mjs,cjs,ts,jsx,tsx}'], // ✅ Ensure TS files are included
    -    languageOptions: {
    -      globals: {
    -        ...globals.browser,
    -        process: 'readonly',
    -        ...globals.jest
    -      },
    -      parser: tseslint.parser,
    -      parserOptions: {
    -        project: './tsconfig.json', // ✅ Ensure this file exists
    -        tsconfigRootDir: process.cwd() // ✅ Use process.cwd() instead of import.meta.dirname
    -      }
    -    },
    -    plugins: {
    -      '@typescript-eslint': tseslint.plugin,
    -      jest: pluginJest
    -    },
    -    rules: {
    -      ...tseslint.configs.recommended.rules, // ✅ TypeScript ESLint rules
    -      ...pluginJs.configs.recommended.rules, // ✅ ESLint recommended rules
    -
    -      // ✅ Jest-specific rules
    -      'jest/no-disabled-tests': 'warn',
    -      'jest/no-focused-tests': 'error',
    -      'jest/no-identical-title': 'error',
    -      'jest/prefer-to-have-length': 'warn',
    -      'jest/valid-expect': 'error'
    -    }
    -  }
    -]
    diff --git a/packages/sdk/package.json b/packages/sdk/package.json
    index e0ca0e0a6..d6a402b9d 100644
    --- a/packages/sdk/package.json
    +++ b/packages/sdk/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/sdk",
    -  "version": "2.1.9",
    +  "version": "2.2.0",
       "type": "module",
       "description": "BSV Blockchain Software Development Kit",
       "main": "dist/cjs/mod.js",
    @@ -232,8 +232,8 @@
         "test": "npm run build && jest",
         "test:watch": "npm run build && jest --watch",
         "test:coverage": "npm run build && jest --coverage --watchman=false",
    -    "lint:ci": "ts-standard src/**/*.ts",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint:ci": "oxlint src",
    +    "lint": "oxlint src",
         "build": "npm run build:ts && npm run build:umd",
         "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
         "build:umd": "rspack --config rspack.config.js",
    @@ -262,28 +262,18 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/sdk#readme",
       "devDependencies": {
    -    "@eslint/js": "^10.0.1",
         "@jest/globals": "^30.4.1",
    -    "@rspack/cli": "^2.0.8",
    -    "@rspack/core": "^2.0.8",
    +    "@rspack/cli": "^2.1.5",
    +    "@rspack/core": "^2.1.5",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    -    "eslint": "^10.5.0",
    -    "globals": "^17.6.0",
    +    "@types/node": "^26.1.1",
         "jest": "^30.4.2",
         "jest-environment-jsdom": "^30.4.1",
    -    "ts-jest": "^29.4.11",
    +    "ts-jest": "^29.4.12",
         "ts-loader": "^9.6.2",
    -    "ts-standard": "^12.0.2",
         "ts2md": "^0.2.8",
         "tsconfig-to-dual-package": "^1.2.0",
         "typescript": "^6.0.3",
    -    "typescript-eslint": "^8.61.0"
    -  },
    -  "ts-standard": {
    -    "project": "tsconfig.eslint.json",
    -    "ignore": [
    -      "dist"
    -    ]
    +    "oxlint": "^1.75.0"
       }
     }
    diff --git a/packages/sdk/src/auth/utils/createNonce.ts b/packages/sdk/src/auth/utils/createNonce.ts
    index 1f4c94501..0696816e5 100644
    --- a/packages/sdk/src/auth/utils/createNonce.ts
    +++ b/packages/sdk/src/auth/utils/createNonce.ts
    @@ -8,7 +8,12 @@ import * as Utils from '../../primitives/utils.js'
     import Random from '../../primitives/Random.js'
     
     /**
    - * Creates a nonce derived from a wallet
    + * Creates a wallet-authenticated challenge token.
    + *
    + * Despite the historical name, this value has no expiry and is not single-use
    + * by itself. Do not use it as a standalone login or replay-prevention token.
    + * Authentication flows must bind the challenge to a signature and track
    + * freshness, as BRC-103 `Peer` does.
      * @param wallet
      * @param counterparty - The counterparty to the nonce creation. Defaults to 'self'.
      * @returns A random nonce derived with a wallet
    diff --git a/packages/sdk/src/auth/utils/verifyNonce.ts b/packages/sdk/src/auth/utils/verifyNonce.ts
    index a4835fc24..431ef1cea 100644
    --- a/packages/sdk/src/auth/utils/verifyNonce.ts
    +++ b/packages/sdk/src/auth/utils/verifyNonce.ts
    @@ -2,7 +2,11 @@ import * as Utils from '../../primitives/utils.js'
     import { WalletInterface, WalletCounterparty, Base64String, OriginatorDomainNameStringUnder250Bytes } from '../../wallet/Wallet.interfaces.js'
     
     /**
    - * Verifies a nonce derived from a wallet
    + * Verifies that a challenge token was derived from the wallet.
    + *
    + * A successful result does not establish freshness, expiry, single use, or
    + * asymmetric proof of key ownership. Use the complete BRC-103 handshake or a
    + * signed, expiring payload for authentication.
      * @param nonce - A nonce to verify as a base64 string.
      * @param wallet
      * @param counterparty - The counterparty to the nonce creation. Defaults to 'self'.
    diff --git a/packages/sdk/src/overlay-tools/SHIPBroadcaster.ts b/packages/sdk/src/overlay-tools/SHIPBroadcaster.ts
    index 49ebd905c..c943d85de 100644
    --- a/packages/sdk/src/overlay-tools/SHIPBroadcaster.ts
    +++ b/packages/sdk/src/overlay-tools/SHIPBroadcaster.ts
    @@ -101,7 +101,9 @@ export class HTTPSOverlayBroadcastFacilitator implements OverlayBroadcastFacilit
         }
         const headers = {
           'Content-Type': 'application/octet-stream',
    -      'X-Topics': JSON.stringify(taggedBEEF.topics)
    +      // OpenAPI "simple" array encoding is comma-separated. Overlay Express
    +      // accepts this canonical form and the legacy JSON array during rollout.
    +      'X-Topics': taggedBEEF.topics.join(',')
         }
         let body
         if (Array.isArray(taggedBEEF.offChainValues)) {
    @@ -114,7 +116,7 @@ export class HTTPSOverlayBroadcastFacilitator implements OverlayBroadcastFacilit
         } else {
           body = new Uint8Array(taggedBEEF.beef)
         }
    -    const response = await fetch(`${url}/submit`, {
    +    const response = await this.httpClient(`${url}/submit`, {
           method: 'POST',
           headers,
           body
    diff --git a/packages/sdk/src/overlay-tools/__tests/SHIPBroadcaster.test.ts b/packages/sdk/src/overlay-tools/__tests/SHIPBroadcaster.test.ts
    index 74e68d602..b07aba0f5 100644
    --- a/packages/sdk/src/overlay-tools/__tests/SHIPBroadcaster.test.ts
    +++ b/packages/sdk/src/overlay-tools/__tests/SHIPBroadcaster.test.ts
    @@ -1,4 +1,4 @@
    -import SHIPCast from '../../overlay-tools/SHIPBroadcaster'
    +import SHIPCast, { HTTPSOverlayBroadcastFacilitator } from '../../overlay-tools/SHIPBroadcaster'
     import LookupResolver from '../../overlay-tools/LookupResolver'
     import { PrivateKey } from '../../primitives/index'
     import { Transaction } from '../../transaction/index'
    @@ -26,6 +26,31 @@ describe('SHIPCast', () => {
         consoleErrorSpy.mockRestore()
       })
     
    +  it('uses the configured HTTP client and canonical comma-separated X-Topics header', async () => {
    +    const httpClient = jest.fn().mockResolvedValue({
    +      ok: true,
    +      json: async () => ({ tm_foo: { outputsToAdmit: [], coinsToRetain: [] } })
    +    })
    +    const facilitator = new HTTPSOverlayBroadcastFacilitator(httpClient as unknown as typeof fetch)
    +
    +    await facilitator.send('https://overlay.example', {
    +      beef: [1, 2, 3],
    +      topics: ['tm_foo', 'tm_bar']
    +    })
    +
    +    expect(httpClient).toHaveBeenCalledWith(
    +      'https://overlay.example/submit',
    +      expect.objectContaining({
    +        method: 'POST',
    +        headers: {
    +          'Content-Type': 'application/octet-stream',
    +          'X-Topics': 'tm_foo,tm_bar'
    +        },
    +        body: new Uint8Array([1, 2, 3])
    +      })
    +    )
    +  })
    +
       it('Handles constructor errors', () => {
         expect(() => new SHIPCast([])).toThrow(
           new Error('At least one topic is required for broadcast.')
    diff --git a/packages/sdk/src/script/templates/PushDrop.ts b/packages/sdk/src/script/templates/PushDrop.ts
    index 05e8d9519..7f71eb0d8 100644
    --- a/packages/sdk/src/script/templates/PushDrop.ts
    +++ b/packages/sdk/src/script/templates/PushDrop.ts
    @@ -95,7 +95,7 @@ export default class PushDrop implements ScriptTemplate {
           let chunk: number[] = script.chunks[i].data ?? []
     
           if (chunk.length === 0) {
    -        if (script.chunks[i].op >= 80 && script.chunks[i].op <= 95) {
    +        if (script.chunks[i].op >= 80 && script.chunks[i].op <= 96) {
               chunk = [script.chunks[i].op - 80]
             } else if (script.chunks[i].op === 0) {
               chunk = [0]
    diff --git a/packages/sdk/src/script/templates/__tests/PushDrop.test.ts b/packages/sdk/src/script/templates/__tests/PushDrop.test.ts
    index 7bce23f9b..68704f5c1 100644
    --- a/packages/sdk/src/script/templates/__tests/PushDrop.test.ts
    +++ b/packages/sdk/src/script/templates/__tests/PushDrop.test.ts
    @@ -235,6 +235,18 @@ describe('PushDrop', () => {
       })
     
       describe('decode', () => {
    +    it('round-trips OP_16 fields without silently dropping their value', async () => {
    +      const fields = [[16], [15]]
    +      const lockingScript = await pushDrop.lock(
    +        fields,
    +        [2, 'pushdrop decode regression'],
    +        '1',
    +        'self'
    +      )
    +
    +      expect(PushDrop.decode(lockingScript).fields).toEqual(fields)
    +    })
    +
         it('decodes the locking script correctly', async () => {
           const fields = [
             Utils.toArray('hello world', 'utf8'),
    diff --git a/packages/sdk/src/transaction/Transaction.ts b/packages/sdk/src/transaction/Transaction.ts
    index 87edf990d..4375f2bd7 100644
    --- a/packages/sdk/src/transaction/Transaction.ts
    +++ b/packages/sdk/src/transaction/Transaction.ts
    @@ -742,8 +742,9 @@ export default class Transaction {
     
       /**
        * Signs a transaction, hydrating all its unlocking scripts based on the provided script templates where they are available.
    +   * @param options - Signing behavior. Set `skipExistingSignatures` to preserve inputs that already have an unlocking script.
        */
    -  async sign (): Promise {
    +  async sign (options: { skipExistingSignatures?: boolean } = {}): Promise {
         this.invalidateSerializationCaches()
         for (const out of this.outputs) {
           if (out.satoshis === undefined) {
    @@ -765,6 +766,9 @@ export default class Transaction {
         try {
           unlockingScripts = await Promise.all(
             this.inputs.map(async (x, i): Promise => {
    +          if (options.skipExistingSignatures === true && this.inputs[i].unlockingScript != null) {
    +            return this.inputs[i].unlockingScript
    +          }
               if (typeof this.inputs[i].unlockingScriptTemplate === 'object') {
                 return await this.inputs[i]?.unlockingScriptTemplate?.sign(this, i)
               } else {
    diff --git a/packages/sdk/src/transaction/__tests/Transaction.additional.test.ts b/packages/sdk/src/transaction/__tests/Transaction.additional.test.ts
    index c1ba75af8..11041a34b 100644
    --- a/packages/sdk/src/transaction/__tests/Transaction.additional.test.ts
    +++ b/packages/sdk/src/transaction/__tests/Transaction.additional.test.ts
    @@ -146,6 +146,30 @@ describe('Transaction – additional coverage', () => {
       })
     
       describe('sign', () => {
    +    it('preserves existing unlocking scripts when requested', async () => {
    +      const existingScript = UnlockingScript.fromHex('51')
    +      const sign = jest.fn(async () => UnlockingScript.fromHex('52'))
    +      const tx = new Transaction(
    +        1,
    +        [{
    +          sourceTXID: '00'.repeat(32),
    +          sourceOutputIndex: 0,
    +          unlockingScript: existingScript,
    +          unlockingScriptTemplate: {
    +            sign,
    +            estimateLength: async () => 1
    +          }
    +        }],
    +        [{ lockingScript: new LockingScript(), satoshis: 0 }],
    +        0
    +      )
    +
    +      await tx.sign({ skipExistingSignatures: true })
    +
    +      expect(sign).not.toHaveBeenCalled()
    +      expect(tx.inputs[0].unlockingScript).toBe(existingScript)
    +    })
    +
         it('throws when an output has undefined satoshis and change is not set', async () => {
           const tx = new Transaction(
             1,
    diff --git a/packages/sdk/src/wallet/ProtoWallet.ts b/packages/sdk/src/wallet/ProtoWallet.ts
    index efd507c18..64993fb02 100644
    --- a/packages/sdk/src/wallet/ProtoWallet.ts
    +++ b/packages/sdk/src/wallet/ProtoWallet.ts
    @@ -154,7 +154,7 @@ export class ProtoWallet {
         const linkageProofBin = [
           ...linkageProof.R.encode(true),
           ...linkageProof.SPrime.encode(true),
    -      ...linkageProof.z.toArray()
    +      ...linkageProof.z.toArray('be', 32)
         ] as number[]
         const revelationTime = new Date().toISOString()
         const { ciphertext: encryptedLinkage } = await this.encrypt({
    diff --git a/packages/sdk/src/wallet/__tests/ProtoWallet.test.ts b/packages/sdk/src/wallet/__tests/ProtoWallet.test.ts
    index 1ebf9e26b..bbb775694 100644
    --- a/packages/sdk/src/wallet/__tests/ProtoWallet.test.ts
    +++ b/packages/sdk/src/wallet/__tests/ProtoWallet.test.ts
    @@ -1,5 +1,5 @@
     import ProtoWallet from '../../wallet/ProtoWallet'
    -import { Utils, PrivateKey, Hash, Random } from '../../primitives/index'
    +import { Utils, PrivateKey, Hash, Random, BigNumber, Schnorr } from '../../primitives/index'
     import { createNonce, verifyNonce } from '../../auth/utils'
     
     const sampleData = [3, 1, 4, 1, 5, 9]
    @@ -450,6 +450,36 @@ describe('ProtoWallet', () => {
         })
       })
       describe('ProtoWallet Key Linkage Revelation', () => {
    +    it('encodes the Schnorr z scalar as a fixed 32-byte value', async () => {
    +      const proverKey = PrivateKey.fromRandom()
    +      const counterpartyKey = PrivateKey.fromRandom()
    +      const verifierKey = PrivateKey.fromRandom()
    +      const proofPoint = PrivateKey.fromRandom().toPublicKey()
    +      const proofSpy = jest.spyOn(Schnorr.prototype, 'generateProof').mockReturnValue({
    +        R: proofPoint,
    +        SPrime: proofPoint,
    +        z: new BigNumber(1)
    +      })
    +
    +      try {
    +        const revelation = await new ProtoWallet(proverKey).revealCounterpartyKeyLinkage({
    +          counterparty: counterpartyKey.toPublicKey().toString(),
    +          verifier: verifierKey.toPublicKey().toString()
    +        })
    +        const { plaintext: proof } = await new ProtoWallet(verifierKey).decrypt({
    +          ciphertext: revelation.encryptedLinkageProof,
    +          protocolID: [2, 'counterparty linkage revelation'],
    +          keyID: revelation.revelationTime,
    +          counterparty: proverKey.toPublicKey().toString()
    +        })
    +
    +        expect(proof).toHaveLength(98)
    +        expect(proof.slice(-32)).toEqual([...Array(31).fill(0), 1])
    +      } finally {
    +        proofSpy.mockRestore()
    +      }
    +    })
    +
         it('Validates the revealCounterpartyKeyLinkage function', async () => {
           // Initialize keys
           const proverKey = PrivateKey.fromRandom()
    diff --git a/packages/sdk/tsconfig.eslint.json b/packages/sdk/tsconfig.eslint.json
    deleted file mode 100644
    index ca45b1774..000000000
    --- a/packages/sdk/tsconfig.eslint.json
    +++ /dev/null
    @@ -1,19 +0,0 @@
    -{
    -  "extends": "./tsconfig.json",
    -  "compilerOptions": {
    -    "types": [
    -      "@types/node"
    -    ],
    -    "noEmit": true,
    -    "strict": true,
    -    "strictNullChecks": true
    -  },
    -  "include": [
    -    "./src/**/*.{ts,tsx,js,jsx}",   // ✅ Keep this if your TypeScript files are in src/
    -    "./eslint.config.js",  // ✅ Adjusted path to be at root
    -    "./jest.config.js",    // ✅ Adjusted path to be at root
    -    "./**/*.js", 
    -    "./**/*.ts",
    -    "./*.ts"               // ✅ Ensures any root-level TS files are included (optional)
    -  ]
    -}
    \ No newline at end of file
    diff --git a/packages/verifast/package.json b/packages/verifast/package.json
    index be6cb9adb..de4e43caf 100644
    --- a/packages/verifast/package.json
    +++ b/packages/verifast/package.json
    @@ -50,19 +50,18 @@
       },
       "devDependencies": {
         "@bsv/sdk": "workspace:^",
    -    "@jest/globals": "^30.0.0",
    +    "@jest/globals": "^30.4.1",
    +    "@rspack/cli": "^2.1.5",
    +    "@rspack/core": "^2.1.5",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    -    "@rspack/cli": "^2.0.8",
    -    "@rspack/core": "^2.0.8",
    -    "jest": "^30.0.0",
    -    "puppeteer-core": "^24.42.0",
    -    "ts-jest": "^29.2.0",
    -    "ts-standard": "^12.0.2",
    -    "tsx": "^4.22.4",
    +    "@types/node": "^26.1.1",
    +    "jest": "^30.4.2",
    +    "puppeteer-core": "^24.43.1",
    +    "ts-jest": "^29.4.12",
         "ts-loader": "^9.6.2",
    +    "tsx": "^4.23.1",
         "typescript": "^6.0.3",
    -    "vite": "^8.0.16"
    +    "vite": "^8.1.5"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.8"
    diff --git a/packages/wallet/btms-permission-module/package.json b/packages/wallet/btms-permission-module/package.json
    index 0f9d664ca..32ff94310 100644
    --- a/packages/wallet/btms-permission-module/package.json
    +++ b/packages/wallet/btms-permission-module/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/btms-permission-module",
    -  "version": "1.1.0",
    +  "version": "1.1.1",
       "description": "BTMS Permission Module for wallet integration",
       "type": "module",
       "main": "dist/index.js",
    @@ -29,10 +29,10 @@
         "@bsv/wallet-toolbox-client": "^2.3.3"
       },
       "devDependencies": {
    -    "@bsv/btms": "^1.1.0",
    +    "@bsv/btms": "workspace:^",
         "@bsv/sdk": "workspace:^",
    -    "@bsv/wallet-toolbox-client": "^2.3.3",
    -    "@types/node": "^26.0.0",
    +    "@bsv/wallet-toolbox-client": "workspace:^",
    +    "@types/node": "^26.1.1",
         "typescript": "^6.0.3"
       },
       "repository": {
    diff --git a/packages/wallet/btms/AGENTS.md b/packages/wallet/btms/AGENTS.md
    index 03fb35983..a63a87ce2 100644
    --- a/packages/wallet/btms/AGENTS.md
    +++ b/packages/wallet/btms/AGENTS.md
    @@ -178,7 +178,7 @@ if (decoded.valid) {
     - **`jest`** ^30.3.0 — Test framework
     - **`ts-jest`** ^29.4.9 — TypeScript support for Jest
     - **`typescript`** ^5.2.2 — Compiler
    -- **`ts-standard`** ^12.0.2 — Linter
    +- **`oxlint`** ^1.75.0 — Linter
     - **`ts2md`** ^0.2.0 — Documentation generator
     
     ### Other ts-stack packages
    diff --git a/packages/wallet/btms/BASELINE.md b/packages/wallet/btms/BASELINE.md
    index 7cd6d25b9..defa78bf5 100644
    --- a/packages/wallet/btms/BASELINE.md
    +++ b/packages/wallet/btms/BASELINE.md
    @@ -33,8 +33,8 @@
     ## Lint
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard --fix src/**/*.ts` |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
     
     ## Dependencies
     | Type | Count | Packages |
    diff --git a/packages/wallet/btms/package.json b/packages/wallet/btms/package.json
    index f3e37b006..6ac0cfb51 100644
    --- a/packages/wallet/btms/package.json
    +++ b/packages/wallet/btms/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/btms",
    -  "version": "1.1.0",
    +  "version": "1.1.1",
       "type": "module",
       "description": "Basic Token Management System - UTXO-based token management for BSV",
       "module": "dist/esm/src/index.js",
    @@ -21,7 +21,7 @@
         "test": "jest",
         "test:watch": "jest --watch",
         "test:coverage": "jest --coverage",
    -    "lint": "ts-standard --fix src/**/*.ts",
    +    "lint": "oxlint src",
         "build": "tsc -b",
         "prepublishOnly": "npm run build",
         "doc": "ts2md --inputFilename=src/index.ts --outputFilename=API.md --filenameSubstring=API --firstHeadingLevel=1"
    @@ -42,13 +42,13 @@
         "directory": "packages/wallet/btms"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@types/jest": "^30.0.0",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-standard": "^12.0.2",
    -    "ts2md": "^0.2.0",
    +    "ts-jest": "^29.4.12",
    +    "ts2md": "^0.2.8",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.6"
    diff --git a/packages/wallet/ts-wallet-relay/package.json b/packages/wallet/ts-wallet-relay/package.json
    index 2c8357ee1..bfd22c9a3 100644
    --- a/packages/wallet/ts-wallet-relay/package.json
    +++ b/packages/wallet/ts-wallet-relay/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/wallet-relay",
    -  "version": "0.2.1",
    +  "version": "0.2.2",
       "description": "BSV mobile wallet relay — relay server and pairing client",
       "type": "module",
       "exports": {
    @@ -65,22 +65,22 @@
         "@bsv/sdk": "workspace:^",
         "@testing-library/jest-dom": "^6.9.1",
         "@testing-library/react": "^16.3.2",
    -    "@types/express": "^5.0.0",
    +    "@types/express": "^5.0.6",
         "@types/jest": "^30.0.0",
    -    "@types/node": "^26.0.0",
    -    "@types/qrcode": "^1.5.0",
    +    "@types/node": "^26.1.1",
    +    "@types/qrcode": "^1.5.6",
         "@types/react": "^19.2.17",
    -    "@types/ws": "^8.5.0",
    +    "@types/ws": "^8.18.1",
         "express": "^5.2.1",
         "jest": "^30.4.2",
         "jest-environment-jsdom": "^30.4.1",
    -    "qrcode": "^1.5.0",
    -    "react": "^19.2.7",
    -    "react-dom": "^19.2.7",
    -    "ts-jest": "^29.4.11",
    -    "tsup": "^8.0.0",
    +    "qrcode": "^1.5.4",
    +    "react": "^19.2.8",
    +    "react-dom": "^19.2.8",
    +    "ts-jest": "^29.4.12",
    +    "tsup": "^8.5.1",
         "typescript": "^6.0.3",
    -    "ws": "^8.21.0"
    +    "ws": "^8.21.1"
       },
       "repository": {
         "type": "git",
    diff --git a/packages/wallet/wallet-toolbox-examples/BASELINE.md b/packages/wallet/wallet-toolbox-examples/BASELINE.md
    index 9339c8a66..76f302c6d 100644
    --- a/packages/wallet/wallet-toolbox-examples/BASELINE.md
    +++ b/packages/wallet/wallet-toolbox-examples/BASELINE.md
    @@ -44,7 +44,7 @@
     ## Known Issues & Incidents
     - Example code only — not intended for production use.
     - No test files despite test/coverage commands being configured.
    -- Uses prettier rather than ts-standard (org standard).
    +- Uses prettier rather than Oxlint (org standard).
     
     ## Migration Gate Checklist (MBGA §13.3)
     - [x] BASELINE.md captured
    diff --git a/packages/wallet/wallet-toolbox-examples/package.json b/packages/wallet/wallet-toolbox-examples/package.json
    index 9ffeef889..a0f81f47a 100644
    --- a/packages/wallet/wallet-toolbox-examples/package.json
    +++ b/packages/wallet/wallet-toolbox-examples/package.json
    @@ -32,29 +32,25 @@
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox-examples#readme",
       "devDependencies": {
    -    "@types/diff": "^8.0.0",
         "@types/fs-extra": "^11.0.4",
         "@types/jest": "^30.0.0",
    -    "@types/jest-diff": "^24.3.0",
    -    "@types/node": "^26.0.0",
    -    "@types/node-fetch": "^2.6.2",
    +    "@types/node": "^26.1.1",
    +    "@types/node-fetch": "^2.6.13",
         "chalk": "^5.6.2",
         "dotenv": "^17.4.2",
    -    "fake-indexeddb": "^6.0.0",
    -    "fs-extra": "^11.3.5",
    +    "fake-indexeddb": "^6.2.5",
    +    "fs-extra": "^11.4.0",
         "jest": "^30.4.2",
         "jest-diff": "^30.4.1",
    -    "jest-simple-summary": "^1.0.2",
    -    "prettier": "^3.8.4",
    +    "prettier": "^3.9.6",
         "sqlite3": "^6.0.1",
    -    "standard": "^17.1.0",
    -    "ts-jest": "^29.4.11",
    -    "ts-node": "^10.9.1",
    +    "ts-jest": "^29.4.12",
    +    "ts-node": "^10.9.2",
         "ts2md": "^0.2.8",
         "typescript": "^6.0.3"
       },
       "dependencies": {
    -    "@bsv/sdk": "^2.1.6",
    -    "@bsv/wallet-toolbox": "^2.3.3"
    +    "@bsv/sdk": "workspace:^",
    +    "@bsv/wallet-toolbox": "workspace:^"
       }
     }
    diff --git a/packages/wallet/wallet-toolbox/BASELINE.md b/packages/wallet/wallet-toolbox/BASELINE.md
    index 8ba70fcf1..97c188e39 100644
    --- a/packages/wallet/wallet-toolbox/BASELINE.md
    +++ b/packages/wallet/wallet-toolbox/BASELINE.md
    @@ -38,10 +38,10 @@
     
     | Field | Value |
     |-------|-------|
    -| Linter | ts-standard |
    -| Lint command | `ts-standard src/**/*.ts` |
    -| Fix command | `ts-standard --fix src/**/*.ts` |
    -| Status | Migrated from prettier. 3472 errors remain (see Known Issues). |
    +| Linter | Oxlint |
    +| Lint command | `oxlint src` |
    +| Fix command | `oxlint --fix src` |
    +| Status | Oxlint errors block; inherited warnings remain visible for progressive cleanup. |
     
     ## Dependencies
     
    @@ -53,18 +53,8 @@
     ## Known Issues & Incidents
     
     - `man.test.ts` tests require external services — not run in CI.
    -- ts-standard lint: 3472 errors remain after migration from prettier. Breakdown by rule:
    -  - `@typescript-eslint/strict-boolean-expressions`: 1232 — requires explicit boolean checks throughout
    -  - `@typescript-eslint/no-non-null-assertion`: 537 — `!` non-null assertions are pervasive
    -  - `@typescript-eslint/explicit-function-return-type`: 320 — missing return type annotations
    -  - `@typescript-eslint/prefer-nullish-coalescing`: 239 — `||` should be `??` in many places
    -  - `@typescript-eslint/no-unused-vars`: 224 — unused variables and parameters
    -  - `@typescript-eslint/promise-function-async`: 180 — functions returning Promise must be async
    -  - `@typescript-eslint/method-signature-style`: 146 — interface method style vs property style
    -  - `@typescript-eslint/restrict-template-expressions`: 134 — template literal type restrictions
    -  - `@typescript-eslint/no-floating-promises`: 94 — unhandled promises
    -  - Other rules: ~362 errors across eqeqeq, dot-notation, brace-style, prefer-optional-chain, etc.
    -  These require semantic/logic-level changes and are deferred to a future cleanup pass.
    +- Oxlint warnings are a tracked cleanup backlog. New lint errors block CI; warning
    +  reductions should be made in focused, reviewable changes.
     
     ## Conformance Vectors
     
    diff --git a/packages/wallet/wallet-toolbox/CONTRIBUTING.md b/packages/wallet/wallet-toolbox/CONTRIBUTING.md
    index a81a9be58..4d37ce0b4 100644
    --- a/packages/wallet/wallet-toolbox/CONTRIBUTING.md
    +++ b/packages/wallet/wallet-toolbox/CONTRIBUTING.md
    @@ -68,7 +68,7 @@ Thank you for considering contributing to the BSV Blockchain Libraries Project!
     
     ## Coding Conventions
     
    -- **Code Style**: We use `ts-standard` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
    +- **Code Style**: We use `Oxlint` for our TypeScript coding style. Run `npm run lint` to ensure your code adheres to this style.
       
     - **No Runtime Dependencies**: All code should be maintained within this library. Do not introduce external dependencies.
       
    diff --git a/packages/wallet/wallet-toolbox/client/package.json b/packages/wallet/wallet-toolbox/client/package.json
    index 8ff4cc3d9..1b8a4388e 100644
    --- a/packages/wallet/wallet-toolbox/client/package.json
    +++ b/packages/wallet/wallet-toolbox/client/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/wallet-toolbox-client",
    -  "version": "2.4.3",
    +  "version": "2.4.4",
       "description": "Client only Wallet Storage",
       "main": "./out/src/index.client.js",
       "types": "./out/src/index.client.d.ts",
    @@ -16,13 +16,16 @@
         "wallet",
         "BRC100"
       ],
    +  "scripts": {
    +    "build": "tsc --build ../tsconfig.client.json"
    +  },
       "bugs": {
         "url": "https://github.com/bsv-blockchain/ts-stack/issues"
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/client#readme",
       "dependencies": {
         "hash-wasm": "^4.12.0",
    -    "idb": "^8.0.2"
    +    "idb": "^8.0.3"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.8"
    @@ -33,6 +36,8 @@
         }
       },
       "devDependencies": {
    -    "@bsv/sdk": "workspace:^"
    +    "@bsv/sdk": "workspace:^",
    +    "@types/node": "^26.1.1",
    +    "typescript": "^6.0.3"
       }
     }
    diff --git a/packages/wallet/wallet-toolbox/mobile/package.json b/packages/wallet/wallet-toolbox/mobile/package.json
    index e8e14ec87..31656bfad 100644
    --- a/packages/wallet/wallet-toolbox/mobile/package.json
    +++ b/packages/wallet/wallet-toolbox/mobile/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/wallet-toolbox-mobile",
    -  "version": "2.4.3",
    +  "version": "2.4.4",
       "description": "Client only Wallet Storage",
       "main": "./out/src/index.mobile.js",
       "types": "./out/src/index.mobile.d.ts",
    @@ -16,13 +16,16 @@
         "wallet",
         "BRC100"
       ],
    +  "scripts": {
    +    "build": "tsc --build ../tsconfig.mobile.json"
    +  },
       "bugs": {
         "url": "https://github.com/bsv-blockchain/ts-stack/issues"
       },
       "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/mobile#readme",
       "dependencies": {
         "hash-wasm": "^4.12.0",
    -    "idb": "^8.0.2"
    +    "idb": "^8.0.3"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.8"
    @@ -33,6 +36,8 @@
         }
       },
       "devDependencies": {
    -    "@bsv/sdk": "workspace:^"
    +    "@bsv/sdk": "workspace:^",
    +    "@types/node": "^26.1.1",
    +    "typescript": "^6.0.3"
       }
     }
    diff --git a/packages/wallet/wallet-toolbox/package.json b/packages/wallet/wallet-toolbox/package.json
    index 6aef3161e..ccc124dc1 100644
    --- a/packages/wallet/wallet-toolbox/package.json
    +++ b/packages/wallet/wallet-toolbox/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@bsv/wallet-toolbox",
    -  "version": "2.4.3",
    +  "version": "2.4.4",
       "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
       "main": "./out/src/index.js",
       "types": "./out/src/index.d.ts",
    @@ -29,8 +29,8 @@
         "test:watch": "npm run build && jest --testPathIgnorePatterns=man.test.ts --watch",
         "test:coverage": "npm run build && jest --testPathIgnorePatterns='man.test.ts|bench.test.ts' --coverage",
         "bench:action-batch": "npm run build && jest --runInBand --runTestsByPath benchmarks/action-batch.bench.test.ts --testPathIgnorePatterns=man.test.ts",
    -    "lint": "ts-standard --fix src/**/*.ts benchmarks/**/*.ts",
    -    "lint:ci": "ts-standard src/**/*.ts benchmarks/**/*.ts",
    +    "lint": "oxlint src benchmarks",
    +    "lint:ci": "oxlint src benchmarks",
         "build": "tsc --build",
         "prepublish": "npm run build && npm run doc && npm run sync-versions",
         "doc": "ts2md",
    @@ -49,31 +49,29 @@
         "express": "^5.2.1",
         "express-rate-limit": "^8.6.0",
         "hash-wasm": "^4.12.0",
    -    "idb": "^8.0.2",
    -    "knex": "^3.2.10",
    -    "mysql2": "^3.22.5",
    -    "ws": "^8.21.0"
    +    "idb": "^8.0.3",
    +    "knex": "^3.3.0",
    +    "mysql2": "^3.23.1",
    +    "ws": "^8.21.1"
       },
       "devDependencies": {
    +    "@bsv/sdk": "workspace:^",
         "@jest/globals": "^30.4.1",
    -    "@types/body-parser": "^1.19.5",
    -    "@types/cors": "^2.8.13",
    -    "@types/diff": "^8.0.0",
    +    "@types/body-parser": "^1.19.6",
    +    "@types/cors": "^2.8.19",
         "@types/fs-extra": "^11.0.4",
         "@types/jest": "^30.0.0",
    -    "@types/jest-diff": "^24.3.0",
    -    "@types/node": "^26.0.0",
    +    "@types/node": "^26.1.1",
         "chalk": "^4.1.2",
    -    "cors": "^2.8.5",
    -    "fake-indexeddb": "^6.0.0",
    -    "fs-extra": "^11.3.5",
    +    "cors": "^2.8.6",
    +    "fake-indexeddb": "^6.2.5",
    +    "fs-extra": "^11.4.0",
         "jest": "^30.4.2",
    -    "ts-jest": "^29.4.11",
    -    "ts-node": "^10.9.1",
    -    "ts-standard": "^12.0.0",
    +    "ts-jest": "^29.4.12",
    +    "ts-node": "^10.9.2",
         "ts2md": "^0.2.8",
         "typescript": "^6.0.3",
    -    "@bsv/sdk": "workspace:^"
    +    "oxlint": "^1.75.0"
       },
       "peerDependencies": {
         "@bsv/sdk": "^2.1.8"
    diff --git a/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.denialcode.test.ts b/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.denialcode.test.ts
    index bfae6216e..dcf156a92 100644
    --- a/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.denialcode.test.ts
    +++ b/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.denialcode.test.ts
    @@ -27,8 +27,8 @@ describe('denial error codes', () => {
         })
       })
     
    -  const ensure = () =>
    -    manager.ensureProtocolPermission({
    +  const ensure = async (): Promise =>
    +    await manager.ensureProtocolPermission({
           originator: 'app.example.com',
           privileged: false,
           protocolID: [1, 'denial test'],
    @@ -40,7 +40,7 @@ describe('denial error codes', () => {
     
       it('individual denyPermission rejects with ERR_PERMISSION_DENIED', async () => {
         const call = ensure()
    -    await new Promise(r => setTimeout(r, 20))
    +    await new Promise(resolve => setTimeout(resolve, 20))
         expect(requestIDs).toHaveLength(1)
     
         await manager.denyPermission(requestIDs[0])
    @@ -55,7 +55,7 @@ describe('denial error codes', () => {
         // Seed a grouped active request directly; the grouped prompt flow itself
         // is covered elsewhere — this pins the rejection shape.
         let rejection: unknown
    -    const pending = new Promise((_, reject) => {
    +    const pending = new Promise((_resolve, reject) => {
           ;(manager as any).activeRequests.set('group-1', {
             request: { type: 'protocol', originator: 'app.example.com' },
             pending: [{ resolve: () => {}, reject }]
    @@ -64,7 +64,7 @@ describe('denial error codes', () => {
         pending.catch(e => { rejection = e })
     
         await (manager as any).denyGroupedPermission('group-1')
    -    await new Promise(r => setTimeout(r, 10))
    +    await new Promise(resolve => setTimeout(resolve, 10))
     
         expect((rejection as any)?.code).toBe('ERR_PERMISSION_DENIED')
       })
    diff --git a/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.mintdedup.test.ts b/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.mintdedup.test.ts
    index 33d4ba181..d041e3c8e 100644
    --- a/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.mintdedup.test.ts
    +++ b/packages/wallet/wallet-toolbox/src/__tests/WalletPermissionsManager.mintdedup.test.ts
    @@ -43,7 +43,7 @@ describe('WalletPermissionsManager duplicate mint prevention', () => {
       let promptCount: number
       let requestIDs: string[]
     
    -  const ensureProto = async (usageType: any) =>
    +  const ensureProto = async (usageType: any): Promise =>
         await manager.ensureProtocolPermission({ ...PROTO, reason: 't', seekPermission: true, usageType })
     
       const mints = (): number => underlying.createAction.mock.calls.length
    @@ -75,16 +75,17 @@ describe('WalletPermissionsManager duplicate mint prevention', () => {
       })
     
       it('an ensure arriving during an in-flight mint waits instead of re-prompting', async () => {
    -    let releaseMint!: () => void
    -    const gate = new Promise(r => { releaseMint = r })
    +    let releaseMint: () => void = () => { throw new Error('mint gate was not initialized') }
    +    const gate = new Promise(resolve => { releaseMint = resolve })
         const originalCreateAction = underlying.createAction.getMockImplementation()
    +    if (originalCreateAction === undefined) throw new Error('createAction mock implementation is required')
         underlying.createAction.mockImplementation(async (args: any) => {
           await gate
    -      return originalCreateAction!(args)
    +      return originalCreateAction(args)
         })
     
         const ensure1 = ensureProto('generic')
    -    await new Promise(r => setTimeout(r, 20))
    +    await new Promise(resolve => setTimeout(resolve, 20))
         expect(promptCount).toBe(1)
     
         // User clicks Grant; mint is now in flight (gated).
    @@ -95,7 +96,7 @@ describe('WalletPermissionsManager duplicate mint prevention', () => {
     
         // A follow-up identical request arrives during the mint window.
         const ensure2 = ensureProto('generic')
    -    await new Promise(r => setTimeout(r, 50))
    +    await new Promise(resolve => setTimeout(resolve, 50))
         expect(promptCount).toBe(1) // no re-prompt
     
         releaseMint()
    @@ -108,7 +109,7 @@ describe('WalletPermissionsManager duplicate mint prevention', () => {
       it('stacked first-contact grants for one permission mint exactly one token', async () => {
         // Four concurrent usage types, no token yet: four prompts by design…
         const ensures = ['generic', 'signing', 'encrypting', 'hmac'].map(ensureProto)
    -    await new Promise(r => setTimeout(r, 30))
    +    await new Promise(resolve => setTimeout(resolve, 30))
         expect(promptCount).toBe(4)
     
         // …but granting them all mints ONE token, not four.
    @@ -121,14 +122,14 @@ describe('WalletPermissionsManager duplicate mint prevention', () => {
         underlying.createAction.mockRejectedValueOnce(new Error('mint failed'))
     
         const ensure1 = ensureProto('generic')
    -    await new Promise(r => setTimeout(r, 20))
    +    await new Promise(resolve => setTimeout(resolve, 20))
         await expect(manager.grantPermission({ requestID: requestIDs[0] })).rejects.toThrow('mint failed')
         await expect(ensure1).resolves.toBe(true) // waiter was already resolved by grant
     
         // The failed mint must not have cached the permission: a new request
         // prompts again (and this time mints successfully).
         const ensure2 = ensureProto('generic')
    -    await new Promise(r => setTimeout(r, 20))
    +    await new Promise(resolve => setTimeout(resolve, 20))
         expect(promptCount).toBe(2)
         await manager.grantPermission({ requestID: requestIDs[1] })
         await expect(ensure2).resolves.toBe(true)
    @@ -136,24 +137,25 @@ describe('WalletPermissionsManager duplicate mint prevention', () => {
       })
     
       it('a grant deduped against a mint that then FAILS falls through and mints its own token', async () => {
    -    let rejectMint!: (e: Error) => void
    -    const gate = new Promise((_, reject) => { rejectMint = reject })
    +    let rejectMint: (e: Error) => void = () => { throw new Error('mint rejection gate was not initialized') }
    +    const gate = new Promise((_resolve, reject) => { rejectMint = reject })
         const originalCreateAction = underlying.createAction.getMockImplementation()
    +    if (originalCreateAction === undefined) throw new Error('createAction mock implementation is required')
         underlying.createAction
           .mockImplementationOnce(async () => await gate) // mint 1: will fail
    -      .mockImplementation(originalCreateAction!) // subsequent mints succeed
    +      .mockImplementation(originalCreateAction) // subsequent mints succeed
     
         // Two stacked prompts for the same permission.
         const ensure1 = ensureProto('generic')
         const ensure2 = ensureProto('signing')
    -    await new Promise(r => setTimeout(r, 20))
    +    await new Promise(resolve => setTimeout(resolve, 20))
         expect(promptCount).toBe(2)
     
         // Grant #1 starts a mint that will fail; grant #2 dedups against it.
         const grant1 = manager.grantPermission({ requestID: requestIDs[0] })
    -    await new Promise(r => setTimeout(r, 10))
    +    await new Promise(resolve => setTimeout(resolve, 10))
         const grant2 = manager.grantPermission({ requestID: requestIDs[1] })
    -    await new Promise(r => setTimeout(r, 10))
    +    await new Promise(resolve => setTimeout(resolve, 10))
     
         rejectMint(new Error('mint 1 failed'))
         await expect(grant1).rejects.toThrow('mint 1 failed')
    diff --git a/packages/wallet/wallet-toolbox/src/index.client.ts b/packages/wallet/wallet-toolbox/src/index.client.ts
    index 6b8046156..6ac43305a 100644
    --- a/packages/wallet/wallet-toolbox/src/index.client.ts
    +++ b/packages/wallet/wallet-toolbox/src/index.client.ts
    @@ -24,3 +24,4 @@ export * from './Wallet'
     export * from './WalletLogger'
     export * from './WalletAuthenticationManager'
     export * from './WalletPermissionsManager'
    +export * from './WalletSettingsManager'
    diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClient.test.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClient.test.ts
    index 672f123cc..dcd43c811 100644
    --- a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClient.test.ts
    +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClient.test.ts
    @@ -62,6 +62,31 @@ describe('StorageClient tests', () => {
         expect(capturedLogs.some(line => line.includes('StorageServer POST handler'))).toBe(false)
       })
     
    +  test('0a basket reads are scoped to the authenticated remote user', async () => {
    +    const attackerStorage = attacker.storage.getActive() as StorageClient
    +    const attackerUser = await server.setup.activeStorage.findUserByIdentityKey(attacker.identityKey)
    +    expect(attackerUser).toBeDefined()
    +    expect(attackerUser!.userId).not.toBe(server.setup.userId)
    +
    +    const baskets = await attacker.storage.findOutputBaskets({ partial: { name: 'default' } })
    +    expect(baskets.length).toBeGreaterThan(0)
    +    expect(baskets.every(basket => basket.userId === attackerUser!.userId)).toBe(true)
    +    expect(baskets.some(basket => basket.userId === server.setup.userId)).toBe(false)
    +
    +    // Preserve old clients that used the unscoped RPC method name, but bind
    +    // their claimed auth object to the authenticated identity on the server.
    +    const legacyBaskets = await Reflect.get(attackerStorage, 'rpcCall').call(
    +      attackerStorage,
    +      'findOutputBaskets',
    +      [
    +        { identityKey: attacker.identityKey, userId: server.setup.userId },
    +        { partial: { name: 'default' } }
    +      ]
    +    )
    +    expect(legacyBaskets.every((basket: any) => basket.userId === attackerUser!.userId)).toBe(true)
    +    expect(legacyBaskets.some((basket: any) => basket.userId === server.setup.userId)).toBe(false)
    +  })
    +
       test('1 repeatable createAction', async () => {
         const wallet = client.wallet
         // wallet.makeLogger = () => console
    diff --git a/packages/wallet/wallet-toolbox/src/wab-client/WABTransport.ts b/packages/wallet/wallet-toolbox/src/wab-client/WABTransport.ts
    index 2c1e86dd7..3be1ab82b 100644
    --- a/packages/wallet/wallet-toolbox/src/wab-client/WABTransport.ts
    +++ b/packages/wallet/wallet-toolbox/src/wab-client/WABTransport.ts
    @@ -176,7 +176,7 @@ export class WABTransport {
       }
     
       createCorrelationId (): string | undefined {
    -    return this.telemetry.enabled === true ? this.telemetry.createCorrelationId() : undefined
    +    return this.telemetry.enabled ? this.telemetry.createCorrelationId() : undefined
       }
     
       async request(path: string, options: WABRequestOptions): Promise {
    diff --git a/packages/wallet/wallet-toolbox/tsconfig.all.json b/packages/wallet/wallet-toolbox/tsconfig.all.json
    index 97f3abb22..931347980 100644
    --- a/packages/wallet/wallet-toolbox/tsconfig.all.json
    +++ b/packages/wallet/wallet-toolbox/tsconfig.all.json
    @@ -4,6 +4,7 @@
         "outDir": "./out",
         "target": "es2022",
         "lib": ["es2022", "dom"],
    +    "types": ["node"],
         "module": "commonjs",
         "sourceMap": true,
         "allowJs": false,
    diff --git a/packages/wallet/wallet-toolbox/tsconfig.client.json b/packages/wallet/wallet-toolbox/tsconfig.client.json
    index 227332626..b786d2fbe 100644
    --- a/packages/wallet/wallet-toolbox/tsconfig.client.json
    +++ b/packages/wallet/wallet-toolbox/tsconfig.client.json
    @@ -4,6 +4,7 @@
         "outDir": "./client/out",
         "target": "es2022",
         "lib": ["es2022", "dom"],
    +    "types": ["node"],
         "module": "commonjs",
         "sourceMap": true,
         "allowJs": false,
    diff --git a/packages/wallet/wallet-toolbox/tsconfig.json b/packages/wallet/wallet-toolbox/tsconfig.json
    index 8bf01bdda..72eeb82d6 100644
    --- a/packages/wallet/wallet-toolbox/tsconfig.json
    +++ b/packages/wallet/wallet-toolbox/tsconfig.json
    @@ -13,12 +13,6 @@
         "references": [
             {
                 "path": "tsconfig.all.json"
    -        },
    -        {
    -            "path": "tsconfig.client.json"
    -        },
    -        {
    -            "path": "tsconfig.mobile.json"
             }
         ]
    -}
    \ No newline at end of file
    +}
    diff --git a/packages/wallet/wallet-toolbox/tsconfig.mobile.json b/packages/wallet/wallet-toolbox/tsconfig.mobile.json
    index c142ef1a0..a2cd346a5 100644
    --- a/packages/wallet/wallet-toolbox/tsconfig.mobile.json
    +++ b/packages/wallet/wallet-toolbox/tsconfig.mobile.json
    @@ -4,6 +4,7 @@
         "outDir": "./mobile/out",
         "target": "es2022",
         "lib": ["es2022", "dom"],
    +    "types": ["node"],
         "module": "commonjs",
         "sourceMap": true,
         "allowJs": false,
    diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
    index c05625bbc..16b4fa8e2 100644
    --- a/pnpm-lock.yaml
    +++ b/pnpm-lock.yaml
    @@ -5,53 +5,22 @@ settings:
       excludeLinksFromLockfile: false
     
     overrides:
    -  '@babel/plugin-transform-modules-systemjs@<7.29.4': 7.29.4
       brace-expansion@<=5.0.7: 5.0.8
    -  dompurify@<=3.4.11: 3.4.12
    -  engine.io@>=6.0.0 <6.6.7: 6.6.7
    -  fast-uri@>=3.0.0 <=3.1.3: 3.1.4
    -  fast-xml-builder@<=1.1.6: 1.1.7
    -  fast-xml-parser@>=5.9.3 <5.10.1: 5.10.1
    -  form-data@>=4.0.0 <4.0.6: 4.0.6
    -  http-proxy-middleware@>=2.0.0 <2.0.10: 2.0.10
    -  immutable@>=5.0.0-beta.1 <5.1.8: 5.1.9
    -  js-yaml@^3.0.0: 3.15.0
    -  js-yaml@^4.0.0: 4.3.0
    -  jsonpath-plus@<10.3.0: 10.4.0
    -  launch-editor@<=2.14.0: 2.14.1
    -  postcss@<=8.5.17: 8.5.18
    -  protobufjs@>=7.5.0 <=7.6.4: 7.6.5
    -  qs@<6.15.2: 6.15.2
    -  shell-quote@<=1.8.4: 1.9.0
    -  tar@<=7.5.20: 7.5.21
    -  undici@^6.0.0: 6.27.0
    -  undici@^7.0.0: 7.28.0
    -  websocket-driver@<0.7.5: 0.7.5
    -  webpack-dev-server@<=5.2.5: 5.2.6
    -  ws@>=8.0.0 <8.21.0: 8.21.0
    -  ip-address@>=10.0.0 <10.1.1: 10.1.1
    -  xml2js@<0.5.0: 0.5.0
     
     importers:
     
       .:
         devDependencies:
    -      '@asyncapi/generator':
    -        specifier: ^3.3.0
    -        version: 3.3.0(@types/babel__core@7.20.5)(@types/node@26.0.0)(encoding@0.1.13)
    -      '@asyncapi/html-template':
    -        specifier: ^3.5.6
    -        version: 3.5.6(@noble/hashes@2.2.0)(@types/babel__core@7.20.5)(encoding@0.1.13)(typescript@4.9.5)
    +      yaml:
    +        specifier: ^2.9.0
    +        version: 2.9.0
     
       conformance/runner:
         dependencies:
           ajv:
    -        specifier: ^8.17.1
    +        specifier: ^8.20.0
             version: 8.20.0
         devDependencies:
    -      ts-standard:
    -        specifier: ^12.0.0
    -        version: 12.0.2(typescript@6.0.3)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -66,10 +35,10 @@ importers:
             version: 30.4.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -77,24 +46,24 @@ importers:
       docs-site:
         dependencies:
           '@mdx-js/react':
    -        specifier: ^3.1.0
    -        version: 3.1.1(@types/react@19.2.17)(react@19.2.7)
    +        specifier: ^3.1.1
    +        version: 3.1.1(@types/react@19.2.17)(react@19.2.8)
           react:
    -        specifier: ^19.2.7
    -        version: 19.2.7
    +        specifier: ^19.2.8
    +        version: 19.2.8
           react-dom:
    -        specifier: ^19.2.7
    -        version: 19.2.7(react@19.2.7)
    +        specifier: ^19.2.8
    +        version: 19.2.8(react@19.2.8)
           react-router-dom:
    -        specifier: ^6.28.0
    -        version: 6.30.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
    +        specifier: ^6.30.4
    +        version: 6.30.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
         devDependencies:
           '@mdx-js/rollup':
    -        specifier: ^3.1.0
    +        specifier: ^3.1.1
             version: 3.1.1(rollup@4.60.2)
           '@shikijs/rehype':
    -        specifier: ^4.2.0
    -        version: 4.2.0
    +        specifier: ^4.3.1
    +        version: 4.3.1
           '@types/react':
             specifier: ^19.2.17
             version: 19.2.17
    @@ -102,10 +71,10 @@ importers:
             specifier: ^19.2.3
             version: 19.2.3(@types/react@19.2.17)
           '@vitejs/plugin-react':
    -        specifier: ^6.0.2
    -        version: 6.0.2(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3))
    +        specifier: ^6.0.4
    +        version: 6.0.4(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0))
           ajv:
    -        specifier: ^8.17.0
    +        specifier: ^8.20.0
             version: 8.20.0
           ajv-formats:
             specifier: ^3.0.1
    @@ -114,13 +83,13 @@ importers:
             specifier: ^4.0.3
             version: 4.0.3
           mermaid:
    -        specifier: ^11.0.0
    -        version: 11.15.0
    +        specifier: ^11.16.0
    +        version: 11.16.0
           pagefind:
    -        specifier: ^1.1.0
    +        specifier: ^1.5.2
             version: 1.5.2
           rehype-autolink-headings:
    -        specifier: ^7.0.0
    +        specifier: ^7.1.0
             version: 7.1.0
           rehype-slug:
             specifier: ^6.0.0
    @@ -129,26 +98,26 @@ importers:
             specifier: ^5.0.0
             version: 5.0.0
           remark-gfm:
    -        specifier: ^4.0.0
    +        specifier: ^4.0.1
             version: 4.0.1
           remark-mdx-frontmatter:
    -        specifier: ^5.0.0
    +        specifier: ^5.2.0
             version: 5.2.0
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
           vite:
    -        specifier: ^8.0.16
    -        version: 8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)
    +        specifier: ^8.1.5
    +        version: 8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)
           vite-react-ssg:
    -        specifier: ^0.9.0
    -        version: 0.9.0(prettier@3.8.4)(react-dom@19.2.7(react@19.2.7))(react-router-dom@6.30.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3))
    +        specifier: ^0.9.2
    +        version: 0.9.2(prettier@3.9.6)(react-dom@19.2.8(react@19.2.8))(react-router-dom@6.30.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0))
     
       packages/helpers/amountinator:
         dependencies:
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox/client
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -158,13 +127,13 @@ importers:
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-node:
             specifier: ^10.9.2
    -        version: 10.9.2(@types/node@26.0.0)(typescript@6.0.3)
    +        version: 10.9.2(@types/node@26.1.1)(typescript@6.0.3)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -172,8 +141,8 @@ importers:
       packages/helpers/bsv-wallet-helper:
         dependencies:
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox/client
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -185,23 +154,23 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           tslib:
             specifier: ^2.8.1
             version: 2.8.1
           tsup:
             specifier: ^8.5.1
    -        version: 8.5.1(postcss@8.5.18)(tsx@4.22.4)(typescript@6.0.3)(yaml@2.8.3)
    +        version: 8.5.1(postcss@8.5.18)(tsx@4.23.1)(typescript@6.0.3)(yaml@2.9.0)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -219,17 +188,17 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -247,20 +216,20 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           '@types/qrcode':
             specifier: ^1.5.6
             version: 1.5.6
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           tsconfig-to-dual-package:
             specifier: ^1.2.0
             version: 1.2.0(typescript@6.0.3)
    @@ -271,15 +240,12 @@ importers:
       packages/helpers/did-client:
         dependencies:
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox/client
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../sdk
    -      '@eslint/js':
    -        specifier: ^10.0.1
    -        version: 10.0.1(eslint@10.5.0)
           '@jest/globals':
             specifier: ^30.4.1
             version: 30.4.1
    @@ -287,29 +253,23 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    -      eslint:
    -        specifier: ^10.5.0
    -        version: 10.5.0
    -      globals:
    -        specifier: ^17.6.0
    -        version: 17.6.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-environment-jsdom:
             specifier: ^30.4.1
             version: 30.4.1
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-loader:
             specifier: ^9.6.2
    -        version: 9.6.2(typescript@6.0.3)(webpack@5.107.2)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 9.6.2(typescript@6.0.3)(webpack@5.109.0)
           ts2md:
             specifier: ^0.2.8
             version: 0.2.8
    @@ -319,40 +279,31 @@ importers:
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    -      typescript-eslint:
    -        specifier: ^8.61.0
    -        version: 8.61.1(eslint@10.5.0)(typescript@6.0.3)
           webpack:
    -        specifier: ^5.107.2
    -        version: 5.107.2(webpack-cli@7.0.3)
    +        specifier: ^5.109.0
    +        version: 5.109.0(webpack-cli@7.2.1)
           webpack-cli:
    -        specifier: ^7.0.3
    -        version: 7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2)
    +        specifier: ^7.2.1
    +        version: 7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0)
     
       packages/helpers/fund-wallet:
         dependencies:
           '@bsv/wallet-toolbox':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)(@types/node@26.0.0)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox
           chalk:
             specifier: ^5.6.2
             version: 5.6.2
    -      crypto:
    -        specifier: ^1.0.1
    -        version: 1.0.1
           dotenv:
             specifier: ^17.4.2
             version: 17.4.2
    -      readline:
    -        specifier: ^1.3.0
    -        version: 1.3.0
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../sdk
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -360,14 +311,14 @@ importers:
       packages/helpers/simple:
         dependencies:
           '@bsv/message-box-client':
    -        specifier: ^2.2.0
    -        version: 2.2.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../messaging/message-box-client
           '@bsv/wallet-toolbox':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)(@types/node@26.0.0)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox/client
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -376,20 +327,20 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           dotenv:
             specifier: ^17.4.2
             version: 17.4.2
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
             specifier: ^29.4.12
    -        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -400,20 +351,20 @@ importers:
             specifier: workspace:^
             version: link:../../sdk
           '@bsv/wallet-toolbox':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)(@types/node@26.0.0)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           tsconfig-to-dual-package:
             specifier: ^1.2.0
             version: 1.2.0(typescript@6.0.3)
    @@ -424,15 +375,15 @@ importers:
       packages/messaging/authsocket:
         dependencies:
           socket.io:
    -        specifier: ^4.8.1
    +        specifier: ^4.8.3
             version: 4.8.3
         devDependencies:
           '@bsv/authsocket-client':
    -        specifier: ^2.1.0
    -        version: 2.1.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../authsocket-client
           '@bsv/message-box-client':
    -        specifier: ^2.2.0
    -        version: 2.2.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../message-box-client
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../sdk
    @@ -441,21 +392,21 @@ importers:
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-environment-jsdom:
             specifier: ^30.4.1
             version: 30.4.1
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-loader:
             specifier: ^9.6.2
    -        version: 9.6.2(typescript@6.0.3)(webpack@5.107.2)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 9.6.2(typescript@6.0.3)(webpack@5.109.0)
           ts2md:
    -        specifier: ^0.2.5
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -464,16 +415,16 @@ importers:
             specifier: ^6.0.3
             version: 6.0.3
           webpack:
    -        specifier: ^5.107.2
    -        version: 5.107.2(webpack-cli@7.0.3)
    +        specifier: ^5.109.0
    +        version: 5.109.0(webpack-cli@7.2.1)
           webpack-cli:
    -        specifier: ^7.0.3
    -        version: 7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2)
    +        specifier: ^7.2.1
    +        version: 7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0)
     
       packages/messaging/authsocket-client:
         dependencies:
           socket.io-client:
    -        specifier: ^4.8.1
    +        specifier: ^4.8.3
             version: 4.8.3
         devDependencies:
           '@bsv/sdk':
    @@ -484,21 +435,21 @@ importers:
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-environment-jsdom:
             specifier: ^30.4.1
             version: 30.4.1
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-loader:
             specifier: ^9.6.2
    -        version: 9.6.2(typescript@6.0.3)(webpack@5.107.2)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 9.6.2(typescript@6.0.3)(webpack@5.109.0)
           ts2md:
    -        specifier: ^0.2.5
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -507,72 +458,54 @@ importers:
             specifier: ^6.0.3
             version: 6.0.3
           webpack:
    -        specifier: ^5.107.2
    -        version: 5.107.2(webpack-cli@7.0.3)
    +        specifier: ^5.109.0
    +        version: 5.109.0(webpack-cli@7.2.1)
           webpack-cli:
    -        specifier: ^7.0.3
    -        version: 7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2)
    +        specifier: ^7.2.1
    +        version: 7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0)
     
       packages/messaging/message-box-client:
         dependencies:
           '@bsv/authsocket-client':
    -        specifier: ^2.1.0
    -        version: 2.1.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../authsocket-client
         devDependencies:
           '@bsv/auth-express-middleware':
    -        specifier: ^2.1.0
    -        version: 2.1.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../middleware/auth-express-middleware
           '@bsv/payment-express-middleware':
    -        specifier: ^2.1.0
    -        version: 2.1.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../middleware/payment-express-middleware
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../sdk
    -      '@eslint/js':
    -        specifier: ^10.0.1
    -        version: 10.0.1(eslint@10.5.0)
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           '@types/supertest':
    -        specifier: ^7.2.0
    -        version: 7.2.0
    -      '@typescript-eslint/eslint-plugin':
    -        specifier: ^8.61.0
    -        version: 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)
    -      '@typescript-eslint/parser':
    -        specifier: ^8.61.0
    -        version: 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    +        specifier: ^7.2.1
    +        version: 7.2.1
           ejs:
             specifier: ^6.0.1
             version: 6.0.1
    -      eslint:
    -        specifier: ^10.5.0
    -        version: 10.5.0
    -      eslint-plugin-react:
    -        specifier: ^7.37.4
    -        version: 7.37.5(eslint@10.5.0)
    -      globals:
    -        specifier: ^17.6.0
    -        version: 17.6.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-fetch-mock:
    -        specifier: ^3.0.3
    -        version: 3.0.3(encoding@0.1.13)
    +        specifier: ^3.2.0
    +        version: 3.2.0(encoding@0.1.13)
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-node:
             specifier: ^10.9.2
    -        version: 10.9.2(@types/node@26.0.0)(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 10.9.2(@types/node@26.1.1)(typescript@6.0.3)
           ts2md:
             specifier: ^0.2.8
             version: 0.2.8
    @@ -582,21 +515,18 @@ importers:
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    -      typescript-eslint:
    -        specifier: ^8.61.0
    -        version: 8.61.1(eslint@10.5.0)(typescript@6.0.3)
           webpack:
    -        specifier: ^5.107.2
    -        version: 5.107.2(webpack-cli@7.0.3)
    +        specifier: ^5.109.0
    +        version: 5.109.0(webpack-cli@7.2.1)
           webpack-bundle-analyzer:
    -        specifier: ^5.3.0
    -        version: 5.3.0
    +        specifier: ^5.3.1
    +        version: 5.3.1
           webpack-cli:
    -        specifier: ^7.0.3
    -        version: 7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2)
    +        specifier: ^7.2.1
    +        version: 7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0)
           webpack-dev-server:
    -        specifier: 5.2.6
    -        version: 5.2.6(tslib@2.8.1)(webpack-cli@7.0.3)(webpack@5.107.2)
    +        specifier: ^5.2.6
    +        version: 5.2.6(tslib@2.8.1)(webpack-cli@7.2.1)(webpack@5.109.0)
           webpack-merge:
             specifier: ^6.0.1
             version: 6.0.1
    @@ -614,19 +544,19 @@ importers:
             version: 5.2.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           joi:
             specifier: ^18.2.3
             version: 18.2.3
           node-fetch:
    -        specifier: ^3
    +        specifier: ^3.3.2
             version: 3.3.2
           supertest:
    -        specifier: ^7.1.4
    +        specifier: ^7.2.2
             version: 7.2.2
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
             specifier: ^0.2.8
             version: 0.2.8
    @@ -644,14 +574,14 @@ importers:
             specifier: ^30.4.1
             version: 30.4.1
           '@types/body-parser':
    -        specifier: ^1.19.5
    +        specifier: ^1.19.6
             version: 1.19.6
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^26.1.1
    +        version: 26.1.1
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
     
       packages/messaging/ts-paymail/docs/examples:
         dependencies:
    @@ -659,21 +589,21 @@ importers:
             specifier: workspace:^
             version: link:../..
           '@bsv/sdk':
    -        specifier: ^2.1.6
    -        version: 2.1.9
    +        specifier: workspace:^
    +        version: link:../../../../sdk
           express:
             specifier: ^5.2.1
             version: 5.2.1
           jwt-simple:
             specifier: ^0.5.6
             version: 0.5.6
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
         devDependencies:
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -684,14 +614,14 @@ importers:
             specifier: workspace:^
             version: link:../../sdk
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
           vitest:
    -        specifier: ^4.1.9
    -        version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@26.0.0)(jsdom@28.1.0(@noble/hashes@2.2.0))(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3))
    +        specifier: ^4.1.10
    +        version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.1)(jsdom@28.1.0(@noble/hashes@2.2.0))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0))
     
       packages/middleware/auth:
         devDependencies:
    @@ -705,23 +635,23 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           tslib:
             specifier: ^2.8.1
             version: 2.8.1
           tsup:
             specifier: ^8.5.1
    -        version: 8.5.1(postcss@8.5.18)(tsx@4.22.4)(typescript@6.0.3)(yaml@2.8.3)
    +        version: 8.5.1(postcss@8.5.18)(tsx@4.23.1)(typescript@6.0.3)(yaml@2.9.0)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -739,10 +669,10 @@ importers:
             specifier: workspace:^
             version: link:../../sdk
           '@types/body-parser':
    -        specifier: ^1.19.5
    +        specifier: ^1.19.6
             version: 1.19.6
           '@types/express':
    -        specifier: ^5.0.0
    +        specifier: ^5.0.6
             version: 5.0.6
           '@types/jest':
             specifier: ^30.0.0
    @@ -752,15 +682,15 @@ importers:
             version: 3.0.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -782,22 +712,22 @@ importers:
             specifier: workspace:^
             version: link:../../sdk
           '@types/body-parser':
    -        specifier: ^1.19.5
    +        specifier: ^1.19.6
             version: 1.19.6
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -809,7 +739,7 @@ importers:
       packages/network/ts-p2p:
         dependencies:
           '@chainsafe/libp2p-gossipsub':
    -        specifier: ^14.1.1
    +        specifier: ^14.1.2
             version: 14.1.2
           '@chainsafe/libp2p-noise':
             specifier: ^17.0.0
    @@ -818,41 +748,41 @@ importers:
             specifier: ^8.0.1
             version: 8.0.1
           '@libp2p/bootstrap':
    -        specifier: ^12.0.25
    -        version: 12.0.25
    +        specifier: ^12.0.27
    +        version: 12.0.27
           '@libp2p/crypto':
    -        specifier: ^5.1.20
    -        version: 5.1.20
    +        specifier: ^5.1.21
    +        version: 5.1.21
           '@libp2p/identify':
    -        specifier: ^4.1.8
    -        version: 4.1.8
    +        specifier: ^4.1.10
    +        version: 4.1.10
           '@libp2p/interface':
    -        specifier: ^3.2.4
    -        version: 3.2.4
    +        specifier: ^3.2.5
    +        version: 3.2.5
           '@libp2p/kad-dht':
    -        specifier: ^16.3.3
    -        version: 16.3.3
    +        specifier: ^16.4.0
    +        version: 16.4.0
           '@libp2p/peer-id':
    -        specifier: ^6.0.11
    -        version: 6.0.11
    +        specifier: ^6.0.12
    +        version: 6.0.12
           '@libp2p/ping':
    -        specifier: ^3.1.7
    -        version: 3.1.7
    +        specifier: ^3.1.9
    +        version: 3.1.9
           '@libp2p/pnet':
    -        specifier: ^3.0.23
    -        version: 3.0.23
    +        specifier: ^3.0.25
    +        version: 3.0.25
           '@libp2p/pubsub-peer-discovery':
             specifier: ^12.0.0
             version: 12.0.0
           '@libp2p/tcp':
    -        specifier: ^11.0.22
    -        version: 11.0.22
    +        specifier: ^11.0.24
    +        version: 11.0.24
           '@multiformats/multiaddr':
             specifier: ^13.0.3
             version: 13.0.3
           libp2p:
    -        specifier: ^3.3.4
    -        version: 3.3.4
    +        specifier: ^3.3.6
    +        version: 3.3.6
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -864,17 +794,17 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           tsx:
    -        specifier: ^4.22.4
    -        version: 4.22.4
    +        specifier: ^4.23.1
    +        version: 4.23.1
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -882,38 +812,38 @@ importers:
       packages/overlays/btms-backend:
         dependencies:
           '@bsv/overlay':
    -        specifier: ^2.1.1
    -        version: 2.1.1(@bsv/sdk@2.1.9)
    +        specifier: workspace:^
    +        version: link:../overlay
           '@bsv/sdk':
    -        specifier: ^2.1.6
    -        version: 2.1.9
    +        specifier: workspace:^
    +        version: link:../../sdk
           mongodb:
    -        specifier: ^7.3.0
    -        version: 7.3.0(socks@2.8.7)
    +        specifier: ^7.5.0
    +        version: 7.5.0(socks@2.8.7)
         devDependencies:
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           mongodb-memory-server:
             specifier: ^11.2.0
             version: 11.2.0(socks@2.8.7)
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-node:
             specifier: ^10.9.2
    -        version: 10.9.2(@types/node@26.0.0)(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 10.9.2(@types/node@26.1.1)(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -932,15 +862,15 @@ importers:
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -952,11 +882,11 @@ importers:
       packages/overlays/overlay:
         dependencies:
           '@bsv/gasp':
    -        specifier: ^1.3.0
    -        version: 1.3.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../gasp-core
           knex:
    -        specifier: ^3.2.10
    -        version: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    +        specifier: ^3.3.0
    +        version: 3.3.0(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.1.1))
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -965,19 +895,19 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -989,14 +919,14 @@ importers:
       packages/overlays/overlay-discovery-services:
         dependencies:
           '@bsv/overlay':
    -        specifier: ^2.1.1
    -        version: 2.1.1(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../overlay
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox/client
           mongodb:
    -        specifier: ^7.3.0
    -        version: 7.3.0(socks@2.8.7)
    +        specifier: ^7.5.0
    +        version: 7.5.0(socks@2.8.7)
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -1009,18 +939,18 @@ importers:
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           mongodb-memory-server:
             specifier: ^11.2.0
             version: 11.2.0(socks@2.8.7)
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -1032,17 +962,17 @@ importers:
       packages/overlays/overlay-express:
         dependencies:
           '@bsv/auth-express-middleware':
    -        specifier: ^2.1.0
    -        version: 2.1.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../middleware/auth-express-middleware
           '@bsv/overlay':
    -        specifier: ^2.1.1
    -        version: 2.1.1(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../overlay
           '@bsv/overlay-discovery-services':
    -        specifier: ^2.1.0
    -        version: 2.1.0(@bsv/sdk@packages+sdk)(socks@2.8.7)
    +        specifier: workspace:^
    +        version: link:../overlay-discovery-services
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../../wallet/wallet-toolbox/client
           body-parser:
             specifier: ^2.3.0
             version: 2.3.0
    @@ -1053,11 +983,11 @@ importers:
             specifier: ^5.2.1
             version: 5.2.1
           knex:
    -        specifier: ^3.2.10
    -        version: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    +        specifier: ^3.3.0
    +        version: 3.3.0(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.1.1))
           mongodb:
    -        specifier: ^7.3.0
    -        version: 7.3.0(socks@2.8.7)
    +        specifier: ^7.5.0
    +        version: 7.5.0(socks@2.8.7)
           uuid:
             specifier: ^14.0.1
             version: 14.0.1
    @@ -1069,28 +999,28 @@ importers:
             specifier: ^30.4.1
             version: 30.4.1
           '@types/body-parser':
    -        specifier: ^1.19.5
    +        specifier: ^1.19.6
             version: 1.19.6
           '@types/express':
    -        specifier: ^5.0.0
    +        specifier: ^5.0.6
             version: 5.0.6
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           tsconfig-to-dual-package:
             specifier: ^1.2.0
    @@ -1102,14 +1032,14 @@ importers:
       packages/overlays/topics:
         dependencies:
           '@bsv/overlay':
    -        specifier: ^2.1.1
    -        version: 2.1.1(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../overlay
           '@bsv/templates':
             specifier: workspace:^
             version: link:../../helpers/ts-templates
           mongodb:
    -        specifier: ^7.3.0
    -        version: 7.3.0(socks@2.8.7)
    +        specifier: ^7.5.0
    +        version: 7.5.0(socks@2.8.7)
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -1121,65 +1051,56 @@ importers:
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           mongodb-memory-server:
             specifier: ^11.2.0
             version: 11.2.0(socks@2.8.7)
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.0
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
     
       packages/sdk:
         devDependencies:
    -      '@eslint/js':
    -        specifier: ^10.0.1
    -        version: 10.0.1(eslint@10.5.0)
           '@jest/globals':
             specifier: ^30.4.1
             version: 30.4.1
           '@rspack/cli':
    -        specifier: ^2.0.8
    -        version: 2.0.8(@rspack/core@2.0.8)
    +        specifier: ^2.1.5
    +        version: 2.1.5(@rspack/core@2.1.5)
           '@rspack/core':
    -        specifier: ^2.0.8
    -        version: 2.0.8
    +        specifier: ^2.1.5
    +        version: 2.1.5
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    -      eslint:
    -        specifier: ^10.5.0
    -        version: 10.5.0
    -      globals:
    -        specifier: ^17.6.0
    -        version: 17.6.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-environment-jsdom:
             specifier: ^30.4.1
             version: 30.4.1
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-loader:
             specifier: ^9.6.2
    -        version: 9.6.2(typescript@6.0.3)(webpack@5.107.2)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 9.6.2(typescript@6.0.3)(webpack@5.109.0)
           ts2md:
             specifier: ^0.2.8
             version: 0.2.8
    @@ -1189,9 +1110,6 @@ importers:
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    -      typescript-eslint:
    -        specifier: ^8.61.0
    -        version: 8.61.1(eslint@10.5.0)(typescript@6.0.3)
     
       packages/verifast:
         devDependencies:
    @@ -1199,44 +1117,41 @@ importers:
             specifier: workspace:^
             version: link:../sdk
           '@jest/globals':
    -        specifier: ^30.0.0
    +        specifier: ^30.4.1
             version: 30.4.1
           '@rspack/cli':
    -        specifier: ^2.0.8
    -        version: 2.0.8(@rspack/core@2.0.8)
    +        specifier: ^2.1.5
    +        version: 2.1.5(@rspack/core@2.1.5)
           '@rspack/core':
    -        specifier: ^2.0.8
    -        version: 2.0.8
    +        specifier: ^2.1.5
    +        version: 2.1.5
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           jest:
    -        specifier: ^30.0.0
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        specifier: ^30.4.2
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           puppeteer-core:
    -        specifier: ^24.42.0
    -        version: 24.42.0
    +        specifier: ^24.43.1
    +        version: 24.43.1
           ts-jest:
    -        specifier: ^29.2.0
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-loader:
             specifier: ^9.6.2
    -        version: 9.6.2(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.1))
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        version: 9.6.2(typescript@6.0.3)(webpack@5.109.0(esbuild@0.28.1))
           tsx:
    -        specifier: ^4.22.4
    -        version: 4.22.4
    +        specifier: ^4.23.1
    +        version: 4.23.1
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
           vite:
    -        specifier: ^8.0.16
    -        version: 8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)
    +        specifier: ^8.1.5
    +        version: 8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)
     
       packages/wallet/btms:
         devDependencies:
    @@ -1248,15 +1163,15 @@ importers:
             version: 30.0.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.2
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts2md:
    -        specifier: ^0.2.0
    +        specifier: ^0.2.8
             version: 0.2.8
           typescript:
             specifier: ^6.0.3
    @@ -1265,17 +1180,17 @@ importers:
       packages/wallet/btms-permission-module:
         devDependencies:
           '@bsv/btms':
    -        specifier: ^1.1.0
    -        version: 1.1.0(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../btms
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../sdk
           '@bsv/wallet-toolbox-client':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@packages+sdk)
    +        specifier: workspace:^
    +        version: link:../wallet-toolbox/client
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
    @@ -1290,55 +1205,55 @@ importers:
             version: 6.9.1
           '@testing-library/react':
             specifier: ^16.3.2
    -        version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
    +        version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
           '@types/express':
    -        specifier: ^5.0.0
    +        specifier: ^5.0.6
             version: 5.0.6
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           '@types/qrcode':
    -        specifier: ^1.5.0
    +        specifier: ^1.5.6
             version: 1.5.6
           '@types/react':
             specifier: ^19.2.17
             version: 19.2.17
           '@types/ws':
    -        specifier: ^8.5.0
    +        specifier: ^8.18.1
             version: 8.18.1
           express:
             specifier: ^5.2.1
             version: 5.2.1
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-environment-jsdom:
             specifier: ^30.4.1
             version: 30.4.1
           qrcode:
    -        specifier: ^1.5.0
    +        specifier: ^1.5.4
             version: 1.5.4
           react:
    -        specifier: ^19.2.7
    -        version: 19.2.7
    +        specifier: ^19.2.8
    +        version: 19.2.8
           react-dom:
    -        specifier: ^19.2.7
    -        version: 19.2.7(react@19.2.7)
    +        specifier: ^19.2.8
    +        version: 19.2.8(react@19.2.8)
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           tsup:
    -        specifier: ^8.0.0
    -        version: 8.5.1(postcss@8.5.18)(tsx@4.22.4)(typescript@6.0.3)(yaml@2.8.3)
    +        specifier: ^8.5.1
    +        version: 8.5.1(postcss@8.5.18)(tsx@4.23.1)(typescript@6.0.3)(yaml@2.9.0)
           typescript:
             specifier: ^6.0.3
             version: 6.0.3
           ws:
    -        specifier: ^8.21.0
    -        version: 8.21.0
    +        specifier: ^8.21.1
    +        version: 8.21.1
     
       packages/wallet/wallet-toolbox:
         dependencies:
    @@ -1367,17 +1282,17 @@ importers:
             specifier: ^4.12.0
             version: 4.12.0
           idb:
    -        specifier: ^8.0.2
    +        specifier: ^8.0.3
             version: 8.0.3
           knex:
    -        specifier: ^3.2.10
    -        version: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    +        specifier: ^3.3.0
    +        version: 3.3.0(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.1.1))
           mysql2:
    -        specifier: ^3.22.5
    -        version: 3.23.1(@types/node@26.0.0)
    +        specifier: ^3.23.1
    +        version: 3.23.1(@types/node@26.1.1)
           ws:
    -        specifier: ^8.21.0
    -        version: 8.21.0
    +        specifier: ^8.21.1
    +        version: 8.21.1
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
    @@ -1386,50 +1301,44 @@ importers:
             specifier: ^30.4.1
             version: 30.4.1
           '@types/body-parser':
    -        specifier: ^1.19.5
    +        specifier: ^1.19.6
             version: 1.19.6
           '@types/cors':
    -        specifier: ^2.8.13
    +        specifier: ^2.8.19
             version: 2.8.19
    -      '@types/diff':
    -        specifier: ^8.0.0
    -        version: 8.0.0
           '@types/fs-extra':
             specifier: ^11.0.4
             version: 11.0.4
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
    -      '@types/jest-diff':
    -        specifier: ^24.3.0
    -        version: 24.3.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           chalk:
             specifier: ^4.1.2
             version: 4.1.2
           cors:
    -        specifier: ^2.8.5
    +        specifier: ^2.8.6
             version: 2.8.6
           fake-indexeddb:
    -        specifier: ^6.0.0
    +        specifier: ^6.2.5
             version: 6.2.5
           fs-extra:
    -        specifier: ^11.3.5
    -        version: 11.3.5
    +        specifier: ^11.4.0
    +        version: 11.4.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
    +      oxlint:
    +        specifier: ^1.75.0
    +        version: 1.75.0
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-node:
    -        specifier: ^10.9.1
    -        version: 10.9.2(@types/node@26.0.0)(typescript@6.0.3)
    -      ts-standard:
    -        specifier: ^12.0.0
    -        version: 12.0.2(typescript@6.0.3)
    +        specifier: ^10.9.2
    +        version: 10.9.2(@types/node@26.1.1)(typescript@6.0.3)
           ts2md:
             specifier: ^0.2.8
             version: 0.2.8
    @@ -1440,29 +1349,23 @@ importers:
       packages/wallet/wallet-toolbox-examples:
         dependencies:
           '@bsv/sdk':
    -        specifier: ^2.1.6
    -        version: 2.1.9
    +        specifier: workspace:^
    +        version: link:../../sdk
           '@bsv/wallet-toolbox':
    -        specifier: ^2.3.3
    -        version: 2.3.3(@bsv/sdk@2.1.9)(@types/node@26.0.0)(sqlite3@6.0.1)
    +        specifier: workspace:^
    +        version: link:../wallet-toolbox
         devDependencies:
    -      '@types/diff':
    -        specifier: ^8.0.0
    -        version: 8.0.0
           '@types/fs-extra':
             specifier: ^11.0.4
             version: 11.0.4
           '@types/jest':
             specifier: ^30.0.0
             version: 30.0.0
    -      '@types/jest-diff':
    -        specifier: ^24.3.0
    -        version: 24.3.0
           '@types/node':
    -        specifier: ^26.0.0
    -        version: 26.0.0
    +        specifier: ^26.1.1
    +        version: 26.1.1
           '@types/node-fetch':
    -        specifier: ^2.6.2
    +        specifier: ^2.6.13
             version: 2.6.13
           chalk:
             specifier: ^5.6.2
    @@ -1471,35 +1374,29 @@ importers:
             specifier: ^17.4.2
             version: 17.4.2
           fake-indexeddb:
    -        specifier: ^6.0.0
    +        specifier: ^6.2.5
             version: 6.2.5
           fs-extra:
    -        specifier: ^11.3.5
    -        version: 11.3.5
    +        specifier: ^11.4.0
    +        version: 11.4.0
           jest:
             specifier: ^30.4.2
    -        version: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +        version: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-diff:
             specifier: ^30.4.1
             version: 30.4.1
    -      jest-simple-summary:
    -        specifier: ^1.0.2
    -        version: 1.0.2
           prettier:
    -        specifier: ^3.8.4
    -        version: 3.8.4
    +        specifier: ^3.9.6
    +        version: 3.9.6
           sqlite3:
             specifier: ^6.0.1
             version: 6.0.1
    -      standard:
    -        specifier: ^17.1.0
    -        version: 17.1.2
           ts-jest:
    -        specifier: ^29.4.11
    -        version: 29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3)
    +        specifier: ^29.4.12
    +        version: 29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3)
           ts-node:
    -        specifier: ^10.9.1
    -        version: 10.9.2(@types/node@26.0.0)(typescript@6.0.3)
    +        specifier: ^10.9.2
    +        version: 10.9.2(@types/node@26.1.1)(typescript@6.0.3)
           ts2md:
             specifier: ^0.2.8
             version: 0.2.8
    @@ -1513,12 +1410,18 @@ importers:
             specifier: ^4.12.0
             version: 4.12.0
           idb:
    -        specifier: ^8.0.2
    +        specifier: ^8.0.3
             version: 8.0.3
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../../sdk
    +      '@types/node':
    +        specifier: ^26.1.1
    +        version: 26.1.1
    +      typescript:
    +        specifier: ^6.0.3
    +        version: 6.0.3
     
       packages/wallet/wallet-toolbox/mobile:
         dependencies:
    @@ -1526,12 +1429,18 @@ importers:
             specifier: ^4.12.0
             version: 4.12.0
           idb:
    -        specifier: ^8.0.2
    +        specifier: ^8.0.3
             version: 8.0.3
         devDependencies:
           '@bsv/sdk':
             specifier: workspace:^
             version: link:../../../sdk
    +      '@types/node':
    +        specifier: ^26.1.1
    +        version: 26.1.1
    +      typescript:
    +        specifier: ^6.0.3
    +        version: 6.0.3
     
     packages:
     
    @@ -1544,26 +1453,6 @@ packages:
       '@antfu/install-pkg@1.1.0':
         resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
     
    -  '@apidevtools/json-schema-ref-parser@11.7.2':
    -    resolution: {integrity: sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==}
    -    engines: {node: '>= 16'}
    -
    -  '@apidevtools/json-schema-ref-parser@11.9.3':
    -    resolution: {integrity: sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==}
    -    engines: {node: '>= 16'}
    -
    -  '@apidevtools/openapi-schemas@2.1.0':
    -    resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==}
    -    engines: {node: '>=10'}
    -
    -  '@apidevtools/swagger-methods@3.0.2':
    -    resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==}
    -
    -  '@apidevtools/swagger-parser@10.1.1':
    -    resolution: {integrity: sha512-u/kozRnsPO/x8QtKYJOqoGtC4kH6yg1lfYkB9Au0WhYB0FNLpyFusttQtvhlwjtG3rOwiRz4D8DnnXa8iEpIKA==}
    -    peerDependencies:
    -      openapi-types: '>=7'
    -
       '@asamuzakjp/css-color@3.2.0':
         resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
     
    @@ -1581,70 +1470,6 @@ packages:
       '@asamuzakjp/nwsapi@2.3.9':
         resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
     
    -  '@asyncapi/avro-schema-parser@3.0.24':
    -    resolution: {integrity: sha512-YMyr2S2heMrWHRyECknjHeejlZl5exUSv9nD1gTejAT13fSf0PqIRydZ9ZuoglCLBg55AeehypR2zLIBu/9kHQ==}
    -
    -  '@asyncapi/generator-components@0.7.0':
    -    resolution: {integrity: sha512-a+321Dww4JJFF3fF1Z8wH7de82ENfHF0Yjbeqjluhs3ac0jwMzJd2dwny5LYWHVKr2PbK+vKwiv6Vz06zCwuJw==}
    -
    -  '@asyncapi/generator-helpers@1.1.0':
    -    resolution: {integrity: sha512-QjvDmLv6yFbHDoVzIRcBB09TXOcqAqTmSCPJ29fR8kjnL1js2G1GwmMIuZRNWCOAK+c5WT4ATUz8PbwAlbeU0Q==}
    -
    -  '@asyncapi/generator-hooks@0.1.0':
    -    resolution: {integrity: sha512-cTfwiXNrNE4Z5ZkbLyX4jCAnJEQgTXpPRhSzTpt08R3Md+2tO8CMQWo4B4C8fSSy3M4aBWePJ4bbILOEqduvUg==}
    -    deprecated: 'Hooks are now part of generator repository and also out of the box integrated with the generator, so no need to set it as dependency any more: https://github.com/asyncapi/generator/releases/tag/%40asyncapi%2Fgenerator%402.5.0'
    -
    -  '@asyncapi/generator-react-sdk@1.1.3':
    -    resolution: {integrity: sha512-8pO8qVqNmASdcJK+uKXHgqE6BcmEQ+c7ypYf8pKNYaXr0FLFifaQGaTkUhG4fjnzNsUro6N+GywGYHRy1PpVng==}
    -
    -  '@asyncapi/generator@3.3.0':
    -    resolution: {integrity: sha512-VZ2gQtuQbnCEPiA2VNEEleaPcn29DhldWwNzn0Spi2SRhzY3TaPybws46vhQp+8G9sW7gaajNYBr1S9KIdLndA==}
    -    engines: {node: '>=24.11', npm: '>=11.5.1'}
    -
    -  '@asyncapi/html-template@3.5.6':
    -    resolution: {integrity: sha512-Z4wb7m2VAkFZ+d/M3nqOv1umiibgMFUDMai/50h4p4wYU1CHFio7fEUiEaVmCjCgsfzbiNYSb9vxTmxEevxHbg==}
    -
    -  '@asyncapi/modelina@5.10.1':
    -    resolution: {integrity: sha512-mvk77+ls2ia+w3uQftJ7s6/Yid4lO+1IgbTkJ94mGSV9Qqk1n+ln5dz2snccARI5ubdy3ofKb3QP2Dq/OGeH8A==}
    -    engines: {node: '>=18'}
    -
    -  '@asyncapi/multi-parser@2.3.0':
    -    resolution: {integrity: sha512-8hZ2k1l+X5ygGfZa3fFNueO5O00df2yCHsiKzVgJdUpL2wRqhaMnMkrPwO6vwYiRzhZdfzVmZ/p8Tz1+8Yn39Q==}
    -
    -  '@asyncapi/openapi-schema-parser@3.0.24':
    -    resolution: {integrity: sha512-7wz2yVDedJMS+TzOuqCvRWJMc6pNHICKZcOhnW6ZvyVLAh7hYIqQE1WA4OoXT4cKVbwSU3V2Q4bZagSsAIQd6Q==}
    -
    -  '@asyncapi/parser@2.1.2':
    -    resolution: {integrity: sha512-2pHKnr2P8EujcrvZo4x4zNwsEIAg5vb1ZEhl2+OH0YBg8EYH/Xx73XZ+bbwLaYIg1gvFjm29jNB9UL3CMeDU5w==}
    -
    -  '@asyncapi/parser@3.0.0-next-major-spec.8':
    -    resolution: {integrity: sha512-d8ebYM08BCsx3Q4AeLke6naU/NrcAXFEVpS6b3EWcKRdUDce+v0X5k9aDH+YXWCaQApEF28UzcxhlSOJvhIFgQ==}
    -
    -  '@asyncapi/parser@3.6.0':
    -    resolution: {integrity: sha512-6S0Yr8vI418a1IrpGsOYbfWVo9+aHvSqN2oSkiY0YJltS/C7oDOt9e0mo6hSld8bg+EeKrtgkVmpW4obh1JFvA==}
    -
    -  '@asyncapi/protobuf-schema-parser@3.6.0':
    -    resolution: {integrity: sha512-z6zVRAMi2bkkgjREoCIvUg7KcacyoEh+VIwQmEni/JPuPFMOD3oPv4kwoftEeiF2+gGiioeIxpkI5x7rmHf2Nw==}
    -    engines: {node: '>=18'}
    -
    -  '@asyncapi/raml-dt-schema-parser@4.0.24':
    -    resolution: {integrity: sha512-Fy9IwCXPpXoG4Mkm7sXgWucSwYg8POwdx16xuHAmV6AerpcM8nk5mT/tARLtR3wrMst3OBwReEVYzwT3esSb8g==}
    -    deprecated: |-
    -      Project is archived. See https://github.com/asyncapi-archived-repos/raml-dt-schema-parser
    -      .
    -
    -  '@asyncapi/react-component@3.1.1':
    -    resolution: {integrity: sha512-ZWnhIfoiNwX1wOAq2S+MZbshgFlm179RzXfSv8d4JKpg6+eiY3929EQPznzGcyxgvQ9tsoicHtbxoOtH/7kJKA==}
    -    peerDependencies:
    -      react: '>=18.0.0'
    -      react-dom: '>=18.0.0'
    -
    -  '@asyncapi/specs@5.1.0':
    -    resolution: {integrity: sha512-yffhETqehkim43luMnPKOwzY0D0YtU4bKpORIXIaid6p5Y5kDLrMGJaEPkNieQp03HMjhjFrnUPtT8kvqe0+aQ==}
    -
    -  '@asyncapi/specs@6.11.1':
    -    resolution: {integrity: sha512-A3WBLqAKGoJ2+6FWFtpjBlCQ1oFCcs4GxF7zsIGvNqp/klGUHjlA3aAcZ9XMMpLGE8zPeYDz2x9FmO6DSuKraQ==}
    -
       '@babel/code-frame@7.29.7':
         resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==}
         engines: {node: '>=6.9.0'}
    @@ -1653,10 +1478,6 @@ packages:
         resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/core@7.12.9':
    -    resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==}
    -    engines: {node: '>=6.9.0'}
    -
       '@babel/core@7.29.7':
         resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
         engines: {node: '>=6.9.0'}
    @@ -1665,39 +1486,14 @@ packages:
         resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/helper-annotate-as-pure@7.29.7':
    -    resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==}
    -    engines: {node: '>=6.9.0'}
    -
       '@babel/helper-compilation-targets@7.29.7':
         resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/helper-create-class-features-plugin@7.29.7':
    -    resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/helper-create-regexp-features-plugin@7.29.7':
    -    resolution: {integrity: sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/helper-define-polyfill-provider@0.6.8':
    -    resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==}
    -    peerDependencies:
    -      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
    -
       '@babel/helper-globals@7.29.7':
         resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/helper-member-expression-to-functions@7.29.7':
    -    resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==}
    -    engines: {node: '>=6.9.0'}
    -
       '@babel/helper-module-imports@7.29.7':
         resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==}
         engines: {node: '>=6.9.0'}
    @@ -1708,30 +1504,10 @@ packages:
         peerDependencies:
           '@babel/core': ^7.0.0
     
    -  '@babel/helper-optimise-call-expression@7.29.7':
    -    resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==}
    -    engines: {node: '>=6.9.0'}
    -
       '@babel/helper-plugin-utils@7.29.7':
         resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/helper-remap-async-to-generator@7.29.7':
    -    resolution: {integrity: sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/helper-replace-supers@7.29.7':
    -    resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/helper-skip-transparent-expression-wrappers@7.29.7':
    -    resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==}
    -    engines: {node: '>=6.9.0'}
    -
       '@babel/helper-string-parser@7.29.7':
         resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
         engines: {node: '>=6.9.0'}
    @@ -1744,10 +1520,6 @@ packages:
         resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
         engines: {node: '>=6.9.0'}
     
    -  '@babel/helper-wrap-function@7.29.7':
    -    resolution: {integrity: sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==}
    -    engines: {node: '>=6.9.0'}
    -
       '@babel/helpers@7.29.7':
         resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==}
         engines: {node: '>=6.9.0'}
    @@ -1757,48 +1529,6 @@ packages:
         engines: {node: '>=6.0.0'}
         hasBin: true
     
    -  '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7':
    -    resolution: {integrity: sha512-j8SrR0zLZrRsC09DlszEx8FpMiwukKffYXMK0d5LmOglO7vGG6sz/BR/20yHqWH+Lnn31JTt2PE3hIWNgM2J6w==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7':
    -    resolution: {integrity: sha512-r8j8escF+U2FUHo0KOhPUdMzUO+jp9fInva6+ACVAF3Y97Ev+5iNZwiqTghmzNeWwDkOPlYuTcfb1vDaoZKmAQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7':
    -    resolution: {integrity: sha512-GE1TFSiuFeGsCxmYXZl8HwoPrVlwe4rHPFE8weieGKZqnDORK+Ar3vgWMgW+AOxQ6/2TgLSKx9p6W7O4rC6qgQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7':
    -    resolution: {integrity: sha512-oBNVCvnO5tND+xSopWvV8WNGfpTfgP4Zr/YXXSj8zfmcPktp5Ku/aZlsIowgSD4fjmgHn6sGmB9APVsU5zOdhA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7':
    -    resolution: {integrity: sha512-QQt9qKHZ2sg/kivaLr7lnQr8HVrQDdBNSfCsTjiDxRuX/K5ORyKq+Bu8Xr0cDE3Dfkv0cw28Ve0EKyKMvulkOw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.13.0
    -
    -  '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7':
    -    resolution: {integrity: sha512-pn6QacGLgvCcwc+syUhKE/qSjV2D1IHDB84RNxWYSt1mW3K/SCtjinZ2p0cETJxAWBjPy3K/1lHwG5BjjPxNlw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2':
    -    resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
       '@babel/plugin-syntax-async-generators@7.8.4':
         resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
         peerDependencies:
    @@ -1820,12 +1550,6 @@ packages:
         peerDependencies:
           '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-syntax-import-assertions@7.29.7':
    -    resolution: {integrity: sha512-/An1OCBN93thpBAGyfsK2pcf0jvju1SAtKkL2Ny++B5Sy6sqgzXDQH1cZxWbF96Wuk+bn41MDA9bLd4VVAw6rw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
       '@babel/plugin-syntax-import-attributes@7.29.7':
         resolution: {integrity: sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==}
         engines: {node: '>=6.9.0'}
    @@ -1896,457 +1620,51 @@ packages:
         peerDependencies:
           '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-syntax-unicode-sets-regex@7.18.6':
    -    resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
    +  '@babel/runtime@7.29.2':
    +    resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
         engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
     
    -  '@babel/plugin-transform-arrow-functions@7.29.7':
    -    resolution: {integrity: sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==}
    +  '@babel/runtime@7.29.7':
    +    resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
         engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-transform-async-generator-functions@7.29.7':
    -    resolution: {integrity: sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==}
    +  '@babel/template@7.29.7':
    +    resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
         engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-transform-async-to-generator@7.29.7':
    -    resolution: {integrity: sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==}
    +  '@babel/traverse@7.29.7':
    +    resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==}
         engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-transform-block-scoped-functions@7.29.7':
    -    resolution: {integrity: sha512-cUSmjh72N+rN4PrkFlN1dJwNCwjVp5d38/CQrEsFggkD10UiFlBFgdH3tv5dNsLuHY+3S8db2xCHjhZcv5WgvA==}
    +  '@babel/types@7.29.7':
    +    resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
         engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
     
    -  '@babel/plugin-transform-block-scoping@7.29.7':
    -    resolution: {integrity: sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    +  '@bcoe/v8-coverage@0.2.3':
    +    resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
     
    -  '@babel/plugin-transform-class-properties@7.29.7':
    -    resolution: {integrity: sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    +  '@braintree/sanitize-url@7.1.2':
    +    resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==}
     
    -  '@babel/plugin-transform-class-static-block@7.29.7':
    -    resolution: {integrity: sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.12.0
    +  '@bramus/specificity@2.4.2':
    +    resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
    +    hasBin: true
     
    -  '@babel/plugin-transform-classes@7.29.7':
    -    resolution: {integrity: sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    +  '@chainsafe/as-chacha20poly1305@0.1.0':
    +    resolution: {integrity: sha512-BpNcL8/lji/GM3+vZ/bgRWqJ1q5kwvTFmGPk7pxm/QQZDbaMI98waOHjEymTjq2JmdD/INdNBFOVSyJofXg7ew==}
     
    -  '@babel/plugin-transform-computed-properties@7.29.7':
    -    resolution: {integrity: sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    +  '@chainsafe/as-sha256@1.2.4':
    +    resolution: {integrity: sha512-3GXDysZOKD6cTYbm48lEdXdUbS7cafjXQZfgHOspTByhoGR/JM3KBXyF3vE6bf63ImjNPyoEZwnQcpYPQ6k3bQ==}
     
    -  '@babel/plugin-transform-destructuring@7.29.7':
    -    resolution: {integrity: sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    +  '@chainsafe/is-ip@2.1.0':
    +    resolution: {integrity: sha512-KIjt+6IfysQ4GCv66xihEitBjvhU/bixbbbFxdJ1sqCp4uJ0wuZiYBPhksZoy4lfaF0k9cwNzY5upEW/VWdw3w==}
     
    -  '@babel/plugin-transform-dotall-regex@7.29.7':
    -    resolution: {integrity: sha512-3qc18hsD2RdZiyJNDNc7HQpv6xbncwh8FYtxNFFzclSyh/trPD9KkVR9BDECUjDLvb7yJVF15GfYUuC+LMkkiQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    +  '@chainsafe/libp2p-gossipsub@14.1.2':
    +    resolution: {integrity: sha512-HuyB1dO+GwqpbvKhq2TdrsvrtNt19iOWLEfjy2N3ItYY1gA2F67KtCOLmZ1NlEcCbjFDg+qRffQMjgkDwHSFOg==}
    +    engines: {npm: '>=8.7.0'}
     
    -  '@babel/plugin-transform-duplicate-keys@7.29.7':
    -    resolution: {integrity: sha512-6IvRRriEMqnBwD6chtxdLpMYCHWEzN+oL5cyQtjykya19UgzbmKhxmhZgKC/LHxS2nYr9Q/qYPZ5Lr6jOL9+yQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7':
    -    resolution: {integrity: sha512-2wiIyo2BjtgU7HufSeDnL9L2O7zr8jmhFKuSr65VpRkUiRKRNpb0mdlk56+XPPKoIrfHqzbMuglDvZun0RISsA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-transform-dynamic-import@7.29.7':
    -    resolution: {integrity: sha512-giOlEm/EFjfjr+te9NsdjkUo2v4f8rS/SXPumRVHAtbNcyNlvtREkU1dZzaIDclNpnaVhlCqRdFKhJBjBikzLg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-explicit-resource-management@7.29.7':
    -    resolution: {integrity: sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-exponentiation-operator@7.29.7':
    -    resolution: {integrity: sha512-zFpMOTLZBdW5LfObqcSbL6kefg4R4eLdmvS0wbN9M6D5Mym/sKm9toOoWyVOa+xDjvCnuWcHls2YonXwHvH3CQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-export-namespace-from@7.29.7':
    -    resolution: {integrity: sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-for-of@7.29.7':
    -    resolution: {integrity: sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-function-name@7.29.7':
    -    resolution: {integrity: sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-json-strings@7.29.7':
    -    resolution: {integrity: sha512-RRnE2+eon1rJAq8MnoF1b5kTpY1vU88twHcvcKMrsqP/jxIRqDVs9iJB5fqPuqyeFAW0wJo4MlUIPpQCq/aRsg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-literals@7.29.7':
    -    resolution: {integrity: sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-logical-assignment-operators@7.29.7':
    -    resolution: {integrity: sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-member-expression-literals@7.29.7':
    -    resolution: {integrity: sha512-hl1kwFZCCiDyfH25Xmco9jTrkPgnS9pmOzSG7W5I4SaGbLeqKv417hcU2RKmaxoPEgsoJh7ZPOrnPGq99bHoUg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-modules-amd@7.29.7':
    -    resolution: {integrity: sha512-fxtQoH3m5ywUSIfaH0FGCzWu4McsYon5bD3K4XnskC7f+OyQMj7rsOMi4NvvmJ83WwBAg4UCe+ov4VZlqEvyew==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-modules-commonjs@7.29.7':
    -    resolution: {integrity: sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-modules-systemjs@7.29.7':
    -    resolution: {integrity: sha512-TM2ZcQLoG2/y4HODiStCo10DibYhWhGWAwVv+EQKmG/7GFl0N+AAmUiXOMKM+aiJ9XBJ9AHVZBvTzMnJ2sM3cQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-modules-umd@7.29.7':
    -    resolution: {integrity: sha512-B4UkaTK3QpgCwJnrxKfMPKdo92CN7OKXAlpAAnM3UPu0Q0lCCk57ylA9AJbRy2v8dDKOPAAWcoR6CMyeoHwRCA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-named-capturing-groups-regex@7.29.7':
    -    resolution: {integrity: sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-transform-new-target@7.29.7':
    -    resolution: {integrity: sha512-fEo41GmsOUhOBlw8ioo6zvjX5Xc2Lqkzlyfqbpsk3eB6TReV18uhxZ0esfEokVbY2+PVJAQHNKxER6lGrzNd3A==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-nullish-coalescing-operator@7.29.7':
    -    resolution: {integrity: sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-numeric-separator@7.29.7':
    -    resolution: {integrity: sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-object-rest-spread@7.29.7':
    -    resolution: {integrity: sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-object-super@7.29.7':
    -    resolution: {integrity: sha512-Ea/diGcw0twB5IlZPO5sgET6fJsLJqPABqTuFWIR+iMPGPZJkATEIWx0wa+aEQ5UY1CBQyP/gkAiLEqn1vBiQA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-optional-catch-binding@7.29.7':
    -    resolution: {integrity: sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-optional-chaining@7.29.7':
    -    resolution: {integrity: sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-parameters@7.29.7':
    -    resolution: {integrity: sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-private-methods@7.29.7':
    -    resolution: {integrity: sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-private-property-in-object@7.29.7':
    -    resolution: {integrity: sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-property-literals@7.29.7':
    -    resolution: {integrity: sha512-bOMRLQuI0A5ZqHq3OWJ89/rXpJ/NJrbVhXiP4zwPGMs6kpcVsuTUNjwoE30K0Qm3mf48a/TnRYYD6vPNqcg6jA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-react-display-name@7.29.7':
    -    resolution: {integrity: sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-react-jsx-development@7.29.7':
    -    resolution: {integrity: sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-react-jsx@7.29.7':
    -    resolution: {integrity: sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-react-pure-annotations@7.29.7':
    -    resolution: {integrity: sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-regenerator@7.29.7':
    -    resolution: {integrity: sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-regexp-modifiers@7.29.7':
    -    resolution: {integrity: sha512-mB5Fs0VWrJ42ZCmc8114v60qetdaUVNkj9PmSZRmanCZM3S9hm0CFRLjRmYIsuXav14l2jvZ+4T8iiCGnhj3nQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/plugin-transform-reserved-words@7.29.7':
    -    resolution: {integrity: sha512-5+YhdpVgmfSmwZyLMftfaiffLRMHjzIRHFHHLdibcSyJm2pasMrKHrO3Ptrt2DRshjvpgjEJJ1zVW14WPq/6QA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-shorthand-properties@7.29.7':
    -    resolution: {integrity: sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-spread@7.29.7':
    -    resolution: {integrity: sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-sticky-regex@7.29.7':
    -    resolution: {integrity: sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-template-literals@7.29.7':
    -    resolution: {integrity: sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-typeof-symbol@7.29.7':
    -    resolution: {integrity: sha512-223mNGoTkBiTEWFoK+Q6Go3tueMRclO8vxxxxquNCYuNI4jWOofFKJRRDu6SDrB8Sgo1UEGW9T4GAQ8ZyRso1A==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-unicode-escapes@7.29.7':
    -    resolution: {integrity: sha512-jCfXxSjf94lf4E0hKE0AByxF6F3/pVFqRdUUNkDJhsY0m1ZKjnN6ZYyMeHNpzflxb/0q5b7t3p+BE+SLF1WOtA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-unicode-property-regex@7.29.7':
    -    resolution: {integrity: sha512-OgZ+zoAJgZLUCunsTRQ5LAjOywDv5zzZ2/hQ5aMw1pGXyY2rtE8/chXYUmu3AlVHKpm10KEdG9aMwbI/K76ZGw==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-unicode-regex@7.29.7':
    -    resolution: {integrity: sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/plugin-transform-unicode-sets-regex@7.29.7':
    -    resolution: {integrity: sha512-BLOhLht9DOJwIxlmp91wHvkXv1lguuHS3/FwUO8HL1H0u8s4hR1gASVFyilu9iGtcTRYqjTZmlsFFeQletntEg==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -
    -  '@babel/preset-env@7.29.7':
    -    resolution: {integrity: sha512-GYzX36n1nsciIb0uyH0GHwxwtNwPQIcpxSeiVLDtG/B7jB5xXgchnmL1f/jCX5o+pwnaDBtO60ONSJhEBJfxYA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/preset-modules@0.1.6-no-external-plugins':
    -    resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0
    -
    -  '@babel/preset-react@7.29.7':
    -    resolution: {integrity: sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA==}
    -    engines: {node: '>=6.9.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0-0
    -
    -  '@babel/runtime@7.29.2':
    -    resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
    -    engines: {node: '>=6.9.0'}
    -
    -  '@babel/runtime@7.29.7':
    -    resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
    -    engines: {node: '>=6.9.0'}
    -
    -  '@babel/template@7.29.7':
    -    resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
    -    engines: {node: '>=6.9.0'}
    -
    -  '@babel/traverse@7.29.7':
    -    resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==}
    -    engines: {node: '>=6.9.0'}
    -
    -  '@babel/types@7.29.7':
    -    resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
    -    engines: {node: '>=6.9.0'}
    -
    -  '@bcoe/v8-coverage@0.2.3':
    -    resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
    -
    -  '@braintree/sanitize-url@7.1.2':
    -    resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==}
    -
    -  '@bramus/specificity@2.4.2':
    -    resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
    -    hasBin: true
    -
    -  '@bsv/auth-express-middleware@2.1.0':
    -    resolution: {integrity: sha512-pdVCr8GBx+xs39KHcoiyIcyuBXTpIB+VKZNykIaVfZzhUyTIMEv1zQ+y8WhonCsvc9B9jcFAeYVI7kZ8IF4Gxw==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/authsocket-client@2.1.0':
    -    resolution: {integrity: sha512-dm2HkXhIgGUDlBKCd7gfSnCJqM4PC3a5QbchT0d3IBizD7GJT8jBcFsnhPQ31EoV0NBFRUgBdptJucS8w8weCQ==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/btms@1.1.0':
    -    resolution: {integrity: sha512-eQBfAwg+0lLSmEirbrAMS6qAKxpkQAq0F5WjLnPPzKREe65Zn3VkXmjP165CqAlvtXPL0aE9GeGL2uHuSRyc6Q==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/gasp@1.3.0':
    -    resolution: {integrity: sha512-5hZxb71aY/TEGHsBkoWz9+bo6qj6YIbxLObBzagfV02Ny6eGUtPhov1MJ9SfmR6POUNM+r4pkACOZmDNSWLPZg==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/message-box-client@2.2.0':
    -    resolution: {integrity: sha512-l/bJOI9p2wetnsYaGcRbtn53soUuQxyqtH0AliyXWuKUY+aXUArAVjCmxy1Fkv+FGsa/uws8N0w/LyI3B7uDsA==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/overlay-discovery-services@2.1.0':
    -    resolution: {integrity: sha512-f1FjYZUpHkCIkaT/ISEyvHzMVHbCh84I9SEpqjh3JCy7bO9BWdFSnYdw+Eb77RuIKuCj+juaVUm4vbZ2KTxyKw==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/overlay@2.1.1':
    -    resolution: {integrity: sha512-eE50GCEKpxPGGvnvmN7SxRJtCQnZn0uvQrFDTLrs5gDFbh19BJDhV6h8/Tf48mLkpkbVYVYEI1/thw/wFUuizg==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2.1.6
    -
    -  '@bsv/payment-express-middleware@2.1.0':
    -    resolution: {integrity: sha512-tiYwQeT6nnVi0pas+SaxPwaOQH1230BbI1T61TQ0btj+/QykE5Jwc+Ae0X1VMh5uj0jiHyJrMkxQ6rbX0fQ3dg==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2
    -
    -  '@bsv/sdk@2.1.9':
    -    resolution: {integrity: sha512-pPbyDNYJJxShCBTiJc7krcZz8DGD2AetMK4CZf0uUMM3tq6M7IPHlqqbp2w4Ps8UGJgJDp8XjMkNLyjGSTe+9w==}
    -
    -  '@bsv/wallet-toolbox-client@2.3.3':
    -    resolution: {integrity: sha512-k+r6kYeYxm5eQZXAj5nRy37Rzrgm950Vw5GzlsxNFLU5x5vPySYT41rI4yI4ZPpXPNVKcorW4VGN4oPIibOWpA==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2.1.6
    -
    -  '@bsv/wallet-toolbox@2.3.3':
    -    resolution: {integrity: sha512-zfXjbz8OoJKT30MbZeHIybywWmmOwLFm1iW83QKdAfmyCS6Mwf1cRuaojQHlATtg9I64If6PIw5qAIgsI2dFkw==}
    -    peerDependencies:
    -      '@bsv/sdk': ^2.1.6
    -
    -  '@chainsafe/as-chacha20poly1305@0.1.0':
    -    resolution: {integrity: sha512-BpNcL8/lji/GM3+vZ/bgRWqJ1q5kwvTFmGPk7pxm/QQZDbaMI98waOHjEymTjq2JmdD/INdNBFOVSyJofXg7ew==}
    -
    -  '@chainsafe/as-sha256@1.2.4':
    -    resolution: {integrity: sha512-3GXDysZOKD6cTYbm48lEdXdUbS7cafjXQZfgHOspTByhoGR/JM3KBXyF3vE6bf63ImjNPyoEZwnQcpYPQ6k3bQ==}
    -
    -  '@chainsafe/is-ip@2.1.0':
    -    resolution: {integrity: sha512-KIjt+6IfysQ4GCv66xihEitBjvhU/bixbbbFxdJ1sqCp4uJ0wuZiYBPhksZoy4lfaF0k9cwNzY5upEW/VWdw3w==}
    -
    -  '@chainsafe/libp2p-gossipsub@14.1.2':
    -    resolution: {integrity: sha512-HuyB1dO+GwqpbvKhq2TdrsvrtNt19iOWLEfjy2N3ItYY1gA2F67KtCOLmZ1NlEcCbjFDg+qRffQMjgkDwHSFOg==}
    -    engines: {npm: '>=8.7.0'}
    -
    -  '@chainsafe/libp2p-noise@17.0.0':
    -    resolution: {integrity: sha512-vwrmY2Y+L1xYhIDiEpl61KHxwrLCZoXzTpwhyk34u+3+6zCAZPL3GxH3i2cs+u5IYNoyLptORdH17RKFXy7upA==}
    +  '@chainsafe/libp2p-noise@17.0.0':
    +    resolution: {integrity: sha512-vwrmY2Y+L1xYhIDiEpl61KHxwrLCZoXzTpwhyk34u+3+6zCAZPL3GxH3i2cs+u5IYNoyLptORdH17RKFXy7upA==}
     
       '@chainsafe/libp2p-yamux@8.0.1':
         resolution: {integrity: sha512-pJsqmUg1cZRJZn/luAtQaq0uLcVfExo51Rg7iRtAEceNYtsKUi/exfegnvTBzTnF1CGmTzVEV3MCLsRhqiNyoA==}
    @@ -2448,12 +1766,27 @@ packages:
       '@emnapi/core@1.10.0':
         resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
     
    +  '@emnapi/core@1.11.1':
    +    resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==}
    +
    +  '@emnapi/core@1.11.2':
    +    resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==}
    +
       '@emnapi/runtime@1.10.0':
         resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
     
    +  '@emnapi/runtime@1.11.1':
    +    resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==}
    +
    +  '@emnapi/runtime@1.11.2':
    +    resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==}
    +
       '@emnapi/wasi-threads@1.2.1':
         resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
     
    +  '@emnapi/wasi-threads@1.2.2':
    +    resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==}
    +
       '@esbuild/aix-ppc64@0.27.7':
         resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
         engines: {node: '>=18'}
    @@ -2766,66 +2099,15 @@ packages:
         cpu: [x64]
         os: [win32]
     
    -  '@eslint-community/eslint-utils@4.9.1':
    -    resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
    -
    -  '@eslint-community/regexpp@4.12.2':
    -    resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
    -    engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
    -
    -  '@eslint/config-array@0.23.5':
    -    resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  '@eslint/config-helpers@0.6.0':
    -    resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  '@eslint/core@1.2.1':
    -    resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  '@eslint/eslintrc@2.1.4':
    -    resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  '@eslint/js@10.0.1':
    -    resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -    peerDependencies:
    -      eslint: ^10.0.0
    -    peerDependenciesMeta:
    -      eslint:
    -        optional: true
    -
    -  '@eslint/js@8.57.1':
    -    resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  '@eslint/object-schema@3.0.5':
    -    resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  '@eslint/plugin-kit@0.7.2':
    -    resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  '@exodus/bytes@1.15.0':
    -    resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==}
    -    engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
    +  '@exodus/bytes@1.15.0':
    +    resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==}
    +    engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
         peerDependencies:
           '@noble/hashes': ^1.8.0 || ^2.0.0
         peerDependenciesMeta:
           '@noble/hashes':
             optional: true
     
    -  '@gar/promise-retry@1.0.3':
    -    resolution: {integrity: sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       '@hapi/address@5.1.1':
         resolution: {integrity: sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==}
         engines: {node: '>=14.0.0'}
    @@ -2846,51 +2128,6 @@ packages:
       '@hapi/topo@6.0.2':
         resolution: {integrity: sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==}
     
    -  '@humanfs/core@0.19.2':
    -    resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
    -    engines: {node: '>=18.18.0'}
    -
    -  '@humanfs/node@0.16.8':
    -    resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
    -    engines: {node: '>=18.18.0'}
    -
    -  '@humanfs/types@0.15.0':
    -    resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
    -    engines: {node: '>=18.18.0'}
    -
    -  '@humanwhocodes/config-array@0.13.0':
    -    resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
    -    engines: {node: '>=10.10.0'}
    -    deprecated: Use @eslint/config-array instead
    -
    -  '@humanwhocodes/module-importer@1.0.1':
    -    resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
    -    engines: {node: '>=12.22'}
    -
    -  '@humanwhocodes/object-schema@2.0.3':
    -    resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
    -    deprecated: Use @eslint/object-schema instead
    -
    -  '@humanwhocodes/retry@0.4.3':
    -    resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
    -    engines: {node: '>=18.18'}
    -
    -  '@hyperjump/json-pointer@0.9.8':
    -    resolution: {integrity: sha512-6D6okhpH5VOS3oSYUtxu8nClsOcp59aC+sS06/tCxEta4T5Gk1yaycLiCkG8kE9eh+9AJUHsvQEJJrWBfLOjvA==}
    -
    -  '@hyperjump/json-schema-core@0.28.5':
    -    resolution: {integrity: sha512-+f5P3oHYCQru3s+Ha+E10rIyEvyK0Hfa2oj3+cDoGaVMbT4Jg5TgCoIM7B5rl3t3KRA7EOmrLjKFGeLi5yd1pg==}
    -    deprecated: This package was rolled into @hyperjump/json-schema as of v1.0.0
    -
    -  '@hyperjump/json-schema@0.23.5':
    -    resolution: {integrity: sha512-gb1jOT6+BlZBR9Nc/tMGDt757YM7rjS71Dml3+TBYebdGOZlSrTzTfVAUfGzOlsceB3gP4K9b7HzAwEGMWmexQ==}
    -
    -  '@hyperjump/json@0.1.0':
    -    resolution: {integrity: sha512-jWsAOHjweWhi0UEBCN57YZzyTt76Z6Fm/OJXOfNBJbEZt569AcTRsjv6Dqj5t4gQhW9td72oquiyaVp9oHbhBQ==}
    -
    -  '@hyperjump/pact@0.2.5':
    -    resolution: {integrity: sha512-93m7gLf40EI8svsKrdPc+KkLsngwX/2ld08xwc0PFioxJSxnfkx1BUHNJVjhG386UUYP6mNe+ZtmIiDXDJ4TQg==}
    -
       '@iconify/types@2.0.0':
         resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
     
    @@ -2905,9 +2142,6 @@ packages:
         resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
         engines: {node: '>=18.0.0'}
     
    -  '@isaacs/string-locale-compare@1.1.0':
    -    resolution: {integrity: sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==}
    -
       '@istanbuljs/load-nyc-config@1.1.0':
         resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
         engines: {node: '>=8'}
    @@ -3030,27 +2264,6 @@ packages:
       '@jridgewell/trace-mapping@0.3.9':
         resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
     
    -  '@jsdevtools/ono@7.1.3':
    -    resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==}
    -
    -  '@jsep-plugin/assignment@1.3.0':
    -    resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==}
    -    engines: {node: '>= 10.16.0'}
    -    peerDependencies:
    -      jsep: ^0.4.0||^1.0.0
    -
    -  '@jsep-plugin/regex@1.0.4':
    -    resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==}
    -    engines: {node: '>= 10.16.0'}
    -    peerDependencies:
    -      jsep: ^0.4.0||^1.0.0
    -
    -  '@jsep-plugin/ternary@1.1.4':
    -    resolution: {integrity: sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==}
    -    engines: {node: '>= 10.16.0'}
    -    peerDependencies:
    -      jsep: ^0.4.0||^1.0.0
    -
       '@jsonjoy.com/base64@1.1.2':
         resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==}
         engines: {node: '>=10.0'}
    @@ -3171,26 +2384,17 @@ packages:
         peerDependencies:
           tslib: '2'
     
    -  '@juggle/resize-observer@3.4.0':
    -    resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
    -
    -  '@kwsites/file-exists@1.1.1':
    -    resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
    -
    -  '@kwsites/promise-deferred@1.1.1':
    -    resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
    -
       '@leichtgewicht/ip-codec@2.0.5':
         resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==}
     
    -  '@libp2p/bootstrap@12.0.25':
    -    resolution: {integrity: sha512-Q2CiaI9Zq2FUCmC7jt3OwgREEff29VB5+A4aw3I7z9qNwBUF7M53Gg77RL3cTvh5qhd9KngK7yUY1HwvxD6Ddw==}
    +  '@libp2p/bootstrap@12.0.27':
    +    resolution: {integrity: sha512-p6sIulcqA0esESAnwaMHfW2Nvs9pRj0OUWHriwDy3lssLNytpCnCppzG5wCqNxRPufrS10sxbwFyoFd6HRw9+Q==}
     
    -  '@libp2p/crypto@5.1.20':
    -    resolution: {integrity: sha512-sPz+CvDWPDb+O8xYsueXDdrV6Kf7PciNEYvcCjOR/VqM0iHwzC7aaM0xPiQqrUDj1nggswbY/E/vNZYJ4aCQaA==}
    +  '@libp2p/crypto@5.1.21':
    +    resolution: {integrity: sha512-GipsBinthJuk7DpwthTUixZHSaKogcxm2glPCP0VkYkEpzZrfEvBEekRvlP5+1Ak8pReaHcz4gPKFA9X6MG0WQ==}
     
    -  '@libp2p/identify@4.1.8':
    -    resolution: {integrity: sha512-qcquky5SjOqe1I83DHJMRwWFUmk6mqwqX8z0JMOVFcXe96czBZ3pbXMksOoUWsGvDSoTHygX0yYn07sVDF+uoQ==}
    +  '@libp2p/identify@4.1.10':
    +    resolution: {integrity: sha512-sD4n8avW/hZ5Du3ZuaNybS8jhBXzsMTeGO9dcwaF0BcHtDFIoYZ1kiMR8pxTePV4hB833TpBwlxhaxmIV1jX8g==}
     
       '@libp2p/interface-internal@2.3.19':
         resolution: {integrity: sha512-v335EB0i5CaNF+0SqT01CTBp0VyjJizpy46KprcshFFjX16UQ8+/QzoTZqmot9WiAmAzwR0b87oKmlAE9cpxzQ==}
    @@ -3198,47 +2402,53 @@ packages:
       '@libp2p/interface-internal@3.1.7':
         resolution: {integrity: sha512-5qzZOx1JU+CdT8UKLWKtM3LOQ3C9aSlRzVLJkLZXVN0ULhmctlAeZckPEEZ5z4pDtLpgFHjr+H9bd7NSTHqtVQ==}
     
    +  '@libp2p/interface-internal@3.1.9':
    +    resolution: {integrity: sha512-YLe27t4t/EWGkLX/S+sOPOc++iga44LGW2WJgxXaGGgMVc9G7C1/mUq+So1AyWxl+NqdvN9jbx03hqhrAo1ltA==}
    +
       '@libp2p/interface@2.11.0':
         resolution: {integrity: sha512-0MUFKoXWHTQW3oWIgSHApmYMUKWO/Y02+7Hpyp+n3z+geD4Xo2Rku2gYWmxcq+Pyjkz6Q9YjDWz3Yb2SoV2E8Q==}
     
    -  '@libp2p/interface@3.2.4':
    -    resolution: {integrity: sha512-o/ZMbsplniVQhz0AW1CinZcfZPEfr7ttu4w7aivrFAs6xDpnJYmN3FTeEgTt93EHs+AEOcIT76V3KMFDZmIEcQ==}
    +  '@libp2p/interface@3.2.5':
    +    resolution: {integrity: sha512-RdTchTdakBBc4ShKKsvoME/bJYsrCoVDpdYQVdd4TQ30TCb8QwWKGClqAtw7gfLNuaUKm41xz06kASW6AZpbDA==}
     
    -  '@libp2p/kad-dht@16.3.3':
    -    resolution: {integrity: sha512-G5BOmuExm/ACP2jx557yZmXhylztyDNLpYsKGCj91Sq7dTvP+EIe4+n0LkKKt//AqHscaQQT2B96RHp5SNOmUw==}
    +  '@libp2p/kad-dht@16.4.0':
    +    resolution: {integrity: sha512-2c2NRjYZU07B/CfGOg8sKBzGfnSW6zJH27WT98GbaCg5vGwbMWW3s3rQ+Hgq/BQN+4cPOXPp2TT2WTz4mZEjKw==}
     
       '@libp2p/logger@5.2.0':
         resolution: {integrity: sha512-OEFS529CnIKfbWEHmuCNESw9q0D0hL8cQ8klQfjIVPur15RcgAEgc1buQ7Y6l0B6tCYg120bp55+e9tGvn8c0g==}
     
    +  '@libp2p/logger@6.2.10':
    +    resolution: {integrity: sha512-recRqNABHG32YXvpMvNepFCuU14d51dF5hs+vR2C/tkqXBQc0Sqg5LtWB2NYPoIJV+JUB50iWLrvBXZUOjLc9Q==}
    +
       '@libp2p/logger@6.2.9':
         resolution: {integrity: sha512-hjuF81KSt9dWNPJZcdJ4SHEuygMLHrPZVTGNzCWu+2jxpJqOHWy9CJS8llLH7pgbDtlq4jJ4uuqihCR5Gjo4gA==}
     
    -  '@libp2p/multistream-select@7.0.22':
    -    resolution: {integrity: sha512-KJ1/i6NVAdPjsGFByB7eECW1j/c54nZIfCyDH3/gl4cLX+l1Pnkm2AgLRuk/3D/tNNVjsSJC2VOwJg6Z8NW3ww==}
    +  '@libp2p/multistream-select@7.0.24':
    +    resolution: {integrity: sha512-upJO+r79XYI0IxEVpTpCW3gK1fxLIoZEywO2N0kn2zwcYSNMqCNe9Ahm1YfRJLTFhusVRue9k4SAMyHvWiAXOA==}
     
       '@libp2p/peer-collections@6.0.35':
         resolution: {integrity: sha512-QiloK3T7DXW7R2cpL38dBnALCHf5pMzs/TyFzlEK33WezA2YFVoj7CtOJKqbn29bmV9uspWOxMgfmLUXf8ALvA==}
     
    -  '@libp2p/peer-collections@7.0.22':
    -    resolution: {integrity: sha512-46Mq8ly8uqcpnADo0wWqTEuP8tRDyRtxz/CbTwVSZfz6TbRM/nIRlhoxZu8EIrYBqBZAu3F+3EB7hrzJDyUerQ==}
    +  '@libp2p/peer-collections@7.0.24':
    +    resolution: {integrity: sha512-RBwYVj0gtO1VMjxjjlAzHqztB9fJyL/U3G5vJrpHdXWtGlXs5ZzpkW65nGXkBExKpoGRAV59WIkOOeRDiX9c2Q==}
     
       '@libp2p/peer-id@5.1.9':
         resolution: {integrity: sha512-cVDp7lX187Epmi/zr0Qq2RsEMmueswP9eIxYSFoMcHL/qcvRFhsxOfUGB8361E26s2WJvC9sXZ0oJS9XVueJhQ==}
     
    -  '@libp2p/peer-id@6.0.11':
    -    resolution: {integrity: sha512-p2Sw8y12gcrmDYGTrbvGQzMhM7ypquCfQX5WdhitI0+ArTSRHHXt7ozdpUWzcq7CNaK5r2q6FIbpz9Yxywg9Hw==}
    +  '@libp2p/peer-id@6.0.12':
    +    resolution: {integrity: sha512-U44MeKs+U1SqZPqS0RDzjjcS9ERix2zJsJkTcqi8I+5flEz4uVAObBDxvkkaTaqRFRXCXEPjL5kA4UbgVubCZQ==}
     
    -  '@libp2p/peer-record@9.0.12':
    -    resolution: {integrity: sha512-tYGHo9gSO1ZqQripsEtpzxMrWDnmCMgFe8c1TKcml8dZUBCAsM9k5js25RKb0HA1aqZ2VX54XPFazpbjVs3tow==}
    +  '@libp2p/peer-record@9.0.13':
    +    resolution: {integrity: sha512-lkdZUNC6h86YECpRE3dB4GLYSiLLuXFBleiM01oEmWtAdTCfRd+vRqNkguSoC6R3tGk/YWRm7cfz39ATPuq7zQ==}
     
    -  '@libp2p/peer-store@12.0.22':
    -    resolution: {integrity: sha512-LoBq4uZp5TvPVcU1DtEsuBEC8Fcq1sprgY+KBoIoecL2bsUpCaQsbPIqbByLR6hCfDgWPv5ChFvIoZwn3YCyDw==}
    +  '@libp2p/peer-store@12.0.24':
    +    resolution: {integrity: sha512-OjyHJoHioCUK3hwfH5Ew5YRzViE0mA8lH/Wl0giQpNmV9H0FVLdlgoq2qDjOk4f6iG/Zpk99MOa4GGra5tAbKg==}
     
    -  '@libp2p/ping@3.1.7':
    -    resolution: {integrity: sha512-CJHX7BELM0iB16BayHYA/Tzi+BSrveAMKF5EkNMU0+XNIMgA5A/1G7Yh/VC11N5RUJmk07eYFZQBEQavfoCgNA==}
    +  '@libp2p/ping@3.1.9':
    +    resolution: {integrity: sha512-X4DbDegzSScE1C16p/9OBZg+SRULDPSPeqHxqUjs3qoFEN1UvLws4pAMwpH4ixMoM3DYDY4+ijvtYaVBBj3ZLw==}
     
    -  '@libp2p/pnet@3.0.23':
    -    resolution: {integrity: sha512-JvziWSTqzjwv6J5Kczjxw2bkHBisPiUrnuMFLmP2hle28o/uuhMNQniBytaRmJYXjRBpgKA5Q2rs6GPU8Vx+tg==}
    +  '@libp2p/pnet@3.0.25':
    +    resolution: {integrity: sha512-YBteYjD72p2CIqLkIE5EBGyE+zd6kB7TiHCKAEjaMFNH2aecByuGUALkQzyXn2P+7nvGyvAjkFZVI9B10LLmZw==}
     
       '@libp2p/pubsub-peer-discovery@12.0.0':
         resolution: {integrity: sha512-72sZwTDBH/iowRumycPLjSlaUd3cwQcjSN2xUagdzNtMt9ryWt7dL4fDGM+VsktSdYmzzOHhL9ZftNfUk7XG7A==}
    @@ -3246,11 +2456,11 @@ packages:
       '@libp2p/pubsub@10.1.18':
         resolution: {integrity: sha512-Bxa0cwkaQvadyJNlJlzH0m1eo7m03G2nCpuKbcv+i0qNbyyTOydBcuoslG/UWFYhRBB9Js9R6zNIsaIgpo+iGw==}
     
    -  '@libp2p/record@4.0.14':
    -    resolution: {integrity: sha512-YObHdE1dkAiVDPR+YHIFcCD5YMppP0lj2shnMj0L5PgLka8lnZgaY5AjiQo+DMvLFhRvNIMHyxlE9WQUbrM1wA==}
    +  '@libp2p/record@4.0.15':
    +    resolution: {integrity: sha512-EaHFtQAlZuM9vCpd+0KnZhTVgV26Uzje7DkyUseGNKTy+Wit9Q94C/+wDThpZuRHnK1FH/CvPxJ4kLj7AoQ1WA==}
     
    -  '@libp2p/tcp@11.0.22':
    -    resolution: {integrity: sha512-q1jeWt0XMk6uZQrNOE9YBPciQPgGdNEroD3Wf/TOf2DvzRHpiG6nyMxS3HFdrlCOnuyxlvpMl4jfCh+YGjdxQw==}
    +  '@libp2p/tcp@11.0.24':
    +    resolution: {integrity: sha512-tRnrl5jD6e6nWUHd++cXYbGiF8+eCK8a0NPNn9Z9hO4Or9lsK9ZfYTBPmjRbF0laJEgem92j2CIPcBihtn8mPA==}
     
       '@libp2p/utils@6.7.2':
         resolution: {integrity: sha512-yglVPcYErb4al3MMTdedVLLsdUvr5KaqrrxohxTl/FXMFBvBs0o3w8lo29nfnTUpnNSHFhWZ9at0ZGNnpT/C/w==}
    @@ -3258,6 +2468,9 @@ packages:
       '@libp2p/utils@7.2.3':
         resolution: {integrity: sha512-7RN1UtSYga3LbpOuW5XsMseQIGawrz5jfWFsgQGI9B130VA6UXKHhzgQbDGHfXLjoNv2RWALp8u6laUvcL65lg==}
     
    +  '@libp2p/utils@7.3.0':
    +    resolution: {integrity: sha512-7mDQQVutmz6LsrehO9W12RI0Hwnx/zQzqlsj1DB0/2vHf8As/4jEntoEM8ko6RAOaDQ7Y5OrJ2Fgd7O9gyVRkA==}
    +
       '@mdx-js/mdx@3.1.1':
         resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
     
    @@ -3272,11 +2485,11 @@ packages:
         peerDependencies:
           rollup: '>=2'
     
    -  '@mermaid-js/parser@1.1.1':
    -    resolution: {integrity: sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==}
    +  '@mermaid-js/parser@1.2.0':
    +    resolution: {integrity: sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==}
     
    -  '@mongodb-js/saslprep@1.4.9':
    -    resolution: {integrity: sha512-RXSxsokhAF/4nWys8An8npsqOI33Ex1Hlzqjw2pZOO+GKtMAR2noGnUdsFiGwsaO/xXI+56mtjTmDA3JXJsvmA==}
    +  '@mongodb-js/saslprep@1.4.12':
    +    resolution: {integrity: sha512-QAfAMwNgnYxZ2C6D1HgeP7Gc4i/uvJRim415PCIL9ptRxWMNbWeLBYb2/9R4pGKny/s1FVu2JA2cxCUBUOggrA==}
     
       '@multiformats/dns@1.0.13':
         resolution: {integrity: sha512-yr4bxtA3MbvJ+2461kYIYMsiiZj/FIqKI64hE4SdvWJUdWF9EtZLar38juf20Sf5tguXKFUruluswAO6JsjS2w==}
    @@ -3290,14 +2503,8 @@ packages:
       '@multiformats/multiaddr@13.0.3':
         resolution: {integrity: sha512-mEqqJ4r3a/uuFMTpRkU316wGNIDQNhuVWpm+ebKTQeYsfv9jXbPONWM6VVnj3KGUrwfsX7GZOyp4TFqEA2SPCw==}
     
    -  '@napi-rs/wasm-runtime@1.1.4':
    -    resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
    -    peerDependencies:
    -      '@emnapi/core': ^1.7.1
    -      '@emnapi/runtime': ^1.7.1
    -
    -  '@napi-rs/wasm-runtime@1.1.5':
    -    resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==}
    +  '@napi-rs/wasm-runtime@1.1.6':
    +    resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
         peerDependencies:
           '@emnapi/core': ^1.7.1
           '@emnapi/runtime': ^1.7.1
    @@ -3322,112 +2529,134 @@ packages:
         resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==}
         engines: {node: '>= 20.19.0'}
     
    -  '@nodable/entities@3.0.0':
    -    resolution: {integrity: sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==}
    -
    -  '@nodelib/fs.scandir@2.1.5':
    -    resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
    -    engines: {node: '>= 8'}
    -
    -  '@nodelib/fs.stat@2.0.5':
    -    resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
    -    engines: {node: '>= 8'}
    -
    -  '@nodelib/fs.walk@1.2.8':
    -    resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
    -    engines: {node: '>= 8'}
    -
    -  '@npmcli/agent@4.0.2':
    -    resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@npmcli/arborist@9.8.0':
    -    resolution: {integrity: sha512-bqjei/1+uait6wA30G7IElMs5VCyGpuVPFQYsvzqhTEEAVmDMsHBCFstcT2lLfeQDvi8MeUQHStfHSArvdTQuw==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -    hasBin: true
    -
    -  '@npmcli/config@8.3.4':
    -    resolution: {integrity: sha512-01rtHedemDNhUXdicU7s+QYz/3JyV5Naj84cvdXGH4mgCdL+agmSYaLF4LUG4vMCLzhBO8YtS0gPpH1FGvbgAw==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    +  '@opentelemetry/api@1.9.1':
    +    resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
    +    engines: {node: '>=8.0.0'}
     
    -  '@npmcli/fs@5.0.0':
    -    resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxc-project/types@0.139.0':
    +    resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==}
     
    -  '@npmcli/git@5.0.8':
    -    resolution: {integrity: sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    +  '@oxlint/binding-android-arm-eabi@1.75.0':
    +    resolution: {integrity: sha512-lutovtFzJqlRaqpZrCqSSGaHZzl9nIxxpjLzhSRLunN6dCLylj0uzlCyQGaQDIys7rrv8kVXiFO+R4Zpn0bX7g==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [android]
     
    -  '@npmcli/git@7.0.2':
    -    resolution: {integrity: sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-android-arm64@1.75.0':
    +    resolution: {integrity: sha512-hXI0hDgHkw4w5nfru72aG7y+2iQJmC4waH/KV6H/hbgA6yAP5jYNx0P9yug15Hs0tWl/+mda3Jjn/2gmDT48tw==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [android]
     
    -  '@npmcli/installed-package-contents@4.0.0':
    -    resolution: {integrity: sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -    hasBin: true
    +  '@oxlint/binding-darwin-arm64@1.75.0':
    +    resolution: {integrity: sha512-D91BWbK/dMYfCcrghspPIuKs2D9LF4Z/OabVSQjw1AO6PWxArD7teDA48bm0ySFqWDaPVqmQRl5GMWNglTXyrQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [darwin]
     
    -  '@npmcli/map-workspaces@3.0.6':
    -    resolution: {integrity: sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    +  '@oxlint/binding-darwin-x64@1.75.0':
    +    resolution: {integrity: sha512-02mpwzf12BonZ6PT0TuQoomvEh2kVl2WGBIKWezCyToIS+rYkQZ6GXnARBAl9A4Ovm2V+Xe7M4KretyqmmcnJQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [darwin]
     
    -  '@npmcli/map-workspaces@5.0.3':
    -    resolution: {integrity: sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-freebsd-x64@1.75.0':
    +    resolution: {integrity: sha512-qZJgLnDaBsiL5YESx2t/TZ8eXkL9fEkKoXEdzegROhlz9A0lgyGnZ0dAzJrh7LJAHQl2K9RdRueN2s/9N7+odg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [freebsd]
     
    -  '@npmcli/metavuln-calculator@9.0.3':
    -    resolution: {integrity: sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-arm-gnueabihf@1.75.0':
    +    resolution: {integrity: sha512-7XlaWA5BJD3XpCfrEqjEe6Zseeb14S7QGa304XfwKignRaKQ+eIj775BQ7nIslggWickl4IsPUFqJ+/gAyNHVg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [linux]
     
    -  '@npmcli/name-from-folder@2.0.0':
    -    resolution: {integrity: sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    +  '@oxlint/binding-linux-arm-musleabihf@1.75.0':
    +    resolution: {integrity: sha512-av6Tpv8yrcMMMOadOqENBhlsLRcGFXXwoQ0hzHhsmS9FJ4Wioy8we427GbcMe2XTxmL2e60T67H1Dyr3up+tAA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm]
    +    os: [linux]
     
    -  '@npmcli/name-from-folder@4.0.0':
    -    resolution: {integrity: sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-arm64-gnu@1.75.0':
    +    resolution: {integrity: sha512-WcUhd8fHT5plrA14lANevl+hOl815mVI5t2hU21oFWrZKFXIVV/Sr4rWQV0NzSvzBupbMLNc5ErEA6Ehxh5jMg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [linux]
    +    libc: [glibc]
     
    -  '@npmcli/node-gyp@5.0.0':
    -    resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-arm64-musl@1.75.0':
    +    resolution: {integrity: sha512-UWzp5wRHFe/ESO3+eEaxXsTkYTGLYjnTsi/I5neEacXSItQ6WNleapfOAeA4x2b8nyhJ4uQxqvtv9pHv8kWJtQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [linux]
    +    libc: [musl]
     
    -  '@npmcli/package-json@5.2.1':
    -    resolution: {integrity: sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    +  '@oxlint/binding-linux-ppc64-gnu@1.75.0':
    +    resolution: {integrity: sha512-XEVRwGMLKCUKrvhLAz4F6AIh8MJrQVdSZtAmPpRZt9tGPsUnamPOcl3dS/ZQzJnar/Ymgc//+xho0L60Emzuxg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [ppc64]
    +    os: [linux]
    +    libc: [glibc]
     
    -  '@npmcli/package-json@7.0.5':
    -    resolution: {integrity: sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-riscv64-gnu@1.75.0':
    +    resolution: {integrity: sha512-mAG4DUXqfLC8cTjMD2kt3jDmVzFREYtDyeLNdLdsCcBc4Zbl2EMuiFektGBilQwkNjYnMvCqJs55U+Hyb+b+jw==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [riscv64]
    +    os: [linux]
    +    libc: [glibc]
     
    -  '@npmcli/promise-spawn@7.0.2':
    -    resolution: {integrity: sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    +  '@oxlint/binding-linux-riscv64-musl@1.75.0':
    +    resolution: {integrity: sha512-95hrAvriAlI+pekSomTFIn0+bawMDlDwTNVmdjsFusTHyL2JWh7TWvRNG/Lkim72uN8OiCcO9wcaC6omLP5E3w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [riscv64]
    +    os: [linux]
    +    libc: [musl]
     
    -  '@npmcli/promise-spawn@9.0.1':
    -    resolution: {integrity: sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-s390x-gnu@1.75.0':
    +    resolution: {integrity: sha512-4b6f2+FrtruAESrCqIKcrarzfrSx+wk2QNcp+RT91/Prc+pMQMAfyZ1rG1c3tFQNl8Bc616tx40uNXyxNBRPbQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [s390x]
    +    os: [linux]
    +    libc: [glibc]
     
    -  '@npmcli/query@5.0.0':
    -    resolution: {integrity: sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-x64-gnu@1.75.0':
    +    resolution: {integrity: sha512-nshAhrUvXFUWOvqQ2soIw7HFNWvpvEV4o0cYSqPtzLiPF5gKyYTDOOTJ6Rn8g8K/iGvPIrbDA4v8+5MvnjJrrg==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [linux]
    +    libc: [glibc]
     
    -  '@npmcli/redact@4.0.0':
    -    resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-linux-x64-musl@1.75.0':
    +    resolution: {integrity: sha512-e4jNxLKnxLC6sYBQRxrI2pgIIxnmMtF8U/VwNYcjTT/CLS+spH624cYVnj07bTKwaEWT37/e025isOs6j/0xqA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [linux]
    +    libc: [musl]
     
    -  '@npmcli/run-script@10.0.4':
    -    resolution: {integrity: sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    +  '@oxlint/binding-openharmony-arm64@1.75.0':
    +    resolution: {integrity: sha512-hZ2lH+1qLf/DiEP9UWuQTK2JWj/BgvMB4jhIV4SmNU1wfEiYYX4TynQyAZXx0j9X4qRYizAL042SKaV+8ynh4w==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [openharmony]
     
    -  '@openapi-contrib/openapi-schema-to-json-schema@3.2.0':
    -    resolution: {integrity: sha512-Gj6C0JwCr8arj0sYuslWXUBSP/KnUlEGnPW4qxlXvAl543oaNQgMgIgkQUA6vs5BCCvwTEiL8m/wdWzfl4UvSw==}
    +  '@oxlint/binding-win32-arm64-msvc@1.75.0':
    +    resolution: {integrity: sha512-Ilj6PNzGDS3bCU0MSJH7Msh0NhH+T/mRp2shwg+q+GHeVlPwP5LEboW96aW+3kVKFk6zYZy1Xi5pZkqZh6X8KQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [arm64]
    +    os: [win32]
     
    -  '@opentelemetry/api@1.9.1':
    -    resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
    -    engines: {node: '>=8.0.0'}
    +  '@oxlint/binding-win32-ia32-msvc@1.75.0':
    +    resolution: {integrity: sha512-QVit2nOEOiPhkmsrksPSkoGCdnZRNkspt8fwoYyP09te1VEbnSj4LAxua4rc8FKTmWkySVe05j8iz9GXYfF1AQ==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [ia32]
    +    os: [win32]
     
    -  '@oxc-project/types@0.133.0':
    -    resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==}
    +  '@oxlint/binding-win32-x64-msvc@1.75.0':
    +    resolution: {integrity: sha512-DSxnNkBUAYARPwJtR12Ig3deWr8w0H997xP6jy33i+e0SyYJw8FKuz4+cZtpmPEhQmvlPJE3X/2vNxDmLkd/rA==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    cpu: [x64]
    +    os: [win32]
     
       '@pagefind/darwin-arm64@1.5.2':
         resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==}
    @@ -3467,92 +2696,86 @@ packages:
       '@paralleldrive/cuid2@2.3.1':
         resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==}
     
    -  '@parcel/watcher-android-arm64@2.5.6':
    -    resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
    +  '@parcel/watcher-android-arm64@2.6.0':
    +    resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm64]
         os: [android]
     
    -  '@parcel/watcher-darwin-arm64@2.5.6':
    -    resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==}
    +  '@parcel/watcher-darwin-arm64@2.6.0':
    +    resolution: {integrity: sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm64]
         os: [darwin]
     
    -  '@parcel/watcher-darwin-x64@2.5.6':
    -    resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==}
    +  '@parcel/watcher-darwin-x64@2.6.0':
    +    resolution: {integrity: sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==}
         engines: {node: '>= 10.0.0'}
         cpu: [x64]
         os: [darwin]
     
    -  '@parcel/watcher-freebsd-x64@2.5.6':
    -    resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==}
    +  '@parcel/watcher-freebsd-x64@2.6.0':
    +    resolution: {integrity: sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==}
         engines: {node: '>= 10.0.0'}
         cpu: [x64]
         os: [freebsd]
     
    -  '@parcel/watcher-linux-arm-glibc@2.5.6':
    -    resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==}
    +  '@parcel/watcher-linux-arm-glibc@2.6.0':
    +    resolution: {integrity: sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm]
         os: [linux]
         libc: [glibc]
     
    -  '@parcel/watcher-linux-arm-musl@2.5.6':
    -    resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
    +  '@parcel/watcher-linux-arm-musl@2.6.0':
    +    resolution: {integrity: sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm]
         os: [linux]
         libc: [musl]
     
    -  '@parcel/watcher-linux-arm64-glibc@2.5.6':
    -    resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
    +  '@parcel/watcher-linux-arm64-glibc@2.6.0':
    +    resolution: {integrity: sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@parcel/watcher-linux-arm64-musl@2.5.6':
    -    resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
    +  '@parcel/watcher-linux-arm64-musl@2.6.0':
    +    resolution: {integrity: sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@parcel/watcher-linux-x64-glibc@2.5.6':
    -    resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
    +  '@parcel/watcher-linux-x64-glibc@2.6.0':
    +    resolution: {integrity: sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==}
         engines: {node: '>= 10.0.0'}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@parcel/watcher-linux-x64-musl@2.5.6':
    -    resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
    +  '@parcel/watcher-linux-x64-musl@2.6.0':
    +    resolution: {integrity: sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==}
         engines: {node: '>= 10.0.0'}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@parcel/watcher-win32-arm64@2.5.6':
    -    resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
    +  '@parcel/watcher-win32-arm64@2.6.0':
    +    resolution: {integrity: sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==}
         engines: {node: '>= 10.0.0'}
         cpu: [arm64]
         os: [win32]
     
    -  '@parcel/watcher-win32-ia32@2.5.6':
    -    resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==}
    -    engines: {node: '>= 10.0.0'}
    -    cpu: [ia32]
    -    os: [win32]
    -
    -  '@parcel/watcher-win32-x64@2.5.6':
    -    resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==}
    +  '@parcel/watcher-win32-x64@2.6.0':
    +    resolution: {integrity: sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==}
         engines: {node: '>= 10.0.0'}
         cpu: [x64]
         os: [win32]
     
    -  '@parcel/watcher@2.5.6':
    -    resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==}
    +  '@parcel/watcher@2.6.0':
    +    resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==}
         engines: {node: '>= 10.0.0'}
     
       '@peculiar/asn1-cms@2.7.0':
    @@ -3596,42 +2819,15 @@ packages:
         resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
         engines: {node: '>=14'}
     
    -  '@pkgr/core@0.2.9':
    -    resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
    -    engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
    +  '@pkgr/core@0.3.6':
    +    resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==}
    +    engines: {node: ^14.18.0 || >=16.0.0}
     
       '@polka/url@1.0.0-next.29':
         resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
     
    -  '@protobufjs/aspromise@1.1.2':
    -    resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
    -
    -  '@protobufjs/base64@1.1.2':
    -    resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
    -
    -  '@protobufjs/codegen@2.0.5':
    -    resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==}
    -
    -  '@protobufjs/eventemitter@1.1.1':
    -    resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==}
    -
    -  '@protobufjs/fetch@1.1.1':
    -    resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==}
    -
    -  '@protobufjs/float@1.0.2':
    -    resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
    -
    -  '@protobufjs/path@1.1.2':
    -    resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
    -
    -  '@protobufjs/pool@1.1.0':
    -    resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
    -
    -  '@protobufjs/utf8@1.1.1':
    -    resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==}
    -
    -  '@puppeteer/browsers@2.13.0':
    -    resolution: {integrity: sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==}
    +  '@puppeteer/browsers@2.13.2':
    +    resolution: {integrity: sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==}
         engines: {node: '>=18'}
         hasBin: true
     
    @@ -3639,97 +2835,97 @@ packages:
         resolution: {integrity: sha512-4An71tdz9X8+3sI4Qqqd2LWd9vS39J7sqd9EU4Scw7TJE/qB10Flv/UuqbPVgfQV9XoK8Np6jNquZitnZq5i+Q==}
         engines: {node: '>=14.0.0'}
     
    -  '@rolldown/binding-android-arm64@1.0.3':
    -    resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==}
    +  '@rolldown/binding-android-arm64@1.1.5':
    +    resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [android]
     
    -  '@rolldown/binding-darwin-arm64@1.0.3':
    -    resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==}
    +  '@rolldown/binding-darwin-arm64@1.1.5':
    +    resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [darwin]
     
    -  '@rolldown/binding-darwin-x64@1.0.3':
    -    resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==}
    +  '@rolldown/binding-darwin-x64@1.1.5':
    +    resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [darwin]
     
    -  '@rolldown/binding-freebsd-x64@1.0.3':
    -    resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==}
    +  '@rolldown/binding-freebsd-x64@1.1.5':
    +    resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [freebsd]
     
    -  '@rolldown/binding-linux-arm-gnueabihf@1.0.3':
    -    resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==}
    +  '@rolldown/binding-linux-arm-gnueabihf@1.1.5':
    +    resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm]
         os: [linux]
     
    -  '@rolldown/binding-linux-arm64-gnu@1.0.3':
    -    resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==}
    +  '@rolldown/binding-linux-arm64-gnu@1.1.5':
    +    resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@rolldown/binding-linux-arm64-musl@1.0.3':
    -    resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==}
    +  '@rolldown/binding-linux-arm64-musl@1.1.5':
    +    resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@rolldown/binding-linux-ppc64-gnu@1.0.3':
    -    resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==}
    +  '@rolldown/binding-linux-ppc64-gnu@1.1.5':
    +    resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [ppc64]
         os: [linux]
         libc: [glibc]
     
    -  '@rolldown/binding-linux-s390x-gnu@1.0.3':
    -    resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==}
    +  '@rolldown/binding-linux-s390x-gnu@1.1.5':
    +    resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [s390x]
         os: [linux]
         libc: [glibc]
     
    -  '@rolldown/binding-linux-x64-gnu@1.0.3':
    -    resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==}
    +  '@rolldown/binding-linux-x64-gnu@1.1.5':
    +    resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@rolldown/binding-linux-x64-musl@1.0.3':
    -    resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==}
    +  '@rolldown/binding-linux-x64-musl@1.1.5':
    +    resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@rolldown/binding-openharmony-arm64@1.0.3':
    -    resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==}
    +  '@rolldown/binding-openharmony-arm64@1.1.5':
    +    resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [openharmony]
     
    -  '@rolldown/binding-wasm32-wasi@1.0.3':
    -    resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==}
    +  '@rolldown/binding-wasm32-wasi@1.1.5':
    +    resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [wasm32]
     
    -  '@rolldown/binding-win32-arm64-msvc@1.0.3':
    -    resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==}
    +  '@rolldown/binding-win32-arm64-msvc@1.1.5':
    +    resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [arm64]
         os: [win32]
     
    -  '@rolldown/binding-win32-x64-msvc@1.0.3':
    -    resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==}
    +  '@rolldown/binding-win32-x64-msvc@1.1.5':
    +    resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         cpu: [x64]
         os: [win32]
    @@ -3737,23 +2933,6 @@ packages:
       '@rolldown/pluginutils@1.0.1':
         resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
     
    -  '@rollup/plugin-babel@5.3.1':
    -    resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
    -    engines: {node: '>= 10.0.0'}
    -    peerDependencies:
    -      '@babel/core': ^7.0.0
    -      '@types/babel__core': ^7.1.9
    -      rollup: ^1.20.0||^2.0.0
    -    peerDependenciesMeta:
    -      '@types/babel__core':
    -        optional: true
    -
    -  '@rollup/pluginutils@3.1.0':
    -    resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
    -    engines: {node: '>= 8.0.0'}
    -    peerDependencies:
    -      rollup: ^1.20.0||^2.0.0
    -
       '@rollup/pluginutils@5.3.0':
         resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
         engines: {node: '>=14.0.0'}
    @@ -3901,64 +3080,76 @@ packages:
         cpu: [x64]
         os: [win32]
     
    -  '@rspack/binding-darwin-arm64@2.0.8':
    -    resolution: {integrity: sha512-vCgbgH7B7qom+uID+RCZsTCOYFb9wC4/4+1U6rMfytrXGVJ72eNQs2tbdjOl0lb18CT3N/n+VkWynUiLk84GwA==}
    +  '@rspack/binding-darwin-arm64@2.1.5':
    +    resolution: {integrity: sha512-XLAN6YSU36qkciJtV9DY9z57pdHOjKy/f1HyoqpZenRg8p46jnXPziV45lfrTZpG+FF6g/jtTUc4dKbeyoWqPw==}
         cpu: [arm64]
         os: [darwin]
     
    -  '@rspack/binding-darwin-x64@2.0.8':
    -    resolution: {integrity: sha512-satPm2PD4B7jDTVlVAdvMVdUszwLvWUEnUDzLb77mvVkezKNDZmuhb+e8s+FfKs8hJpNbZ9VAejuA2rr8o985w==}
    +  '@rspack/binding-darwin-x64@2.1.5':
    +    resolution: {integrity: sha512-KLW7PV86jyCOyqJSqrkZdvYUWYCFX/Q4LsGmVc8tyDA8jBYLMHJDewC/lNf9ot3rU2SoLDZKhDUh7q7dX0FRmg==}
         cpu: [x64]
         os: [darwin]
     
    -  '@rspack/binding-linux-arm64-gnu@2.0.8':
    -    resolution: {integrity: sha512-pSI+npPQE/uDtiboqvcOIRJbEV2+B+H1xffmko/gw50la92oTUW60kVULFwsb6L0+GVCzIcwX3yq60GtYIn+Ug==}
    +  '@rspack/binding-linux-arm64-gnu@2.1.5':
    +    resolution: {integrity: sha512-KOooAC8L+Ljx5sY7ZuMeaXCQ310FNWaPWXcYQJpFPApF3qyLeSfuOftUGwxcxeo5U0mS5OY3zxp7/5CaHWKYjg==}
         cpu: [arm64]
         os: [linux]
         libc: [glibc]
     
    -  '@rspack/binding-linux-arm64-musl@2.0.8':
    -    resolution: {integrity: sha512-igjJ43yxWQ72GZqjDDZSSHax9/Vg+6rLMmOvFglTJUkQpB4Tyvu/YjW+WRjYj2xRw6blOjLxUSJWASvuSqqlvg==}
    +  '@rspack/binding-linux-arm64-musl@2.1.5':
    +    resolution: {integrity: sha512-0GFc07gT71+uRbHtejDecBfSL0fs7dQAwCtXYieXboACauL7UvS3Hwr6v8A91aGtAcvLotnCaIa3CWWYwtYlYQ==}
         cpu: [arm64]
         os: [linux]
         libc: [musl]
     
    -  '@rspack/binding-linux-x64-gnu@2.0.8':
    -    resolution: {integrity: sha512-zrkoEOnqj1hOEBO5T2I/2Ts2HSJsYFh1qXwMpK4dMJFGGNWDfNeUa6/LF5uq3VINF3JUl7RL47AgrucoSZJXPA==}
    +  '@rspack/binding-linux-riscv64-gnu@2.1.5':
    +    resolution: {integrity: sha512-isQQDp3fBzPSZpLVFzPqVXIVA4I9b9mKs58TfUgOzDP/1g1582YSV3iFopgFogvEliihXDuuXvM6aAkP+w8Z+Q==}
    +    cpu: [riscv64]
    +    os: [linux]
    +    libc: [glibc]
    +
    +  '@rspack/binding-linux-riscv64-musl@2.1.5':
    +    resolution: {integrity: sha512-/SP6VknY4kH60BYplI2FDNAJCo4U4DUszLxhKsgVlgA5ImgHC8Ew2AsKgidk7ceiYV9OcKzYuWYe9tVpysBYVA==}
    +    cpu: [riscv64]
    +    os: [linux]
    +    libc: [musl]
    +
    +  '@rspack/binding-linux-x64-gnu@2.1.5':
    +    resolution: {integrity: sha512-/GJmS+buA4pilT10gs5mfAhAZxSHXpDD8veZ3QpYvNUuoU9gvempAq9TgjbyNN/vc5pf76GdXPXKFMiehudYSA==}
         cpu: [x64]
         os: [linux]
         libc: [glibc]
     
    -  '@rspack/binding-linux-x64-musl@2.0.8':
    -    resolution: {integrity: sha512-6CtDaGZjNDvJd9TBp7a9zABbrPORO21W96+3ZcGBn0YNUPUk4ARxIxrTTpeJ/1F41QDM8AYIkGDdqEYMqTYBsA==}
    +  '@rspack/binding-linux-x64-musl@2.1.5':
    +    resolution: {integrity: sha512-iwS3t75nZ2TnUjB05KtvpvjpdkOy/nLxbaOnwjbdnNZZXpUaMadLbllGAWayHPGCMsL2yKBEhVEESZpR7tK3SA==}
         cpu: [x64]
         os: [linux]
         libc: [musl]
     
    -  '@rspack/binding-wasm32-wasi@2.0.8':
    -    resolution: {integrity: sha512-Yf4SiqTUroT5Ju+te0YAY2xxKOb35tECsO21v7hYyGa705wrgoAK/MmF7enOvs9GR1iZIqgiLD/wxsIxl8GjJw==}
    +  '@rspack/binding-wasm32-wasi@2.1.5':
    +    resolution: {integrity: sha512-jOhW69t1H/jcRaSMB5U8jVzWP18j0YQIlo0nT8W+KvNVScJeyOze4FFc+5RIS7VmuT8/jid7hUyydZOfm6UgqA==}
         cpu: [wasm32]
     
    -  '@rspack/binding-win32-arm64-msvc@2.0.8':
    -    resolution: {integrity: sha512-8NCuiQsAhXrwRBy57QZoypqrws/zLBkaQVGiB8hksr6v++8hNigNjqpQARLbd0iyMuHsQQ++8+auGk6xlDXmzw==}
    +  '@rspack/binding-win32-arm64-msvc@2.1.5':
    +    resolution: {integrity: sha512-OLfMXmtFBcrWr9BRGKXJYrWgYR0JSaoAWr3EVFDjKGi/YR5aUwQSGc3AJPBph9g0YsdSqRuUhtQGtCk84DeeEA==}
         cpu: [arm64]
         os: [win32]
     
    -  '@rspack/binding-win32-ia32-msvc@2.0.8':
    -    resolution: {integrity: sha512-bxiekytbX7V9KFAra+HkwtNWC6pYfHEBBZFpiT0xUs3mCFOmAAFVBsBSQsoCP9AdCEXoMAvNdnrHNw3iov4OZw==}
    +  '@rspack/binding-win32-ia32-msvc@2.1.5':
    +    resolution: {integrity: sha512-p4OSmnj21+AY8vpIADveLEBXfXJRXonOTYim2VLVWV4TbXfhYNMLiX3qESHCdNnn6lVJM0q6zxxzEUfTyAKydw==}
         cpu: [ia32]
         os: [win32]
     
    -  '@rspack/binding-win32-x64-msvc@2.0.8':
    -    resolution: {integrity: sha512-7zPs8YCe/ZVJTwd+5lpB0CP0tkn2pONf/T1ycmVY76u21Nrwt8mXQGc/2yH2eWP4B7fikYBr3hGr7mpR2fajqQ==}
    +  '@rspack/binding-win32-x64-msvc@2.1.5':
    +    resolution: {integrity: sha512-YCkLLDGMkHsw5CpcsFtFhzCu+JZEsNrcH9O1GpWMkyxR2ku2Fq1i2wEHYSm26HyW+PJ3+Fv347MPWMFZIz9q2g==}
         cpu: [x64]
         os: [win32]
     
    -  '@rspack/binding@2.0.8':
    -    resolution: {integrity: sha512-3uZ+y8aQxq33ty2srMxg2Nu0XuBI6vVrG50rkDaXqwWqOohfgGUSfFuQK7EnSUNy4aFUQlCG6NHialQHJov0wg==}
    +  '@rspack/binding@2.1.5':
    +    resolution: {integrity: sha512-lF3ZLeeyV0AN3BL0m2jAmNZD5pP9IHsQ8gUXN7mo0g4xsW6nf6hsN7o9CnEHECz5uUZb+EoWsuWzAAmnA9Ip8Q==}
     
    -  '@rspack/cli@2.0.8':
    -    resolution: {integrity: sha512-b7MrVE9kvCs8L7hhPdHR6AvQ5wyD3KeBYD+DZMynt+545rvJYnT11LVNjqQJqAYHrgBTmf+9CNPYmeJvEZesWw==}
    +  '@rspack/cli@2.1.5':
    +    resolution: {integrity: sha512-N6Bm8sxHwatNoiZR68+/VKvVMDh19ya39t2Nfxu1/fBmGCrQX1ct8uPooVSysLtUF2Qx31sSRl1DX1SS0eYt2A==}
         hasBin: true
         peerDependencies:
           '@rspack/core': ^2.0.0-0
    @@ -3967,8 +3158,8 @@ packages:
           '@rspack/dev-server':
             optional: true
     
    -  '@rspack/core@2.0.8':
    -    resolution: {integrity: sha512-+NLGJf8gZxihDmMFzjlly3toc2SMjeDmuvz0/Cai9AMdV4F+Pqcnt2BA9V4e3SY2jmhJQtPwgyyLtR1RiJO77g==}
    +  '@rspack/core@2.1.5':
    +    resolution: {integrity: sha512-YHjL7xVXycAWsjJtF39cRZ2u+ddiNFxY+FcNgEBe6Y8OaLeUfMfjba3gK+B1Oj32UcKD6BmXGsPfu9p+OII/Yw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         peerDependencies:
           '@module-federation/runtime-tools': ^0.24.1 || ^2.0.0
    @@ -3979,76 +3170,43 @@ packages:
           '@swc/helpers':
             optional: true
     
    -  '@rtsao/scc@1.1.0':
    -    resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
    -
    -  '@shikijs/core@4.2.0':
    -    resolution: {integrity: sha512-Hc87Ab1Ld/vEbZRCbwx344I5v+4RU8CVToUTRkqXL1+TjbuOp9U5Xa0M23V4GEWHxVn+yO5otb+HkQVm3ptWQQ==}
    +  '@shikijs/core@4.3.1':
    +    resolution: {integrity: sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==}
         engines: {node: '>=20'}
     
    -  '@shikijs/engine-javascript@4.2.0':
    -    resolution: {integrity: sha512-fjETeq1k5ffyXqRgS6+3hpvqseLalp1kjNfRbXpUgWR8FpZ1CmQfiNHovc5lncYjt/Vg5JK/WJEmLahjwMa0og==}
    +  '@shikijs/engine-javascript@4.3.1':
    +    resolution: {integrity: sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ==}
         engines: {node: '>=20'}
     
    -  '@shikijs/engine-oniguruma@4.2.0':
    -    resolution: {integrity: sha512-hTorK1dffPkpbMUk6Z+828PgRo7d07HbnizoP0hNPFjhxMHctj0Px/qoHeGMYafc6ju+u9iMldN4JbVzNQM++g==}
    +  '@shikijs/engine-oniguruma@4.3.1':
    +    resolution: {integrity: sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg==}
         engines: {node: '>=20'}
     
    -  '@shikijs/langs@4.2.0':
    -    resolution: {integrity: sha512-bwrVRlJ0wUhZxAbVdvBbv2TTC9yLsh4C/IO5Ofz0T8MQntgDvyVnkbjw9vi50r1kx7RCIJdnJnjZAwmAsXFLZQ==}
    +  '@shikijs/langs@4.3.1':
    +    resolution: {integrity: sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ==}
         engines: {node: '>=20'}
     
    -  '@shikijs/primitive@4.2.0':
    -    resolution: {integrity: sha512-NOq+DtUkVBJtZMVXL5A0vI0Xk8nvDYaXetFHSJFlOqjDZIVhIPRYFdGkSoElDqNuegikcc3A76SNUa8dTqtAYA==}
    +  '@shikijs/primitive@4.3.1':
    +    resolution: {integrity: sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A==}
         engines: {node: '>=20'}
     
    -  '@shikijs/rehype@4.2.0':
    -    resolution: {integrity: sha512-ST3EWye/dwF1gWskczJNBnwFtDzEQ9ceytXZtyc/GfwR5V0qJrkoSGZO55O3SAKDDsXkTDcsfwd9pVe7ROlAHg==}
    +  '@shikijs/rehype@4.3.1':
    +    resolution: {integrity: sha512-oshrlfUF3VPUJfnp5K1lLwsS/SRBKrIxONpdWebSKZXdBE3UsZnxgqpvRUA8UsofS7vmjFOCAHIT71ECbmOxTw==}
         engines: {node: '>=20'}
     
    -  '@shikijs/themes@4.2.0':
    -    resolution: {integrity: sha512-RX8IHYeLv8Cu2W6ruc3RxUqWn0IYCqSrMBzi/uRGAmfyDNOnNO5BF/Px7o97n4XTpmFTo5GbRaazuOWj+2ak2w==}
    +  '@shikijs/themes@4.3.1':
    +    resolution: {integrity: sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA==}
         engines: {node: '>=20'}
     
    -  '@shikijs/types@4.2.0':
    -    resolution: {integrity: sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw==}
    +  '@shikijs/types@4.3.1':
    +    resolution: {integrity: sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==}
         engines: {node: '>=20'}
     
       '@shikijs/vscode-textmate@10.0.2':
         resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
     
    -  '@sigstore/bundle@4.0.0':
    -    resolution: {integrity: sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@sigstore/core@3.2.1':
    -    resolution: {integrity: sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@sigstore/protobuf-specs@0.5.1':
    -    resolution: {integrity: sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==}
    -    engines: {node: ^18.17.0 || >=20.5.0}
    -
    -  '@sigstore/sign@4.1.1':
    -    resolution: {integrity: sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@sigstore/tuf@4.0.2':
    -    resolution: {integrity: sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@sigstore/verify@3.1.1':
    -    resolution: {integrity: sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@simple-git/args-pathspec@1.0.3':
    -    resolution: {integrity: sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==}
    -
    -  '@simple-git/argv-parser@1.1.1':
    -    resolution: {integrity: sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==}
    -
    -  '@sinclair/typebox@0.34.49':
    -    resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==}
    +  '@sinclair/typebox@0.34.52':
    +    resolution: {integrity: sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==}
     
       '@sindresorhus/fnv1a@3.1.0':
         resolution: {integrity: sha512-KV321z5m/0nuAg83W1dPLy85HpHDk7Sdi4fJbwvacWsEhAh+rZUW4ZfGcXmUIvjZg4ss2bcwNlRhJ7GBEUG08w==}
    @@ -4066,79 +3224,6 @@ packages:
       '@standard-schema/spec@1.1.0':
         resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
     
    -  '@stoplight/better-ajv-errors@1.0.3':
    -    resolution: {integrity: sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==}
    -    engines: {node: ^12.20 || >= 14.13}
    -    peerDependencies:
    -      ajv: '>=8'
    -
    -  '@stoplight/json-ref-readers@1.2.2':
    -    resolution: {integrity: sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==}
    -    engines: {node: '>=8.3.0'}
    -
    -  '@stoplight/json-ref-resolver@3.1.6':
    -    resolution: {integrity: sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==}
    -    engines: {node: '>=8.3.0'}
    -
    -  '@stoplight/json@3.21.0':
    -    resolution: {integrity: sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==}
    -    engines: {node: '>=8.3.0'}
    -
    -  '@stoplight/json@3.21.7':
    -    resolution: {integrity: sha512-xcJXgKFqv/uCEgtGlPxy3tPA+4I+ZI4vAuMJ885+ThkTHFVkC+0Fm58lA9NlsyjnkpxFh4YiQWpH+KefHdbA0A==}
    -    engines: {node: '>=8.3.0'}
    -
    -  '@stoplight/ordered-object-literal@1.0.5':
    -    resolution: {integrity: sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==}
    -    engines: {node: '>=8'}
    -
    -  '@stoplight/path@1.3.2':
    -    resolution: {integrity: sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==}
    -    engines: {node: '>=8'}
    -
    -  '@stoplight/spectral-core@1.23.0':
    -    resolution: {integrity: sha512-WvdgmiiJrjiMrcw7ByxfcYtUvAXNp2MhAfcEIXP3Mn8ZOVwyAWIsFjLlsE5zRqj0LuN8+7OQM/L+BMcHj6x/BQ==}
    -    engines: {node: ^16.20 || ^18.18 || >= 20.17}
    -
    -  '@stoplight/spectral-formats@1.8.3':
    -    resolution: {integrity: sha512-lfYzkHYS2mZQdm3k+TQ0lvXZ66vdBzJuy6awA4kXgQ0jWBbOC/FHzhBk5BaIVo2QRLUAGjMqWSd72WFryi+EvA==}
    -    engines: {node: ^16.20 || ^18.18 || >= 20.17}
    -
    -  '@stoplight/spectral-functions@1.10.3':
    -    resolution: {integrity: sha512-AM7Gbh7pv1Mpc6fdVuR7N6C5t5KT3QKDHeBPA27Cw/GAch1VJnHkCV9R/SxDrvOgZ3tL1xrtAGFuNFwRvVdz3g==}
    -    engines: {node: ^16.20 || ^18.18 || >= 20.17}
    -
    -  '@stoplight/spectral-parsers@1.0.5':
    -    resolution: {integrity: sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==}
    -    engines: {node: ^16.20 || ^18.18 || >= 20.17}
    -
    -  '@stoplight/spectral-ref-resolver@1.0.5':
    -    resolution: {integrity: sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==}
    -    engines: {node: ^16.20 || ^18.18 || >= 20.17}
    -
    -  '@stoplight/spectral-runtime@1.1.5':
    -    resolution: {integrity: sha512-6/HSCQBKnI4M5qonCKos2W7oggXv+U/ml+m/cAd4eJAYfIVEmaLUo03qSWIIl4cBc5ujJPmn2WnCiRrz1++P7Q==}
    -    engines: {node: ^16.20 || ^18.18 || >= 20.17}
    -
    -  '@stoplight/types@13.20.0':
    -    resolution: {integrity: sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==}
    -    engines: {node: ^12.20 || >=14.13}
    -
    -  '@stoplight/types@13.6.0':
    -    resolution: {integrity: sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==}
    -    engines: {node: ^12.20 || >=14.13}
    -
    -  '@stoplight/types@14.1.1':
    -    resolution: {integrity: sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==}
    -    engines: {node: ^12.20 || >=14.13}
    -
    -  '@stoplight/yaml-ast-parser@0.0.50':
    -    resolution: {integrity: sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==}
    -
    -  '@stoplight/yaml@4.3.0':
    -    resolution: {integrity: sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==}
    -    engines: {node: '>=10.8'}
    -
       '@testing-library/dom@10.4.1':
         resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
         engines: {node: '>=18'}
    @@ -4177,16 +3262,8 @@ packages:
       '@tsconfig/node16@1.0.4':
         resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
     
    -  '@tufjs/canonical-json@2.0.0':
    -    resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    -
    -  '@tufjs/models@4.1.0':
    -    resolution: {integrity: sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  '@tybys/wasm-util@0.10.2':
    -    resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
    +  '@tybys/wasm-util@0.10.3':
    +    resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==}
     
       '@types/aria-query@5.0.4':
         resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
    @@ -4323,22 +3400,9 @@ packages:
       '@types/deep-eql@4.0.2':
         resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
     
    -  '@types/diff@8.0.0':
    -    resolution: {integrity: sha512-o7jqJM04gfaYrdCecCVMbZhNdG6T1MHg/oQoRFdERLV+4d+V7FijhiEAbFu0Usww84Yijk9yH58U4Jk4HbtzZw==}
    -    deprecated: This is a stub types definition. diff provides its own type definitions, so you do not need this installed.
    -
    -  '@types/es-aggregate-error@1.0.6':
    -    resolution: {integrity: sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==}
    -
    -  '@types/esrecurse@4.3.1':
    -    resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
    -
       '@types/estree-jsx@1.0.5':
         resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
     
    -  '@types/estree@0.0.39':
    -    resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
    -
       '@types/estree@1.0.8':
         resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
     
    @@ -4381,10 +3445,6 @@ packages:
       '@types/istanbul-reports@3.0.4':
         resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
     
    -  '@types/jest-diff@24.3.0':
    -    resolution: {integrity: sha512-vx1CRDeDUwQ0Pc7v+hS61O1ETA81kD04IMEC0hS1kPyVtHDdZrokAvpF7MT9VI/fVSzicelUZNCepDvhRV1PeA==}
    -    deprecated: This is a stub types definition. jest-diff provides its own type definitions, so you do not need this installed.
    -
       '@types/jest@30.0.0':
         resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==}
     
    @@ -4394,9 +3454,6 @@ packages:
       '@types/json-schema@7.0.15':
         resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
     
    -  '@types/json5@0.0.29':
    -    resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
    -
       '@types/jsonfile@6.1.4':
         resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==}
     
    @@ -4421,18 +3478,12 @@ packages:
       '@types/node-fetch@2.6.13':
         resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==}
     
    -  '@types/node@16.18.126':
    -    resolution: {integrity: sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==}
    -
    -  '@types/node@26.0.0':
    -    resolution: {integrity: sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==}
    +  '@types/node@26.1.1':
    +    resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==}
     
       '@types/parse-json@4.0.2':
         resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
     
    -  '@types/protocol-buffers-schema@3.4.3':
    -    resolution: {integrity: sha512-8cCg6BiIj4jS0LXUFq3sndmd46yyPLYqMzvXLcTM1MRubh3sfZlQiehoCjGDxSHTqGSjjx8EtVNryIAl0njQWg==}
    -
       '@types/qrcode@1.5.6':
         resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
     
    @@ -4453,9 +3504,6 @@ packages:
       '@types/retry@0.12.2':
         resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==}
     
    -  '@types/semver@7.7.1':
    -    resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==}
    -
       '@types/send@0.17.6':
         resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==}
     
    @@ -4480,8 +3528,8 @@ packages:
       '@types/superagent@8.1.10':
         resolution: {integrity: sha512-nbt4IWXABhW0jGmmpRzCFNlbmwCTzZ2gTUsNIr+X+ItdqPms+PAJZbWsNzpS2USqXjcoNLQcO6nXo60zcPQiIg==}
     
    -  '@types/supertest@7.2.0':
    -    resolution: {integrity: sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw==}
    +  '@types/supertest@7.2.1':
    +    resolution: {integrity: sha512-4CbBvoYVLHL7+yhbYrZET0vsvuyXTC05aRe7dNQkwMzm56auceoy6Yu3K50uZmwfHna1os3CMSgM/3QVkUtPTw==}
     
       '@types/tough-cookie@4.0.5':
         resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
    @@ -4495,9 +3543,6 @@ packages:
       '@types/unist@3.0.3':
         resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
     
    -  '@types/urijs@1.19.26':
    -    resolution: {integrity: sha512-wkXrVzX5yoqLnndOwFsieJA7oKM8cNkOKJtf/3vVGSUFkWDKZvFHpIl9Pvqb/T9UsawBBFMTTD8xu7sK5MWuvg==}
    -
       '@types/webidl-conversions@7.0.3':
         resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
     
    @@ -4516,144 +3561,27 @@ packages:
       '@types/yauzl@2.10.3':
         resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
     
    -  '@typescript-eslint/eslint-plugin@5.62.0':
    -    resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      '@typescript-eslint/parser': ^5.0.0
    -      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
    -      typescript: '*'
    -    peerDependenciesMeta:
    -      typescript:
    -        optional: true
    -
    -  '@typescript-eslint/eslint-plugin@8.61.1':
    -    resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      '@typescript-eslint/parser': ^8.61.1
    -      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
    -      typescript: '>=4.8.4 <6.1.0'
    -
    -  '@typescript-eslint/parser@5.62.0':
    -    resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
    -      typescript: '*'
    -    peerDependenciesMeta:
    -      typescript:
    -        optional: true
    +  '@ungap/structured-clone@1.3.0':
    +    resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
    +    deprecated: Potential CWE-502 - Update to 1.3.1 or higher
     
    -  '@typescript-eslint/parser@8.61.1':
    -    resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
    -      typescript: '>=4.8.4 <6.1.0'
    +  '@ungap/structured-clone@1.3.3':
    +    resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==}
     
    -  '@typescript-eslint/project-service@8.61.1':
    -    resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      typescript: '>=4.8.4 <6.1.0'
    +  '@unrs/resolver-binding-android-arm-eabi@1.12.2':
    +    resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==}
    +    cpu: [arm]
    +    os: [android]
     
    -  '@typescript-eslint/scope-manager@5.62.0':
    -    resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    +  '@unrs/resolver-binding-android-arm64@1.12.2':
    +    resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==}
    +    cpu: [arm64]
    +    os: [android]
     
    -  '@typescript-eslint/scope-manager@8.61.1':
    -    resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -
    -  '@typescript-eslint/tsconfig-utils@8.61.1':
    -    resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      typescript: '>=4.8.4 <6.1.0'
    -
    -  '@typescript-eslint/type-utils@5.62.0':
    -    resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      eslint: '*'
    -      typescript: '*'
    -    peerDependenciesMeta:
    -      typescript:
    -        optional: true
    -
    -  '@typescript-eslint/type-utils@8.61.1':
    -    resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
    -      typescript: '>=4.8.4 <6.1.0'
    -
    -  '@typescript-eslint/types@5.62.0':
    -    resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  '@typescript-eslint/types@8.61.1':
    -    resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -
    -  '@typescript-eslint/typescript-estree@5.62.0':
    -    resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      typescript: '*'
    -    peerDependenciesMeta:
    -      typescript:
    -        optional: true
    -
    -  '@typescript-eslint/typescript-estree@8.61.1':
    -    resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      typescript: '>=4.8.4 <6.1.0'
    -
    -  '@typescript-eslint/utils@5.62.0':
    -    resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
    -
    -  '@typescript-eslint/utils@8.61.1':
    -    resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
    -      typescript: '>=4.8.4 <6.1.0'
    -
    -  '@typescript-eslint/visitor-keys@5.62.0':
    -    resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  '@typescript-eslint/visitor-keys@8.61.1':
    -    resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -
    -  '@ungap/structured-clone@1.3.0':
    -    resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
    -    deprecated: Potential CWE-502 - Update to 1.3.1 or higher
    -
    -  '@ungap/structured-clone@1.3.1':
    -    resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==}
    -
    -  '@unrs/resolver-binding-android-arm-eabi@1.12.2':
    -    resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==}
    -    cpu: [arm]
    -    os: [android]
    -
    -  '@unrs/resolver-binding-android-arm64@1.12.2':
    -    resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==}
    -    cpu: [arm64]
    -    os: [android]
    -
    -  '@unrs/resolver-binding-darwin-arm64@1.12.2':
    -    resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==}
    -    cpu: [arm64]
    -    os: [darwin]
    +  '@unrs/resolver-binding-darwin-arm64@1.12.2':
    +    resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==}
    +    cpu: [arm64]
    +    os: [darwin]
     
       '@unrs/resolver-binding-darwin-x64@1.12.2':
         resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==}
    @@ -4763,8 +3691,8 @@ packages:
       '@upsetjs/venn.js@2.0.0':
         resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
     
    -  '@vitejs/plugin-react@6.0.2':
    -    resolution: {integrity: sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==}
    +  '@vitejs/plugin-react@6.0.4':
    +    resolution: {integrity: sha512-XcCQz0TBpBgljhj0gMuuDj49i6Ytqh5q1osT/Gp5uAVJUCTWxyskk/l1jwYYiu2xcNHHipdMz40EGfM1VdamVg==}
         engines: {node: ^20.19.0 || >=22.12.0}
         peerDependencies:
           '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0
    @@ -4776,11 +3704,11 @@ packages:
           babel-plugin-react-compiler:
             optional: true
     
    -  '@vitest/expect@4.1.9':
    -    resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==}
    +  '@vitest/expect@4.1.10':
    +    resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==}
     
    -  '@vitest/mocker@4.1.9':
    -    resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==}
    +  '@vitest/mocker@4.1.10':
    +    resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==}
         peerDependencies:
           msw: ^2.4.9
           vite: ^6.0.0 || ^7.0.0 || ^8.0.0
    @@ -4790,20 +3718,20 @@ packages:
           vite:
             optional: true
     
    -  '@vitest/pretty-format@4.1.9':
    -    resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==}
    +  '@vitest/pretty-format@4.1.10':
    +    resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==}
     
    -  '@vitest/runner@4.1.9':
    -    resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==}
    +  '@vitest/runner@4.1.10':
    +    resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==}
     
    -  '@vitest/snapshot@4.1.9':
    -    resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==}
    +  '@vitest/snapshot@4.1.10':
    +    resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==}
     
    -  '@vitest/spy@4.1.9':
    -    resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==}
    +  '@vitest/spy@4.1.10':
    +    resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==}
     
    -  '@vitest/utils@4.1.9':
    -    resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==}
    +  '@vitest/utils@4.1.10':
    +    resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==}
     
       '@webassemblyjs/ast@1.14.1':
         resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==}
    @@ -4856,18 +3784,10 @@ packages:
       '@xtuc/long@4.2.2':
         resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
     
    -  abbrev@2.0.0:
    -    resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
       abbrev@4.0.0:
         resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==}
         engines: {node: ^20.17.0 || >=22.9.0}
     
    -  abort-controller@3.0.0:
    -    resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
    -    engines: {node: '>=6.5'}
    -
       abort-error@1.0.2:
         resolution: {integrity: sha512-lVgvB2NyPLqbXXhVmXcYFTC1x5K7CiVdPgdY7LGgFQWC8506oN01sPN3i9cl9ynuwF4iJ0TS9exnR7cZ9FuX4w==}
     
    @@ -4879,12 +3799,6 @@ packages:
         resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
         engines: {node: '>= 0.6'}
     
    -  acorn-import-phases@1.0.4:
    -    resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==}
    -    engines: {node: '>=10.13.0'}
    -    peerDependencies:
    -      acorn: ^8.14.0
    -
       acorn-jsx@5.3.2:
         resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
         peerDependencies:
    @@ -4899,23 +3813,15 @@ packages:
         engines: {node: '>=0.4.0'}
         hasBin: true
     
    +  acorn@8.17.0:
    +    resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
    +    engines: {node: '>=0.4.0'}
    +    hasBin: true
    +
       agent-base@7.1.4:
         resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
         engines: {node: '>= 14'}
     
    -  ajv-draft-04@1.0.0:
    -    resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
    -    peerDependencies:
    -      ajv: ^8.5.0
    -    peerDependenciesMeta:
    -      ajv:
    -        optional: true
    -
    -  ajv-errors@3.0.0:
    -    resolution: {integrity: sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==}
    -    peerDependencies:
    -      ajv: ^8.0.1
    -
       ajv-formats@2.1.1:
         resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
         peerDependencies:
    @@ -4937,22 +3843,9 @@ packages:
         peerDependencies:
           ajv: ^8.8.2
     
    -  ajv@5.5.2:
    -    resolution: {integrity: sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==}
    -
    -  ajv@6.15.0:
    -    resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
    -
    -  ajv@6.5.2:
    -    resolution: {integrity: sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==}
    -
       ajv@8.20.0:
         resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
     
    -  alterschema@1.1.3:
    -    resolution: {integrity: sha512-VqKTk8lX8LHVRvSOgEZDGPeEYOvrSOjlX/1PAi4el7ac8acC6/6a99HuVjfU6N1tNrHV5dU0sQDmuOjRvBf/Sw==}
    -    hasBin: true
    -
       ansi-escapes@4.3.2:
         resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
         engines: {node: '>=8'}
    @@ -4993,9 +3886,6 @@ packages:
         resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
         engines: {node: '>= 8'}
     
    -  anynum@1.0.1:
    -    resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==}
    -
       arg@4.1.3:
         resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
     
    @@ -5012,45 +3902,9 @@ packages:
         resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
         engines: {node: '>= 0.4'}
     
    -  array-buffer-byte-length@1.0.2:
    -    resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
    -    engines: {node: '>= 0.4'}
    -
       array-flatten@1.1.1:
         resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
     
    -  array-includes@3.1.9:
    -    resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  array-union@2.1.0:
    -    resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
    -    engines: {node: '>=8'}
    -
    -  array.prototype.findlast@1.2.5:
    -    resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  array.prototype.findlastindex@1.2.6:
    -    resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  array.prototype.flat@1.3.3:
    -    resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
    -    engines: {node: '>= 0.4'}
    -
    -  array.prototype.flatmap@1.3.3:
    -    resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
    -    engines: {node: '>= 0.4'}
    -
    -  array.prototype.tosorted@1.1.4:
    -    resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
    -    engines: {node: '>= 0.4'}
    -
    -  arraybuffer.prototype.slice@1.0.4:
    -    resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
    -    engines: {node: '>= 0.4'}
    -
       asap@2.0.6:
         resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
     
    @@ -5070,24 +3924,12 @@ packages:
         resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
         hasBin: true
     
    -  async-function@1.0.0:
    -    resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
    -    engines: {node: '>= 0.4'}
    -
       async-mutex@0.5.0:
         resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==}
     
       asynckit@0.4.0:
         resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
     
    -  available-typed-arrays@1.0.7:
    -    resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  avsc@5.7.9:
    -    resolution: {integrity: sha512-yOA4wFeI7ET3v32Di/sUybQ+ttP20JHSW3mxLuNGeO0uD6PPcvLrIQXSvy/rhJOWU5JrYh7U4OHplWMmtAtjMg==}
    -    engines: {node: '>=0.11'}
    -
       aws-ssl-profiles@1.1.2:
         resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
         engines: {node: '>= 6.0.0'}
    @@ -5118,24 +3960,6 @@ packages:
         resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
         engines: {node: '>=10', npm: '>=6'}
     
    -  babel-plugin-polyfill-corejs2@0.4.17:
    -    resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==}
    -    peerDependencies:
    -      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
    -
    -  babel-plugin-polyfill-corejs3@0.14.2:
    -    resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==}
    -    peerDependencies:
    -      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
    -
    -  babel-plugin-polyfill-regenerator@0.6.8:
    -    resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==}
    -    peerDependencies:
    -      '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
    -
    -  babel-plugin-source-map-support@2.2.0:
    -    resolution: {integrity: sha512-YWB1DfnYjPakY0J16nemRW2HEqsX/zEBQJAbiZsc4q7Zn5aOoVqA1hoaQbXheeBHBXPFiS6da1WFrSbcnXHNWg==}
    -
       babel-preset-current-node-syntax@1.2.0:
         resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==}
         peerDependencies:
    @@ -5162,6 +3986,14 @@ packages:
           bare-abort-controller:
             optional: true
     
    +  bare-events@2.9.1:
    +    resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==}
    +    peerDependencies:
    +      bare-abort-controller: '*'
    +    peerDependenciesMeta:
    +      bare-abort-controller:
    +        optional: true
    +
       bare-fs@4.7.1:
         resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==}
         engines: {bare: '>=1.16.0'}
    @@ -5171,6 +4003,15 @@ packages:
           bare-buffer:
             optional: true
     
    +  bare-fs@4.7.4:
    +    resolution: {integrity: sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==}
    +    engines: {bare: '>=1.16.0'}
    +    peerDependencies:
    +      bare-buffer: '*'
    +    peerDependenciesMeta:
    +      bare-buffer:
    +        optional: true
    +
       bare-os@3.9.0:
         resolution: {integrity: sha512-JTjuZyNIDpw+GytMO4a6TK1VXdVKKJr6DRxEHasyuYyShV2deuiHJK/ahGZlebc+SG0/wJCB9XK8gprBGDFi/Q==}
         engines: {bare: '>=1.14.0'}
    @@ -5178,6 +4019,9 @@ packages:
       bare-path@3.0.0:
         resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==}
     
    +  bare-path@3.1.1:
    +    resolution: {integrity: sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==}
    +
       bare-stream@2.13.1:
         resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==}
         peerDependencies:
    @@ -5192,9 +4036,26 @@ packages:
           bare-events:
             optional: true
     
    +  bare-stream@2.13.3:
    +    resolution: {integrity: sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==}
    +    peerDependencies:
    +      bare-abort-controller: '*'
    +      bare-buffer: '*'
    +      bare-events: '*'
    +    peerDependenciesMeta:
    +      bare-abort-controller:
    +        optional: true
    +      bare-buffer:
    +        optional: true
    +      bare-events:
    +        optional: true
    +
       bare-url@2.4.3:
         resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==}
     
    +  bare-url@2.4.6:
    +    resolution: {integrity: sha512-iQxPClE07hETVpbRoX7JXX3v/ZQViCxe/SYCxylRLzdEx1xJAufPptfiOqR8tqiCtmbtMDANKWszzjLu1PMAZQ==}
    +
       base64-js@1.5.1:
         resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
     
    @@ -5207,6 +4068,11 @@ packages:
         engines: {node: '>=6.0.0'}
         hasBin: true
     
    +  baseline-browser-mapping@2.11.1:
    +    resolution: {integrity: sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==}
    +    engines: {node: '>=6.0.0'}
    +    hasBin: true
    +
       basic-ftp@5.3.1:
         resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==}
         engines: {node: '>=10.0.0'}
    @@ -5221,10 +4087,6 @@ packages:
       bidi-js@1.0.3:
         resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
     
    -  bin-links@6.0.2:
    -    resolution: {integrity: sha512-frE1t78WOwJ45PKV2cF2tNPjTcs9L1J9s6VkrV59wanRP4GlaomuxYPVma7BwthMg8WnfSory4w5PTE6FZZ81w==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       binary-extensions@2.3.0:
         resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
         engines: {node: '>=8'}
    @@ -5235,8 +4097,8 @@ packages:
       bl@4.1.0:
         resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
     
    -  body-parser@1.20.5:
    -    resolution: {integrity: sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==}
    +  body-parser@1.20.6:
    +    resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==}
         engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
     
       body-parser@2.2.2:
    @@ -5263,6 +4125,11 @@ packages:
         engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
         hasBin: true
     
    +  browserslist@4.28.7:
    +    resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==}
    +    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
    +    hasBin: true
    +
       bs-logger@0.2.6:
         resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
         engines: {node: '>= 6'}
    @@ -5283,9 +4150,6 @@ packages:
       buffer@5.7.1:
         resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
     
    -  builtins@5.1.0:
    -    resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==}
    -
       bundle-name@4.1.0:
         resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
         engines: {node: '>=18'}
    @@ -5308,32 +4172,18 @@ packages:
         resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
         engines: {node: '>=8'}
     
    -  cacache@20.0.4:
    -    resolution: {integrity: sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       call-bind-apply-helpers@1.0.2:
         resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
         engines: {node: '>= 0.4'}
     
    -  call-bind@1.0.9:
    -    resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==}
    -    engines: {node: '>= 0.4'}
    -
       call-bound@1.0.4:
         resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
         engines: {node: '>= 0.4'}
     
    -  call-me-maybe@1.0.2:
    -    resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
    -
       callsites@3.1.0:
         resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
         engines: {node: '>=6'}
     
    -  camel-case@4.1.2:
    -    resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
    -
       camelcase@5.3.1:
         resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
         engines: {node: '>=6'}
    @@ -5345,13 +4195,17 @@ packages:
       caniuse-lite@1.0.30001793:
         resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==}
     
    -  capital-case@1.0.4:
    -    resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
    +  caniuse-lite@1.0.30001806:
    +    resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==}
     
       cborg@5.1.3:
         resolution: {integrity: sha512-DddFYcafyPlnoF33ezbrh3jXT8QnuTQiy/LEL4xoMVH60WIBQbLwb2npNquSM0WouEMvl5xTJ1Y8iECaMdh3gg==}
         hasBin: true
     
    +  cborg@5.1.8:
    +    resolution: {integrity: sha512-enonPtLyeEF8M8GF/5NdjLHmRGslrwKR2LvkN+yFYQJw7mzt6iOoPvkVs3vcb3rUvltzL0QfvtM6FQ44o8nhSg==}
    +    hasBin: true
    +
       ccount@2.0.1:
         resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
     
    @@ -5367,9 +4221,6 @@ packages:
         resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
         engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
     
    -  change-case@4.1.2:
    -    resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==}
    -
       char-regex@1.0.2:
         resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
         engines: {node: '>=10'}
    @@ -5428,10 +4279,6 @@ packages:
         resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
         engines: {node: '>=6'}
     
    -  cmd-shim@8.0.0:
    -    resolution: {integrity: sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       co@4.6.0:
         resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
         engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
    @@ -5477,14 +4324,6 @@ packages:
         resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
         engines: {node: '>= 6'}
     
    -  commander@5.1.0:
    -    resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==}
    -    engines: {node: '>= 6'}
    -
    -  commander@6.2.1:
    -    resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
    -    engines: {node: '>= 6'}
    -
       commander@7.2.0:
         resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
         engines: {node: '>= 10'}
    @@ -5493,10 +4332,6 @@ packages:
         resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
         engines: {node: '>= 12'}
     
    -  common-ancestor-path@2.0.0:
    -    resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==}
    -    engines: {node: '>= 18'}
    -
       commondir@1.0.1:
         resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
     
    @@ -5522,9 +4357,6 @@ packages:
         resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
         engines: {node: ^14.18.0 || >=16.10.0}
     
    -  constant-case@3.0.4:
    -    resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
    -
       content-disposition@0.5.4:
         resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
         engines: {node: '>= 0.6'}
    @@ -5541,9 +4373,6 @@ packages:
         resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==}
         engines: {node: '>=18'}
     
    -  convert-source-map@1.9.0:
    -    resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
    -
       convert-source-map@2.0.0:
         resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
     
    @@ -5561,9 +4390,6 @@ packages:
       cookiejar@2.1.4:
         resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
     
    -  core-js-compat@3.49.0:
    -    resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==}
    -
       core-util-is@1.0.3:
         resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
     
    @@ -5581,15 +4407,6 @@ packages:
         resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
         engines: {node: '>=10'}
     
    -  cosmiconfig@9.0.1:
    -    resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==}
    -    engines: {node: '>=14'}
    -    peerDependencies:
    -      typescript: '>=4.9.5'
    -    peerDependenciesMeta:
    -      typescript:
    -        optional: true
    -
       create-require@1.1.1:
         resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
     
    @@ -5603,10 +4420,6 @@ packages:
         resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
         engines: {node: '>= 8'}
     
    -  crypto@1.0.1:
    -    resolution: {integrity: sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==}
    -    deprecated: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.
    -
       css-tree@3.2.1:
         resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
         engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
    @@ -5614,11 +4427,6 @@ packages:
       css.escape@1.5.1:
         resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
     
    -  cssesc@3.0.0:
    -    resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
    -    engines: {node: '>=4'}
    -    hasBin: true
    -
       cssstyle@4.6.0:
         resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==}
         engines: {node: '>=18'}
    @@ -5802,18 +4610,6 @@ packages:
         resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
         engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
     
    -  data-view-buffer@1.0.2:
    -    resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  data-view-byte-length@1.0.2:
    -    resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  data-view-byte-offset@1.0.1:
    -    resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
    -    engines: {node: '>= 0.4'}
    -
       datastore-core@12.0.1:
         resolution: {integrity: sha512-pfgIE5LG0Z5oyc6TxiLaF/0j4Gh1Yrs2+Ck/qssf9Oxw4s4YKC3zpqifuzThnKakAFWONr/vRv+66Koc0yJvyA==}
     
    @@ -5828,14 +4624,6 @@ packages:
           supports-color:
             optional: true
     
    -  debug@3.2.7:
    -    resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
    -    peerDependencies:
    -      supports-color: '*'
    -    peerDependenciesMeta:
    -      supports-color:
    -        optional: true
    -
       debug@4.3.4:
         resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
         engines: {node: '>=6.0'}
    @@ -5880,9 +4668,6 @@ packages:
         resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
         engines: {node: '>=4.0.0'}
     
    -  deep-is@0.1.4:
    -    resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
    -
       deepmerge@4.3.1:
         resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
         engines: {node: '>=0.10.0'}
    @@ -5895,18 +4680,10 @@ packages:
         resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==}
         engines: {node: '>=18'}
     
    -  define-data-property@1.1.4:
    -    resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
    -    engines: {node: '>= 0.4'}
    -
       define-lazy-prop@3.0.0:
         resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
         engines: {node: '>=12'}
     
    -  define-properties@1.2.1:
    -    resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
    -    engines: {node: '>= 0.4'}
    -
       degenerator@5.0.1:
         resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
         engines: {node: '>= 14'}
    @@ -5938,10 +4715,6 @@ packages:
         resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
         engines: {node: '>= 0.8'}
     
    -  dependency-graph@0.11.0:
    -    resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==}
    -    engines: {node: '>= 0.6.0'}
    -
       dequal@2.0.3:
         resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
         engines: {node: '>=6'}
    @@ -5964,8 +4737,8 @@ packages:
       devlop@1.1.0:
         resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
     
    -  devtools-protocol@0.0.1595872:
    -    resolution: {integrity: sha512-kRfgp8vWVjBu/fbYCiVFiOqsCk3CrMKEo3WbgGT2NXK2dG7vawWPBljixajVgGK9II8rDO9G0oD0zLt3I1daRg==}
    +  devtools-protocol@0.0.1608973:
    +    resolution: {integrity: sha512-Tpm17fxYzt+J7VrGdc1k8YdRqS3YV7se/M6KeemEqvUbq/n7At1rWVuXMxQgpWkdwSdIEKYbU//Bve+Shm4YNQ==}
     
       dezalgo@1.0.4:
         resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
    @@ -5974,41 +4747,27 @@ packages:
         resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==}
         engines: {node: '>=0.3.1'}
     
    -  diff@9.0.0:
    -    resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==}
    -    engines: {node: '>=0.3.1'}
    -
       dijkstrajs@1.0.3:
         resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
     
    -  dir-glob@3.0.1:
    -    resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
    -    engines: {node: '>=8'}
    -
       dns-packet@5.6.1:
         resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==}
         engines: {node: '>=6'}
     
    -  doctrine@2.1.0:
    -    resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
    -    engines: {node: '>=0.10.0'}
    -
    -  doctrine@3.0.0:
    -    resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
    -    engines: {node: '>=6.0.0'}
    -
       dom-accessibility-api@0.5.16:
         resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
     
       dom-accessibility-api@0.6.3:
         resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
     
    +  domexception@4.0.0:
    +    resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==}
    +    engines: {node: '>=12'}
    +    deprecated: Use your platform's native DOMException instead
    +
       dompurify@3.4.12:
         resolution: {integrity: sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==}
     
    -  dot-case@3.0.4:
    -    resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
    -
       dotenv@17.4.2:
         resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==}
         engines: {node: '>=12'}
    @@ -6031,6 +4790,9 @@ packages:
       electron-to-chromium@1.5.361:
         resolution: {integrity: sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==}
     
    +  electron-to-chromium@1.5.395:
    +    resolution: {integrity: sha512-7zt9Aw+SrmxLWLN0zhaTWZQiCdryLVrYTq5R7iZakLvi2UQPYMMsROYV/2qVCzMeCiSXHwKOU+sZ4zOVVlrtKA==}
    +
       emittery@0.13.1:
         resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
         engines: {node: '>=12'}
    @@ -6051,19 +4813,19 @@ packages:
       end-of-stream@1.4.5:
         resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
     
    -  engine.io-client@6.6.4:
    -    resolution: {integrity: sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==}
    +  engine.io-client@6.6.6:
    +    resolution: {integrity: sha512-iY6QdftLQ9pyiPoX082bpf/u1UewnOaJrtJIF9T0++QB34lZrj0uP+Q/bj8AlUsAxqhnkTV2BS8SBZSxOmoV5Q==}
     
       engine.io-parser@5.2.3:
         resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==}
         engines: {node: '>=10.0.0'}
     
    -  engine.io@6.6.7:
    -    resolution: {integrity: sha512-DgOngfDKM2EviOH3Mr9m7ks1q8roetLy/IMmYthAYzbpInMbYc/GS+fWFA3rl1gvwKVsQrVV61fo5emD1y3OJQ==}
    +  engine.io@6.6.9:
    +    resolution: {integrity: sha512-clKkw4C7nJ22mGgoVcCg6V/W/TxdNyIOTr89k2ONZu81qqkddPFDF0LXcbAwhzPD8DjkiRCjzuiO6Y+fkpD4vg==}
         engines: {node: '>=10.2.0'}
     
    -  enhanced-resolve@5.22.0:
    -    resolution: {integrity: sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==}
    +  enhanced-resolve@5.24.3:
    +    resolution: {integrity: sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==}
         engines: {node: '>=10.13.0'}
     
       entities@6.0.1:
    @@ -6083,20 +4845,9 @@ packages:
         engines: {node: '>=4'}
         hasBin: true
     
    -  err-code@2.0.3:
    -    resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
    -
       error-ex@1.3.4:
         resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==}
     
    -  es-abstract@1.24.2:
    -    resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==}
    -    engines: {node: '>= 0.4'}
    -
    -  es-aggregate-error@1.0.14:
    -    resolution: {integrity: sha512-3YxX6rVb07B5TV11AV5wsL7nQCHXNwoHPsQC8S4AmBiqYhyNCJ5BRKXkXyDJvs8QzXN20NgRtxe3dEEQD9NLHA==}
    -    engines: {node: '>= 0.4'}
    -
       es-define-property@1.0.1:
         resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
         engines: {node: '>= 0.4'}
    @@ -6105,10 +4856,6 @@ packages:
         resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
         engines: {node: '>= 0.4'}
     
    -  es-iterator-helpers@1.3.2:
    -    resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==}
    -    engines: {node: '>= 0.4'}
    -
       es-module-lexer@2.1.0:
         resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
     
    @@ -6116,16 +4863,12 @@ packages:
         resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
         engines: {node: '>= 0.4'}
     
    -  es-set-tostringtag@2.1.0:
    -    resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
    -    engines: {node: '>= 0.4'}
    -
    -  es-shim-unscopables@1.1.0:
    -    resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==}
    +  es-object-atoms@1.1.2:
    +    resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
         engines: {node: '>= 0.4'}
     
    -  es-to-primitive@1.3.0:
    -    resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
    +  es-set-tostringtag@2.1.0:
    +    resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
         engines: {node: '>= 0.4'}
     
       es-toolkit@1.47.0:
    @@ -6154,18 +4897,10 @@ packages:
       escape-html@1.0.3:
         resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
     
    -  escape-string-regexp@1.0.5:
    -    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
    -    engines: {node: '>=0.8.0'}
    -
       escape-string-regexp@2.0.0:
         resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
         engines: {node: '>=8'}
     
    -  escape-string-regexp@4.0.0:
    -    resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
    -    engines: {node: '>=10'}
    -
       escape-string-regexp@5.0.0:
         resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
         engines: {node: '>=12'}
    @@ -6175,172 +4910,18 @@ packages:
         engines: {node: '>=6.0'}
         hasBin: true
     
    -  eslint-config-standard-jsx@11.0.0:
    -    resolution: {integrity: sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ==}
    -    peerDependencies:
    -      eslint: ^8.8.0
    -      eslint-plugin-react: ^7.28.0
    -
    -  eslint-config-standard-with-typescript@23.0.0:
    -    resolution: {integrity: sha512-iaaWifImn37Z1OXbNW1es7KI+S7D408F9ys0bpaQf2temeBWlvb0Nc5qHkOgYaRb5QxTZT32GGeN1gtswASOXA==}
    -    deprecated: Please use eslint-config-love, instead.
    -    peerDependencies:
    -      '@typescript-eslint/eslint-plugin': ^5.0.0
    -      eslint: ^8.0.1
    -      eslint-plugin-import: ^2.25.2
    -      eslint-plugin-n: ^15.0.0
    -      eslint-plugin-promise: ^6.0.0
    -      typescript: '*'
    -
    -  eslint-config-standard@17.0.0:
    -    resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==}
    -    peerDependencies:
    -      eslint: ^8.0.1
    -      eslint-plugin-import: ^2.25.2
    -      eslint-plugin-n: ^15.0.0
    -      eslint-plugin-promise: ^6.0.0
    -
    -  eslint-config-standard@17.1.0:
    -    resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==}
    -    engines: {node: '>=12.0.0'}
    -    peerDependencies:
    -      eslint: ^8.0.1
    -      eslint-plugin-import: ^2.25.2
    -      eslint-plugin-n: '^15.0.0 || ^16.0.0 '
    -      eslint-plugin-promise: ^6.0.0
    -
    -  eslint-import-resolver-node@0.3.10:
    -    resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==}
    -
    -  eslint-module-utils@2.12.1:
    -    resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==}
    -    engines: {node: '>=4'}
    -    peerDependencies:
    -      '@typescript-eslint/parser': '*'
    -      eslint: '*'
    -      eslint-import-resolver-node: '*'
    -      eslint-import-resolver-typescript: '*'
    -      eslint-import-resolver-webpack: '*'
    -    peerDependenciesMeta:
    -      '@typescript-eslint/parser':
    -        optional: true
    -      eslint:
    -        optional: true
    -      eslint-import-resolver-node:
    -        optional: true
    -      eslint-import-resolver-typescript:
    -        optional: true
    -      eslint-import-resolver-webpack:
    -        optional: true
    -
    -  eslint-plugin-es@4.1.0:
    -    resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==}
    -    engines: {node: '>=8.10.0'}
    -    peerDependencies:
    -      eslint: '>=4.19.1'
    -
    -  eslint-plugin-import@2.32.0:
    -    resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==}
    -    engines: {node: '>=4'}
    -    peerDependencies:
    -      '@typescript-eslint/parser': '*'
    -      eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
    -    peerDependenciesMeta:
    -      '@typescript-eslint/parser':
    -        optional: true
    -
    -  eslint-plugin-n@15.7.0:
    -    resolution: {integrity: sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==}
    -    engines: {node: '>=12.22.0'}
    -    peerDependencies:
    -      eslint: '>=7.0.0'
    -
    -  eslint-plugin-promise@6.6.0:
    -    resolution: {integrity: sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    peerDependencies:
    -      eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
    -
    -  eslint-plugin-react@7.37.5:
    -    resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==}
    -    engines: {node: '>=4'}
    -    peerDependencies:
    -      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
    -
       eslint-scope@5.1.1:
         resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
         engines: {node: '>=8.0.0'}
     
    -  eslint-scope@7.2.2:
    -    resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  eslint-scope@9.1.2:
    -    resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  eslint-utils@2.1.0:
    -    resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
    +  esm@3.2.25:
    +    resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
         engines: {node: '>=6'}
     
    -  eslint-utils@3.0.0:
    -    resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
    -    engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
    -    peerDependencies:
    -      eslint: '>=5'
    -
    -  eslint-visitor-keys@1.3.0:
    -    resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
    +  esprima@4.0.1:
    +    resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
         engines: {node: '>=4'}
    -
    -  eslint-visitor-keys@2.1.0:
    -    resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
    -    engines: {node: '>=10'}
    -
    -  eslint-visitor-keys@3.4.3:
    -    resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  eslint-visitor-keys@5.0.1:
    -    resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  eslint@10.5.0:
    -    resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -    hasBin: true
    -    peerDependencies:
    -      jiti: '*'
    -    peerDependenciesMeta:
    -      jiti:
    -        optional: true
    -
    -  eslint@8.57.1:
    -    resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
    -    hasBin: true
    -
    -  esm@3.2.25:
    -    resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
    -    engines: {node: '>=6'}
    -
    -  espree@11.2.0:
    -    resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==}
    -    engines: {node: ^20.19.0 || ^22.13.0 || >=24}
    -
    -  espree@9.6.1:
    -    resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  esprima@4.0.1:
    -    resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
    -    engines: {node: '>=4'}
    -    hasBin: true
    -
    -  esquery@1.7.0:
    -    resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
    -    engines: {node: '>=0.10'}
    +    hasBin: true
     
       esrecurse@4.3.0:
         resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
    @@ -6375,9 +4956,6 @@ packages:
       estree-util-visit@2.0.0:
         resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
     
    -  estree-walker@1.0.1:
    -    resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
    -
       estree-walker@2.0.2:
         resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
     
    @@ -6392,10 +4970,6 @@ packages:
         resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
         engines: {node: '>= 0.6'}
     
    -  event-target-shim@5.0.1:
    -    resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
    -    engines: {node: '>=6'}
    -
       eventemitter3@4.0.7:
         resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
     
    @@ -6432,10 +5006,6 @@ packages:
       exponential-backoff@3.1.3:
         resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==}
     
    -  expr-eval-fork@3.0.3:
    -    resolution: {integrity: sha512-BhC+hbc5lIVjygr840n5DEkW3MQq7H9o+mc1/N7Z5uIiCFVyESLL5DIE7LNq4CYUNxy+XjA+3jRrL/h0Kt2xcg==}
    -    engines: {node: '>=16.9.0'}
    -
       express-rate-limit@8.6.0:
         resolution: {integrity: sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA==}
         engines: {node: '>= 16'}
    @@ -6466,50 +5036,21 @@ packages:
         resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==}
         engines: {node: '>=18'}
     
    -  fast-deep-equal@1.1.0:
    -    resolution: {integrity: sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==}
    -
    -  fast-deep-equal@2.0.1:
    -    resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==}
    -
       fast-deep-equal@3.1.3:
         resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
     
       fast-fifo@1.3.2:
         resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
     
    -  fast-glob@3.3.3:
    -    resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
    -    engines: {node: '>=8.6.0'}
    -
       fast-json-stable-stringify@2.1.0:
         resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
     
    -  fast-levenshtein@2.0.6:
    -    resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
    -
    -  fast-memoize@2.5.2:
    -    resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==}
    -
       fast-safe-stringify@2.1.1:
         resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
     
       fast-uri@3.1.4:
         resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==}
     
    -  fast-xml-builder@1.2.0:
    -    resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==}
    -
    -  fast-xml-parser@5.10.1:
    -    resolution: {integrity: sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==}
    -    hasBin: true
    -
    -  fastest-stable-stringify@2.0.2:
    -    resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==}
    -
    -  fastq@1.20.1:
    -    resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
    -
       fault@2.0.1:
         resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
     
    @@ -6536,25 +5077,9 @@ packages:
         resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
         engines: {node: ^12.20 || >= 14.13}
     
    -  file-entry-cache@6.0.1:
    -    resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
    -    engines: {node: ^10.12.0 || >=12.0.0}
    -
    -  file-entry-cache@8.0.0:
    -    resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
    -    engines: {node: '>=16.0.0'}
    -
       file-uri-to-path@1.0.0:
         resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
     
    -  filename-reserved-regex@2.0.0:
    -    resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==}
    -    engines: {node: '>=4'}
    -
    -  filenamify@4.3.0:
    -    resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==}
    -    engines: {node: '>=8'}
    -
       fill-range@7.1.1:
         resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
         engines: {node: '>=8'}
    @@ -6571,40 +5096,17 @@ packages:
         resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
         engines: {node: '>=8'}
     
    -  find-up@3.0.0:
    -    resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
    -    engines: {node: '>=6'}
    -
       find-up@4.1.0:
         resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
         engines: {node: '>=8'}
     
    -  find-up@5.0.0:
    -    resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
    -    engines: {node: '>=10'}
    -
    -  find-up@6.3.0:
    -    resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
       fix-dts-default-cjs-exports@1.0.1:
         resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==}
     
    -  flat-cache@3.2.0:
    -    resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
    -    engines: {node: ^10.12.0 || >=12.0.0}
    -
    -  flat-cache@4.0.1:
    -    resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
    -    engines: {node: '>=16'}
    -
       flat@5.0.2:
         resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
         hasBin: true
     
    -  flatted@3.4.2:
    -    resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
    -
       follow-redirects@1.16.0:
         resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
         engines: {node: '>=4.0'}
    @@ -6614,16 +5116,6 @@ packages:
           debug:
             optional: true
     
    -  for-each@0.3.5:
    -    resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
    -    engines: {node: '>= 0.4'}
    -
    -  foreach@2.0.6:
    -    resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==}
    -
    -  foreachasync@3.0.0:
    -    resolution: {integrity: sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw==}
    -
       foreground-child@3.3.1:
         resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
         engines: {node: '>=14'}
    @@ -6659,23 +5151,13 @@ packages:
       fs-constants@1.0.0:
         resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
     
    -  fs-extra@0.6.4:
    -    resolution: {integrity: sha512-5rU898vl/Z948L+kkJedbmo/iltzmiF5bn/eEk0j/SgrPpI+Ydau9xlJPicV7Av2CHYBGz5LAlwTnBU80j1zPQ==}
    -
    -  fs-extra@11.3.4:
    -    resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==}
    -    engines: {node: '>=14.14'}
    -
       fs-extra@11.3.5:
         resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==}
         engines: {node: '>=14.14'}
     
    -  fs-minipass@3.0.3:
    -    resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
    -  fs.extra@1.3.2:
    -    resolution: {integrity: sha512-Ig401VXtyrWrz23k9KxAx9OrnL8AHSLNhQ8YJH2wSYuH0ZUfxwBeY6zXkd/oOyVRFTlpEu/0n5gHeuZt7aqbkw==}
    +  fs-extra@11.4.0:
    +    resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==}
    +    engines: {node: '>=14.14'}
     
       fs.realpath@1.0.0:
         resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
    @@ -6688,20 +5170,9 @@ packages:
       function-bind@1.1.2:
         resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
     
    -  function.prototype.name@1.1.8:
    -    resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
    -    engines: {node: '>= 0.4'}
    -
    -  functions-have-names@1.2.3:
    -    resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
    -
       generate-function@2.3.1:
         resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
     
    -  generator-function@2.0.1:
    -    resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
    -    engines: {node: '>= 0.4'}
    -
       gensync@1.0.0-beta.2:
         resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
         engines: {node: '>=6.9.0'}
    @@ -6725,10 +5196,6 @@ packages:
         resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
         engines: {node: '>= 0.4'}
     
    -  get-stdin@8.0.0:
    -    resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==}
    -    engines: {node: '>=10'}
    -
       get-stream@5.2.0:
         resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
         engines: {node: '>=8'}
    @@ -6737,10 +5204,6 @@ packages:
         resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
         engines: {node: '>=10'}
     
    -  get-symbol-description@1.1.0:
    -    resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
    -    engines: {node: '>= 0.4'}
    -
       get-uri@6.0.5:
         resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==}
         engines: {node: '>= 14'}
    @@ -6758,52 +5221,21 @@ packages:
         resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
         engines: {node: '>= 6'}
     
    -  glob-parent@6.0.2:
    -    resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
    -    engines: {node: '>=10.13.0'}
    -
       glob-to-regex.js@1.2.0:
         resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==}
         engines: {node: '>=10.0'}
         peerDependencies:
           tslib: '2'
     
    -  glob-to-regexp@0.4.1:
    -    resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
    -
       glob@10.5.0:
         resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
         deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
         hasBin: true
     
    -  glob@13.0.6:
    -    resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
    -    engines: {node: 18 || 20 || >=22}
    -
       glob@7.2.3:
         resolution: {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
     
    -  global-dirs@3.0.1:
    -    resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==}
    -    engines: {node: '>=10'}
    -
    -  globals@13.24.0:
    -    resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
    -    engines: {node: '>=8'}
    -
    -  globals@17.6.0:
    -    resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==}
    -    engines: {node: '>=18'}
    -
    -  globalthis@1.0.4:
    -    resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  globby@11.1.0:
    -    resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
    -    engines: {node: '>=10'}
    -
       gopd@1.2.0:
         resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
         engines: {node: '>= 0.4'}
    @@ -6811,9 +5243,6 @@ packages:
       graceful-fs@4.2.11:
         resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
     
    -  graphemer@1.4.0:
    -    resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
    -
       gray-matter@4.0.3:
         resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
         engines: {node: '>=6.0'}
    @@ -6832,21 +5261,10 @@ packages:
         engines: {node: '>=0.4.7'}
         hasBin: true
     
    -  has-bigints@1.1.0:
    -    resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
    -    engines: {node: '>= 0.4'}
    -
       has-flag@4.0.0:
         resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
         engines: {node: '>=8'}
     
    -  has-property-descriptors@1.0.2:
    -    resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
    -
    -  has-proto@1.2.0:
    -    resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
    -    engines: {node: '>= 0.4'}
    -
       has-symbols@1.1.0:
         resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
         engines: {node: '>= 0.4'}
    @@ -6890,20 +5308,6 @@ packages:
       hast-util-whitespace@3.0.0:
         resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
     
    -  header-case@2.0.4:
    -    resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
    -
    -  highlight.js@10.7.3:
    -    resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
    -
    -  hosted-git-info@7.0.2:
    -    resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    -
    -  hosted-git-info@9.0.3:
    -    resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       hpack.js@2.1.6:
         resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==}
     
    @@ -6927,9 +5331,6 @@ packages:
       html5parser@2.0.2:
         resolution: {integrity: sha512-L0y+IdTVxHsovmye8MBtFgBvWZnq1C9WnI/SmJszxoQjmUH1psX2uzDk21O5k5et6udxdGjwxkbmT9eVRoG05w==}
     
    -  http-cache-semantics@4.2.0:
    -    resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
    -
       http-deceiver@1.2.7:
         resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==}
     
    @@ -6991,21 +5392,6 @@ packages:
       ieee754@1.2.1:
         resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
     
    -  ignore-walk@8.0.0:
    -    resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  ignore@5.3.2:
    -    resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
    -    engines: {node: '>= 4'}
    -
    -  ignore@7.0.5:
    -    resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
    -    engines: {node: '>= 4'}
    -
    -  immer@9.0.21:
    -    resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
    -
       immutable@5.1.9:
         resolution: {integrity: sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==}
     
    @@ -7039,18 +5425,6 @@ packages:
       ini@1.3.8:
         resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
     
    -  ini@2.0.0:
    -    resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
    -    engines: {node: '>=10'}
    -
    -  ini@4.1.3:
    -    resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
    -  ini@6.0.0:
    -    resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       inline-style-parser@0.2.7:
         resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
     
    @@ -7066,10 +5440,6 @@ packages:
       interface-store@8.0.0:
         resolution: {integrity: sha512-e2+s3EEROzM+Wlas4hU3zveTUscvVMf1BOvdsJfpzFm19SoEXLVadpACjWOnM491HqGpvtfFnevyiaN8W+I6Eg==}
     
    -  internal-slot@1.1.0:
    -    resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
    -    engines: {node: '>= 0.4'}
    -
       internmap@1.0.1:
         resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
     
    @@ -7110,45 +5480,17 @@ packages:
       is-alphanumerical@2.0.1:
         resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
     
    -  is-array-buffer@3.0.5:
    -    resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
    -    engines: {node: '>= 0.4'}
    -
       is-arrayish@0.2.1:
         resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
     
    -  is-async-function@2.1.1:
    -    resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-bigint@1.1.0:
    -    resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
    -    engines: {node: '>= 0.4'}
    -
       is-binary-path@2.1.0:
         resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
         engines: {node: '>=8'}
     
    -  is-boolean-object@1.2.2:
    -    resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-callable@1.2.7:
    -    resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
    -    engines: {node: '>= 0.4'}
    -
       is-core-module@2.16.2:
         resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
         engines: {node: '>= 0.4'}
     
    -  is-data-view@1.0.2:
    -    resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-date-object@1.1.0:
    -    resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
    -    engines: {node: '>= 0.4'}
    -
       is-decimal@2.0.1:
         resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
     
    @@ -7173,10 +5515,6 @@ packages:
         resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
         engines: {node: '>=0.10.0'}
     
    -  is-finalizationregistry@1.1.1:
    -    resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
    -    engines: {node: '>= 0.4'}
    -
       is-fullwidth-code-point@3.0.0:
         resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
         engines: {node: '>=8'}
    @@ -7185,10 +5523,6 @@ packages:
         resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
         engines: {node: '>=6'}
     
    -  is-generator-function@1.1.2:
    -    resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
    -    engines: {node: '>= 0.4'}
    -
       is-glob@4.0.3:
         resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
         engines: {node: '>=0.10.0'}
    @@ -7204,30 +5538,14 @@ packages:
       is-loopback-addr@2.0.2:
         resolution: {integrity: sha512-26POf2KRCno/KTNL5Q0b/9TYnL00xEsSaLfiFRmjM7m7Lw7ZMmFybzzuX4CcsLAluZGd+niLUiMRxEooVE3aqg==}
     
    -  is-map@2.0.3:
    -    resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-negative-zero@2.0.3:
    -    resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
    -    engines: {node: '>= 0.4'}
    -
       is-network-error@1.3.2:
         resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==}
         engines: {node: '>=16'}
     
    -  is-number-object@1.1.1:
    -    resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
    -    engines: {node: '>= 0.4'}
    -
       is-number@7.0.0:
         resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
         engines: {node: '>=0.12.0'}
     
    -  is-path-inside@3.0.3:
    -    resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
    -    engines: {node: '>=8'}
    -
       is-plain-obj@3.0.0:
         resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==}
         engines: {node: '>=10'}
    @@ -7249,49 +5567,10 @@ packages:
       is-property@1.0.2:
         resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==}
     
    -  is-regex@1.2.1:
    -    resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-set@2.0.3:
    -    resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-shared-array-buffer@1.0.4:
    -    resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
    -    engines: {node: '>= 0.4'}
    -
       is-stream@2.0.1:
         resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
         engines: {node: '>=8'}
     
    -  is-string@1.1.1:
    -    resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-symbol@1.1.1:
    -    resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-typed-array@1.1.15:
    -    resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-unsafe@2.0.0:
    -    resolution: {integrity: sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==}
    -
    -  is-weakmap@2.0.2:
    -    resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-weakref@1.1.1:
    -    resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
    -    engines: {node: '>= 0.4'}
    -
    -  is-weakset@2.0.4:
    -    resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
    -    engines: {node: '>= 0.4'}
    -
       is-wsl@2.2.0:
         resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
         engines: {node: '>=8'}
    @@ -7303,16 +5582,9 @@ packages:
       isarray@1.0.0:
         resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
     
    -  isarray@2.0.5:
    -    resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
    -
       isexe@2.0.0:
         resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
     
    -  isexe@3.1.5:
    -    resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
    -    engines: {node: '>=18'}
    -
       isexe@4.0.0:
         resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==}
         engines: {node: '>=20'}
    @@ -7321,10 +5593,6 @@ packages:
         resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
         engines: {node: '>=0.10.0'}
     
    -  isomorphic-dompurify@2.36.0:
    -    resolution: {integrity: sha512-E8YkGyPY3a/U5s0WOoc8Ok+3SWL/33yn2IHCoxCFLBUUPVy9WGa++akJZFxQCcJIhI+UvYhbrbnTIFQkHKZbgA==}
    -    engines: {node: '>=20.19.5'}
    -
       istanbul-lib-coverage@3.2.2:
         resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
         engines: {node: '>=8'}
    @@ -7392,8 +5660,8 @@ packages:
       it-pushable@3.2.4:
         resolution: {integrity: sha512-WSD7Ss4oCRfDZJT4ldLWr0Bom/muY90xxoJ5PQnU3uSKf0kxCOeehqZtiJX1ARqn+ymXGh1bxpDW9bDNHp2ivQ==}
     
    -  it-queue@1.1.3:
    -    resolution: {integrity: sha512-RP+zN7tq+4EtuUZw5uXDpOmpgd66oKb15I4rKNvNMuB278nMJVRBHakQjnQAjqcVUySo4hEA3XnT3Ge6EvHH5w==}
    +  it-queue@1.1.4:
    +    resolution: {integrity: sha512-cGH0+YfMPmwQ+lV+MhJcOXqOgE04h0zQCXvDUmvGGTyW0VqxJZbi7V+PQFEuPVN/5dHQg5RY9aVjMCgmxXaE5Q==}
     
       it-queueless-pushable@2.0.5:
         resolution: {integrity: sha512-BaKqGLL1AQMR1AEaxiM09vzJQVXHHhfhh9UV0qPqORw/8Rm8igDQqT1qHregfHIb1NIW9jxQ/aXBibHJyuivuQ==}
    @@ -7414,10 +5682,6 @@ packages:
       it-take@3.0.11:
         resolution: {integrity: sha512-zvoeEjLViGFyhYT5KNCgmcIH90Si8lCve4aTMvgej/ZQRfB9YzrcJW3UHIJjbQ9TiAnsT4vsWDImEFQNk5xmnA==}
     
    -  iterator.prototype@1.1.5:
    -    resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
    -    engines: {node: '>= 0.4'}
    -
       jackspeak@3.4.3:
         resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
     
    @@ -7479,8 +5743,9 @@ packages:
         resolution: {integrity: sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==}
         engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
     
    -  jest-fetch-mock@3.0.3:
    -    resolution: {integrity: sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==}
    +  jest-fetch-mock@3.2.0:
    +    resolution: {integrity: sha512-7yGuHznS2mQSUr17H6Q/YMKExuey1ush3Vdvm1QsUzi7PzajSNBiAvMxtS1nucKJYiIF3g4qTtHxG9T10vJjWg==}
    +    engines: {node: '>=12'}
     
       jest-haste-map@30.4.1:
         resolution: {integrity: sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==}
    @@ -7531,9 +5796,6 @@ packages:
         resolution: {integrity: sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==}
         engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
     
    -  jest-simple-summary@1.0.2:
    -    resolution: {integrity: sha512-lYg30USp6YB5eiMIhWprJdMDjxy4apjFZb9Rdpwe5/um5xyJE6GAZVhlK0wqxTTLhYaHz1Gej1DAUFVQzvvPow==}
    -
       jest-snapshot@30.4.1:
         resolution: {integrity: sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==}
         engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
    @@ -7568,10 +5830,6 @@ packages:
           node-notifier:
             optional: true
     
    -  jmespath@0.15.0:
    -    resolution: {integrity: sha512-+kHj8HXArPfpPEKGLZ+kB5ONRTCiGQXo8RQYL0hH8t6pWXUBBK5KkkQmTNOwKK4LEsd0yTsgtjJVm4UBSZea4w==}
    -    engines: {node: '>= 0.6.0'}
    -
       joi@18.2.3:
         resolution: {integrity: sha512-N5A3KTWQpPWT4ExxxPlUx7WmykGXRzhNidWhV41d6Abu9YfI2NyWCJuxdPnslJCPWtbRpSVOWSnSS6GakLM/Rg==}
         engines: {node: '>= 20'}
    @@ -7618,104 +5876,25 @@ packages:
           canvas:
             optional: true
     
    -  jsep@1.4.0:
    -    resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==}
    -    engines: {node: '>= 10.16.0'}
    -
       jsesc@3.1.0:
         resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
         engines: {node: '>=6'}
         hasBin: true
     
    -  json-buffer@3.0.1:
    -    resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
    -
    -  json-e@4.8.2:
    -    resolution: {integrity: sha512-0EzcoDOkNdiAG66q9d1FGHaWJbFy6Sz2Tf9U4kXyV+nMEbA3NUnpiQBdJm3qTqa9js7fATq35/fRYT+RHZcvNw==}
    -    engines: {node: '>=12'}
    -
    -  json-parse-better-errors@1.0.2:
    -    resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
    -
       json-parse-even-better-errors@2.3.1:
         resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
     
    -  json-parse-even-better-errors@3.0.2:
    -    resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
    -  json-parse-even-better-errors@5.0.0:
    -    resolution: {integrity: sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  json-pointer@0.6.2:
    -    resolution: {integrity: sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==}
    -
    -  json-schema-migrate@0.2.0:
    -    resolution: {integrity: sha512-dq4/oHWmtw/+0ytnXsDqVn+VsVweTEmzm5jLgguPn9BjSzn6/q58ZiZx3BHiQyJs612f0T5Z+MrUEUUY5DHsRg==}
    -
    -  json-schema-traverse@0.3.1:
    -    resolution: {integrity: sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==}
    -
    -  json-schema-traverse@0.4.1:
    -    resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
    -
       json-schema-traverse@1.0.0:
         resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
     
    -  json-stable-stringify-without-jsonify@1.0.1:
    -    resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
    -
    -  json-stringify-nice@1.1.4:
    -    resolution: {integrity: sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==}
    -
    -  json5@1.0.2:
    -    resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
    -    hasBin: true
    -
       json5@2.2.3:
         resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
         engines: {node: '>=6'}
         hasBin: true
     
    -  jsonc-parser@2.2.1:
    -    resolution: {integrity: sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==}
    -
    -  jsonfile@1.0.1:
    -    resolution: {integrity: sha512-KbsDJNRfRPF5v49tMNf9sqyyGqGLBcz1v5kZT01kG5ns5mQSltwxCKVmUzVKtEinkUnTDtSrp6ngWpV7Xw0ZlA==}
    -
       jsonfile@6.2.1:
         resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==}
     
    -  jsonparse@1.3.1:
    -    resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
    -    engines: {'0': node >= 0.2.0}
    -
    -  jsonpath-plus@10.4.0:
    -    resolution: {integrity: sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==}
    -    engines: {node: '>=18.0.0'}
    -    hasBin: true
    -
    -  jsonpointer@5.0.1:
    -    resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
    -    engines: {node: '>=0.10.0'}
    -
    -  jsx-ast-utils@3.3.5:
    -    resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
    -    engines: {node: '>=4.0'}
    -
    -  just-curry-it@3.2.1:
    -    resolution: {integrity: sha512-Q8206k8pTY7krW32cdmPsP+DqqLgWx/hYPSj9/+7SYqSqz7UuwPbfSe07lQtvuuaVyiSJveXk0E5RydOuWwsEg==}
    -
    -  just-curry-it@5.3.0:
    -    resolution: {integrity: sha512-silMIRiFjUWlfaDhkgSzpuAyQ6EX/o09Eu8ZBfmFwQMbax7+LQzeIU2CBrICT6Ne4l86ITCGvUCBpCubWYy0Yw==}
    -
    -  just-diff-apply@5.5.0:
    -    resolution: {integrity: sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==}
    -
    -  just-diff@6.0.2:
    -    resolution: {integrity: sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==}
    -
       jwt-simple@0.5.6:
         resolution: {integrity: sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==}
         engines: {node: '>= 0.4.0'}
    @@ -7724,9 +5903,6 @@ packages:
         resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==}
         hasBin: true
     
    -  keyv@4.5.4:
    -    resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
    -
       khroma@2.1.0:
         resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==}
     
    @@ -7734,12 +5910,13 @@ packages:
         resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
         engines: {node: '>=0.10.0'}
     
    -  knex@3.2.10:
    -    resolution: {integrity: sha512-oypTHfrc9i72iyxaUQBKHOxhcr0xM65MPf6FpN02nimsftXwzXprIkLjfXdubvhbu4PMWLp023q8o8CYvHSuZw==}
    +  knex@3.3.0:
    +    resolution: {integrity: sha512-LgWl031hNuLv9Lhxdd9093zULa2aNcoP04Bk29e5NidgRcEr/T0rAr2WYi4BhjTiCDoQiRU56meUE5rppLKZzQ==}
         engines: {node: '>=16'}
         hasBin: true
         peerDependencies:
           better-sqlite3: '*'
    +      mariadb: '*'
           mysql: '*'
           mysql2: '*'
           pg: '*'
    @@ -7750,6 +5927,8 @@ packages:
         peerDependenciesMeta:
           better-sqlite3:
             optional: true
    +      mariadb:
    +        optional: true
           mysql:
             optional: true
           mysql2:
    @@ -7781,16 +5960,8 @@ packages:
         resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
         engines: {node: '>=6'}
     
    -  levenshtein-edit-distance@2.0.5:
    -    resolution: {integrity: sha512-Yuraz7QnMX/JENJU1HA6UtdsbhRzoSFnGpVGVryjQgHtl2s/YmVgmNYkVs5yzVZ9aAvQR9wPBUH3lG755ylxGA==}
    -    hasBin: true
    -
    -  levn@0.4.1:
    -    resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
    -    engines: {node: '>= 0.8.0'}
    -
    -  libp2p@3.3.4:
    -    resolution: {integrity: sha512-K/B7XNepJcDB8g+M36Uh6wQDmhPyN5pyEsVwJPBtrXjouC0xBFmU9z5gRh2phRD0oRj9xvIZQwklo2v3zH4AiQ==}
    +  libp2p@3.3.6:
    +    resolution: {integrity: sha512-iMC6d7Mg+q0x9gwUmw6BGBc/QccOBkx1T6l0xZF4CmVonBe5ndPD5Xryn+EbThxx+37enfTmEZ3XMZAiVbcg4g==}
     
       lightningcss-android-arm64@1.32.0:
         resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
    @@ -7873,60 +6044,23 @@ packages:
       lines-and-columns@1.2.4:
         resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
     
    -  load-json-file@5.3.0:
    -    resolution: {integrity: sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==}
    -    engines: {node: '>=6'}
    -
    -  load-json-file@7.0.1:
    -    resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
       load-tsconfig@0.2.5:
         resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
         engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     
    -  loader-runner@4.3.2:
    -    resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==}
    -    engines: {node: '>=6.11.5'}
    -
    -  locate-path@3.0.0:
    -    resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
    -    engines: {node: '>=6'}
    -
       locate-path@5.0.0:
         resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
         engines: {node: '>=8'}
     
    -  locate-path@6.0.0:
    -    resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
    -    engines: {node: '>=10'}
    -
    -  locate-path@7.2.0:
    -    resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
       lodash-es@4.18.1:
         resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
     
    -  lodash.debounce@4.0.8:
    -    resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
    -
       lodash.memoize@4.1.2:
         resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
     
    -  lodash.merge@4.6.2:
    -    resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
    -
    -  lodash.topath@4.5.2:
    -    resolution: {integrity: sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==}
    -
       lodash@4.18.1:
         resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
     
    -  loglevel@1.9.2:
    -    resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==}
    -    engines: {node: '>= 0.6.0'}
    -
       long@5.3.2:
         resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
     
    @@ -7937,9 +6071,6 @@ packages:
         resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
         hasBin: true
     
    -  lower-case@2.0.2:
    -    resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
    -
       lru-cache@10.4.3:
         resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
     
    @@ -7979,10 +6110,6 @@ packages:
       make-error@1.3.6:
         resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
     
    -  make-fetch-happen@15.0.6:
    -    resolution: {integrity: sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       makeerror@1.0.12:
         resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
     
    @@ -7998,11 +6125,6 @@ packages:
         engines: {node: '>= 20'}
         hasBin: true
     
    -  marked@4.3.0:
    -    resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
    -    engines: {node: '>= 12'}
    -    hasBin: true
    -
       math-intrinsics@1.1.0:
         resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
         engines: {node: '>= 0.4'}
    @@ -8087,12 +6209,8 @@ packages:
       merge-stream@2.0.0:
         resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
     
    -  merge2@1.4.1:
    -    resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
    -    engines: {node: '>= 8'}
    -
    -  mermaid@11.15.0:
    -    resolution: {integrity: sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==}
    +  mermaid@11.16.0:
    +    resolution: {integrity: sha512-Zvm3kbstgdpvIJPPItlL7fppIZ3kibvc1oZIGxdvk9t6UFz6flv+Jw7FtRGKwfcI8OckmH04LqG6LlS6X4B1pA==}
     
       methods@1.1.2:
         resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
    @@ -8251,10 +6369,6 @@ packages:
       minimalistic-assert@1.0.1:
         resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
     
    -  minimatch@10.2.5:
    -    resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
    -    engines: {node: 18 || 20 || >=22}
    -
       minimatch@3.1.5:
         resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
     
    @@ -8265,48 +6379,63 @@ packages:
       minimist@1.2.8:
         resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
     
    -  minipass-collect@2.0.1:
    -    resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==}
    -    engines: {node: '>=16 || 14 >=14.17'}
    -
    -  minipass-fetch@5.0.2:
    -    resolution: {integrity: sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  minipass-flush@1.0.7:
    -    resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==}
    -    engines: {node: '>= 8'}
    -
    -  minipass-pipeline@1.2.4:
    -    resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==}
    -    engines: {node: '>=8'}
    -
    -  minipass-sized@2.0.0:
    -    resolution: {integrity: sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==}
    -    engines: {node: '>=8'}
    -
    -  minipass@3.3.6:
    -    resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
    -    engines: {node: '>=8'}
    -
    -  minipass@7.1.3:
    -    resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
    -    engines: {node: '>=16 || 14 >=14.17'}
    -
    -  minizlib@3.1.0:
    -    resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
    -    engines: {node: '>= 18'}
    -
    -  mitt@3.0.1:
    -    resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
    -
    +  minimizer-webpack-plugin@5.6.1:
    +    resolution: {integrity: sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==}
    +    engines: {node: '>= 10.13.0'}
    +    peerDependencies:
    +      '@minify-html/node': '*'
    +      '@swc/core': '*'
    +      '@swc/css': '*'
    +      '@swc/html': '*'
    +      clean-css: '*'
    +      cssnano: '*'
    +      csso: '*'
    +      esbuild: '*'
    +      html-minifier-terser: '*'
    +      lightningcss: '*'
    +      postcss: '*'
    +      uglify-js: '*'
    +      webpack: ^5.1.0
    +    peerDependenciesMeta:
    +      '@minify-html/node':
    +        optional: true
    +      '@swc/core':
    +        optional: true
    +      '@swc/css':
    +        optional: true
    +      '@swc/html':
    +        optional: true
    +      clean-css:
    +        optional: true
    +      cssnano:
    +        optional: true
    +      csso:
    +        optional: true
    +      esbuild:
    +        optional: true
    +      html-minifier-terser:
    +        optional: true
    +      lightningcss:
    +        optional: true
    +      postcss:
    +        optional: true
    +      uglify-js:
    +        optional: true
    +
    +  minipass@7.1.3:
    +    resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
    +    engines: {node: '>=16 || 14 >=14.17'}
    +
    +  minizlib@3.1.0:
    +    resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
    +    engines: {node: '>= 18'}
    +
    +  mitt@3.0.1:
    +    resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
    +
       mkdirp-classic@0.5.3:
         resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
     
    -  mkdirp@0.3.5:
    -    resolution: {integrity: sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==}
    -    deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
    -
       mlly@1.8.2:
         resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
     
    @@ -8322,15 +6451,15 @@ packages:
         resolution: {integrity: sha512-506AD8qvClVx8Raw/WhAUUWBgIXPyi856iC01aa5vAzHmn6WOXC6ulvudkTF7oTMzJxkyA0A84VpD4BpyfqJ9w==}
         engines: {node: '>=20.19.0'}
     
    -  mongodb@7.3.0:
    -    resolution: {integrity: sha512-WpCqSx7JAU9vcyjm/SU7ydnHls2YrfU3Y3sx4Ml9D7sPe4mXPlaapndiurDXrQ7/VvJkB4/i7b7WovHb8bd8sg==}
    +  mongodb@7.5.0:
    +    resolution: {integrity: sha512-5FnrEDLnvp6ycUOGLNLLU33BfCx2qmp2mJjGPDwKLruYsVzXVSK5fsGpoDXvsXJwBfBsD7ebMRdawbDxC2814g==}
         engines: {node: '>=20.19.0'}
         peerDependencies:
           '@aws-sdk/credential-providers': ^3.806.0
           '@mongodb-js/zstd': ^7.0.0
           gcp-metadata: ^7.0.1
           kerberos: ^7.0.0
    -      mongodb-client-encryption: '>=7.0.0 <7.1.0'
    +      mongodb-client-encryption: ^7.2.0
           snappy: ^7.3.2
           socks: ^2.8.6
         peerDependenciesMeta:
    @@ -8349,9 +6478,6 @@ packages:
           socks:
             optional: true
     
    -  moo@0.5.3:
    -    resolution: {integrity: sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==}
    -
       mortice@3.3.1:
         resolution: {integrity: sha512-t3oESfijIPGsmsdLEKjF+grHfrbnKSXflJtgb1wY14cjxZpS6GnhHRXTxxzCAoCCnq1YYfpEPwY3gjiCPhOufQ==}
     
    @@ -8382,6 +6508,9 @@ packages:
       multiformats@14.0.0:
         resolution: {integrity: sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==}
     
    +  multiformats@14.0.5:
    +    resolution: {integrity: sha512-vbIm83F2yZ1pWJGS0yl0ysracIvv56LtbrIyiIQHoLdYDJOMoLfVFsXhh9DUH4SFdkdkFhucyWniihsNzVEjkQ==}
    +
       mysql2@3.23.1:
         resolution: {integrity: sha512-tTuRnC7qCet2IOfSNMYZ5SwXuBnfvBPAcIA28P0gtruXyZlU1LMxA6uha32kYypoFgyYklMqhLWwt4laYwXR/Q==}
         engines: {node: '>= 8.0'}
    @@ -8408,16 +6537,9 @@ packages:
         engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
         hasBin: true
     
    -  natural-compare-lite@1.4.0:
    -    resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
    -
       natural-compare@1.4.0:
         resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
     
    -  ncp@0.4.2:
    -    resolution: {integrity: sha512-PfGU8jYWdRl4FqJfCy0IzbkGyFHntfWygZg46nFk/dJD/XRrk2cj0SsKSX9n5u5gE0E0YfEpKWrEkfjnlZSTXA==}
    -    hasBin: true
    -
       negotiator@0.6.3:
         resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
         engines: {node: '>= 0.6'}
    @@ -8433,9 +6555,6 @@ packages:
       neo-async@2.6.2:
         resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
     
    -  nested-error-stacks@2.0.1:
    -    resolution: {integrity: sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==}
    -
       netmask@2.1.1:
         resolution: {integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==}
         engines: {node: '>= 0.4.0'}
    @@ -8444,13 +6563,6 @@ packages:
         resolution: {integrity: sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew==}
         engines: {node: '>=12.22.0'}
     
    -  nimma@0.2.3:
    -    resolution: {integrity: sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==}
    -    engines: {node: ^12.20 || >=14.13}
    -
    -  no-case@3.0.4:
    -    resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
    -
       node-abi@3.92.0:
         resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==}
         engines: {node: '>=10'}
    @@ -8467,19 +6579,6 @@ packages:
         engines: {node: '>=10.5.0'}
         deprecated: Use your platform's native DOMException instead
     
    -  node-exports-info@1.6.0:
    -    resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==}
    -    engines: {node: '>= 0.4'}
    -
    -  node-fetch@2.6.7:
    -    resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
    -    engines: {node: 4.x || >=6.0.0}
    -    peerDependencies:
    -      encoding: ^0.1.0
    -    peerDependenciesMeta:
    -      encoding:
    -        optional: true
    -
       node-fetch@2.7.0:
         resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
         engines: {node: 4.x || >=6.0.0}
    @@ -8498,11 +6597,6 @@ packages:
         engines: {node: ^20.17.0 || >=22.9.0}
         hasBin: true
     
    -  node-gyp@12.4.0:
    -    resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -    hasBin: true
    -
       node-int64@0.4.0:
         resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
     
    @@ -8513,68 +6607,19 @@ packages:
         resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==}
         engines: {node: '>=18'}
     
    -  nopt@7.2.1:
    -    resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -    hasBin: true
    +  node-releases@2.0.51:
    +    resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==}
    +    engines: {node: '>=18'}
     
       nopt@9.0.0:
         resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==}
         engines: {node: ^20.17.0 || >=22.9.0}
         hasBin: true
     
    -  normalize-package-data@6.0.2:
    -    resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    -
       normalize-path@3.0.0:
         resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
         engines: {node: '>=0.10.0'}
     
    -  npm-bundled@5.0.0:
    -    resolution: {integrity: sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  npm-install-checks@6.3.0:
    -    resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
    -  npm-install-checks@8.0.0:
    -    resolution: {integrity: sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  npm-normalize-package-bin@3.0.1:
    -    resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
    -  npm-normalize-package-bin@5.0.0:
    -    resolution: {integrity: sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  npm-package-arg@11.0.3:
    -    resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    -
    -  npm-package-arg@13.0.2:
    -    resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  npm-packlist@10.0.4:
    -    resolution: {integrity: sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  npm-pick-manifest@11.0.3:
    -    resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  npm-pick-manifest@9.1.0:
    -    resolution: {integrity: sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==}
    -    engines: {node: ^16.14.0 || >=18.0.0}
    -
    -  npm-registry-fetch@19.1.1:
    -    resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       npm-run-path@4.0.1:
         resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
         engines: {node: '>=8'}
    @@ -8582,42 +6627,17 @@ packages:
       nwsapi@2.2.23:
         resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==}
     
    +  nwsapi@2.2.24:
    +    resolution: {integrity: sha512-7YRhZ3jS45LwmSCT4b2sVFHt/WuovaktDU07QrtOBY2PXskss5a9jfmR9jptyumwXST+rFjrmppMY1KT/yn35A==}
    +
       object-assign@4.1.1:
         resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
         engines: {node: '>=0.10.0'}
     
    -  object-hash@3.0.0:
    -    resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
    -    engines: {node: '>= 6'}
    -
       object-inspect@1.13.4:
         resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
         engines: {node: '>= 0.4'}
     
    -  object-keys@1.1.1:
    -    resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
    -    engines: {node: '>= 0.4'}
    -
    -  object.assign@4.1.7:
    -    resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
    -    engines: {node: '>= 0.4'}
    -
    -  object.entries@1.1.9:
    -    resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==}
    -    engines: {node: '>= 0.4'}
    -
    -  object.fromentries@2.0.8:
    -    resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  object.groupby@1.0.3:
    -    resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  object.values@1.2.1:
    -    resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
    -    engines: {node: '>= 0.4'}
    -
       obuf@1.1.2:
         resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==}
     
    @@ -8649,23 +6669,22 @@ packages:
         resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
         engines: {node: '>=18'}
     
    -  openapi-sampler@1.7.2:
    -    resolution: {integrity: sha512-OKytvqB5XIaTgA9xtw8W8UTar+uymW2xPVpFN0NihMtuHPdPTGxBEhGnfFnJW5g/gOSIvkP+H0Xh3XhVI9/n7g==}
    -
    -  openapi-types@12.1.3:
    -    resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
    -
       opener@1.5.2:
         resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
         hasBin: true
     
    -  optionator@0.9.4:
    -    resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
    -    engines: {node: '>= 0.8.0'}
    -
    -  own-keys@1.0.1:
    -    resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
    -    engines: {node: '>= 0.4'}
    +  oxlint@1.75.0:
    +    resolution: {integrity: sha512-m9WzjRcRYA/uqIZDa9tclrieoPJ/ln1QYTKdFx6NUOs8uY5DiHlIwRQoCrHT6OM6O3ww3l2skY5gO7G7ZphE7g==}
    +    engines: {node: ^20.19.0 || >=22.12.0}
    +    hasBin: true
    +    peerDependencies:
    +      oxlint-tsgolint: '>=7.0.2001'
    +      vite-plus: '*'
    +    peerDependenciesMeta:
    +      oxlint-tsgolint:
    +        optional: true
    +      vite-plus:
    +        optional: true
     
       p-defer@4.0.1:
         resolution: {integrity: sha512-Mr5KC5efvAK5VUptYEIopP1bakB85k2IWXaRC0rsh1uwn1L6M0LVml8OIQ4Gudg4oyZakf7FmeRLkMMtZW1i5A==}
    @@ -8683,38 +6702,14 @@ packages:
         resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
         engines: {node: '>=10'}
     
    -  p-limit@4.0.0:
    -    resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
    -  p-locate@3.0.0:
    -    resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
    -    engines: {node: '>=6'}
    -
       p-locate@4.1.0:
         resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
         engines: {node: '>=8'}
     
    -  p-locate@5.0.0:
    -    resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
    -    engines: {node: '>=10'}
    -
    -  p-locate@6.0.0:
    -    resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
    -  p-map@7.0.4:
    -    resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==}
    -    engines: {node: '>=18'}
    -
       p-queue@8.1.1:
         resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==}
         engines: {node: '>=18'}
     
    -  p-queue@9.1.2:
    -    resolution: {integrity: sha512-ktsDOALzTYTWWF1PbkNVg2rOt+HaOaMWJMUnt7T3qf5tvZ1L8dBW3tObzprBcXNMKkwj+yFSLqHso0x+UFcJXw==}
    -    engines: {node: '>=20'}
    -
       p-queue@9.3.0:
         resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==}
         engines: {node: '>=20'}
    @@ -8753,33 +6748,17 @@ packages:
       package-manager-detector@1.6.0:
         resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
     
    -  pacote@21.5.1:
    -    resolution: {integrity: sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -    hasBin: true
    -
       pagefind@1.5.2:
         resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==}
         hasBin: true
     
    -  param-case@3.0.4:
    -    resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
    -
       parent-module@1.0.1:
         resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
         engines: {node: '>=6'}
     
    -  parse-conflict-json@5.0.1:
    -    resolution: {integrity: sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       parse-entities@4.0.2:
         resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
     
    -  parse-json@4.0.0:
    -    resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
    -    engines: {node: '>=4'}
    -
       parse-json@5.2.0:
         resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
         engines: {node: '>=8'}
    @@ -8794,34 +6773,13 @@ packages:
         resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
         engines: {node: '>= 0.8'}
     
    -  pascal-case@3.1.2:
    -    resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
    -
    -  path-case@3.0.4:
    -    resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
    -
       path-data-parser@0.1.0:
         resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==}
     
    -  path-equal@1.2.5:
    -    resolution: {integrity: sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==}
    -
    -  path-exists@3.0.0:
    -    resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
    -    engines: {node: '>=4'}
    -
       path-exists@4.0.0:
         resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
         engines: {node: '>=8'}
     
    -  path-exists@5.0.0:
    -    resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
    -  path-expression-matcher@1.6.2:
    -    resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==}
    -    engines: {node: '>=14.0.0'}
    -
       path-is-absolute@1.0.1:
         resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
         engines: {node: '>=0.10.0'}
    @@ -8837,10 +6795,6 @@ packages:
         resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
         engines: {node: '>=16 || 14 >=14.18'}
     
    -  path-scurry@2.0.2:
    -    resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
    -    engines: {node: 18 || 20 || >=22}
    -
       path-to-regexp@0.1.13:
         resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==}
     
    @@ -8871,22 +6825,14 @@ packages:
         resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
         engines: {node: '>=12'}
     
    -  pify@4.0.1:
    -    resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
    -    engines: {node: '>=6'}
    +  picomatch@4.0.5:
    +    resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
    +    engines: {node: '>=12'}
     
       pirates@4.0.7:
         resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
         engines: {node: '>= 6'}
     
    -  pkg-conf@3.1.0:
    -    resolution: {integrity: sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==}
    -    engines: {node: '>=6'}
    -
    -  pkg-conf@4.0.0:
    -    resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==}
    -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
    -
       pkg-dir@4.2.0:
         resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
         engines: {node: '>=8'}
    @@ -8908,20 +6854,12 @@ packages:
       points-on-path@0.2.1:
         resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==}
     
    -  pony-cause@1.1.1:
    -    resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==}
    -    engines: {node: '>=12.0.0'}
    -
    -  possible-typed-array-names@1.1.0:
    -    resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
    -    engines: {node: '>= 0.4'}
    -
       postcss-load-config@6.0.1:
         resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
         engines: {node: '>= 18'}
         peerDependencies:
           jiti: '>=1.21.0'
    -      postcss: 8.5.18
    +      postcss: '>=8.0.9'
           tsx: ^4.8.1
           yaml: ^2.4.2
         peerDependenciesMeta:
    @@ -8934,10 +6872,6 @@ packages:
           yaml:
             optional: true
     
    -  postcss-selector-parser@7.1.4:
    -    resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==}
    -    engines: {node: '>=4'}
    -
       postcss@8.5.18:
         resolution: {integrity: sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==}
         engines: {node: ^10 || ^12 || >=14}
    @@ -8948,17 +6882,8 @@ packages:
         deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available.
         hasBin: true
     
    -  prelude-ls@1.2.1:
    -    resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
    -    engines: {node: '>= 0.8.0'}
    -
    -  prettier@3.8.3:
    -    resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
    -    engines: {node: '>=14'}
    -    hasBin: true
    -
    -  prettier@3.8.4:
    -    resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==}
    +  prettier@3.9.6:
    +    resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==}
         engines: {node: '>=14'}
         hasBin: true
     
    @@ -8970,10 +6895,6 @@ packages:
         resolution: {integrity: sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==}
         engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
     
    -  proc-log@4.2.0:
    -    resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
       proc-log@6.1.0:
         resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==}
         engines: {node: ^20.17.0 || >=22.9.0}
    @@ -8981,10 +6902,6 @@ packages:
       process-nextick-args@2.0.1:
         resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
     
    -  proggy@4.0.0:
    -    resolution: {integrity: sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       progress-events@1.1.0:
         resolution: {integrity: sha512-82DVc5tI36neVB3IjdXR11ztwGuoBc98em9ijzubeZKxI47OlV2Znq6mlPqE5xPDzO2Uw98GHiQSjj2favBCRQ==}
     
    @@ -8992,27 +6909,6 @@ packages:
         resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
         engines: {node: '>=0.4.0'}
     
    -  promise-all-reject-late@1.0.1:
    -    resolution: {integrity: sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==}
    -
    -  promise-call-limit@3.0.2:
    -    resolution: {integrity: sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==}
    -
    -  promise-inflight@1.0.1:
    -    resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
    -    peerDependencies:
    -      bluebird: '*'
    -    peerDependenciesMeta:
    -      bluebird:
    -        optional: true
    -
    -  promise-polyfill@8.3.0:
    -    resolution: {integrity: sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==}
    -
    -  promise-retry@2.0.1:
    -    resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
    -    engines: {node: '>=10'}
    -
       prop-types@15.8.1:
         resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
     
    @@ -9022,10 +6918,6 @@ packages:
       property-information@7.2.0:
         resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
     
    -  protobufjs@7.6.5:
    -    resolution: {integrity: sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==}
    -    engines: {node: '>=12.0.0'}
    -
       protons-runtime@5.6.0:
         resolution: {integrity: sha512-/Kde+sB9DsMFrddJT/UZWe6XqvL7SL5dbag/DBCElFKhkwDj7XKt53S+mzLyaDP5OqS0wXjV5SA572uWDaT0Hg==}
     
    @@ -9046,9 +6938,6 @@ packages:
       psl@1.15.0:
         resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
     
    -  pubsub-js@1.9.5:
    -    resolution: {integrity: sha512-5MZ0I9i5JWVO7SizvOviKvZU2qaBbl2KQX150FAA+fJBwYpwOUId7aNygURWSdPzlsA/xZ/InUKXqBbzM0czTA==}
    -
       pump@3.0.4:
         resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
     
    @@ -9056,15 +6945,10 @@ packages:
         resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
         engines: {node: '>=6'}
     
    -  puppeteer-core@24.42.0:
    -    resolution: {integrity: sha512-T4zXokk/izH01fYPhyyev1A4piWiOKrYq7CUFpdoYQxmOnXoV6YjUabmfIjCYkNspSoAXIxRid3Tw+Vg0fthYg==}
    +  puppeteer-core@24.43.1:
    +    resolution: {integrity: sha512-T5ScUMAsmhdNbgDR41AGESYeS6V9MSgetkSnVhhW+gXvzC42VesKCn5ld87gAZDJ6vLHL9GkRvY9WtQWSnwFbw==}
         engines: {node: '>=18'}
     
    -  puppeteer@24.42.0:
    -    resolution: {integrity: sha512-94MoPfFp2eY3eYIMdINkez4IOP5TMHntlZbVx06fHlQTtiQiYgaY0L2Zzfod8PVUkPqP7m3Qlre2v8YS8cudPA==}
    -    engines: {node: '>=18'}
    -    hasBin: true
    -
       pure-rand@7.0.1:
         resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==}
     
    @@ -9087,9 +6971,6 @@ packages:
       querystringify@2.2.0:
         resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
     
    -  queue-microtask@1.2.3:
    -    resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
    -
       race-event@1.6.1:
         resolution: {integrity: sha512-vi7WH5g5KoTFpu2mme/HqZiWH14XSOtg5rfp6raBskBHl7wnmy3F/biAIyY5MsK+BHWhoPhxtZ1Y2R7OHHaWyQ==}
     
    @@ -9099,10 +6980,6 @@ packages:
       race-signal@2.0.0:
         resolution: {integrity: sha512-P31bLhE4ByBX/70QDXMutxnqgwrF1WUXea1O8DXuviAgkdbQ1iQMQotNgzJIBC9yUSn08u/acZrMUhgw7w6GpA==}
     
    -  ramldt2jsonschema@1.2.3:
    -    resolution: {integrity: sha512-+wLDAV2NNv9NkfEUOYStaDu/6RYgYXeC1zLtXE+dMU/jDfjpN4iJnBGycDwFTFaIQGosOQhxph7fEX6Mpwxdug==}
    -    hasBin: true
    -
       random-int@3.1.0:
         resolution: {integrity: sha512-h8CRz8cpvzj0hC/iH/1Gapgcl2TQ6xtnCpyOI5WvWfXf/yrDx2DOU+tD9rX23j36IF11xg1KqB9W11Z18JPMdw==}
         engines: {node: '>=12'}
    @@ -9123,20 +7000,10 @@ packages:
         resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
         hasBin: true
     
    -  react-dom@18.3.1:
    -    resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
    -    peerDependencies:
    -      react: ^18.3.1
    -
    -  react-dom@19.2.7:
    -    resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==}
    +  react-dom@19.2.8:
    +    resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==}
         peerDependencies:
    -      react: ^19.2.7
    -
    -  react-error-boundary@4.1.2:
    -    resolution: {integrity: sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==}
    -    peerDependencies:
    -      react: '>=16.13.1'
    +      react: ^19.2.8
     
       react-fast-compare@3.2.2:
         resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
    @@ -9156,8 +7023,8 @@ packages:
       react-is@18.3.1:
         resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
     
    -  react-is@19.2.7:
    -    resolution: {integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==}
    +  react-is@19.2.8:
    +    resolution: {integrity: sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==}
     
       react-router-dom@6.30.4:
         resolution: {integrity: sha512-q4HvNl+mmDdkS0g+MqiBZNteQJCuimWoOyHMy4T/RQLAn9Z29+E91QXRaxOujeMl2HTzRSS0KFPd7lxX3PjV0Q==}
    @@ -9172,26 +7039,10 @@ packages:
         peerDependencies:
           react: '>=16.8'
     
    -  react@17.0.2:
    -    resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
    -    engines: {node: '>=0.10.0'}
    -
    -  react@18.3.1:
    -    resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
    +  react@19.2.8:
    +    resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==}
         engines: {node: '>=0.10.0'}
     
    -  react@19.2.7:
    -    resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==}
    -    engines: {node: '>=0.10.0'}
    -
    -  read-cmd-shim@6.0.0:
    -    resolution: {integrity: sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
    -  read-package-json-fast@3.0.2:
    -    resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
       readable-stream@2.3.8:
         resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
     
    @@ -9207,9 +7058,6 @@ packages:
         resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
         engines: {node: '>= 14.18.0'}
     
    -  readline@1.3.0:
    -    resolution: {integrity: sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==}
    -
       rechoir@0.8.0:
         resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
         engines: {node: '>= 10.13.0'}
    @@ -9235,17 +7083,6 @@ packages:
       reflect-metadata@0.2.2:
         resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
     
    -  reflect.getprototypeof@1.0.10:
    -    resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
    -    engines: {node: '>= 0.4'}
    -
    -  regenerate-unicode-properties@10.2.2:
    -    resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==}
    -    engines: {node: '>=4'}
    -
    -  regenerate@1.4.2:
    -    resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==}
    -
       regex-recursion@6.0.2:
         resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
     
    @@ -9255,25 +7092,6 @@ packages:
       regex@6.1.0:
         resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
     
    -  regexp.prototype.flags@1.5.4:
    -    resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
    -    engines: {node: '>= 0.4'}
    -
    -  regexpp@3.2.0:
    -    resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
    -    engines: {node: '>=8'}
    -
    -  regexpu-core@6.4.0:
    -    resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==}
    -    engines: {node: '>=4'}
    -
    -  regjsgen@0.8.0:
    -    resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==}
    -
    -  regjsparser@0.13.2:
    -    resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==}
    -    hasBin: true
    -
       rehype-autolink-headings@7.1.0:
         resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==}
     
    @@ -9315,10 +7133,6 @@ packages:
       require-main-filename@2.0.0:
         resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
     
    -  requireg@0.2.2:
    -    resolution: {integrity: sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==}
    -    engines: {node: '>= 4.0.0'}
    -
       requires-port@1.0.0:
         resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
     
    @@ -9334,10 +7148,6 @@ packages:
         resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
         engines: {node: '>=8'}
     
    -  resolve-pkg@2.0.0:
    -    resolution: {integrity: sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==}
    -    engines: {node: '>=8'}
    -
       resolve-tsconfig@1.3.0:
         resolution: {integrity: sha512-Ba5mo3soshb2CnIcNFz75F/80H/2eMVxrlmdgoSDNH7Lr6UAoT3BvxNtc7+VXqKSBlC0SJk2qSXOTcy0/p7cFw==}
         engines: {node: '>=16', pnpm: '>=7'}
    @@ -9349,54 +7159,18 @@ packages:
         engines: {node: '>= 0.4'}
         hasBin: true
     
    -  resolve@1.7.1:
    -    resolution: {integrity: sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==}
    -
    -  resolve@2.0.0-next.6:
    -    resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==}
    -    engines: {node: '>= 0.4'}
    -    hasBin: true
    -
    -  resolve@2.0.0-next.7:
    -    resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==}
    -    engines: {node: '>= 0.4'}
    -    hasBin: true
    -
    -  retry@0.12.0:
    -    resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
    -    engines: {node: '>= 4'}
    -
       retry@0.13.1:
         resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
         engines: {node: '>= 4'}
     
    -  reusify@1.1.0:
    -    resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
    -    engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
    -
    -  rimraf@2.2.8:
    -    resolution: {integrity: sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg==}
    -    deprecated: Rimraf versions prior to v4 are no longer supported
    -    hasBin: true
    -
    -  rimraf@3.0.2:
    -    resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
    -    deprecated: Rimraf versions prior to v4 are no longer supported
    -    hasBin: true
    -
       robust-predicates@3.0.3:
         resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==}
     
    -  rolldown@1.0.3:
    -    resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==}
    +  rolldown@1.1.5:
    +    resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==}
         engines: {node: ^20.19.0 || >=22.12.0}
         hasBin: true
     
    -  rollup@2.80.0:
    -    resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==}
    -    engines: {node: '>=10.0.0'}
    -    hasBin: true
    -
       rollup@4.60.2:
         resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==}
         engines: {node: '>=18.0.0', npm: '>=8.0.0'}
    @@ -9419,37 +7193,15 @@ packages:
         resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==}
         engines: {node: '>=18'}
     
    -  run-parallel@1.2.0:
    -    resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
    -
       rw@1.3.3:
         resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
     
    -  safe-array-concat@1.1.4:
    -    resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==}
    -    engines: {node: '>=0.4'}
    -
       safe-buffer@5.1.2:
         resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
     
       safe-buffer@5.2.1:
         resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
     
    -  safe-push-apply@1.0.0:
    -    resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
    -    engines: {node: '>= 0.4'}
    -
    -  safe-regex-test@1.1.0:
    -    resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
    -    engines: {node: '>= 0.4'}
    -
    -  safe-stable-stringify@1.1.1:
    -    resolution: {integrity: sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==}
    -
    -  safe-stable-stringify@2.5.0:
    -    resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
    -    engines: {node: '>=10'}
    -
       safer-buffer@2.1.2:
         resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
     
    @@ -9458,17 +7210,10 @@ packages:
         engines: {node: '>=14.0.0'}
         hasBin: true
     
    -  sax@1.6.0:
    -    resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
    -    engines: {node: '>=11.0.0'}
    -
       saxes@6.0.0:
         resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
         engines: {node: '>=v12.22.7'}
     
    -  scheduler@0.23.2:
    -    resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
    -
       scheduler@0.27.0:
         resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
     
    @@ -9487,19 +7232,10 @@ packages:
         resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==}
         engines: {node: '>=18'}
     
    -  semver@5.7.2:
    -    resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
    -    hasBin: true
    -
       semver@6.3.1:
         resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
         hasBin: true
     
    -  semver@7.8.1:
    -    resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==}
    -    engines: {node: '>=10'}
    -    hasBin: true
    -
       semver@7.8.5:
         resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
         engines: {node: '>=10'}
    @@ -9513,9 +7249,6 @@ packages:
         resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
         engines: {node: '>= 18'}
     
    -  sentence-case@3.0.4:
    -    resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
    -
       serve-index@1.9.2:
         resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==}
         engines: {node: '>= 0.8.0'}
    @@ -9531,18 +7264,6 @@ packages:
       set-blocking@2.0.0:
         resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
     
    -  set-function-length@1.2.2:
    -    resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
    -    engines: {node: '>= 0.4'}
    -
    -  set-function-name@2.0.2:
    -    resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  set-proto@1.0.0:
    -    resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
    -    engines: {node: '>= 0.4'}
    -
       setprototypeof@1.2.0:
         resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
     
    @@ -9568,8 +7289,8 @@ packages:
       shellwords@0.1.1:
         resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==}
     
    -  shiki@4.2.0:
    -    resolution: {integrity: sha512-hjNax6o/ylDy9lefQEaSDtzaT3iVNtZ3WmpQnbuQNoG4xvnSKf2kSKbihZVO4JRG1TTMejs7CmNRYlWgAL66pQ==}
    +  shiki@4.3.1:
    +    resolution: {integrity: sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw==}
         engines: {node: '>=20'}
     
       side-channel-list@1.0.1:
    @@ -9584,10 +7305,6 @@ packages:
         resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
         engines: {node: '>= 0.4'}
     
    -  side-channel@1.1.0:
    -    resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
    -    engines: {node: '>= 0.4'}
    -
       side-channel@1.1.1:
         resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
         engines: {node: '>= 0.4'}
    @@ -9602,19 +7319,12 @@ packages:
         resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
         engines: {node: '>=14'}
     
    -  sigstore@4.1.1:
    -    resolution: {integrity: sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       simple-concat@1.0.1:
         resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
     
       simple-get@4.0.1:
         resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
     
    -  simple-git@3.36.0:
    -    resolution: {integrity: sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==}
    -
       sirv@3.0.2:
         resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
         engines: {node: '>=18'}
    @@ -9630,18 +7340,15 @@ packages:
         resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
         engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
     
    -  snake-case@3.0.4:
    -    resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
    -
    -  socket.io-adapter@2.5.6:
    -    resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==}
    +  socket.io-adapter@2.5.8:
    +    resolution: {integrity: sha512-6Oy52pbg+kvdCVvjcN+FnY7BvxZ7cIHNScbvztT/It5d0vbwoJoVZmF2gjJmnV0/4WlXRfG15zc45ySk9Ah8bw==}
     
       socket.io-client@4.8.3:
         resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==}
         engines: {node: '>=10.0.0'}
     
    -  socket.io-parser@4.2.6:
    -    resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==}
    +  socket.io-parser@4.2.7:
    +    resolution: {integrity: sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg==}
         engines: {node: '>=10.0.0'}
     
       socket.io@4.8.3:
    @@ -9669,10 +7376,6 @@ packages:
       source-map-support@0.5.21:
         resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
     
    -  source-map@0.5.7:
    -    resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
    -    engines: {node: '>=0.10.0'}
    -
       source-map@0.6.1:
         resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
         engines: {node: '>=0.10.0'}
    @@ -9687,21 +7390,6 @@ packages:
       sparse-bitfield@3.0.3:
         resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==}
     
    -  spdx-correct@3.2.0:
    -    resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
    -
    -  spdx-exceptions@2.5.0:
    -    resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
    -
    -  spdx-expression-parse@3.0.1:
    -    resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
    -
    -  spdx-expression-parse@4.0.0:
    -    resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==}
    -
    -  spdx-license-ids@3.0.23:
    -    resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==}
    -
       spdy-transport@3.0.0:
         resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==}
     
    @@ -9720,10 +7408,6 @@ packages:
         resolution: {integrity: sha512-X0czUUMG2tmSqJpEQa3tCuZSHKIx8PwM53vLZzKp/o6Rpy25fiVfjdbnZ988M8+O3ZWR1ih0K255VumCb3MAnQ==}
         engines: {node: '>=20.17.0'}
     
    -  ssri@13.0.1:
    -    resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       stack-utils@2.0.6:
         resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
         engines: {node: '>=10'}
    @@ -9731,15 +7415,6 @@ packages:
       stackback@0.0.2:
         resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
     
    -  standard-engine@15.1.0:
    -    resolution: {integrity: sha512-VHysfoyxFu/ukT+9v49d4BRXIokFRZuH3z1VRxzFArZdjSCFpro6rEIU3ji7e4AoAtuSfKBkiOmsrDqKW5ZSRw==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -
    -  standard@17.1.2:
    -    resolution: {integrity: sha512-WLm12WoXveKkvnPnPnaFUUHuOB2cUdAsJ4AiGHL2G0UNMrcRAWY2WriQaV8IQ3oRmYr0AWUbLNr94ekYFAHOrA==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    hasBin: true
    -
       statuses@1.5.0:
         resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
         engines: {node: '>= 0.6'}
    @@ -9751,13 +7426,12 @@ packages:
       std-env@4.1.0:
         resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
     
    -  stop-iteration-iterator@1.1.0:
    -    resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
    -    engines: {node: '>= 0.4'}
    -
       streamx@2.25.0:
         resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==}
     
    +  streamx@2.28.0:
    +    resolution: {integrity: sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==}
    +
       string-length@4.0.2:
         resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
         engines: {node: '>=10'}
    @@ -9770,25 +7444,6 @@ packages:
         resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
         engines: {node: '>=12'}
     
    -  string.prototype.matchall@4.0.12:
    -    resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
    -    engines: {node: '>= 0.4'}
    -
    -  string.prototype.repeat@1.0.0:
    -    resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
    -
    -  string.prototype.trim@1.2.10:
    -    resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==}
    -    engines: {node: '>= 0.4'}
    -
    -  string.prototype.trimend@1.0.9:
    -    resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  string.prototype.trimstart@1.0.8:
    -    resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
    -    engines: {node: '>= 0.4'}
    -
       string_decoder@1.1.1:
         resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
     
    @@ -9810,10 +7465,6 @@ packages:
         resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
         engines: {node: '>=0.10.0'}
     
    -  strip-bom@3.0.0:
    -    resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
    -    engines: {node: '>=4'}
    -
       strip-bom@4.0.0:
         resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
         engines: {node: '>=8'}
    @@ -9834,13 +7485,6 @@ packages:
         resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
         engines: {node: '>=8'}
     
    -  strip-outer@1.0.1:
    -    resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==}
    -    engines: {node: '>=0.10.0'}
    -
    -  strnum@2.4.1:
    -    resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==}
    -
       style-to-js@1.1.21:
         resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==}
     
    @@ -9882,12 +7526,8 @@ packages:
       symbol-tree@3.2.4:
         resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
     
    -  sync-fetch@0.5.2:
    -    resolution: {integrity: sha512-6gBqqkHrYvkH65WI2bzrDwrIKmt3U10s4Exnz3dYuE5Ah62FIfNv/F63inrNhu2Nyh3GH5f42GKU3RrSJoaUyQ==}
    -    engines: {node: '>=14'}
    -
    -  synckit@0.11.12:
    -    resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
    +  synckit@0.11.13:
    +    resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==}
         engines: {node: ^14.18.0 || >=16.0.0}
     
       tapable@2.3.3:
    @@ -9897,8 +7537,8 @@ packages:
       tar-fs@2.1.4:
         resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==}
     
    -  tar-fs@3.1.2:
    -    resolution: {integrity: sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==}
    +  tar-fs@3.1.3:
    +    resolution: {integrity: sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==}
     
       tar-stream@2.2.0:
         resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
    @@ -9911,58 +7551,15 @@ packages:
         resolution: {integrity: sha512-XdhtCvlMywwxpCW8YEq3lOXBJpUPTR2OHHcwLPO3HwsJqOHa2Ok/oJ7ruGzp+JrKoRPVCzJwAdEjqLW/vNRPHA==}
         engines: {node: '>=18'}
     
    -  tarn@3.0.2:
    -    resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==}
    +  tarn@3.1.2:
    +    resolution: {integrity: sha512-3RTvqKZcK/17jnJ8rMKFXbyNogywTs1z0gVPPwFsJGX46rkmUHOdIaSQ/aVO1rS7nH+soiXiWk7rvUXxndm8Dg==}
         engines: {node: '>=8.0.0'}
     
       teex@1.0.1:
         resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==}
     
    -  terser-webpack-plugin@5.6.0:
    -    resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==}
    -    engines: {node: '>= 10.13.0'}
    -    peerDependencies:
    -      '@minify-html/node': '*'
    -      '@swc/core': '*'
    -      '@swc/css': '*'
    -      '@swc/html': '*'
    -      clean-css: '*'
    -      cssnano: '*'
    -      csso: '*'
    -      esbuild: '*'
    -      html-minifier-terser: '*'
    -      lightningcss: '*'
    -      postcss: '*'
    -      uglify-js: '*'
    -      webpack: ^5.1.0
    -    peerDependenciesMeta:
    -      '@minify-html/node':
    -        optional: true
    -      '@swc/core':
    -        optional: true
    -      '@swc/css':
    -        optional: true
    -      '@swc/html':
    -        optional: true
    -      clean-css:
    -        optional: true
    -      cssnano:
    -        optional: true
    -      csso:
    -        optional: true
    -      esbuild:
    -        optional: true
    -      html-minifier-terser:
    -        optional: true
    -      lightningcss:
    -        optional: true
    -      postcss:
    -        optional: true
    -      uglify-js:
    -        optional: true
    -
    -  terser@5.48.0:
    -    resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==}
    +  terser@5.49.0:
    +    resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==}
         engines: {node: '>=10'}
         hasBin: true
     
    @@ -9973,9 +7570,6 @@ packages:
       text-decoder@1.2.7:
         resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==}
     
    -  text-table@0.2.0:
    -    resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
    -
       thenify-all@1.6.0:
         resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
         engines: {node: '>=0.8'}
    @@ -10083,26 +7677,12 @@ packages:
         resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
         hasBin: true
     
    -  treeverse@3.0.0:
    -    resolution: {integrity: sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
       trim-lines@3.0.1:
         resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
     
    -  trim-repeated@1.0.0:
    -    resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==}
    -    engines: {node: '>=0.10.0'}
    -
       trough@2.2.0:
         resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
     
    -  ts-api-utils@2.5.0:
    -    resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
    -    engines: {node: '>=18.12'}
    -    peerDependencies:
    -      typescript: '>=4.8.4'
    -
       ts-dedent@2.2.0:
         resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
         engines: {node: '>=6.10'}
    @@ -10110,33 +7690,6 @@ packages:
       ts-interface-checker@0.1.13:
         resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
     
    -  ts-jest@29.4.11:
    -    resolution: {integrity: sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==}
    -    engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0}
    -    hasBin: true
    -    peerDependencies:
    -      '@babel/core': '>=7.0.0-beta.0 <8'
    -      '@jest/transform': ^29.0.0 || ^30.0.0
    -      '@jest/types': ^29.0.0 || ^30.0.0
    -      babel-jest: ^29.0.0 || ^30.0.0
    -      esbuild: '*'
    -      jest: ^29.0.0 || ^30.0.0
    -      jest-util: ^29.0.0 || ^30.0.0
    -      typescript: '>=4.3 <7'
    -    peerDependenciesMeta:
    -      '@babel/core':
    -        optional: true
    -      '@jest/transform':
    -        optional: true
    -      '@jest/types':
    -        optional: true
    -      babel-jest:
    -        optional: true
    -      esbuild:
    -        optional: true
    -      jest-util:
    -        optional: true
    -
       ts-jest@29.4.12:
         resolution: {integrity: sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==}
         engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0}
    @@ -10189,20 +7742,10 @@ packages:
           '@swc/wasm':
             optional: true
     
    -  ts-standard@12.0.2:
    -    resolution: {integrity: sha512-XX2wrB9fKKTfBj4yD3ABm9iShzZcS2iWcPK8XzlBvuL20+wMiLgiz/k5tXgZwTaYq5wRhbks1Y9PelhujF/9ag==}
    -    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
    -    hasBin: true
    -    peerDependencies:
    -      typescript: '*'
    -
       ts2md@0.2.8:
         resolution: {integrity: sha512-N//+ifSuygSfj8s169G3MZF9MwI7r65lwA10gwR6hnetfCTV6lBHinn/Ax9UT0YH5Qof9Wl2OjbP41Ny7/i+iw==}
         hasBin: true
     
    -  tsconfig-paths@3.15.0:
    -    resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
    -
       tsconfig-to-dual-package@1.2.0:
         resolution: {integrity: sha512-UtMinqTLfWr9fX6KidLsEcCJoA/jSLPIS00ohpQybMSxA3LlJCRf2DsGPw4AJJ8AP4FOHfbQJFJ5XgLoL7RoLw==}
         engines: {node: '>=18.3.0 || >=16.17.0'}
    @@ -10223,7 +7766,7 @@ packages:
         peerDependencies:
           '@microsoft/api-extractor': ^7.36.0
           '@swc/core': ^1
    -      postcss: 8.5.18
    +      postcss: ^8.4.12
           typescript: '>=4.5.0'
         peerDependenciesMeta:
           '@microsoft/api-extractor':
    @@ -10235,14 +7778,8 @@ packages:
           typescript:
             optional: true
     
    -  tsutils@3.21.0:
    -    resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
    -    engines: {node: '>= 6'}
    -    peerDependencies:
    -      typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
    -
    -  tsx@4.22.4:
    -    resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==}
    +  tsx@4.23.1:
    +    resolution: {integrity: sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==}
         engines: {node: '>=18.0.0'}
         hasBin: true
     
    @@ -10250,33 +7787,17 @@ packages:
         resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==}
         engines: {node: '>= 6.0.0'}
     
    -  tuf-js@4.1.0:
    -    resolution: {integrity: sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       tunnel-agent@0.6.0:
         resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
     
    -  type-check@0.4.0:
    -    resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
    -    engines: {node: '>= 0.8.0'}
    -
       type-detect@4.0.8:
         resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
         engines: {node: '>=4'}
     
    -  type-fest@0.20.2:
    -    resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
    -    engines: {node: '>=10'}
    -
       type-fest@0.21.3:
         resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
         engines: {node: '>=10'}
     
    -  type-fest@0.3.1:
    -    resolution: {integrity: sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==}
    -    engines: {node: '>=6'}
    -
       type-fest@4.41.0:
         resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
         engines: {node: '>=16'}
    @@ -10289,41 +7810,9 @@ packages:
         resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==}
         engines: {node: '>= 18'}
     
    -  typed-array-buffer@1.0.3:
    -    resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
    -    engines: {node: '>= 0.4'}
    -
    -  typed-array-byte-length@1.0.3:
    -    resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
    -    engines: {node: '>= 0.4'}
    -
    -  typed-array-byte-offset@1.0.4:
    -    resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
    -    engines: {node: '>= 0.4'}
    -
    -  typed-array-length@1.0.7:
    -    resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
    -    engines: {node: '>= 0.4'}
    -
       typed-query-selector@2.12.2:
         resolution: {integrity: sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==}
     
    -  typescript-eslint@8.61.1:
    -    resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==}
    -    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    -    peerDependencies:
    -      eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
    -      typescript: '>=4.8.4 <6.1.0'
    -
    -  typescript-json-schema@0.58.1:
    -    resolution: {integrity: sha512-EcmquhfGEmEJOAezLZC6CzY0rPNzfXuky+Z3zoXULEEncW8e13aAjmC2r8ppT1bvvDekJj1TJ4xVhOdkjYtkUA==}
    -    hasBin: true
    -
    -  typescript@4.9.5:
    -    resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
    -    engines: {node: '>=4.2.0'}
    -    hasBin: true
    -
       typescript@5.9.3:
         resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
         engines: {node: '>=14.17'}
    @@ -10360,10 +7849,6 @@ packages:
       uint8arrays@6.1.1:
         resolution: {integrity: sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==}
     
    -  unbox-primitive@1.1.0:
    -    resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
    -    engines: {node: '>= 0.4'}
    -
       undici-types@8.3.0:
         resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==}
     
    @@ -10375,22 +7860,6 @@ packages:
         resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==}
         engines: {node: '>=20.18.1'}
     
    -  unicode-canonical-property-names-ecmascript@2.0.1:
    -    resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
    -    engines: {node: '>=4'}
    -
    -  unicode-match-property-ecmascript@2.0.0:
    -    resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==}
    -    engines: {node: '>=4'}
    -
    -  unicode-match-property-value-ecmascript@2.2.1:
    -    resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==}
    -    engines: {node: '>=4'}
    -
    -  unicode-property-aliases-ecmascript@2.2.0:
    -    resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==}
    -    engines: {node: '>=4'}
    -
       unified@11.0.5:
         resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
     
    @@ -10440,37 +7909,15 @@ packages:
         peerDependencies:
           browserslist: '>= 4.21.0'
     
    -  upper-case-first@2.0.2:
    -    resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
    -
    -  upper-case@2.0.2:
    -    resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}
    -
    -  uri-js@4.4.1:
    -    resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
    -
    -  urijs@1.19.11:
    -    resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==}
    -
       url-parse@1.5.10:
         resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
     
    -  use-resize-observer@9.1.0:
    -    resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==}
    -    peerDependencies:
    -      react: 16.8.0 - 18
    -      react-dom: 16.8.0 - 18
    -
       utf8-codec@1.0.0:
         resolution: {integrity: sha512-S/QSLezp3qvG4ld5PUfXiH7mCFxLKjSVZRFkB3DOjgwHuJPFDkInAXc/anf7BAbHt/D38ozDzL+QMZ6/7gsI6w==}
     
       util-deprecate@1.0.2:
         resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
     
    -  utility-types@3.11.0:
    -    resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==}
    -    engines: {node: '>= 4'}
    -
       utils-merge@1.0.1:
         resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
         engines: {node: '>= 0.4.0'}
    @@ -10495,33 +7942,18 @@ packages:
         resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==}
         engines: {node: '>=10.12.0'}
     
    -  validate-npm-package-license@3.0.4:
    -    resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
    -
    -  validate-npm-package-name@5.0.1:
    -    resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==}
    -    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
    -
    -  validate-npm-package-name@7.0.2:
    -    resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       vary@1.1.2:
         resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
         engines: {node: '>= 0.8'}
     
    -  version-guard@1.1.3:
    -    resolution: {integrity: sha512-JwPr6erhX53EWH/HCSzfy1tTFrtPXUe927wdM1jqBBeYp1OM+qPHjWbsvv6pIBduqdgxxS+ScfG7S28pzyr2DQ==}
    -    engines: {node: '>=0.10.48'}
    -
       vfile-message@4.0.3:
         resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
     
       vfile@6.0.3:
         resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
     
    -  vite-react-ssg@0.9.0:
    -    resolution: {integrity: sha512-p2gs03xrtyL6Vl+kT/ePKr1vPfjZAe1NGY8gnGdS4Rs2qE5xNwfweBBw/+IUwnn9g5Oj7Wu2fd+DTyhQbhRtNg==}
    +  vite-react-ssg@0.9.2:
    +    resolution: {integrity: sha512-spwcC9RtCwGkuQHBkzLNLiuqnSvvQKDas4JFEIi2/tOG06O9MSNIgT4s48hMpOz2Cso8uyNHwB0s7gAnlh4SbA==}
         hasBin: true
         peerDependencies:
           '@tanstack/react-router': '*'
    @@ -10533,7 +7965,7 @@ packages:
           react-dom: ^17.0.2 || ^18.0.0 || ^19.0.0
           react-router-dom: ^6.14.1
           styled-components: ^6.0.0
    -      vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
    +      vite: ^6.4.0 || ^7.3.0 || ^8.0.0
         peerDependenciesMeta:
           '@tanstack/react-router':
             optional: true
    @@ -10550,13 +7982,13 @@ packages:
           styled-components:
             optional: true
     
    -  vite@8.0.16:
    -    resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==}
    +  vite@8.1.5:
    +    resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==}
         engines: {node: ^20.19.0 || >=22.12.0}
         hasBin: true
         peerDependencies:
           '@types/node': ^20.19.0 || >=22.12.0
    -      '@vitejs/devtools': ^0.1.18
    +      '@vitejs/devtools': ^0.3.0
           esbuild: ^0.27.0 || ^0.28.0
           jiti: '>=1.21.0'
           less: ^4.0.0
    @@ -10593,20 +8025,20 @@ packages:
           yaml:
             optional: true
     
    -  vitest@4.1.9:
    -    resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==}
    +  vitest@4.1.10:
    +    resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==}
         engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
         hasBin: true
         peerDependencies:
           '@edge-runtime/vm': '*'
           '@opentelemetry/api': ^1.9.0
           '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
    -      '@vitest/browser-playwright': 4.1.9
    -      '@vitest/browser-preview': 4.1.9
    -      '@vitest/browser-webdriverio': 4.1.9
    -      '@vitest/coverage-istanbul': 4.1.9
    -      '@vitest/coverage-v8': 4.1.9
    -      '@vitest/ui': 4.1.9
    +      '@vitest/browser-playwright': 4.1.10
    +      '@vitest/browser-preview': 4.1.10
    +      '@vitest/browser-webdriverio': 4.1.10
    +      '@vitest/coverage-istanbul': 4.1.10
    +      '@vitest/coverage-v8': 4.1.10
    +      '@vitest/ui': 4.1.10
           happy-dom: '*'
           jsdom: '*'
           vite: ^6.0.0 || ^7.0.0 || ^8.0.0
    @@ -10638,21 +8070,11 @@ packages:
         resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
         engines: {node: '>=18'}
     
    -  walk-up-path@3.0.1:
    -    resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==}
    -
    -  walk-up-path@4.0.0:
    -    resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
    -    engines: {node: 20 || >=22}
    -
    -  walk@2.3.15:
    -    resolution: {integrity: sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg==}
    -
       walker@1.0.8:
         resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
     
    -  watchpack@2.5.1:
    -    resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==}
    +  watchpack@2.5.2:
    +    resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==}
         engines: {node: '>=10.13.0'}
     
       wbuf@1.7.3:
    @@ -10665,9 +8087,6 @@ packages:
         resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
         engines: {node: '>= 8'}
     
    -  webapi-parser@0.5.0:
    -    resolution: {integrity: sha512-fPt6XuMqLSvBz8exwX4QE1UT+pROLHa00EMDCdO0ybICduwQ1V4f7AWX4pNOpCp+x+0FjczEsOxtQU0d8L3QKw==}
    -
       webdriver-bidi-protocol@0.4.1:
         resolution: {integrity: sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==}
     
    @@ -10682,20 +8101,29 @@ packages:
         resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
         engines: {node: '>=20'}
     
    -  webpack-bundle-analyzer@5.3.0:
    -    resolution: {integrity: sha512-PEhAoqiJ+47d0uLMx/+zo5XOvaU+Vk6N2ZLht7H3n09QLy/fhyvqGNwjdRUHJDgMN8crBR2ZwVHkIswT3Xuawg==}
    +  webpack-bundle-analyzer@5.3.1:
    +    resolution: {integrity: sha512-wP2EusncRGL1tZyMHC/umLkjPdYMkTL9nPEKh8G8dkYCJ9TyF6xnXFqjhdqmv5J900irN/g0P5jMvLT22krEXQ==}
         engines: {node: '>= 20.9.0'}
         hasBin: true
     
    -  webpack-cli@7.0.3:
    -    resolution: {integrity: sha512-2E2C6A1e2El7791zQgTH7LPIuwLjRliow9OHS/qlJc9pwhZlCoL/uiwqd/1WSlXT83wJfmfDbkcqHXuXoPJZ3g==}
    +  webpack-cli@7.2.1:
    +    resolution: {integrity: sha512-YwSGbcZdfz12DM8JIseVPr3oBb09IgVCVc4vY3oDvZnI/mALTGPAP1QiqOi4/bBLSJrRHaqDIXeHcNA0+G38aw==}
         engines: {node: '>=20.9.0'}
         hasBin: true
         peerDependencies:
    +      js-yaml: ^4.0.0 || ^5.0.0
    +      json5: ^2.2.3
    +      toml: ^3.0.0 || ^4.0.0
           webpack: ^5.101.0
           webpack-bundle-analyzer: ^4.0.0 || ^5.0.0
    -      webpack-dev-server: 5.2.6
    +      webpack-dev-server: ^5.0.0 || ^6.0.0
         peerDependenciesMeta:
    +      js-yaml:
    +        optional: true
    +      json5:
    +        optional: true
    +      toml:
    +        optional: true
           webpack-bundle-analyzer:
             optional: true
           webpack-dev-server:
    @@ -10727,12 +8155,12 @@ packages:
         resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==}
         engines: {node: '>=18.0.0'}
     
    -  webpack-sources@3.5.0:
    -    resolution: {integrity: sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==}
    +  webpack-sources@3.5.1:
    +    resolution: {integrity: sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==}
         engines: {node: '>=10.13.0'}
     
    -  webpack@5.107.2:
    -    resolution: {integrity: sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ==}
    +  webpack@5.109.0:
    +    resolution: {integrity: sha512-vomrngskVVXEZF9sMZfYAd4pXZUnfaWdJGlF+BTNF+gJBCKYCQBnOeVPlrh39Ewl7nlCsirDplMy6o5g9xJHBg==}
         engines: {node: '>=10.13.0'}
         hasBin: true
         peerDependencies:
    @@ -10777,35 +8205,14 @@ packages:
         resolution: {integrity: sha512-XUguZbDxCA2wBn2LoFtcEhXL6AXo+hVjGonwhSTTTU9SzbWG8Xu3onNIpzf9j/mYUcJQ0f+m37SzG77G851uFw==}
         engines: {node: '>=16.0.0', npm: '>=7.0.0'}
     
    -  which-boxed-primitive@1.1.1:
    -    resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
    -    engines: {node: '>= 0.4'}
    -
    -  which-builtin-type@1.2.1:
    -    resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
    -    engines: {node: '>= 0.4'}
    -
    -  which-collection@1.0.2:
    -    resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
    -    engines: {node: '>= 0.4'}
    -
       which-module@2.0.1:
         resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
     
    -  which-typed-array@1.1.20:
    -    resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==}
    -    engines: {node: '>= 0.4'}
    -
       which@2.0.2:
         resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
         engines: {node: '>= 8'}
         hasBin: true
     
    -  which@4.0.0:
    -    resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
    -    engines: {node: ^16.13.0 || >=18.0.0}
    -    hasBin: true
    -
       which@6.0.1:
         resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==}
         engines: {node: ^20.17.0 || >=22.9.0}
    @@ -10819,10 +8226,6 @@ packages:
       wildcard@2.0.1:
         resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==}
     
    -  word-wrap@1.2.5:
    -    resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
    -    engines: {node: '>=0.10.0'}
    -
       wordwrap@1.0.0:
         resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
     
    @@ -10845,10 +8248,6 @@ packages:
         resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
         engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
     
    -  write-file-atomic@7.0.1:
    -    resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==}
    -    engines: {node: ^20.17.0 || >=22.9.0}
    -
       ws@8.21.0:
         resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
         engines: {node: '>=10.0.0'}
    @@ -10861,34 +8260,26 @@ packages:
           utf-8-validate:
             optional: true
     
    +  ws@8.21.1:
    +    resolution: {integrity: sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==}
    +    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
    +
       wsl-utils@0.1.0:
         resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
         engines: {node: '>=18'}
     
    -  xdg-basedir@4.0.0:
    -    resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==}
    -    engines: {node: '>=8'}
    -
       xml-name-validator@5.0.0:
         resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
         engines: {node: '>=18'}
     
    -  xml-naming@0.1.0:
    -    resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==}
    -    engines: {node: '>=16.0.0'}
    -
    -  xml-naming@0.3.0:
    -    resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==}
    -    engines: {node: '>=16.0.0'}
    -
    -  xml2js@0.5.0:
    -    resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==}
    -    engines: {node: '>=4.0.0'}
    -
    -  xmlbuilder@11.0.1:
    -    resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
    -    engines: {node: '>=4.0'}
    -
       xmlchars@2.2.0:
         resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
     
    @@ -10909,9 +8300,6 @@ packages:
       yallist@3.1.1:
         resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
     
    -  yallist@4.0.0:
    -    resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
    -
       yallist@5.0.0:
         resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
         engines: {node: '>=18'}
    @@ -10925,6 +8313,11 @@ packages:
         engines: {node: '>= 14.6'}
         hasBin: true
     
    +  yaml@2.9.0:
    +    resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
    +    engines: {node: '>= 14.6'}
    +    hasBin: true
    +
       yargs-parser@18.1.3:
         resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
         engines: {node: '>=6'}
    @@ -10937,10 +8330,6 @@ packages:
         resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
         engines: {node: '>=8'}
     
    -  yargs@17.7.2:
    -    resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
    -    engines: {node: '>=12'}
    -
       yargs@17.7.3:
         resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==}
         engines: {node: '>=12'}
    @@ -10960,10 +8349,6 @@ packages:
         resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
         engines: {node: '>=10'}
     
    -  yocto-queue@1.2.2:
    -    resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
    -    engines: {node: '>=12.20'}
    -
       zod@3.25.76:
         resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
     
    @@ -10972,7 +8357,8 @@ packages:
     
     snapshots:
     
    -  '@acemir/cssom@0.9.31': {}
    +  '@acemir/cssom@0.9.31':
    +    optional: true
     
       '@adobe/css-tools@4.4.4': {}
     
    @@ -10981,33 +8367,6 @@ snapshots:
           package-manager-detector: 1.6.0
           tinyexec: 1.2.2
     
    -  '@apidevtools/json-schema-ref-parser@11.7.2':
    -    dependencies:
    -      '@jsdevtools/ono': 7.1.3
    -      '@types/json-schema': 7.0.15
    -      js-yaml: 4.3.0
    -
    -  '@apidevtools/json-schema-ref-parser@11.9.3':
    -    dependencies:
    -      '@jsdevtools/ono': 7.1.3
    -      '@types/json-schema': 7.0.15
    -      js-yaml: 4.3.0
    -
    -  '@apidevtools/openapi-schemas@2.1.0': {}
    -
    -  '@apidevtools/swagger-methods@3.0.2': {}
    -
    -  '@apidevtools/swagger-parser@10.1.1(openapi-types@12.1.3)':
    -    dependencies:
    -      '@apidevtools/json-schema-ref-parser': 11.7.2
    -      '@apidevtools/openapi-schemas': 2.1.0
    -      '@apidevtools/swagger-methods': 3.0.2
    -      '@jsdevtools/ono': 7.1.3
    -      ajv: 8.20.0
    -      ajv-draft-04: 1.0.0(ajv@8.20.0)
    -      call-me-maybe: 1.0.2
    -      openapi-types: 12.1.3
    -
       '@asamuzakjp/css-color@3.2.0':
         dependencies:
           '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
    @@ -11023,6 +8382,7 @@ snapshots:
           '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
           '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
           '@csstools/css-tokenizer': 4.0.0
    +    optional: true
     
       '@asamuzakjp/dom-selector@6.8.1':
         dependencies:
    @@ -11031,299 +8391,23 @@ snapshots:
           css-tree: 3.2.1
           is-potential-custom-element-name: 1.0.1
           lru-cache: 11.5.1
    +    optional: true
     
    -  '@asamuzakjp/generational-cache@1.0.1': {}
    +  '@asamuzakjp/generational-cache@1.0.1':
    +    optional: true
     
    -  '@asamuzakjp/nwsapi@2.3.9': {}
    +  '@asamuzakjp/nwsapi@2.3.9':
    +    optional: true
     
    -  '@asyncapi/avro-schema-parser@3.0.24(encoding@0.1.13)':
    +  '@babel/code-frame@7.29.7':
         dependencies:
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@types/json-schema': 7.0.15
    -      avsc: 5.7.9
    -    transitivePeerDependencies:
    -      - encoding
    +      '@babel/helper-validator-identifier': 7.29.7
    +      js-tokens: 4.0.0
    +      picocolors: 1.1.1
    +
    +  '@babel/compat-data@7.29.7': {}
     
    -  '@asyncapi/generator-components@0.7.0(@types/babel__core@7.20.5)(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/generator-helpers': 1.1.0
    -      '@asyncapi/generator-react-sdk': 1.1.3(@types/babel__core@7.20.5)(encoding@0.1.13)
    -      '@asyncapi/modelina': 5.10.1(encoding@0.1.13)
    -    transitivePeerDependencies:
    -      - '@swc/core'
    -      - '@swc/wasm'
    -      - '@types/babel__core'
    -      - encoding
    -      - supports-color
    -
    -  '@asyncapi/generator-helpers@1.1.0': {}
    -
    -  '@asyncapi/generator-hooks@0.1.0':
    -    dependencies:
    -      fs.extra: 1.3.2
    -
    -  '@asyncapi/generator-react-sdk@1.1.3(@types/babel__core@7.20.5)(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@babel/core': 7.12.9
    -      '@babel/preset-env': 7.29.7(@babel/core@7.12.9)
    -      '@babel/preset-react': 7.29.7(@babel/core@7.12.9)
    -      '@rollup/plugin-babel': 5.3.1(@babel/core@7.12.9)(@types/babel__core@7.20.5)(rollup@2.80.0)
    -      babel-plugin-source-map-support: 2.2.0
    -      prop-types: 15.8.1
    -      react: 17.0.2
    -      rollup: 2.80.0
    -      source-map-support: 0.5.21
    -    transitivePeerDependencies:
    -      - '@types/babel__core'
    -      - encoding
    -      - supports-color
    -
    -  '@asyncapi/generator@3.3.0(@types/babel__core@7.20.5)(@types/node@26.0.0)(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/generator-components': 0.7.0(@types/babel__core@7.20.5)(encoding@0.1.13)
    -      '@asyncapi/generator-helpers': 1.1.0
    -      '@asyncapi/generator-hooks': 0.1.0
    -      '@asyncapi/generator-react-sdk': 1.1.3(@types/babel__core@7.20.5)(encoding@0.1.13)
    -      '@asyncapi/multi-parser': 2.3.0(encoding@0.1.13)
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@npmcli/arborist': 9.8.0
    -      '@npmcli/config': 8.3.4
    -      ajv: 8.20.0
    -      commander: 6.2.1
    -      filenamify: 4.3.0
    -      fs.extra: 1.3.2
    -      global-dirs: 3.0.1
    -      jmespath: 0.15.0
    -      js-yaml: 4.3.0
    -      levenshtein-edit-distance: 2.0.5
    -      loglevel: 1.9.2
    -      minimatch: 3.1.5
    -      node-fetch: 2.7.0(encoding@0.1.13)
    -      requireg: 0.2.2
    -      resolve-from: 5.0.0
    -      resolve-pkg: 2.0.0
    -      semver: 7.8.5
    -      simple-git: 3.36.0
    -      ts-node: 10.9.2(@types/node@26.0.0)(typescript@4.9.5)
    -      typescript: 4.9.5
    -    transitivePeerDependencies:
    -      - '@swc/core'
    -      - '@swc/wasm'
    -      - '@types/babel__core'
    -      - '@types/node'
    -      - bluebird
    -      - encoding
    -      - supports-color
    -
    -  '@asyncapi/html-template@3.5.6(@noble/hashes@2.2.0)(@types/babel__core@7.20.5)(encoding@0.1.13)(typescript@4.9.5)':
    -    dependencies:
    -      '@asyncapi/generator-react-sdk': 1.1.3(@types/babel__core@7.20.5)(encoding@0.1.13)
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@asyncapi/react-component': 3.1.1(@noble/hashes@2.2.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
    -      highlight.js: 10.7.3
    -      puppeteer: 24.42.0(typescript@4.9.5)
    -      react: 18.3.1
    -      react-dom: 18.3.1(react@18.3.1)
    -      rimraf: 3.0.2
    -      sync-fetch: 0.5.2(encoding@0.1.13)
    -    transitivePeerDependencies:
    -      - '@noble/hashes'
    -      - '@types/babel__core'
    -      - bare-abort-controller
    -      - bare-buffer
    -      - bufferutil
    -      - canvas
    -      - encoding
    -      - react-native-b4a
    -      - supports-color
    -      - typescript
    -      - utf-8-validate
    -
    -  '@asyncapi/modelina@5.10.1(encoding@0.1.13)':
    -    dependencies:
    -      '@apidevtools/json-schema-ref-parser': 11.9.3
    -      '@apidevtools/swagger-parser': 10.1.1(openapi-types@12.1.3)
    -      '@asyncapi/multi-parser': 2.3.0(encoding@0.1.13)
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      alterschema: 1.1.3(encoding@0.1.13)
    -      change-case: 4.1.2
    -      fast-xml-parser: 5.10.1
    -      js-yaml: 4.3.0
    -      openapi-types: 12.1.3
    -      typescript-json-schema: 0.58.1
    -    transitivePeerDependencies:
    -      - '@swc/core'
    -      - '@swc/wasm'
    -      - encoding
    -
    -  '@asyncapi/multi-parser@2.3.0(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/avro-schema-parser': 3.0.24(encoding@0.1.13)
    -      '@asyncapi/openapi-schema-parser': 3.0.24(encoding@0.1.13)
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@asyncapi/protobuf-schema-parser': 3.6.0(encoding@0.1.13)
    -      '@asyncapi/raml-dt-schema-parser': 4.0.24(encoding@0.1.13)
    -      parserapiv1: '@asyncapi/parser@2.1.2(encoding@0.1.13)'
    -      parserapiv2: '@asyncapi/parser@3.0.0-next-major-spec.8(encoding@0.1.13)'
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/openapi-schema-parser@3.0.24(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0
    -      ajv: 8.20.0
    -      ajv-errors: 3.0.0(ajv@8.20.0)
    -      ajv-formats: 2.1.1(ajv@8.20.0)
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/parser@2.1.2(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/specs': 5.1.0
    -      '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/json-ref-readers': 1.2.2(encoding@0.1.13)
    -      '@stoplight/json-ref-resolver': 3.1.6
    -      '@stoplight/spectral-core': 1.23.0(encoding@0.1.13)
    -      '@stoplight/spectral-functions': 1.10.3(encoding@0.1.13)
    -      '@stoplight/spectral-parsers': 1.0.5
    -      '@stoplight/spectral-ref-resolver': 1.0.5(encoding@0.1.13)
    -      '@stoplight/types': 13.20.0
    -      '@types/json-schema': 7.0.15
    -      '@types/urijs': 1.19.26
    -      ajv: 8.20.0
    -      ajv-errors: 3.0.0(ajv@8.20.0)
    -      ajv-formats: 2.1.1(ajv@8.20.0)
    -      avsc: 5.7.9
    -      js-yaml: 4.3.0
    -      jsonpath-plus: 10.4.0
    -      node-fetch: 2.6.7(encoding@0.1.13)
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/parser@3.0.0-next-major-spec.8(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/specs': 6.11.1
    -      '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0
    -      '@stoplight/json-ref-resolver': 3.1.6
    -      '@stoplight/spectral-core': 1.23.0(encoding@0.1.13)
    -      '@stoplight/spectral-functions': 1.10.3(encoding@0.1.13)
    -      '@stoplight/spectral-parsers': 1.0.5
    -      '@types/json-schema': 7.0.15
    -      '@types/urijs': 1.19.26
    -      ajv: 8.20.0
    -      ajv-errors: 3.0.0(ajv@8.20.0)
    -      ajv-formats: 2.1.1(ajv@8.20.0)
    -      avsc: 5.7.9
    -      js-yaml: 4.3.0
    -      jsonpath-plus: 10.4.0
    -      node-fetch: 2.6.7(encoding@0.1.13)
    -      ramldt2jsonschema: 1.2.3
    -      webapi-parser: 0.5.0
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/parser@3.6.0(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/specs': 6.11.1
    -      '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0
    -      '@stoplight/json': 3.21.0
    -      '@stoplight/json-ref-readers': 1.2.2(encoding@0.1.13)
    -      '@stoplight/json-ref-resolver': 3.1.6
    -      '@stoplight/spectral-core': 1.23.0(encoding@0.1.13)
    -      '@stoplight/spectral-functions': 1.10.3(encoding@0.1.13)
    -      '@stoplight/spectral-parsers': 1.0.5
    -      '@stoplight/spectral-ref-resolver': 1.0.5(encoding@0.1.13)
    -      '@stoplight/types': 13.20.0
    -      '@types/json-schema': 7.0.15
    -      '@types/urijs': 1.19.26
    -      ajv: 8.20.0
    -      ajv-errors: 3.0.0(ajv@8.20.0)
    -      ajv-formats: 2.1.1(ajv@8.20.0)
    -      avsc: 5.7.9
    -      js-yaml: 4.3.0
    -      jsonpath-plus: 10.4.0
    -      node-fetch: 2.6.7(encoding@0.1.13)
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/protobuf-schema-parser@3.6.0(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@types/protocol-buffers-schema': 3.4.3
    -      protobufjs: 7.6.5
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/raml-dt-schema-parser@4.0.24(encoding@0.1.13)':
    -    dependencies:
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      js-yaml: 4.3.0
    -      ramldt2jsonschema: 1.2.3
    -      webapi-parser: 0.5.0
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@asyncapi/react-component@3.1.1(@noble/hashes@2.2.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
    -    dependencies:
    -      '@asyncapi/avro-schema-parser': 3.0.24(encoding@0.1.13)
    -      '@asyncapi/openapi-schema-parser': 3.0.24(encoding@0.1.13)
    -      '@asyncapi/parser': 3.6.0(encoding@0.1.13)
    -      '@asyncapi/protobuf-schema-parser': 3.6.0(encoding@0.1.13)
    -      highlight.js: 10.7.3
    -      isomorphic-dompurify: 2.36.0(@noble/hashes@2.2.0)
    -      marked: 4.3.0
    -      openapi-sampler: 1.7.2
    -      react: 18.3.1
    -      react-dom: 18.3.1(react@18.3.1)
    -      react-error-boundary: 4.1.2(react@18.3.1)
    -      use-resize-observer: 9.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
    -    transitivePeerDependencies:
    -      - '@noble/hashes'
    -      - canvas
    -      - encoding
    -      - supports-color
    -
    -  '@asyncapi/specs@5.1.0':
    -    dependencies:
    -      '@types/json-schema': 7.0.15
    -
    -  '@asyncapi/specs@6.11.1':
    -    dependencies:
    -      '@types/json-schema': 7.0.15
    -
    -  '@babel/code-frame@7.29.7':
    -    dependencies:
    -      '@babel/helper-validator-identifier': 7.29.7
    -      js-tokens: 4.0.0
    -      picocolors: 1.1.1
    -
    -  '@babel/compat-data@7.29.7': {}
    -
    -  '@babel/core@7.12.9':
    -    dependencies:
    -      '@babel/code-frame': 7.29.7
    -      '@babel/generator': 7.29.7
    -      '@babel/helper-module-transforms': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helpers': 7.29.7
    -      '@babel/parser': 7.29.7
    -      '@babel/template': 7.29.7
    -      '@babel/traverse': 7.29.7
    -      '@babel/types': 7.29.7
    -      convert-source-map: 1.9.0
    -      debug: 4.4.3
    -      gensync: 1.0.0-beta.2
    -      json5: 2.2.3
    -      lodash: 4.18.1
    -      resolve: 1.22.12
    -      semver: 5.7.2
    -      source-map: 0.5.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/core@7.29.7':
    +  '@babel/core@7.29.7':
         dependencies:
           '@babel/code-frame': 7.29.7
           '@babel/generator': 7.29.7
    @@ -11351,747 +8435,133 @@ snapshots:
           '@jridgewell/trace-mapping': 0.3.31
           jsesc: 3.1.0
     
    -  '@babel/helper-annotate-as-pure@7.29.7':
    -    dependencies:
    -      '@babel/types': 7.29.7
    -
       '@babel/helper-compilation-targets@7.29.7':
         dependencies:
           '@babel/compat-data': 7.29.7
           '@babel/helper-validator-option': 7.29.7
    -      browserslist: 4.28.2
    +      browserslist: 4.28.7
           lru-cache: 5.1.1
           semver: 6.3.1
     
    -  '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    -      '@babel/helper-member-expression-to-functions': 7.29.7
    -      '@babel/helper-optimise-call-expression': 7.29.7
    -      '@babel/helper-replace-supers': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-skip-transparent-expression-wrappers': 7.29.7
    -      '@babel/traverse': 7.29.7
    -      semver: 6.3.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-create-regexp-features-plugin@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    -      regexpu-core: 6.4.0
    -      semver: 6.3.1
    -
    -  '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-compilation-targets': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -      debug: 4.4.3
    -      lodash.debounce: 4.0.8
    -      resolve: 1.22.12
    -    transitivePeerDependencies:
    -      - supports-color
    -
       '@babel/helper-globals@7.29.7': {}
     
    -  '@babel/helper-member-expression-to-functions@7.29.7':
    -    dependencies:
    -      '@babel/traverse': 7.29.7
    -      '@babel/types': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
       '@babel/helper-module-imports@7.29.7':
         dependencies:
    -      '@babel/traverse': 7.29.7
    -      '@babel/types': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-module-transforms@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-imports': 7.29.7
    -      '@babel/helper-validator-identifier': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-module-imports': 7.29.7
    -      '@babel/helper-validator-identifier': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-optimise-call-expression@7.29.7':
    -    dependencies:
    -      '@babel/types': 7.29.7
    -
    -  '@babel/helper-plugin-utils@7.29.7': {}
    -
    -  '@babel/helper-remap-async-to-generator@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    -      '@babel/helper-wrap-function': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-replace-supers@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-member-expression-to-functions': 7.29.7
    -      '@babel/helper-optimise-call-expression': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-skip-transparent-expression-wrappers@7.29.7':
    -    dependencies:
    -      '@babel/traverse': 7.29.7
    -      '@babel/types': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helper-string-parser@7.29.7': {}
    -
    -  '@babel/helper-validator-identifier@7.29.7': {}
    -
    -  '@babel/helper-validator-option@7.29.7': {}
    -
    -  '@babel/helper-wrap-function@7.29.7':
    -    dependencies:
    -      '@babel/template': 7.29.7
    -      '@babel/traverse': 7.29.7
    -      '@babel/types': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/helpers@7.29.7':
    -    dependencies:
    -      '@babel/template': 7.29.7
    -      '@babel/types': 7.29.7
    -
    -  '@babel/parser@7.29.7':
    -    dependencies:
    -      '@babel/types': 7.29.7
    -
    -  '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-skip-transparent-expression-wrappers': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-skip-transparent-expression-wrappers': 7.29.7
    -      '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -
    -  '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-import-assertions@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7)':
    -    dependencies:
    -      '@babel/core': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-arrow-functions@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-async-generator-functions@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.12.9)
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-async-to-generator@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-imports': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-block-scoped-functions@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-block-scoping@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-class-properties@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-class-static-block@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-classes@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    -      '@babel/helper-compilation-targets': 7.29.7
    -      '@babel/helper-globals': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-replace-supers': 7.29.7(@babel/core@7.12.9)
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-computed-properties@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/template': 7.29.7
    -
    -  '@babel/plugin-transform-destructuring@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-dotall-regex@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-duplicate-keys@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-dynamic-import@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-explicit-resource-management@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-exponentiation-operator@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-export-namespace-from@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-for-of@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-skip-transparent-expression-wrappers': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-function-name@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-compilation-targets': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-json-strings@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-literals@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-logical-assignment-operators@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-member-expression-literals@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-modules-amd@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-transforms': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-transforms': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-modules-systemjs@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-transforms': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-validator-identifier': 7.29.7
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-modules-umd@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-transforms': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-named-capturing-groups-regex@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-new-target@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-nullish-coalescing-operator@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-numeric-separator@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-object-rest-spread@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-compilation-targets': 7.29.7
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.12.9)
    -      '@babel/traverse': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-object-super@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-replace-supers': 7.29.7(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-optional-catch-binding@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-optional-chaining@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-skip-transparent-expression-wrappers': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@babel/plugin-transform-parameters@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    -
    -  '@babel/plugin-transform-private-methods@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    +      '@babel/traverse': 7.29.7
    +      '@babel/types': 7.29.7
         transitivePeerDependencies:
           - supports-color
     
    -  '@babel/plugin-transform-private-property-in-object@7.29.7(@babel/core@7.12.9)':
    +  '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    -      '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.12.9)
    -      '@babel/helper-plugin-utils': 7.29.7
    +      '@babel/core': 7.29.7
    +      '@babel/helper-module-imports': 7.29.7
    +      '@babel/helper-validator-identifier': 7.29.7
    +      '@babel/traverse': 7.29.7
         transitivePeerDependencies:
           - supports-color
     
    -  '@babel/plugin-transform-property-literals@7.29.7(@babel/core@7.12.9)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    +  '@babel/helper-plugin-utils@7.29.7': {}
    +
    +  '@babel/helper-string-parser@7.29.7': {}
    +
    +  '@babel/helper-validator-identifier@7.29.7': {}
     
    -  '@babel/plugin-transform-react-display-name@7.29.7(@babel/core@7.12.9)':
    +  '@babel/helper-validator-option@7.29.7': {}
    +
    +  '@babel/helpers@7.29.7':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-plugin-utils': 7.29.7
    +      '@babel/template': 7.29.7
    +      '@babel/types': 7.29.7
     
    -  '@babel/plugin-transform-react-jsx-development@7.29.7(@babel/core@7.12.9)':
    +  '@babel/parser@7.29.7':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
    +      '@babel/types': 7.29.7
     
    -  '@babel/plugin-transform-react-jsx@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    -      '@babel/helper-module-imports': 7.29.7
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.12.9)
    -      '@babel/types': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
     
    -  '@babel/plugin-transform-react-pure-annotations@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-annotate-as-pure': 7.29.7
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-regenerator@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-regexp-modifiers@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-reserved-words@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-shorthand-properties@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-spread@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-skip-transparent-expression-wrappers': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
     
    -  '@babel/plugin-transform-sticky-regex@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-template-literals@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-typeof-symbol@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-unicode-escapes@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-unicode-property-regex@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-unicode-regex@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/plugin-transform-unicode-sets-regex@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.12.9)
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
     
    -  '@babel/preset-env@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/compat-data': 7.29.7
    -      '@babel/core': 7.12.9
    -      '@babel/helper-compilation-targets': 7.29.7
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-validator-option': 7.29.7
    -      '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.12.9)
    -      '@babel/plugin-syntax-import-assertions': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-syntax-import-attributes': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.12.9)
    -      '@babel/plugin-transform-arrow-functions': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-async-generator-functions': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-async-to-generator': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-block-scoped-functions': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-block-scoping': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-class-properties': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-class-static-block': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-classes': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-computed-properties': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-dotall-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-duplicate-keys': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-dynamic-import': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-explicit-resource-management': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-exponentiation-operator': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-export-namespace-from': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-for-of': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-function-name': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-json-strings': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-literals': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-logical-assignment-operators': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-member-expression-literals': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-modules-amd': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-modules-systemjs': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-modules-umd': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-named-capturing-groups-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-new-target': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-nullish-coalescing-operator': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-numeric-separator': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-object-rest-spread': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-object-super': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-optional-catch-binding': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-parameters': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-private-methods': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-private-property-in-object': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-property-literals': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-regenerator': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-regexp-modifiers': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-reserved-words': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-shorthand-properties': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-spread': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-sticky-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-template-literals': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-typeof-symbol': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-unicode-escapes': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-unicode-property-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-unicode-sets-regex': 7.29.7(@babel/core@7.12.9)
    -      '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.12.9)
    -      babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.12.9)
    -      babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.12.9)
    -      babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.12.9)
    -      core-js-compat: 3.49.0
    -      semver: 6.3.1
    -    transitivePeerDependencies:
    -      - supports-color
     
    -  '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/types': 7.29.7
    -      esutils: 2.0.3
     
    -  '@babel/preset-react@7.29.7(@babel/core@7.12.9)':
    +  '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7)':
         dependencies:
    -      '@babel/core': 7.12.9
    +      '@babel/core': 7.29.7
           '@babel/helper-plugin-utils': 7.29.7
    -      '@babel/helper-validator-option': 7.29.7
    -      '@babel/plugin-transform-react-display-name': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.12.9)
    -      '@babel/plugin-transform-react-pure-annotations': 7.29.7(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
     
       '@babel/runtime@7.29.2': {}
     
    @@ -12127,176 +8597,7 @@ snapshots:
       '@bramus/specificity@2.4.2':
         dependencies:
           css-tree: 3.2.1
    -
    -  '@bsv/auth-express-middleware@2.1.0(@bsv/sdk@2.1.9)':
    -    dependencies:
    -      '@bsv/sdk': 2.1.9
    -      express: 5.2.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@bsv/auth-express-middleware@2.1.0(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/sdk': link:packages/sdk
    -      express: 5.2.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@bsv/authsocket-client@2.1.0(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/sdk': link:packages/sdk
    -      socket.io-client: 4.8.3
    -    transitivePeerDependencies:
    -      - bufferutil
    -      - supports-color
    -      - utf-8-validate
    -
    -  '@bsv/btms@1.1.0(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/sdk': link:packages/sdk
    -
    -  '@bsv/gasp@1.3.0(@bsv/sdk@2.1.9)':
    -    dependencies:
    -      '@bsv/sdk': 2.1.9
    -
    -  '@bsv/gasp@1.3.0(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/sdk': link:packages/sdk
    -
    -  '@bsv/message-box-client@2.2.0(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/authsocket-client': 2.1.0(@bsv/sdk@packages+sdk)
    -      '@bsv/sdk': link:packages/sdk
    -    transitivePeerDependencies:
    -      - bufferutil
    -      - supports-color
    -      - utf-8-validate
    -
    -  '@bsv/overlay-discovery-services@2.1.0(@bsv/sdk@packages+sdk)(socks@2.8.7)':
    -    dependencies:
    -      '@bsv/overlay': 2.1.1(@bsv/sdk@packages+sdk)
    -      '@bsv/sdk': link:packages/sdk
    -      '@bsv/wallet-toolbox-client': 2.3.3(@bsv/sdk@packages+sdk)
    -      mongodb: 7.3.0(socks@2.8.7)
    -    transitivePeerDependencies:
    -      - '@aws-sdk/credential-providers'
    -      - '@mongodb-js/zstd'
    -      - better-sqlite3
    -      - gcp-metadata
    -      - kerberos
    -      - mongodb-client-encryption
    -      - mysql
    -      - mysql2
    -      - pg
    -      - pg-native
    -      - pg-query-stream
    -      - snappy
    -      - socks
    -      - sqlite3
    -      - supports-color
    -      - tedious
    -
    -  '@bsv/overlay@2.1.1(@bsv/sdk@2.1.9)':
    -    dependencies:
    -      '@bsv/gasp': 1.3.0(@bsv/sdk@2.1.9)
    -      '@bsv/sdk': 2.1.9
    -      knex: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    -    transitivePeerDependencies:
    -      - better-sqlite3
    -      - mysql
    -      - mysql2
    -      - pg
    -      - pg-native
    -      - pg-query-stream
    -      - sqlite3
    -      - supports-color
    -      - tedious
    -
    -  '@bsv/overlay@2.1.1(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/gasp': 1.3.0(@bsv/sdk@packages+sdk)
    -      '@bsv/sdk': link:packages/sdk
    -      knex: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    -    transitivePeerDependencies:
    -      - better-sqlite3
    -      - mysql
    -      - mysql2
    -      - pg
    -      - pg-native
    -      - pg-query-stream
    -      - sqlite3
    -      - supports-color
    -      - tedious
    -
    -  '@bsv/payment-express-middleware@2.1.0(@bsv/sdk@2.1.9)':
    -    dependencies:
    -      '@bsv/sdk': 2.1.9
    -      express: 5.2.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@bsv/payment-express-middleware@2.1.0(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/sdk': link:packages/sdk
    -      express: 5.2.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@bsv/sdk@2.1.9': {}
    -
    -  '@bsv/wallet-toolbox-client@2.3.3(@bsv/sdk@packages+sdk)':
    -    dependencies:
    -      '@bsv/sdk': link:packages/sdk
    -      hash-wasm: 4.12.0
    -      idb: 8.0.3
    -
    -  '@bsv/wallet-toolbox@2.3.3(@bsv/sdk@2.1.9)(@types/node@26.0.0)(sqlite3@6.0.1)':
    -    dependencies:
    -      '@bsv/auth-express-middleware': 2.1.0(@bsv/sdk@2.1.9)
    -      '@bsv/payment-express-middleware': 2.1.0(@bsv/sdk@2.1.9)
    -      '@bsv/sdk': 2.1.9
    -      better-sqlite3: 12.11.1
    -      express: 5.2.1
    -      hash-wasm: 4.12.0
    -      idb: 8.0.3
    -      knex: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    -      mysql2: 3.23.1(@types/node@26.0.0)
    -      ws: 8.21.0
    -    transitivePeerDependencies:
    -      - '@types/node'
    -      - bufferutil
    -      - mysql
    -      - pg
    -      - pg-native
    -      - pg-query-stream
    -      - sqlite3
    -      - supports-color
    -      - tedious
    -      - utf-8-validate
    -
    -  '@bsv/wallet-toolbox@2.3.3(@bsv/sdk@packages+sdk)(@types/node@26.0.0)':
    -    dependencies:
    -      '@bsv/auth-express-middleware': 2.1.0(@bsv/sdk@packages+sdk)
    -      '@bsv/payment-express-middleware': 2.1.0(@bsv/sdk@packages+sdk)
    -      '@bsv/sdk': link:packages/sdk
    -      better-sqlite3: 12.11.1
    -      express: 5.2.1
    -      hash-wasm: 4.12.0
    -      idb: 8.0.3
    -      knex: 3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1)
    -      mysql2: 3.23.1(@types/node@26.0.0)
    -      ws: 8.21.0
    -    transitivePeerDependencies:
    -      - '@types/node'
    -      - bufferutil
    -      - mysql
    -      - pg
    -      - pg-native
    -      - pg-query-stream
    -      - sqlite3
    -      - supports-color
    -      - tedious
    -      - utf-8-validate
    +    optional: true
     
       '@chainsafe/as-chacha20poly1305@0.1.0': {}
     
    @@ -12306,7 +8607,7 @@ snapshots:
     
       '@chainsafe/libp2p-gossipsub@14.1.2':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    +      '@libp2p/crypto': 5.1.21
           '@libp2p/interface': 2.11.0
           '@libp2p/interface-internal': 2.3.19
           '@libp2p/peer-id': 5.1.9
    @@ -12325,9 +8626,9 @@ snapshots:
         dependencies:
           '@chainsafe/as-chacha20poly1305': 0.1.0
           '@chainsafe/as-sha256': 1.2.4
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/peer-id': 6.0.11
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/peer-id': 6.0.12
           '@libp2p/utils': 7.2.3
           '@noble/ciphers': 2.2.0
           '@noble/curves': 2.2.0
    @@ -12339,7 +8640,7 @@ snapshots:
     
       '@chainsafe/libp2p-yamux@8.0.1':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/interface': 3.2.5
           '@libp2p/utils': 7.2.3
           race-signal: 2.0.0
           uint8arraylist: 2.4.9
    @@ -12367,7 +8668,8 @@ snapshots:
     
       '@csstools/color-helpers@5.1.0': {}
     
    -  '@csstools/color-helpers@6.0.2': {}
    +  '@csstools/color-helpers@6.0.2':
    +    optional: true
     
       '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
         dependencies:
    @@ -12378,6 +8680,7 @@ snapshots:
         dependencies:
           '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
           '@csstools/css-tokenizer': 4.0.0
    +    optional: true
     
       '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
         dependencies:
    @@ -12392,6 +8695,7 @@ snapshots:
           '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
           '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
           '@csstools/css-tokenizer': 4.0.0
    +    optional: true
     
       '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)':
         dependencies:
    @@ -12400,14 +8704,17 @@ snapshots:
       '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
         dependencies:
           '@csstools/css-tokenizer': 4.0.0
    +    optional: true
     
       '@csstools/css-syntax-patches-for-csstree@1.1.3(css-tree@3.2.1)':
         optionalDependencies:
           css-tree: 3.2.1
    +    optional: true
     
       '@csstools/css-tokenizer@3.0.4': {}
     
    -  '@csstools/css-tokenizer@4.0.0': {}
    +  '@csstools/css-tokenizer@4.0.0':
    +    optional: true
     
       '@discoveryjs/json-ext@0.6.3': {}
     
    @@ -12424,16 +8731,43 @@ snapshots:
           tslib: 2.8.1
         optional: true
     
    +  '@emnapi/core@1.11.1':
    +    dependencies:
    +      '@emnapi/wasi-threads': 1.2.2
    +      tslib: 2.8.1
    +    optional: true
    +
    +  '@emnapi/core@1.11.2':
    +    dependencies:
    +      '@emnapi/wasi-threads': 1.2.2
    +      tslib: 2.8.1
    +    optional: true
    +
       '@emnapi/runtime@1.10.0':
         dependencies:
           tslib: 2.8.1
         optional: true
     
    +  '@emnapi/runtime@1.11.1':
    +    dependencies:
    +      tslib: 2.8.1
    +    optional: true
    +
    +  '@emnapi/runtime@1.11.2':
    +    dependencies:
    +      tslib: 2.8.1
    +    optional: true
    +
       '@emnapi/wasi-threads@1.2.1':
         dependencies:
           tslib: 2.8.1
         optional: true
     
    +  '@emnapi/wasi-threads@1.2.2':
    +    dependencies:
    +      tslib: 2.8.1
    +    optional: true
    +
       '@esbuild/aix-ppc64@0.27.7':
         optional: true
     
    @@ -12590,141 +8924,26 @@ snapshots:
       '@esbuild/win32-x64@0.28.1':
         optional: true
     
    -  '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0)':
    -    dependencies:
    -      eslint: 10.5.0
    -      eslint-visitor-keys: 3.4.3
    -
    -  '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)':
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-visitor-keys: 3.4.3
    -
    -  '@eslint-community/regexpp@4.12.2': {}
    -
    -  '@eslint/config-array@0.23.5':
    -    dependencies:
    -      '@eslint/object-schema': 3.0.5
    -      debug: 4.4.3
    -      minimatch: 10.2.5
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@eslint/config-helpers@0.6.0':
    -    dependencies:
    -      '@eslint/core': 1.2.1
    -
    -  '@eslint/core@1.2.1':
    -    dependencies:
    -      '@types/json-schema': 7.0.15
    -
    -  '@eslint/eslintrc@2.1.4':
    -    dependencies:
    -      ajv: 6.15.0
    -      debug: 4.4.3
    -      espree: 9.6.1
    -      globals: 13.24.0
    -      ignore: 5.3.2
    -      import-fresh: 3.3.1
    -      js-yaml: 4.3.0
    -      minimatch: 3.1.5
    -      strip-json-comments: 3.1.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@eslint/js@10.0.1(eslint@10.5.0)':
    -    optionalDependencies:
    -      eslint: 10.5.0
    -
    -  '@eslint/js@8.57.1': {}
    -
    -  '@eslint/object-schema@3.0.5': {}
    -
    -  '@eslint/plugin-kit@0.7.2':
    -    dependencies:
    -      '@eslint/core': 1.2.1
    -      levn: 0.4.1
    -
       '@exodus/bytes@1.15.0(@noble/hashes@2.2.0)':
         optionalDependencies:
           '@noble/hashes': 2.2.0
    +    optional: true
     
    -  '@gar/promise-retry@1.0.3': {}
    -
    -  '@hapi/address@5.1.1':
    -    dependencies:
    -      '@hapi/hoek': 11.0.7
    -
    -  '@hapi/formula@3.0.2': {}
    -
    -  '@hapi/hoek@11.0.7': {}
    -
    -  '@hapi/pinpoint@2.0.1': {}
    -
    -  '@hapi/tlds@1.1.7': {}
    -
    -  '@hapi/topo@6.0.2':
    -    dependencies:
    -      '@hapi/hoek': 11.0.7
    -
    -  '@humanfs/core@0.19.2':
    -    dependencies:
    -      '@humanfs/types': 0.15.0
    -
    -  '@humanfs/node@0.16.8':
    -    dependencies:
    -      '@humanfs/core': 0.19.2
    -      '@humanfs/types': 0.15.0
    -      '@humanwhocodes/retry': 0.4.3
    -
    -  '@humanfs/types@0.15.0': {}
    -
    -  '@humanwhocodes/config-array@0.13.0':
    -    dependencies:
    -      '@humanwhocodes/object-schema': 2.0.3
    -      debug: 4.4.3
    -      minimatch: 3.1.5
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@humanwhocodes/module-importer@1.0.1': {}
    -
    -  '@humanwhocodes/object-schema@2.0.3': {}
    -
    -  '@humanwhocodes/retry@0.4.3': {}
    -
    -  '@hyperjump/json-pointer@0.9.8':
    -    dependencies:
    -      just-curry-it: 5.3.0
    -
    -  '@hyperjump/json-schema-core@0.28.5(encoding@0.1.13)':
    -    dependencies:
    -      '@hyperjump/json': 0.1.0
    -      '@hyperjump/json-pointer': 0.9.8
    -      '@hyperjump/pact': 0.2.5
    -      content-type: 1.0.5
    -      node-fetch: 2.7.0(encoding@0.1.13)
    -      pubsub-js: 1.9.5
    -      uri-js: 4.4.1
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  '@hyperjump/json-schema@0.23.5(encoding@0.1.13)':
    +  '@hapi/address@5.1.1':
         dependencies:
    -      '@hyperjump/json-schema-core': 0.28.5(encoding@0.1.13)
    -      fastest-stable-stringify: 2.0.2
    -      just-curry-it: 5.3.0
    -    transitivePeerDependencies:
    -      - encoding
    +      '@hapi/hoek': 11.0.7
     
    -  '@hyperjump/json@0.1.0':
    -    dependencies:
    -      '@hyperjump/json-pointer': 0.9.8
    -      moo: 0.5.3
    +  '@hapi/formula@3.0.2': {}
    +
    +  '@hapi/hoek@11.0.7': {}
     
    -  '@hyperjump/pact@0.2.5':
    +  '@hapi/pinpoint@2.0.1': {}
    +
    +  '@hapi/tlds@1.1.7': {}
    +
    +  '@hapi/topo@6.0.2':
         dependencies:
    -      just-curry-it: 3.2.1
    +      '@hapi/hoek': 11.0.7
     
       '@iconify/types@2.0.0': {}
     
    @@ -12747,8 +8966,6 @@ snapshots:
         dependencies:
           minipass: 7.1.3
     
    -  '@isaacs/string-locale-compare@1.1.0': {}
    -
       '@istanbuljs/load-nyc-config@1.1.0':
         dependencies:
           camelcase: 5.3.1
    @@ -12762,13 +8979,13 @@ snapshots:
       '@jest/console@30.4.1':
         dependencies:
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           chalk: 4.1.2
           jest-message-util: 30.4.1
           jest-util: 30.4.1
           slash: 3.0.0
     
    -  '@jest/core@30.4.2(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))':
    +  '@jest/core@30.4.2(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))':
         dependencies:
           '@jest/console': 30.4.1
           '@jest/pattern': 30.4.0
    @@ -12776,7 +8993,7 @@ snapshots:
           '@jest/test-result': 30.4.1
           '@jest/transform': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           ansi-escapes: 4.3.2
           chalk: 4.1.2
           ci-info: 4.4.0
    @@ -12784,7 +9001,7 @@ snapshots:
           fast-json-stable-stringify: 2.1.0
           graceful-fs: 4.2.11
           jest-changed-files: 30.4.1
    -      jest-config: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      jest-config: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-haste-map: 30.4.1
           jest-message-util: 30.4.1
           jest-regex-util: 30.4.0
    @@ -12814,7 +9031,7 @@ snapshots:
           '@jest/fake-timers': 30.4.1
           '@jest/types': 30.4.1
           '@types/jsdom': 21.1.7
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jest-mock: 30.4.1
           jest-util: 30.4.1
           jsdom: 26.1.0
    @@ -12823,7 +9040,7 @@ snapshots:
         dependencies:
           '@jest/fake-timers': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jest-mock: 30.4.1
     
       '@jest/expect-utils@30.4.1':
    @@ -12841,7 +9058,7 @@ snapshots:
         dependencies:
           '@jest/types': 30.4.1
           '@sinonjs/fake-timers': 15.4.0
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jest-message-util: 30.4.1
           jest-mock: 30.4.1
           jest-util: 30.4.1
    @@ -12859,7 +9076,7 @@ snapshots:
     
       '@jest/pattern@30.4.0':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jest-regex-util: 30.4.0
     
       '@jest/reporters@30.4.1(node-notifier@8.0.2)':
    @@ -12870,7 +9087,7 @@ snapshots:
           '@jest/transform': 30.4.1
           '@jest/types': 30.4.1
           '@jridgewell/trace-mapping': 0.3.31
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           chalk: 4.1.2
           collect-v8-coverage: 1.0.3
           exit-x: 0.2.2
    @@ -12894,7 +9111,7 @@ snapshots:
     
       '@jest/schemas@30.4.1':
         dependencies:
    -      '@sinclair/typebox': 0.34.49
    +      '@sinclair/typebox': 0.34.52
     
       '@jest/snapshot-utils@30.4.1':
         dependencies:
    @@ -12948,7 +9165,7 @@ snapshots:
           '@jest/schemas': 30.4.1
           '@types/istanbul-lib-coverage': 2.0.6
           '@types/istanbul-reports': 3.0.4
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           '@types/yargs': 17.0.35
           chalk: 4.1.2
     
    @@ -12981,20 +9198,6 @@ snapshots:
           '@jridgewell/resolve-uri': 3.1.2
           '@jridgewell/sourcemap-codec': 1.5.5
     
    -  '@jsdevtools/ono@7.1.3': {}
    -
    -  '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)':
    -    dependencies:
    -      jsep: 1.4.0
    -
    -  '@jsep-plugin/regex@1.0.4(jsep@1.4.0)':
    -    dependencies:
    -      jsep: 1.4.0
    -
    -  '@jsep-plugin/ternary@1.1.4(jsep@1.4.0)':
    -    dependencies:
    -      jsep: 1.4.0
    -
       '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)':
         dependencies:
           tslib: 2.8.1
    @@ -13122,30 +9325,20 @@ snapshots:
           '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1)
           tslib: 2.8.1
     
    -  '@juggle/resize-observer@3.4.0': {}
    -
    -  '@kwsites/file-exists@1.1.1':
    -    dependencies:
    -      debug: 4.4.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@kwsites/promise-deferred@1.1.1': {}
    -
       '@leichtgewicht/ip-codec@2.0.5': {}
     
    -  '@libp2p/bootstrap@12.0.25':
    +  '@libp2p/bootstrap@12.0.27':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/interface-internal': 3.1.7
    -      '@libp2p/peer-id': 6.0.11
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/interface-internal': 3.1.9
    +      '@libp2p/peer-id': 6.0.12
           '@multiformats/multiaddr': 13.0.3
           '@multiformats/multiaddr-matcher': 3.0.2
           main-event: 1.0.4
     
    -  '@libp2p/crypto@5.1.20':
    +  '@libp2p/crypto@5.1.21':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/interface': 3.2.5
           '@noble/curves': 2.2.0
           '@noble/hashes': 2.2.0
           multiformats: 14.0.0
    @@ -13153,14 +9346,14 @@ snapshots:
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
     
    -  '@libp2p/identify@4.1.8':
    +  '@libp2p/identify@4.1.10':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/interface-internal': 3.1.7
    -      '@libp2p/peer-id': 6.0.11
    -      '@libp2p/peer-record': 9.0.12
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/interface-internal': 3.1.9
    +      '@libp2p/peer-id': 6.0.12
    +      '@libp2p/peer-record': 9.0.13
    +      '@libp2p/utils': 7.3.0
           '@multiformats/multiaddr': 13.0.3
           '@multiformats/multiaddr-matcher': 3.0.2
           it-drain: 3.0.12
    @@ -13179,8 +9372,15 @@ snapshots:
     
       '@libp2p/interface-internal@3.1.7':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/peer-collections': 7.0.22
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/peer-collections': 7.0.24
    +      '@multiformats/multiaddr': 13.0.3
    +      progress-events: 1.1.0
    +
    +  '@libp2p/interface-internal@3.1.9':
    +    dependencies:
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/peer-collections': 7.0.24
           '@multiformats/multiaddr': 13.0.3
           progress-events: 1.1.0
     
    @@ -13195,7 +9395,7 @@ snapshots:
           progress-events: 1.1.0
           uint8arraylist: 2.4.9
     
    -  '@libp2p/interface@3.2.4':
    +  '@libp2p/interface@3.2.5':
         dependencies:
           '@multiformats/dns': 1.0.13
           '@multiformats/multiaddr': 13.0.3
    @@ -13204,16 +9404,16 @@ snapshots:
           progress-events: 1.1.0
           uint8arraylist: 3.0.2
     
    -  '@libp2p/kad-dht@16.3.3':
    +  '@libp2p/kad-dht@16.4.0':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/interface-internal': 3.1.7
    -      '@libp2p/peer-collections': 7.0.22
    -      '@libp2p/peer-id': 6.0.11
    -      '@libp2p/ping': 3.1.7
    -      '@libp2p/record': 4.0.14
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/interface-internal': 3.1.9
    +      '@libp2p/peer-collections': 7.0.24
    +      '@libp2p/peer-id': 6.0.12
    +      '@libp2p/ping': 3.1.9
    +      '@libp2p/record': 4.0.15
    +      '@libp2p/utils': 7.3.0
           '@multiformats/multiaddr': 13.0.3
           '@multiformats/multiaddr-matcher': 3.0.2
           any-signal: 4.2.0
    @@ -13246,18 +9446,26 @@ snapshots:
           multiformats: 13.4.2
           weald: 1.1.3
     
    +  '@libp2p/logger@6.2.10':
    +    dependencies:
    +      '@libp2p/interface': 3.2.5
    +      '@multiformats/multiaddr': 13.0.3
    +      interface-datastore: 10.0.1
    +      multiformats: 14.0.0
    +      weald: 1.1.3
    +
       '@libp2p/logger@6.2.9':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/interface': 3.2.5
           '@multiformats/multiaddr': 13.0.3
           interface-datastore: 10.0.1
           multiformats: 14.0.0
           weald: 1.1.3
     
    -  '@libp2p/multistream-select@7.0.22':
    +  '@libp2p/multistream-select@7.0.24':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/utils': 7.3.0
           it-length-prefixed: 11.0.1
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
    @@ -13269,46 +9477,46 @@ snapshots:
           '@libp2p/utils': 6.7.2
           multiformats: 13.4.2
     
    -  '@libp2p/peer-collections@7.0.22':
    +  '@libp2p/peer-collections@7.0.24':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/peer-id': 6.0.11
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/peer-id': 6.0.12
    +      '@libp2p/utils': 7.3.0
           multiformats: 14.0.0
     
       '@libp2p/peer-id@5.1.9':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    +      '@libp2p/crypto': 5.1.21
           '@libp2p/interface': 2.11.0
           multiformats: 13.4.2
           uint8arrays: 5.1.1
     
    -  '@libp2p/peer-id@6.0.11':
    +  '@libp2p/peer-id@6.0.12':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
           multiformats: 14.0.0
           uint8arrays: 6.1.1
     
    -  '@libp2p/peer-record@9.0.12':
    +  '@libp2p/peer-record@9.0.13':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/peer-id': 6.0.11
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/peer-id': 6.0.12
           '@multiformats/multiaddr': 13.0.3
    -      multiformats: 14.0.0
    +      multiformats: 14.0.5
           protons-runtime: 7.0.0
           uint8-varint: 3.0.0
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
     
    -  '@libp2p/peer-store@12.0.22':
    +  '@libp2p/peer-store@12.0.24':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/peer-collections': 7.0.22
    -      '@libp2p/peer-id': 6.0.11
    -      '@libp2p/peer-record': 9.0.12
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/peer-collections': 7.0.24
    +      '@libp2p/peer-id': 6.0.12
    +      '@libp2p/peer-record': 9.0.13
           '@multiformats/multiaddr': 13.0.3
           interface-datastore: 10.0.1
           it-all: 3.0.11
    @@ -13319,29 +9527,29 @@ snapshots:
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
     
    -  '@libp2p/ping@3.1.7':
    +  '@libp2p/ping@3.1.9':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/interface-internal': 3.1.7
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/interface-internal': 3.1.9
           p-event: 7.1.0
           race-signal: 2.0.0
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
     
    -  '@libp2p/pnet@3.0.23':
    +  '@libp2p/pnet@3.0.25':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/utils': 7.3.0
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
           xsalsa20: 1.2.0
     
       '@libp2p/pubsub-peer-discovery@12.0.0':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
           '@libp2p/interface-internal': 3.1.7
    -      '@libp2p/peer-id': 6.0.11
    +      '@libp2p/peer-id': 6.0.12
           '@multiformats/multiaddr': 13.0.3
           protons-runtime: 5.6.0
           uint8arraylist: 2.4.9
    @@ -13349,7 +9557,7 @@ snapshots:
     
       '@libp2p/pubsub@10.1.18':
         dependencies:
    -      '@libp2p/crypto': 5.1.20
    +      '@libp2p/crypto': 5.1.21
           '@libp2p/interface': 2.11.0
           '@libp2p/interface-internal': 2.3.19
           '@libp2p/peer-collections': 6.0.35
    @@ -13364,16 +9572,16 @@ snapshots:
           uint8arraylist: 2.4.9
           uint8arrays: 5.1.1
     
    -  '@libp2p/record@4.0.14':
    +  '@libp2p/record@4.0.15':
         dependencies:
           protons-runtime: 7.0.0
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
     
    -  '@libp2p/tcp@11.0.22':
    +  '@libp2p/tcp@11.0.24':
         dependencies:
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/utils': 7.3.0
           '@multiformats/multiaddr': 13.0.3
           '@multiformats/multiaddr-matcher': 3.0.2
           main-event: 1.0.4
    @@ -13385,7 +9593,7 @@ snapshots:
         dependencies:
           '@chainsafe/is-ip': 2.1.0
           '@chainsafe/netmask': 2.0.0
    -      '@libp2p/crypto': 5.1.20
    +      '@libp2p/crypto': 5.1.21
           '@libp2p/interface': 2.11.0
           '@libp2p/logger': 5.2.0
           '@multiformats/multiaddr': 12.5.1
    @@ -13411,7 +9619,7 @@ snapshots:
         dependencies:
           '@chainsafe/is-ip': 2.1.0
           '@chainsafe/netmask': 2.0.0
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/interface': 3.2.5
           '@libp2p/logger': 6.2.9
           '@multiformats/multiaddr': 13.0.3
           '@multiformats/multiaddr-matcher': 3.0.2
    @@ -13434,6 +9642,34 @@ snapshots:
           uint8arraylist: 3.0.2
           uint8arrays: 6.1.1
     
    +  '@libp2p/utils@7.3.0':
    +    dependencies:
    +      '@chainsafe/is-ip': 2.1.0
    +      '@chainsafe/netmask': 2.0.0
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/logger': 6.2.10
    +      '@multiformats/multiaddr': 13.0.3
    +      '@multiformats/multiaddr-matcher': 3.0.2
    +      '@sindresorhus/fnv1a': 3.1.0
    +      any-signal: 4.2.0
    +      cborg: 5.1.8
    +      delay: 7.0.0
    +      is-loopback-addr: 2.0.2
    +      it-length-prefixed: 11.0.1
    +      it-pipe: 3.0.1
    +      it-pushable: 3.2.4
    +      it-stream-types: 2.0.4
    +      main-event: 1.0.4
    +      netmask: 2.1.1
    +      p-defer: 4.0.1
    +      p-event: 7.1.0
    +      progress-events: 1.1.0
    +      protons-runtime: 7.0.0
    +      race-signal: 2.0.0
    +      uint8-varint: 3.0.0
    +      uint8arraylist: 3.0.2
    +      uint8arrays: 6.1.1
    +
       '@mdx-js/mdx@3.1.1':
         dependencies:
           '@types/estree': 1.0.9
    @@ -13464,11 +9700,11 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7)':
    +  '@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.8)':
         dependencies:
           '@types/mdx': 2.0.13
           '@types/react': 19.2.17
    -      react: 19.2.7
    +      react: 19.2.8
     
       '@mdx-js/rollup@3.1.1(rollup@4.60.2)':
         dependencies:
    @@ -13480,18 +9716,18 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  '@mermaid-js/parser@1.1.1':
    +  '@mermaid-js/parser@1.2.0':
         dependencies:
           '@chevrotain/types': 11.1.2
     
    -  '@mongodb-js/saslprep@1.4.9':
    +  '@mongodb-js/saslprep@1.4.12':
         dependencies:
           sparse-bitfield: 3.0.3
     
       '@multiformats/dns@1.0.13':
         dependencies:
           '@dnsquery/dns-packet': 6.1.1
    -      '@libp2p/interface': 3.2.4
    +      '@libp2p/interface': 3.2.5
           hashlru: 2.3.0
           p-queue: 9.3.0
           progress-events: 1.1.0
    @@ -13518,18 +9754,25 @@ snapshots:
           uint8-varint: 3.0.0
           uint8arrays: 6.1.1
     
    -  '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
    +  '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
         dependencies:
           '@emnapi/core': 1.10.0
           '@emnapi/runtime': 1.10.0
    -      '@tybys/wasm-util': 0.10.2
    +      '@tybys/wasm-util': 0.10.3
         optional: true
     
    -  '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
    +  '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
         dependencies:
    -      '@emnapi/core': 1.10.0
    -      '@emnapi/runtime': 1.10.0
    -      '@tybys/wasm-util': 0.10.2
    +      '@emnapi/core': 1.11.1
    +      '@emnapi/runtime': 1.11.1
    +      '@tybys/wasm-util': 0.10.3
    +    optional: true
    +
    +  '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)':
    +    dependencies:
    +      '@emnapi/core': 1.11.2
    +      '@emnapi/runtime': 1.11.2
    +      '@tybys/wasm-util': 0.10.3
         optional: true
     
       '@noble/ciphers@2.2.0': {}
    @@ -13544,198 +9787,67 @@ snapshots:
     
       '@noble/hashes@2.2.0': {}
     
    -  '@nodable/entities@3.0.0': {}
    -
    -  '@nodelib/fs.scandir@2.1.5':
    -    dependencies:
    -      '@nodelib/fs.stat': 2.0.5
    -      run-parallel: 1.2.0
    -
    -  '@nodelib/fs.stat@2.0.5': {}
    -
    -  '@nodelib/fs.walk@1.2.8':
    -    dependencies:
    -      '@nodelib/fs.scandir': 2.1.5
    -      fastq: 1.20.1
    -
    -  '@npmcli/agent@4.0.2':
    -    dependencies:
    -      agent-base: 7.1.4
    -      http-proxy-agent: 7.0.2
    -      https-proxy-agent: 7.0.6
    -      lru-cache: 11.5.1
    -      socks-proxy-agent: 8.0.5
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@npmcli/arborist@9.8.0':
    -    dependencies:
    -      '@gar/promise-retry': 1.0.3
    -      '@isaacs/string-locale-compare': 1.1.0
    -      '@npmcli/fs': 5.0.0
    -      '@npmcli/installed-package-contents': 4.0.0
    -      '@npmcli/map-workspaces': 5.0.3
    -      '@npmcli/metavuln-calculator': 9.0.3
    -      '@npmcli/name-from-folder': 4.0.0
    -      '@npmcli/node-gyp': 5.0.0
    -      '@npmcli/package-json': 7.0.5
    -      '@npmcli/query': 5.0.0
    -      '@npmcli/redact': 4.0.0
    -      '@npmcli/run-script': 10.0.4
    -      bin-links: 6.0.2
    -      cacache: 20.0.4
    -      common-ancestor-path: 2.0.0
    -      hosted-git-info: 9.0.3
    -      json-stringify-nice: 1.1.4
    -      lru-cache: 11.5.1
    -      minimatch: 10.2.5
    -      nopt: 9.0.0
    -      npm-install-checks: 8.0.0
    -      npm-package-arg: 13.0.2
    -      npm-pick-manifest: 11.0.3
    -      npm-registry-fetch: 19.1.1
    -      pacote: 21.5.1
    -      parse-conflict-json: 5.0.1
    -      proc-log: 6.1.0
    -      proggy: 4.0.0
    -      promise-all-reject-late: 1.0.1
    -      promise-call-limit: 3.0.2
    -      semver: 7.8.5
    -      ssri: 13.0.1
    -      treeverse: 3.0.0
    -      walk-up-path: 4.0.0
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@npmcli/config@8.3.4':
    -    dependencies:
    -      '@npmcli/map-workspaces': 3.0.6
    -      '@npmcli/package-json': 5.2.1
    -      ci-info: 4.4.0
    -      ini: 4.1.3
    -      nopt: 7.2.1
    -      proc-log: 4.2.0
    -      semver: 7.8.5
    -      walk-up-path: 3.0.1
    -    transitivePeerDependencies:
    -      - bluebird
    +  '@opentelemetry/api@1.9.1':
    +    optional: true
     
    -  '@npmcli/fs@5.0.0':
    -    dependencies:
    -      semver: 7.8.5
    +  '@oxc-project/types@0.139.0': {}
     
    -  '@npmcli/git@5.0.8':
    -    dependencies:
    -      '@npmcli/promise-spawn': 7.0.2
    -      ini: 4.1.3
    -      lru-cache: 10.4.3
    -      npm-pick-manifest: 9.1.0
    -      proc-log: 4.2.0
    -      promise-inflight: 1.0.1
    -      promise-retry: 2.0.1
    -      semver: 7.8.5
    -      which: 4.0.0
    -    transitivePeerDependencies:
    -      - bluebird
    +  '@oxlint/binding-android-arm-eabi@1.75.0':
    +    optional: true
     
    -  '@npmcli/git@7.0.2':
    -    dependencies:
    -      '@gar/promise-retry': 1.0.3
    -      '@npmcli/promise-spawn': 9.0.1
    -      ini: 6.0.0
    -      lru-cache: 11.5.1
    -      npm-pick-manifest: 11.0.3
    -      proc-log: 6.1.0
    -      semver: 7.8.5
    -      which: 6.0.1
    +  '@oxlint/binding-android-arm64@1.75.0':
    +    optional: true
     
    -  '@npmcli/installed-package-contents@4.0.0':
    -    dependencies:
    -      npm-bundled: 5.0.0
    -      npm-normalize-package-bin: 5.0.0
    +  '@oxlint/binding-darwin-arm64@1.75.0':
    +    optional: true
     
    -  '@npmcli/map-workspaces@3.0.6':
    -    dependencies:
    -      '@npmcli/name-from-folder': 2.0.0
    -      glob: 10.5.0
    -      minimatch: 9.0.9
    -      read-package-json-fast: 3.0.2
    +  '@oxlint/binding-darwin-x64@1.75.0':
    +    optional: true
     
    -  '@npmcli/map-workspaces@5.0.3':
    -    dependencies:
    -      '@npmcli/name-from-folder': 4.0.0
    -      '@npmcli/package-json': 7.0.5
    -      glob: 13.0.6
    -      minimatch: 10.2.5
    +  '@oxlint/binding-freebsd-x64@1.75.0':
    +    optional: true
     
    -  '@npmcli/metavuln-calculator@9.0.3':
    -    dependencies:
    -      cacache: 20.0.4
    -      json-parse-even-better-errors: 5.0.0
    -      pacote: 21.5.1
    -      proc-log: 6.1.0
    -      semver: 7.8.5
    -    transitivePeerDependencies:
    -      - supports-color
    +  '@oxlint/binding-linux-arm-gnueabihf@1.75.0':
    +    optional: true
     
    -  '@npmcli/name-from-folder@2.0.0': {}
    +  '@oxlint/binding-linux-arm-musleabihf@1.75.0':
    +    optional: true
     
    -  '@npmcli/name-from-folder@4.0.0': {}
    +  '@oxlint/binding-linux-arm64-gnu@1.75.0':
    +    optional: true
     
    -  '@npmcli/node-gyp@5.0.0': {}
    +  '@oxlint/binding-linux-arm64-musl@1.75.0':
    +    optional: true
     
    -  '@npmcli/package-json@5.2.1':
    -    dependencies:
    -      '@npmcli/git': 5.0.8
    -      glob: 10.5.0
    -      hosted-git-info: 7.0.2
    -      json-parse-even-better-errors: 3.0.2
    -      normalize-package-data: 6.0.2
    -      proc-log: 4.2.0
    -      semver: 7.8.5
    -    transitivePeerDependencies:
    -      - bluebird
    +  '@oxlint/binding-linux-ppc64-gnu@1.75.0':
    +    optional: true
     
    -  '@npmcli/package-json@7.0.5':
    -    dependencies:
    -      '@npmcli/git': 7.0.2
    -      glob: 13.0.6
    -      hosted-git-info: 9.0.3
    -      json-parse-even-better-errors: 5.0.0
    -      proc-log: 6.1.0
    -      semver: 7.8.5
    -      spdx-expression-parse: 4.0.0
    +  '@oxlint/binding-linux-riscv64-gnu@1.75.0':
    +    optional: true
     
    -  '@npmcli/promise-spawn@7.0.2':
    -    dependencies:
    -      which: 4.0.0
    +  '@oxlint/binding-linux-riscv64-musl@1.75.0':
    +    optional: true
     
    -  '@npmcli/promise-spawn@9.0.1':
    -    dependencies:
    -      which: 6.0.1
    +  '@oxlint/binding-linux-s390x-gnu@1.75.0':
    +    optional: true
     
    -  '@npmcli/query@5.0.0':
    -    dependencies:
    -      postcss-selector-parser: 7.1.4
    +  '@oxlint/binding-linux-x64-gnu@1.75.0':
    +    optional: true
     
    -  '@npmcli/redact@4.0.0': {}
    +  '@oxlint/binding-linux-x64-musl@1.75.0':
    +    optional: true
     
    -  '@npmcli/run-script@10.0.4':
    -    dependencies:
    -      '@npmcli/node-gyp': 5.0.0
    -      '@npmcli/package-json': 7.0.5
    -      '@npmcli/promise-spawn': 9.0.1
    -      node-gyp: 12.4.0
    -      proc-log: 6.1.0
    +  '@oxlint/binding-openharmony-arm64@1.75.0':
    +    optional: true
     
    -  '@openapi-contrib/openapi-schema-to-json-schema@3.2.0':
    -    dependencies:
    -      fast-deep-equal: 3.1.3
    +  '@oxlint/binding-win32-arm64-msvc@1.75.0':
    +    optional: true
     
    -  '@opentelemetry/api@1.9.1':
    +  '@oxlint/binding-win32-ia32-msvc@1.75.0':
         optional: true
     
    -  '@oxc-project/types@0.133.0': {}
    +  '@oxlint/binding-win32-x64-msvc@1.75.0':
    +    optional: true
     
       '@pagefind/darwin-arm64@1.5.2':
         optional: true
    @@ -13762,65 +9874,61 @@ snapshots:
         dependencies:
           '@noble/hashes': 1.8.0
     
    -  '@parcel/watcher-android-arm64@2.5.6':
    -    optional: true
    -
    -  '@parcel/watcher-darwin-arm64@2.5.6':
    +  '@parcel/watcher-android-arm64@2.6.0':
         optional: true
     
    -  '@parcel/watcher-darwin-x64@2.5.6':
    +  '@parcel/watcher-darwin-arm64@2.6.0':
         optional: true
     
    -  '@parcel/watcher-freebsd-x64@2.5.6':
    +  '@parcel/watcher-darwin-x64@2.6.0':
         optional: true
     
    -  '@parcel/watcher-linux-arm-glibc@2.5.6':
    +  '@parcel/watcher-freebsd-x64@2.6.0':
         optional: true
     
    -  '@parcel/watcher-linux-arm-musl@2.5.6':
    +  '@parcel/watcher-linux-arm-glibc@2.6.0':
         optional: true
     
    -  '@parcel/watcher-linux-arm64-glibc@2.5.6':
    +  '@parcel/watcher-linux-arm-musl@2.6.0':
         optional: true
     
    -  '@parcel/watcher-linux-arm64-musl@2.5.6':
    +  '@parcel/watcher-linux-arm64-glibc@2.6.0':
         optional: true
     
    -  '@parcel/watcher-linux-x64-glibc@2.5.6':
    +  '@parcel/watcher-linux-arm64-musl@2.6.0':
         optional: true
     
    -  '@parcel/watcher-linux-x64-musl@2.5.6':
    +  '@parcel/watcher-linux-x64-glibc@2.6.0':
         optional: true
     
    -  '@parcel/watcher-win32-arm64@2.5.6':
    +  '@parcel/watcher-linux-x64-musl@2.6.0':
         optional: true
     
    -  '@parcel/watcher-win32-ia32@2.5.6':
    +  '@parcel/watcher-win32-arm64@2.6.0':
         optional: true
     
    -  '@parcel/watcher-win32-x64@2.5.6':
    +  '@parcel/watcher-win32-x64@2.6.0':
         optional: true
     
    -  '@parcel/watcher@2.5.6':
    +  '@parcel/watcher@2.6.0':
         dependencies:
           detect-libc: 2.1.2
           is-glob: 4.0.3
           node-addon-api: 7.1.1
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
         optionalDependencies:
    -      '@parcel/watcher-android-arm64': 2.5.6
    -      '@parcel/watcher-darwin-arm64': 2.5.6
    -      '@parcel/watcher-darwin-x64': 2.5.6
    -      '@parcel/watcher-freebsd-x64': 2.5.6
    -      '@parcel/watcher-linux-arm-glibc': 2.5.6
    -      '@parcel/watcher-linux-arm-musl': 2.5.6
    -      '@parcel/watcher-linux-arm64-glibc': 2.5.6
    -      '@parcel/watcher-linux-arm64-musl': 2.5.6
    -      '@parcel/watcher-linux-x64-glibc': 2.5.6
    -      '@parcel/watcher-linux-x64-musl': 2.5.6
    -      '@parcel/watcher-win32-arm64': 2.5.6
    -      '@parcel/watcher-win32-ia32': 2.5.6
    -      '@parcel/watcher-win32-x64': 2.5.6
    +      '@parcel/watcher-android-arm64': 2.6.0
    +      '@parcel/watcher-darwin-arm64': 2.6.0
    +      '@parcel/watcher-darwin-x64': 2.6.0
    +      '@parcel/watcher-freebsd-x64': 2.6.0
    +      '@parcel/watcher-linux-arm-glibc': 2.6.0
    +      '@parcel/watcher-linux-arm-musl': 2.6.0
    +      '@parcel/watcher-linux-arm64-glibc': 2.6.0
    +      '@parcel/watcher-linux-arm64-musl': 2.6.0
    +      '@parcel/watcher-linux-x64-glibc': 2.6.0
    +      '@parcel/watcher-linux-x64-musl': 2.6.0
    +      '@parcel/watcher-win32-arm64': 2.6.0
    +      '@parcel/watcher-win32-x64': 2.6.0
         optional: true
     
       '@peculiar/asn1-cms@2.7.0':
    @@ -13920,39 +10028,19 @@ snapshots:
       '@pkgjs/parseargs@0.11.0':
         optional: true
     
    -  '@pkgr/core@0.2.9': {}
    +  '@pkgr/core@0.3.6': {}
     
       '@polka/url@1.0.0-next.29': {}
     
    -  '@protobufjs/aspromise@1.1.2': {}
    -
    -  '@protobufjs/base64@1.1.2': {}
    -
    -  '@protobufjs/codegen@2.0.5': {}
    -
    -  '@protobufjs/eventemitter@1.1.1': {}
    -
    -  '@protobufjs/fetch@1.1.1':
    -    dependencies:
    -      '@protobufjs/aspromise': 1.1.2
    -
    -  '@protobufjs/float@1.0.2': {}
    -
    -  '@protobufjs/path@1.1.2': {}
    -
    -  '@protobufjs/pool@1.1.0': {}
    -
    -  '@protobufjs/utf8@1.1.1': {}
    -
    -  '@puppeteer/browsers@2.13.0':
    +  '@puppeteer/browsers@2.13.2':
         dependencies:
           debug: 4.4.3
           extract-zip: 2.0.1
           progress: 2.0.3
           proxy-agent: 6.5.0
           semver: 7.8.5
    -      tar-fs: 3.1.2
    -      yargs: 17.7.2
    +      tar-fs: 3.1.3
    +      yargs: 17.7.3
         transitivePeerDependencies:
           - bare-abort-controller
           - bare-buffer
    @@ -13961,75 +10049,57 @@ snapshots:
     
       '@remix-run/router@1.23.3': {}
     
    -  '@rolldown/binding-android-arm64@1.0.3':
    +  '@rolldown/binding-android-arm64@1.1.5':
         optional: true
     
    -  '@rolldown/binding-darwin-arm64@1.0.3':
    +  '@rolldown/binding-darwin-arm64@1.1.5':
         optional: true
     
    -  '@rolldown/binding-darwin-x64@1.0.3':
    +  '@rolldown/binding-darwin-x64@1.1.5':
         optional: true
     
    -  '@rolldown/binding-freebsd-x64@1.0.3':
    +  '@rolldown/binding-freebsd-x64@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-arm-gnueabihf@1.0.3':
    +  '@rolldown/binding-linux-arm-gnueabihf@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-arm64-gnu@1.0.3':
    +  '@rolldown/binding-linux-arm64-gnu@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-arm64-musl@1.0.3':
    +  '@rolldown/binding-linux-arm64-musl@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-ppc64-gnu@1.0.3':
    +  '@rolldown/binding-linux-ppc64-gnu@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-s390x-gnu@1.0.3':
    +  '@rolldown/binding-linux-s390x-gnu@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-x64-gnu@1.0.3':
    +  '@rolldown/binding-linux-x64-gnu@1.1.5':
         optional: true
     
    -  '@rolldown/binding-linux-x64-musl@1.0.3':
    +  '@rolldown/binding-linux-x64-musl@1.1.5':
         optional: true
     
    -  '@rolldown/binding-openharmony-arm64@1.0.3':
    +  '@rolldown/binding-openharmony-arm64@1.1.5':
         optional: true
     
    -  '@rolldown/binding-wasm32-wasi@1.0.3':
    +  '@rolldown/binding-wasm32-wasi@1.1.5':
         dependencies:
    -      '@emnapi/core': 1.10.0
    -      '@emnapi/runtime': 1.10.0
    -      '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
    +      '@emnapi/core': 1.11.1
    +      '@emnapi/runtime': 1.11.1
    +      '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
         optional: true
     
    -  '@rolldown/binding-win32-arm64-msvc@1.0.3':
    +  '@rolldown/binding-win32-arm64-msvc@1.1.5':
         optional: true
     
    -  '@rolldown/binding-win32-x64-msvc@1.0.3':
    +  '@rolldown/binding-win32-x64-msvc@1.1.5':
         optional: true
     
       '@rolldown/pluginutils@1.0.1': {}
     
    -  '@rollup/plugin-babel@5.3.1(@babel/core@7.12.9)(@types/babel__core@7.20.5)(rollup@2.80.0)':
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-module-imports': 7.29.7
    -      '@rollup/pluginutils': 3.1.0(rollup@2.80.0)
    -      rollup: 2.80.0
    -    optionalDependencies:
    -      '@types/babel__core': 7.20.5
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@rollup/pluginutils@3.1.0(rollup@2.80.0)':
    -    dependencies:
    -      '@types/estree': 0.0.39
    -      estree-walker: 1.0.1
    -      picomatch: 2.3.2
    -      rollup: 2.80.0
    -
       '@rollup/pluginutils@5.3.0(rollup@4.60.2)':
         dependencies:
           '@types/estree': 1.0.9
    @@ -14113,317 +10183,133 @@ snapshots:
       '@rollup/rollup-win32-x64-msvc@4.60.2':
         optional: true
     
    -  '@rspack/binding-darwin-arm64@2.0.8':
    -    optional: true
    -
    -  '@rspack/binding-darwin-x64@2.0.8':
    -    optional: true
    -
    -  '@rspack/binding-linux-arm64-gnu@2.0.8':
    +  '@rspack/binding-darwin-arm64@2.1.5':
         optional: true
     
    -  '@rspack/binding-linux-arm64-musl@2.0.8':
    +  '@rspack/binding-darwin-x64@2.1.5':
         optional: true
     
    -  '@rspack/binding-linux-x64-gnu@2.0.8':
    +  '@rspack/binding-linux-arm64-gnu@2.1.5':
         optional: true
     
    -  '@rspack/binding-linux-x64-musl@2.0.8':
    +  '@rspack/binding-linux-arm64-musl@2.1.5':
         optional: true
     
    -  '@rspack/binding-wasm32-wasi@2.0.8':
    -    dependencies:
    -      '@emnapi/core': 1.10.0
    -      '@emnapi/runtime': 1.10.0
    -      '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
    -    optional: true
    -
    -  '@rspack/binding-win32-arm64-msvc@2.0.8':
    -    optional: true
    -
    -  '@rspack/binding-win32-ia32-msvc@2.0.8':
    +  '@rspack/binding-linux-riscv64-gnu@2.1.5':
         optional: true
     
    -  '@rspack/binding-win32-x64-msvc@2.0.8':
    +  '@rspack/binding-linux-riscv64-musl@2.1.5':
         optional: true
     
    -  '@rspack/binding@2.0.8':
    -    optionalDependencies:
    -      '@rspack/binding-darwin-arm64': 2.0.8
    -      '@rspack/binding-darwin-x64': 2.0.8
    -      '@rspack/binding-linux-arm64-gnu': 2.0.8
    -      '@rspack/binding-linux-arm64-musl': 2.0.8
    -      '@rspack/binding-linux-x64-gnu': 2.0.8
    -      '@rspack/binding-linux-x64-musl': 2.0.8
    -      '@rspack/binding-wasm32-wasi': 2.0.8
    -      '@rspack/binding-win32-arm64-msvc': 2.0.8
    -      '@rspack/binding-win32-ia32-msvc': 2.0.8
    -      '@rspack/binding-win32-x64-msvc': 2.0.8
    -
    -  '@rspack/cli@2.0.8(@rspack/core@2.0.8)':
    -    dependencies:
    -      '@rspack/core': 2.0.8
    -
    -  '@rspack/core@2.0.8':
    -    dependencies:
    -      '@rspack/binding': 2.0.8
    -
    -  '@rtsao/scc@1.1.0': {}
    -
    -  '@shikijs/core@4.2.0':
    -    dependencies:
    -      '@shikijs/primitive': 4.2.0
    -      '@shikijs/types': 4.2.0
    -      '@shikijs/vscode-textmate': 10.0.2
    -      '@types/hast': 3.0.4
    -      hast-util-to-html: 9.0.5
    -
    -  '@shikijs/engine-javascript@4.2.0':
    -    dependencies:
    -      '@shikijs/types': 4.2.0
    -      '@shikijs/vscode-textmate': 10.0.2
    -      oniguruma-to-es: 4.3.6
    -
    -  '@shikijs/engine-oniguruma@4.2.0':
    -    dependencies:
    -      '@shikijs/types': 4.2.0
    -      '@shikijs/vscode-textmate': 10.0.2
    -
    -  '@shikijs/langs@4.2.0':
    -    dependencies:
    -      '@shikijs/types': 4.2.0
    -
    -  '@shikijs/primitive@4.2.0':
    -    dependencies:
    -      '@shikijs/types': 4.2.0
    -      '@shikijs/vscode-textmate': 10.0.2
    -      '@types/hast': 3.0.4
    -
    -  '@shikijs/rehype@4.2.0':
    -    dependencies:
    -      '@shikijs/types': 4.2.0
    -      '@types/hast': 3.0.4
    -      hast-util-to-string: 3.0.1
    -      shiki: 4.2.0
    -      unified: 11.0.5
    -      unist-util-visit: 5.1.0
    -
    -  '@shikijs/themes@4.2.0':
    -    dependencies:
    -      '@shikijs/types': 4.2.0
    -
    -  '@shikijs/types@4.2.0':
    -    dependencies:
    -      '@shikijs/vscode-textmate': 10.0.2
    -      '@types/hast': 3.0.4
    -
    -  '@shikijs/vscode-textmate@10.0.2': {}
    -
    -  '@sigstore/bundle@4.0.0':
    -    dependencies:
    -      '@sigstore/protobuf-specs': 0.5.1
    -
    -  '@sigstore/core@3.2.1': {}
    -
    -  '@sigstore/protobuf-specs@0.5.1': {}
    -
    -  '@sigstore/sign@4.1.1':
    -    dependencies:
    -      '@gar/promise-retry': 1.0.3
    -      '@sigstore/bundle': 4.0.0
    -      '@sigstore/core': 3.2.1
    -      '@sigstore/protobuf-specs': 0.5.1
    -      make-fetch-happen: 15.0.6
    -      proc-log: 6.1.0
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@sigstore/tuf@4.0.2':
    -    dependencies:
    -      '@sigstore/protobuf-specs': 0.5.1
    -      tuf-js: 4.1.0
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@sigstore/verify@3.1.1':
    -    dependencies:
    -      '@sigstore/bundle': 4.0.0
    -      '@sigstore/core': 3.2.1
    -      '@sigstore/protobuf-specs': 0.5.1
    -
    -  '@simple-git/args-pathspec@1.0.3': {}
    -
    -  '@simple-git/argv-parser@1.1.1':
    -    dependencies:
    -      '@simple-git/args-pathspec': 1.0.3
    -
    -  '@sinclair/typebox@0.34.49': {}
    +  '@rspack/binding-linux-x64-gnu@2.1.5':
    +    optional: true
     
    -  '@sindresorhus/fnv1a@3.1.0': {}
    +  '@rspack/binding-linux-x64-musl@2.1.5':
    +    optional: true
     
    -  '@sinonjs/commons@3.0.1':
    +  '@rspack/binding-wasm32-wasi@2.1.5':
         dependencies:
    -      type-detect: 4.0.8
    +      '@emnapi/core': 1.11.2
    +      '@emnapi/runtime': 1.11.2
    +      '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)
    +    optional: true
     
    -  '@sinonjs/fake-timers@15.4.0':
    -    dependencies:
    -      '@sinonjs/commons': 3.0.1
    +  '@rspack/binding-win32-arm64-msvc@2.1.5':
    +    optional: true
     
    -  '@socket.io/component-emitter@3.1.2': {}
    +  '@rspack/binding-win32-ia32-msvc@2.1.5':
    +    optional: true
     
    -  '@standard-schema/spec@1.1.0': {}
    +  '@rspack/binding-win32-x64-msvc@2.1.5':
    +    optional: true
     
    -  '@stoplight/better-ajv-errors@1.0.3(ajv@8.20.0)':
    -    dependencies:
    -      ajv: 8.20.0
    -      jsonpointer: 5.0.1
    -      leven: 3.1.0
    +  '@rspack/binding@2.1.5':
    +    optionalDependencies:
    +      '@rspack/binding-darwin-arm64': 2.1.5
    +      '@rspack/binding-darwin-x64': 2.1.5
    +      '@rspack/binding-linux-arm64-gnu': 2.1.5
    +      '@rspack/binding-linux-arm64-musl': 2.1.5
    +      '@rspack/binding-linux-riscv64-gnu': 2.1.5
    +      '@rspack/binding-linux-riscv64-musl': 2.1.5
    +      '@rspack/binding-linux-x64-gnu': 2.1.5
    +      '@rspack/binding-linux-x64-musl': 2.1.5
    +      '@rspack/binding-wasm32-wasi': 2.1.5
    +      '@rspack/binding-win32-arm64-msvc': 2.1.5
    +      '@rspack/binding-win32-ia32-msvc': 2.1.5
    +      '@rspack/binding-win32-x64-msvc': 2.1.5
     
    -  '@stoplight/json-ref-readers@1.2.2(encoding@0.1.13)':
    +  '@rspack/cli@2.1.5(@rspack/core@2.1.5)':
         dependencies:
    -      node-fetch: 2.7.0(encoding@0.1.13)
    -      tslib: 1.14.1
    -    transitivePeerDependencies:
    -      - encoding
    +      '@rspack/core': 2.1.5
     
    -  '@stoplight/json-ref-resolver@3.1.6':
    +  '@rspack/core@2.1.5':
         dependencies:
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/path': 1.3.2
    -      '@stoplight/types': 13.20.0
    -      '@types/urijs': 1.19.26
    -      dependency-graph: 0.11.0
    -      fast-memoize: 2.5.2
    -      immer: 9.0.21
    -      lodash: 4.18.1
    -      tslib: 2.8.1
    -      urijs: 1.19.11
    +      '@rspack/binding': 2.1.5
     
    -  '@stoplight/json@3.21.0':
    +  '@shikijs/core@4.3.1':
         dependencies:
    -      '@stoplight/ordered-object-literal': 1.0.5
    -      '@stoplight/path': 1.3.2
    -      '@stoplight/types': 13.20.0
    -      jsonc-parser: 2.2.1
    -      lodash: 4.18.1
    -      safe-stable-stringify: 1.1.1
    +      '@shikijs/primitive': 4.3.1
    +      '@shikijs/types': 4.3.1
    +      '@shikijs/vscode-textmate': 10.0.2
    +      '@types/hast': 3.0.4
    +      hast-util-to-html: 9.0.5
     
    -  '@stoplight/json@3.21.7':
    +  '@shikijs/engine-javascript@4.3.1':
         dependencies:
    -      '@stoplight/ordered-object-literal': 1.0.5
    -      '@stoplight/path': 1.3.2
    -      '@stoplight/types': 13.20.0
    -      jsonc-parser: 2.2.1
    -      lodash: 4.18.1
    -      safe-stable-stringify: 1.1.1
    -
    -  '@stoplight/ordered-object-literal@1.0.5': {}
    -
    -  '@stoplight/path@1.3.2': {}
    +      '@shikijs/types': 4.3.1
    +      '@shikijs/vscode-textmate': 10.0.2
    +      oniguruma-to-es: 4.3.6
     
    -  '@stoplight/spectral-core@1.23.0(encoding@0.1.13)':
    +  '@shikijs/engine-oniguruma@4.3.1':
         dependencies:
    -      '@stoplight/better-ajv-errors': 1.0.3(ajv@8.20.0)
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/path': 1.3.2
    -      '@stoplight/spectral-parsers': 1.0.5
    -      '@stoplight/spectral-ref-resolver': 1.0.5(encoding@0.1.13)
    -      '@stoplight/spectral-runtime': 1.1.5(encoding@0.1.13)
    -      '@stoplight/types': 13.6.0
    -      '@types/es-aggregate-error': 1.0.6
    -      '@types/json-schema': 7.0.15
    -      ajv: 8.20.0
    -      ajv-errors: 3.0.0(ajv@8.20.0)
    -      ajv-formats: 2.1.1(ajv@8.20.0)
    -      es-aggregate-error: 1.0.14
    -      expr-eval-fork: 3.0.3
    -      jsonpath-plus: 10.4.0
    -      lodash: 4.18.1
    -      lodash.topath: 4.5.2
    -      minimatch: 3.1.5
    -      nimma: 0.2.3
    -      pony-cause: 1.1.1
    -      tslib: 2.8.1
    -    transitivePeerDependencies:
    -      - encoding
    +      '@shikijs/types': 4.3.1
    +      '@shikijs/vscode-textmate': 10.0.2
     
    -  '@stoplight/spectral-formats@1.8.3(encoding@0.1.13)':
    +  '@shikijs/langs@4.3.1':
         dependencies:
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/spectral-core': 1.23.0(encoding@0.1.13)
    -      '@types/json-schema': 7.0.15
    -      tslib: 2.8.1
    -    transitivePeerDependencies:
    -      - encoding
    +      '@shikijs/types': 4.3.1
     
    -  '@stoplight/spectral-functions@1.10.3(encoding@0.1.13)':
    +  '@shikijs/primitive@4.3.1':
         dependencies:
    -      '@stoplight/better-ajv-errors': 1.0.3(ajv@8.20.0)
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/spectral-core': 1.23.0(encoding@0.1.13)
    -      '@stoplight/spectral-formats': 1.8.3(encoding@0.1.13)
    -      '@stoplight/spectral-runtime': 1.1.5(encoding@0.1.13)
    -      ajv: 8.20.0
    -      ajv-draft-04: 1.0.0(ajv@8.20.0)
    -      ajv-errors: 3.0.0(ajv@8.20.0)
    -      ajv-formats: 2.1.1(ajv@8.20.0)
    -      lodash: 4.18.1
    -      tslib: 2.8.1
    -    transitivePeerDependencies:
    -      - encoding
    +      '@shikijs/types': 4.3.1
    +      '@shikijs/vscode-textmate': 10.0.2
    +      '@types/hast': 3.0.4
     
    -  '@stoplight/spectral-parsers@1.0.5':
    +  '@shikijs/rehype@4.3.1':
         dependencies:
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/types': 14.1.1
    -      '@stoplight/yaml': 4.3.0
    -      tslib: 2.8.1
    +      '@shikijs/types': 4.3.1
    +      '@types/hast': 3.0.4
    +      hast-util-to-string: 3.0.1
    +      shiki: 4.3.1
    +      unified: 11.0.5
    +      unist-util-visit: 5.1.0
     
    -  '@stoplight/spectral-ref-resolver@1.0.5(encoding@0.1.13)':
    +  '@shikijs/themes@4.3.1':
         dependencies:
    -      '@stoplight/json-ref-readers': 1.2.2(encoding@0.1.13)
    -      '@stoplight/json-ref-resolver': 3.1.6
    -      '@stoplight/spectral-runtime': 1.1.5(encoding@0.1.13)
    -      dependency-graph: 0.11.0
    -      tslib: 2.8.1
    -    transitivePeerDependencies:
    -      - encoding
    +      '@shikijs/types': 4.3.1
     
    -  '@stoplight/spectral-runtime@1.1.5(encoding@0.1.13)':
    +  '@shikijs/types@4.3.1':
         dependencies:
    -      '@stoplight/json': 3.21.7
    -      '@stoplight/path': 1.3.2
    -      '@stoplight/types': 13.20.0
    -      abort-controller: 3.0.0
    -      lodash: 4.18.1
    -      node-fetch: 2.7.0(encoding@0.1.13)
    -      tslib: 2.8.1
    -    transitivePeerDependencies:
    -      - encoding
    +      '@shikijs/vscode-textmate': 10.0.2
    +      '@types/hast': 3.0.4
     
    -  '@stoplight/types@13.20.0':
    -    dependencies:
    -      '@types/json-schema': 7.0.15
    -      utility-types: 3.11.0
    +  '@shikijs/vscode-textmate@10.0.2': {}
     
    -  '@stoplight/types@13.6.0':
    +  '@sinclair/typebox@0.34.52': {}
    +
    +  '@sindresorhus/fnv1a@3.1.0': {}
    +
    +  '@sinonjs/commons@3.0.1':
         dependencies:
    -      '@types/json-schema': 7.0.15
    -      utility-types: 3.11.0
    +      type-detect: 4.0.8
     
    -  '@stoplight/types@14.1.1':
    +  '@sinonjs/fake-timers@15.4.0':
         dependencies:
    -      '@types/json-schema': 7.0.15
    -      utility-types: 3.11.0
    +      '@sinonjs/commons': 3.0.1
     
    -  '@stoplight/yaml-ast-parser@0.0.50': {}
    +  '@socket.io/component-emitter@3.1.2': {}
     
    -  '@stoplight/yaml@4.3.0':
    -    dependencies:
    -      '@stoplight/ordered-object-literal': 1.0.5
    -      '@stoplight/types': 14.1.1
    -      '@stoplight/yaml-ast-parser': 0.0.50
    -      tslib: 2.8.1
    +  '@standard-schema/spec@1.1.0': {}
     
       '@testing-library/dom@10.4.1':
         dependencies:
    @@ -14445,12 +10331,12 @@ snapshots:
           picocolors: 1.1.1
           redent: 3.0.0
     
    -  '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
    +  '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
         dependencies:
           '@babel/runtime': 7.29.2
           '@testing-library/dom': 10.4.1
    -      react: 19.2.7
    -      react-dom: 19.2.7(react@19.2.7)
    +      react: 19.2.8
    +      react-dom: 19.2.8(react@19.2.8)
         optionalDependencies:
           '@types/react': 19.2.17
           '@types/react-dom': 19.2.3(@types/react@19.2.17)
    @@ -14465,14 +10351,7 @@ snapshots:
     
       '@tsconfig/node16@1.0.4': {}
     
    -  '@tufjs/canonical-json@2.0.0': {}
    -
    -  '@tufjs/models@4.1.0':
    -    dependencies:
    -      '@tufjs/canonical-json': 2.0.0
    -      minimatch: 10.2.5
    -
    -  '@tybys/wasm-util@0.10.2':
    +  '@tybys/wasm-util@0.10.3':
         dependencies:
           tslib: 2.8.1
         optional: true
    @@ -14503,11 +10382,11 @@ snapshots:
       '@types/body-parser@1.19.6':
         dependencies:
           '@types/connect': 3.4.38
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/bonjour@3.5.13':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/chai@5.2.3':
         dependencies:
    @@ -14517,17 +10396,17 @@ snapshots:
       '@types/connect-history-api-fallback@1.5.4':
         dependencies:
           '@types/express-serve-static-core': 5.1.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/connect@3.4.38':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/cookiejar@2.1.5': {}
     
       '@types/cors@2.8.19':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/d3-array@3.2.2': {}
     
    @@ -14652,36 +10531,24 @@ snapshots:
     
       '@types/deep-eql@4.0.2': {}
     
    -  '@types/diff@8.0.0':
    -    dependencies:
    -      diff: 9.0.0
    -
    -  '@types/es-aggregate-error@1.0.6':
    -    dependencies:
    -      '@types/node': 26.0.0
    -
    -  '@types/esrecurse@4.3.1': {}
    -
       '@types/estree-jsx@1.0.5':
         dependencies:
           '@types/estree': 1.0.9
     
    -  '@types/estree@0.0.39': {}
    -
       '@types/estree@1.0.8': {}
     
       '@types/estree@1.0.9': {}
     
       '@types/express-serve-static-core@4.19.8':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           '@types/qs': 6.15.1
           '@types/range-parser': 1.2.7
           '@types/send': 1.2.1
     
       '@types/express-serve-static-core@5.1.1':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           '@types/qs': 6.15.1
           '@types/range-parser': 1.2.7
           '@types/send': 1.2.1
    @@ -14702,7 +10569,7 @@ snapshots:
       '@types/fs-extra@11.0.4':
         dependencies:
           '@types/jsonfile': 6.1.4
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/geojson@7946.0.16': {}
     
    @@ -14714,7 +10581,7 @@ snapshots:
     
       '@types/http-proxy@1.17.17':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/istanbul-lib-coverage@2.0.6': {}
     
    @@ -14726,10 +10593,6 @@ snapshots:
         dependencies:
           '@types/istanbul-lib-report': 3.0.3
     
    -  '@types/jest-diff@24.3.0':
    -    dependencies:
    -      jest-diff: 30.4.1
    -
       '@types/jest@30.0.0':
         dependencies:
           expect: 30.4.1
    @@ -14737,17 +10600,15 @@ snapshots:
     
       '@types/jsdom@21.1.7':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           '@types/tough-cookie': 4.0.5
           parse5: 7.3.0
     
       '@types/json-schema@7.0.15': {}
     
    -  '@types/json5@0.0.29': {}
    -
       '@types/jsonfile@6.1.4':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/mdast@4.0.4':
         dependencies:
    @@ -14765,25 +10626,19 @@ snapshots:
     
       '@types/node-fetch@2.6.13':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           form-data: 4.0.6
     
    -  '@types/node@16.18.126': {}
    -
    -  '@types/node@26.0.0':
    +  '@types/node@26.1.1':
         dependencies:
           undici-types: 8.3.0
     
       '@types/parse-json@4.0.2':
         optional: true
     
    -  '@types/protocol-buffers-schema@3.4.3':
    -    dependencies:
    -      '@types/node': 26.0.0
    -
       '@types/qrcode@1.5.6':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/qs@6.15.1': {}
     
    @@ -14799,16 +10654,14 @@ snapshots:
     
       '@types/retry@0.12.2': {}
     
    -  '@types/semver@7.7.1': {}
    -
       '@types/send@0.17.6':
         dependencies:
           '@types/mime': 1.3.5
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/send@1.2.1':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/serve-index@1.9.4':
         dependencies:
    @@ -14817,17 +10670,17 @@ snapshots:
       '@types/serve-static@1.15.10':
         dependencies:
           '@types/http-errors': 2.0.5
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           '@types/send': 0.17.6
     
       '@types/serve-static@2.2.0':
         dependencies:
           '@types/http-errors': 2.0.5
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/sockjs@0.3.36':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/stack-utils@2.0.3': {}
     
    @@ -14835,10 +10688,10 @@ snapshots:
         dependencies:
           '@types/cookiejar': 2.1.5
           '@types/methods': 1.1.4
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           form-data: 4.0.6
     
    -  '@types/supertest@7.2.0':
    +  '@types/supertest@7.2.1':
         dependencies:
           '@types/methods': 1.1.4
           '@types/superagent': 8.1.10
    @@ -14852,8 +10705,6 @@ snapshots:
     
       '@types/unist@3.0.3': {}
     
    -  '@types/urijs@1.19.26': {}
    -
       '@types/webidl-conversions@7.0.3': {}
     
       '@types/whatwg-url@13.0.0':
    @@ -14862,7 +10713,7 @@ snapshots:
     
       '@types/ws@8.18.1':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
     
       '@types/yargs-parser@21.0.3': {}
     
    @@ -14872,187 +10723,12 @@ snapshots:
     
       '@types/yauzl@2.10.3':
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
         optional: true
     
    -  '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3)':
    -    dependencies:
    -      '@eslint-community/regexpp': 4.12.2
    -      '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      '@typescript-eslint/scope-manager': 5.62.0
    -      '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      debug: 4.4.3
    -      eslint: 8.57.1
    -      graphemer: 1.4.0
    -      ignore: 5.3.2
    -      natural-compare-lite: 1.4.0
    -      semver: 7.8.5
    -      tsutils: 3.21.0(typescript@6.0.3)
    -    optionalDependencies:
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)':
    -    dependencies:
    -      '@eslint-community/regexpp': 4.12.2
    -      '@typescript-eslint/parser': 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    -      '@typescript-eslint/scope-manager': 8.61.1
    -      '@typescript-eslint/type-utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    -      '@typescript-eslint/utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    -      '@typescript-eslint/visitor-keys': 8.61.1
    -      eslint: 10.5.0
    -      ignore: 7.0.5
    -      natural-compare: 1.4.0
    -      ts-api-utils: 2.5.0(typescript@6.0.3)
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/scope-manager': 5.62.0
    -      '@typescript-eslint/types': 5.62.0
    -      '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.3)
    -      debug: 4.4.3
    -      eslint: 8.57.1
    -    optionalDependencies:
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/scope-manager': 8.61.1
    -      '@typescript-eslint/types': 8.61.1
    -      '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3)
    -      '@typescript-eslint/visitor-keys': 8.61.1
    -      debug: 4.4.3
    -      eslint: 10.5.0
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/project-service@8.61.1(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3)
    -      '@typescript-eslint/types': 8.61.1
    -      debug: 4.4.3
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/scope-manager@5.62.0':
    -    dependencies:
    -      '@typescript-eslint/types': 5.62.0
    -      '@typescript-eslint/visitor-keys': 5.62.0
    -
    -  '@typescript-eslint/scope-manager@8.61.1':
    -    dependencies:
    -      '@typescript-eslint/types': 8.61.1
    -      '@typescript-eslint/visitor-keys': 8.61.1
    -
    -  '@typescript-eslint/tsconfig-utils@8.61.1(typescript@6.0.3)':
    -    dependencies:
    -      typescript: 6.0.3
    -
    -  '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.3)
    -      '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      debug: 4.4.3
    -      eslint: 8.57.1
    -      tsutils: 3.21.0(typescript@6.0.3)
    -    optionalDependencies:
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/type-utils@8.61.1(eslint@10.5.0)(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/types': 8.61.1
    -      '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3)
    -      '@typescript-eslint/utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    -      debug: 4.4.3
    -      eslint: 10.5.0
    -      ts-api-utils: 2.5.0(typescript@6.0.3)
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/types@5.62.0': {}
    -
    -  '@typescript-eslint/types@8.61.1': {}
    -
    -  '@typescript-eslint/typescript-estree@5.62.0(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/types': 5.62.0
    -      '@typescript-eslint/visitor-keys': 5.62.0
    -      debug: 4.4.3
    -      globby: 11.1.0
    -      is-glob: 4.0.3
    -      semver: 7.8.5
    -      tsutils: 3.21.0(typescript@6.0.3)
    -    optionalDependencies:
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/typescript-estree@8.61.1(typescript@6.0.3)':
    -    dependencies:
    -      '@typescript-eslint/project-service': 8.61.1(typescript@6.0.3)
    -      '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3)
    -      '@typescript-eslint/types': 8.61.1
    -      '@typescript-eslint/visitor-keys': 8.61.1
    -      debug: 4.4.3
    -      minimatch: 10.2.5
    -      semver: 7.8.5
    -      tinyglobby: 0.2.17
    -      ts-api-utils: 2.5.0(typescript@6.0.3)
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@6.0.3)':
    -    dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1)
    -      '@types/json-schema': 7.0.15
    -      '@types/semver': 7.7.1
    -      '@typescript-eslint/scope-manager': 5.62.0
    -      '@typescript-eslint/types': 5.62.0
    -      '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.3)
    -      eslint: 8.57.1
    -      eslint-scope: 5.1.1
    -      semver: 7.8.5
    -    transitivePeerDependencies:
    -      - supports-color
    -      - typescript
    -
    -  '@typescript-eslint/utils@8.61.1(eslint@10.5.0)(typescript@6.0.3)':
    -    dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0)
    -      '@typescript-eslint/scope-manager': 8.61.1
    -      '@typescript-eslint/types': 8.61.1
    -      '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3)
    -      eslint: 10.5.0
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  '@typescript-eslint/visitor-keys@5.62.0':
    -    dependencies:
    -      '@typescript-eslint/types': 5.62.0
    -      eslint-visitor-keys: 3.4.3
    -
    -  '@typescript-eslint/visitor-keys@8.61.1':
    -    dependencies:
    -      '@typescript-eslint/types': 8.61.1
    -      eslint-visitor-keys: 5.0.1
    -
       '@ungap/structured-clone@1.3.0': {}
     
    -  '@ungap/structured-clone@1.3.1': {}
    +  '@ungap/structured-clone@1.3.3': {}
     
       '@unrs/resolver-binding-android-arm-eabi@1.12.2':
         optional: true
    @@ -15112,7 +10788,7 @@ snapshots:
         dependencies:
           '@emnapi/core': 1.10.0
           '@emnapi/runtime': 1.10.0
    -      '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
    +      '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
         optional: true
     
       '@unrs/resolver-binding-win32-arm64-msvc@1.12.2':
    @@ -15129,49 +10805,49 @@ snapshots:
           d3-selection: 3.0.0
           d3-transition: 3.0.1(d3-selection@3.0.0)
     
    -  '@vitejs/plugin-react@6.0.2(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3))':
    +  '@vitejs/plugin-react@6.0.4(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0))':
         dependencies:
           '@rolldown/pluginutils': 1.0.1
    -      vite: 8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)
    +      vite: 8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)
     
    -  '@vitest/expect@4.1.9':
    +  '@vitest/expect@4.1.10':
         dependencies:
           '@standard-schema/spec': 1.1.0
           '@types/chai': 5.2.3
    -      '@vitest/spy': 4.1.9
    -      '@vitest/utils': 4.1.9
    +      '@vitest/spy': 4.1.10
    +      '@vitest/utils': 4.1.10
           chai: 6.2.2
           tinyrainbow: 3.1.0
     
    -  '@vitest/mocker@4.1.9(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3))':
    +  '@vitest/mocker@4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0))':
         dependencies:
    -      '@vitest/spy': 4.1.9
    +      '@vitest/spy': 4.1.10
           estree-walker: 3.0.3
           magic-string: 0.30.21
         optionalDependencies:
    -      vite: 8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)
    +      vite: 8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)
     
    -  '@vitest/pretty-format@4.1.9':
    +  '@vitest/pretty-format@4.1.10':
         dependencies:
           tinyrainbow: 3.1.0
     
    -  '@vitest/runner@4.1.9':
    +  '@vitest/runner@4.1.10':
         dependencies:
    -      '@vitest/utils': 4.1.9
    +      '@vitest/utils': 4.1.10
           pathe: 2.0.3
     
    -  '@vitest/snapshot@4.1.9':
    +  '@vitest/snapshot@4.1.10':
         dependencies:
    -      '@vitest/pretty-format': 4.1.9
    -      '@vitest/utils': 4.1.9
    +      '@vitest/pretty-format': 4.1.10
    +      '@vitest/utils': 4.1.10
           magic-string: 0.30.21
           pathe: 2.0.3
     
    -  '@vitest/spy@4.1.9': {}
    +  '@vitest/spy@4.1.10': {}
     
    -  '@vitest/utils@4.1.9':
    +  '@vitest/utils@4.1.10':
         dependencies:
    -      '@vitest/pretty-format': 4.1.9
    +      '@vitest/pretty-format': 4.1.10
           convert-source-map: 2.0.0
           tinyrainbow: 3.1.0
     
    @@ -15255,13 +10931,8 @@ snapshots:
     
       '@xtuc/long@4.2.2': {}
     
    -  abbrev@2.0.0: {}
    -
    -  abbrev@4.0.0: {}
    -
    -  abort-controller@3.0.0:
    -    dependencies:
    -      event-target-shim: 5.0.1
    +  abbrev@4.0.0:
    +    optional: true
     
       abort-error@1.0.2: {}
     
    @@ -15275,29 +10946,23 @@ snapshots:
           mime-types: 3.0.2
           negotiator: 1.0.0
     
    -  acorn-import-phases@1.0.4(acorn@8.16.0):
    +  acorn-jsx@5.3.2(acorn@8.16.0):
         dependencies:
           acorn: 8.16.0
     
    -  acorn-jsx@5.3.2(acorn@8.16.0):
    +  acorn-jsx@5.3.2(acorn@8.17.0):
         dependencies:
    -      acorn: 8.16.0
    +      acorn: 8.17.0
     
       acorn-walk@8.3.5:
         dependencies:
    -      acorn: 8.16.0
    +      acorn: 8.17.0
     
       acorn@8.16.0: {}
     
    -  agent-base@7.1.4: {}
    -
    -  ajv-draft-04@1.0.0(ajv@8.20.0):
    -    optionalDependencies:
    -      ajv: 8.20.0
    +  acorn@8.17.0: {}
     
    -  ajv-errors@3.0.0(ajv@8.20.0):
    -    dependencies:
    -      ajv: 8.20.0
    +  agent-base@7.1.4: {}
     
       ajv-formats@2.1.1(ajv@8.20.0):
         optionalDependencies:
    @@ -15312,27 +10977,6 @@ snapshots:
           ajv: 8.20.0
           fast-deep-equal: 3.1.3
     
    -  ajv@5.5.2:
    -    dependencies:
    -      co: 4.6.0
    -      fast-deep-equal: 1.1.0
    -      fast-json-stable-stringify: 2.1.0
    -      json-schema-traverse: 0.3.1
    -
    -  ajv@6.15.0:
    -    dependencies:
    -      fast-deep-equal: 3.1.3
    -      fast-json-stable-stringify: 2.1.0
    -      json-schema-traverse: 0.4.1
    -      uri-js: 4.4.1
    -
    -  ajv@6.5.2:
    -    dependencies:
    -      fast-deep-equal: 2.0.1
    -      fast-json-stable-stringify: 2.1.0
    -      json-schema-traverse: 0.4.1
    -      uri-js: 4.4.1
    -
       ajv@8.20.0:
         dependencies:
           fast-deep-equal: 3.1.3
    @@ -15340,15 +10984,6 @@ snapshots:
           json-schema-traverse: 1.0.0
           require-from-string: 2.0.2
     
    -  alterschema@1.1.3(encoding@0.1.13):
    -    dependencies:
    -      '@hyperjump/json-schema': 0.23.5(encoding@0.1.13)
    -      json-e: 4.8.2
    -      lodash: 4.18.1
    -      object-hash: 3.0.0
    -    transitivePeerDependencies:
    -      - encoding
    -
       ansi-escapes@4.3.2:
         dependencies:
           type-fest: 0.21.3
    @@ -15376,15 +11011,14 @@ snapshots:
           normalize-path: 3.0.0
           picomatch: 2.3.2
     
    -  anynum@1.0.1: {}
    -
       arg@4.1.3: {}
     
       argparse@1.0.10:
         dependencies:
           sprintf-js: 1.0.3
     
    -  argparse@2.0.1: {}
    +  argparse@2.0.1:
    +    optional: true
     
       aria-query@5.3.0:
         dependencies:
    @@ -15392,77 +11026,8 @@ snapshots:
     
       aria-query@5.3.2: {}
     
    -  array-buffer-byte-length@1.0.2:
    -    dependencies:
    -      call-bound: 1.0.4
    -      is-array-buffer: 3.0.5
    -
       array-flatten@1.1.1: {}
     
    -  array-includes@3.1.9:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-object-atoms: 1.1.1
    -      get-intrinsic: 1.3.0
    -      is-string: 1.1.1
    -      math-intrinsics: 1.1.0
    -
    -  array-union@2.1.0: {}
    -
    -  array.prototype.findlast@1.2.5:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      es-object-atoms: 1.1.1
    -      es-shim-unscopables: 1.1.0
    -
    -  array.prototype.findlastindex@1.2.6:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      es-object-atoms: 1.1.1
    -      es-shim-unscopables: 1.1.0
    -
    -  array.prototype.flat@1.3.3:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-shim-unscopables: 1.1.0
    -
    -  array.prototype.flatmap@1.3.3:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-shim-unscopables: 1.1.0
    -
    -  array.prototype.tosorted@1.1.4:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      es-shim-unscopables: 1.1.0
    -
    -  arraybuffer.prototype.slice@1.0.4:
    -    dependencies:
    -      array-buffer-byte-length: 1.0.2
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      get-intrinsic: 1.3.0
    -      is-array-buffer: 3.0.5
    -
       asap@2.0.6: {}
     
       asn1js@3.0.10:
    @@ -15479,20 +11044,12 @@ snapshots:
     
       astring@1.9.0: {}
     
    -  async-function@1.0.0: {}
    -
       async-mutex@0.5.0:
         dependencies:
           tslib: 2.8.1
     
       asynckit@0.4.0: {}
     
    -  available-typed-arrays@1.0.7:
    -    dependencies:
    -      possible-typed-array-names: 1.1.0
    -
    -  avsc@5.7.9: {}
    -
       aws-ssl-profiles@1.1.2: {}
     
       b4a@1.8.1: {}
    @@ -15531,36 +11088,6 @@ snapshots:
           resolve: 1.22.12
         optional: true
     
    -  babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.12.9):
    -    dependencies:
    -      '@babel/compat-data': 7.29.7
    -      '@babel/core': 7.12.9
    -      '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.12.9)
    -      semver: 6.3.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.12.9):
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.12.9)
    -      core-js-compat: 3.49.0
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.12.9):
    -    dependencies:
    -      '@babel/core': 7.12.9
    -      '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.12.9)
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  babel-plugin-source-map-support@2.2.0:
    -    dependencies:
    -      '@babel/helper-module-imports': 7.29.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
       babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.7):
         dependencies:
           '@babel/core': 7.29.7
    @@ -15592,6 +11119,9 @@ snapshots:
     
       bare-events@2.8.3: {}
     
    +  bare-events@2.9.1:
    +    optional: true
    +
       bare-fs@4.7.1:
         dependencies:
           bare-events: 2.8.3
    @@ -15603,12 +11133,27 @@ snapshots:
           - bare-abort-controller
           - react-native-b4a
     
    +  bare-fs@4.7.4:
    +    dependencies:
    +      bare-events: 2.9.1
    +      bare-path: 3.1.1
    +      bare-stream: 2.13.3(bare-events@2.9.1)
    +      bare-url: 2.4.6
    +      fast-fifo: 1.3.2
    +    transitivePeerDependencies:
    +      - bare-abort-controller
    +      - react-native-b4a
    +    optional: true
    +
       bare-os@3.9.0: {}
     
       bare-path@3.0.0:
         dependencies:
           bare-os: 3.9.0
     
    +  bare-path@3.1.1:
    +    optional: true
    +
       bare-stream@2.13.1(bare-events@2.8.3):
         dependencies:
           streamx: 2.25.0
    @@ -15618,16 +11163,34 @@ snapshots:
         transitivePeerDependencies:
           - react-native-b4a
     
    +  bare-stream@2.13.3(bare-events@2.9.1):
    +    dependencies:
    +      b4a: 1.8.1
    +      streamx: 2.28.0
    +      teex: 1.0.1
    +    optionalDependencies:
    +      bare-events: 2.9.1
    +    transitivePeerDependencies:
    +      - react-native-b4a
    +    optional: true
    +
       bare-url@2.4.3:
         dependencies:
           bare-path: 3.0.0
     
    +  bare-url@2.4.6:
    +    dependencies:
    +      bare-path: 3.1.1
    +    optional: true
    +
       base64-js@1.5.1: {}
     
       base64id@2.0.0: {}
     
       baseline-browser-mapping@2.10.32: {}
     
    +  baseline-browser-mapping@2.11.1: {}
    +
       basic-ftp@5.3.1: {}
     
       batch@0.6.1: {}
    @@ -15640,14 +11203,7 @@ snapshots:
       bidi-js@1.0.3:
         dependencies:
           require-from-string: 2.0.2
    -
    -  bin-links@6.0.2:
    -    dependencies:
    -      cmd-shim: 8.0.0
    -      npm-normalize-package-bin: 5.0.0
    -      proc-log: 6.1.0
    -      read-cmd-shim: 6.0.0
    -      write-file-atomic: 7.0.1
    +    optional: true
     
       binary-extensions@2.3.0: {}
     
    @@ -15661,7 +11217,7 @@ snapshots:
           inherits: 2.0.4
           readable-stream: 3.6.2
     
    -  body-parser@1.20.5:
    +  body-parser@1.20.6:
         dependencies:
           bytes: 3.1.2
           content-type: 1.0.5
    @@ -15727,6 +11283,14 @@ snapshots:
           node-releases: 2.0.46
           update-browserslist-db: 1.2.3(browserslist@4.28.2)
     
    +  browserslist@4.28.7:
    +    dependencies:
    +      baseline-browser-mapping: 2.11.1
    +      caniuse-lite: 1.0.30001806
    +      electron-to-chromium: 1.5.395
    +      node-releases: 2.0.51
    +      update-browserslist-db: 1.2.3(browserslist@4.28.7)
    +
       bs-logger@0.2.6:
         dependencies:
           fast-json-stable-stringify: 2.1.0
    @@ -15746,10 +11310,6 @@ snapshots:
           base64-js: 1.5.1
           ieee754: 1.2.1
     
    -  builtins@5.1.0:
    -    dependencies:
    -      semver: 7.8.5
    -
       bundle-name@4.1.0:
         dependencies:
           run-applescript: 7.1.0
    @@ -15765,59 +11325,30 @@ snapshots:
     
       cac@6.7.14: {}
     
    -  cacache@20.0.4:
    -    dependencies:
    -      '@npmcli/fs': 5.0.0
    -      fs-minipass: 3.0.3
    -      glob: 13.0.6
    -      lru-cache: 11.5.1
    -      minipass: 7.1.3
    -      minipass-collect: 2.0.1
    -      minipass-flush: 1.0.7
    -      minipass-pipeline: 1.2.4
    -      p-map: 7.0.4
    -      ssri: 13.0.1
    -
       call-bind-apply-helpers@1.0.2:
         dependencies:
           es-errors: 1.3.0
           function-bind: 1.1.2
     
    -  call-bind@1.0.9:
    -    dependencies:
    -      call-bind-apply-helpers: 1.0.2
    -      es-define-property: 1.0.1
    -      get-intrinsic: 1.3.0
    -      set-function-length: 1.2.2
    -
       call-bound@1.0.4:
         dependencies:
           call-bind-apply-helpers: 1.0.2
           get-intrinsic: 1.3.0
     
    -  call-me-maybe@1.0.2: {}
    -
       callsites@3.1.0: {}
     
    -  camel-case@4.1.2:
    -    dependencies:
    -      pascal-case: 3.1.2
    -      tslib: 2.8.1
    -
       camelcase@5.3.1: {}
     
       camelcase@6.3.0: {}
     
       caniuse-lite@1.0.30001793: {}
     
    -  capital-case@1.0.4:
    -    dependencies:
    -      no-case: 3.0.4
    -      tslib: 2.8.1
    -      upper-case-first: 2.0.2
    +  caniuse-lite@1.0.30001806: {}
     
       cborg@5.1.3: {}
     
    +  cborg@5.1.8: {}
    +
       ccount@2.0.1: {}
     
       chai@6.2.2: {}
    @@ -15829,21 +11360,6 @@ snapshots:
     
       chalk@5.6.2: {}
     
    -  change-case@4.1.2:
    -    dependencies:
    -      camel-case: 4.1.2
    -      capital-case: 1.0.4
    -      constant-case: 3.0.4
    -      dot-case: 3.0.4
    -      header-case: 2.0.4
    -      no-case: 3.0.4
    -      param-case: 3.0.4
    -      pascal-case: 3.1.2
    -      path-case: 3.0.4
    -      sentence-case: 3.0.4
    -      snake-case: 3.0.4
    -      tslib: 2.8.1
    -
       char-regex@1.0.2: {}
     
       character-entities-html4@2.1.0: {}
    @@ -15876,9 +11392,9 @@ snapshots:
     
       chrome-trace-event@1.0.4: {}
     
    -  chromium-bidi@14.0.0(devtools-protocol@0.0.1595872):
    +  chromium-bidi@14.0.0(devtools-protocol@0.0.1608973):
         dependencies:
    -      devtools-protocol: 0.0.1595872
    +      devtools-protocol: 0.0.1608973
           mitt: 3.0.1
           zod: 3.25.76
     
    @@ -15904,8 +11420,6 @@ snapshots:
           kind-of: 6.0.3
           shallow-clone: 3.0.1
     
    -  cmd-shim@8.0.0: {}
    -
       co@4.6.0: {}
     
       collapse-white-space@2.1.0: {}
    @@ -15936,16 +11450,10 @@ snapshots:
     
       commander@4.1.1: {}
     
    -  commander@5.1.0: {}
    -
    -  commander@6.2.1: {}
    -
       commander@7.2.0: {}
     
       commander@8.3.0: {}
     
    -  common-ancestor-path@2.0.0: {}
    -
       commondir@1.0.1: {}
     
       component-emitter@1.3.1: {}
    @@ -15972,12 +11480,6 @@ snapshots:
     
       consola@3.4.2: {}
     
    -  constant-case@3.0.4:
    -    dependencies:
    -      no-case: 3.0.4
    -      tslib: 2.8.1
    -      upper-case: 2.0.2
    -
       content-disposition@0.5.4:
         dependencies:
           safe-buffer: 5.2.1
    @@ -15988,8 +11490,6 @@ snapshots:
     
       content-type@2.0.0: {}
     
    -  convert-source-map@1.9.0: {}
    -
       convert-source-map@2.0.0: {}
     
       cookie-signature@1.0.7: {}
    @@ -16000,10 +11500,6 @@ snapshots:
     
       cookiejar@2.1.4: {}
     
    -  core-js-compat@3.49.0:
    -    dependencies:
    -      browserslist: 4.28.2
    -
       core-util-is@1.0.3: {}
     
       cors@2.8.6:
    @@ -16028,15 +11524,6 @@ snapshots:
           yaml: 1.10.3
         optional: true
     
    -  cosmiconfig@9.0.1(typescript@4.9.5):
    -    dependencies:
    -      env-paths: 2.2.1
    -      import-fresh: 3.3.1
    -      js-yaml: 4.3.0
    -      parse-json: 5.2.0
    -    optionalDependencies:
    -      typescript: 4.9.5
    -
       create-require@1.1.1: {}
     
       cross-fetch@3.2.0(encoding@0.1.13):
    @@ -16057,17 +11544,14 @@ snapshots:
           shebang-command: 2.0.0
           which: 2.0.2
     
    -  crypto@1.0.1: {}
    -
       css-tree@3.2.1:
         dependencies:
           mdn-data: 2.27.1
           source-map-js: 1.2.1
    +    optional: true
     
       css.escape@1.5.1: {}
     
    -  cssesc@3.0.0: {}
    -
       cssstyle@4.6.0:
         dependencies:
           '@asamuzakjp/css-color': 3.2.0
    @@ -16079,6 +11563,7 @@ snapshots:
           '@csstools/css-syntax-patches-for-csstree': 1.1.3(css-tree@3.2.1)
           css-tree: 3.2.1
           lru-cache: 11.5.1
    +    optional: true
     
       csstype@3.2.3: {}
     
    @@ -16281,28 +11766,11 @@ snapshots:
           whatwg-url: 16.0.1(@noble/hashes@2.2.0)
         transitivePeerDependencies:
           - '@noble/hashes'
    -
    -  data-view-buffer@1.0.2:
    -    dependencies:
    -      call-bound: 1.0.4
    -      es-errors: 1.3.0
    -      is-data-view: 1.0.2
    -
    -  data-view-byte-length@1.0.2:
    -    dependencies:
    -      call-bound: 1.0.4
    -      es-errors: 1.3.0
    -      is-data-view: 1.0.2
    -
    -  data-view-byte-offset@1.0.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -      es-errors: 1.3.0
    -      is-data-view: 1.0.2
    +    optional: true
     
       datastore-core@12.0.1:
         dependencies:
    -      '@libp2p/logger': 6.2.9
    +      '@libp2p/logger': 6.2.10
           abort-error: 1.0.2
           interface-datastore: 10.0.1
           interface-store: 8.0.0
    @@ -16320,10 +11788,6 @@ snapshots:
         dependencies:
           ms: 2.0.0
     
    -  debug@3.2.7:
    -    dependencies:
    -      ms: 2.1.3
    -
       debug@4.3.4:
         dependencies:
           ms: 2.1.2
    @@ -16350,8 +11814,6 @@ snapshots:
     
       deep-extend@0.6.0: {}
     
    -  deep-is@0.1.4: {}
    -
       deepmerge@4.3.1: {}
     
       default-browser-id@5.0.1: {}
    @@ -16361,20 +11823,8 @@ snapshots:
           bundle-name: 4.1.0
           default-browser-id: 5.0.1
     
    -  define-data-property@1.1.4:
    -    dependencies:
    -      es-define-property: 1.0.1
    -      es-errors: 1.3.0
    -      gopd: 1.2.0
    -
       define-lazy-prop@3.0.0: {}
     
    -  define-properties@1.2.1:
    -    dependencies:
    -      define-data-property: 1.1.4
    -      has-property-descriptors: 1.0.2
    -      object-keys: 1.1.1
    -
       degenerator@5.0.1:
         dependencies:
           ast-types: 0.13.4
    @@ -16400,8 +11850,6 @@ snapshots:
     
       depd@2.0.0: {}
     
    -  dependency-graph@0.11.0: {}
    -
       dequal@2.0.3: {}
     
       destroy@1.2.0: {}
    @@ -16416,7 +11864,7 @@ snapshots:
         dependencies:
           dequal: 2.0.3
     
    -  devtools-protocol@0.0.1595872: {}
    +  devtools-protocol@0.0.1608973: {}
     
       dezalgo@1.0.4:
         dependencies:
    @@ -16425,39 +11873,24 @@ snapshots:
     
       diff@4.0.4: {}
     
    -  diff@9.0.0: {}
    -
       dijkstrajs@1.0.3: {}
     
    -  dir-glob@3.0.1:
    -    dependencies:
    -      path-type: 4.0.0
    -
       dns-packet@5.6.1:
         dependencies:
           '@leichtgewicht/ip-codec': 2.0.5
     
    -  doctrine@2.1.0:
    -    dependencies:
    -      esutils: 2.0.3
    -
    -  doctrine@3.0.0:
    -    dependencies:
    -      esutils: 2.0.3
    -
       dom-accessibility-api@0.5.16: {}
     
       dom-accessibility-api@0.6.3: {}
     
    +  domexception@4.0.0:
    +    dependencies:
    +      webidl-conversions: 7.0.0
    +
       dompurify@3.4.12:
         optionalDependencies:
           '@types/trusted-types': 2.0.7
     
    -  dot-case@3.0.4:
    -    dependencies:
    -      no-case: 3.0.4
    -      tslib: 2.8.1
    -
       dotenv@17.4.2: {}
     
       dunder-proto@1.0.1:
    @@ -16474,6 +11907,8 @@ snapshots:
     
       electron-to-chromium@1.5.361: {}
     
    +  electron-to-chromium@1.5.395: {}
    +
       emittery@0.13.1: {}
     
       emoji-regex@8.0.0: {}
    @@ -16491,12 +11926,12 @@ snapshots:
         dependencies:
           once: 1.4.0
     
    -  engine.io-client@6.6.4:
    +  engine.io-client@6.6.6:
         dependencies:
           '@socket.io/component-emitter': 3.1.2
           debug: 4.4.3
           engine.io-parser: 5.2.3
    -      ws: 8.21.0
    +      ws: 8.21.1
           xmlhttprequest-ssl: 2.1.2
         transitivePeerDependencies:
           - bufferutil
    @@ -16505,10 +11940,10 @@ snapshots:
     
       engine.io-parser@5.2.3: {}
     
    -  engine.io@6.6.7:
    +  engine.io@6.6.9:
         dependencies:
           '@types/cors': 2.8.19
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           '@types/ws': 8.18.1
           accepts: 1.3.8
           base64id: 2.0.0
    @@ -16516,128 +11951,45 @@ snapshots:
           cors: 2.8.6
           debug: 4.4.3
           engine.io-parser: 5.2.3
    -      ws: 8.21.0
    +      ws: 8.21.1
         transitivePeerDependencies:
           - bufferutil
           - supports-color
           - utf-8-validate
     
    -  enhanced-resolve@5.22.0:
    +  enhanced-resolve@5.24.3:
         dependencies:
           graceful-fs: 4.2.11
           tapable: 2.3.3
     
       entities@6.0.1: {}
     
    -  entities@8.0.0: {}
    +  entities@8.0.0:
    +    optional: true
     
    -  env-paths@2.2.1: {}
    +  env-paths@2.2.1:
    +    optional: true
     
       envinfo@7.21.0: {}
     
    -  err-code@2.0.3: {}
    -
       error-ex@1.3.4:
         dependencies:
           is-arrayish: 0.2.1
     
    -  es-abstract@1.24.2:
    -    dependencies:
    -      array-buffer-byte-length: 1.0.2
    -      arraybuffer.prototype.slice: 1.0.4
    -      available-typed-arrays: 1.0.7
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      data-view-buffer: 1.0.2
    -      data-view-byte-length: 1.0.2
    -      data-view-byte-offset: 1.0.1
    -      es-define-property: 1.0.1
    -      es-errors: 1.3.0
    -      es-object-atoms: 1.1.1
    -      es-set-tostringtag: 2.1.0
    -      es-to-primitive: 1.3.0
    -      function.prototype.name: 1.1.8
    -      get-intrinsic: 1.3.0
    -      get-proto: 1.0.1
    -      get-symbol-description: 1.1.0
    -      globalthis: 1.0.4
    -      gopd: 1.2.0
    -      has-property-descriptors: 1.0.2
    -      has-proto: 1.2.0
    -      has-symbols: 1.1.0
    -      hasown: 2.0.3
    -      internal-slot: 1.1.0
    -      is-array-buffer: 3.0.5
    -      is-callable: 1.2.7
    -      is-data-view: 1.0.2
    -      is-negative-zero: 2.0.3
    -      is-regex: 1.2.1
    -      is-set: 2.0.3
    -      is-shared-array-buffer: 1.0.4
    -      is-string: 1.1.1
    -      is-typed-array: 1.1.15
    -      is-weakref: 1.1.1
    -      math-intrinsics: 1.1.0
    -      object-inspect: 1.13.4
    -      object-keys: 1.1.1
    -      object.assign: 4.1.7
    -      own-keys: 1.0.1
    -      regexp.prototype.flags: 1.5.4
    -      safe-array-concat: 1.1.4
    -      safe-push-apply: 1.0.0
    -      safe-regex-test: 1.1.0
    -      set-proto: 1.0.0
    -      stop-iteration-iterator: 1.1.0
    -      string.prototype.trim: 1.2.10
    -      string.prototype.trimend: 1.0.9
    -      string.prototype.trimstart: 1.0.8
    -      typed-array-buffer: 1.0.3
    -      typed-array-byte-length: 1.0.3
    -      typed-array-byte-offset: 1.0.4
    -      typed-array-length: 1.0.7
    -      unbox-primitive: 1.1.0
    -      which-typed-array: 1.1.20
    -
    -  es-aggregate-error@1.0.14:
    -    dependencies:
    -      define-data-property: 1.1.4
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      function-bind: 1.1.2
    -      globalthis: 1.0.4
    -      has-property-descriptors: 1.0.2
    -      set-function-name: 2.0.2
    -
       es-define-property@1.0.1: {}
     
       es-errors@1.3.0: {}
     
    -  es-iterator-helpers@1.3.2:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      es-set-tostringtag: 2.1.0
    -      function-bind: 1.1.2
    -      get-intrinsic: 1.3.0
    -      globalthis: 1.0.4
    -      gopd: 1.2.0
    -      has-property-descriptors: 1.0.2
    -      has-proto: 1.2.0
    -      has-symbols: 1.1.0
    -      internal-slot: 1.1.0
    -      iterator.prototype: 1.1.5
    -      math-intrinsics: 1.1.0
    -
       es-module-lexer@2.1.0: {}
     
       es-object-atoms@1.1.1:
         dependencies:
           es-errors: 1.3.0
     
    +  es-object-atoms@1.1.2:
    +    dependencies:
    +      es-errors: 1.3.0
    +
       es-set-tostringtag@2.1.0:
         dependencies:
           es-errors: 1.3.0
    @@ -16645,16 +11997,6 @@ snapshots:
           has-tostringtag: 1.0.2
           hasown: 2.0.4
     
    -  es-shim-unscopables@1.1.0:
    -    dependencies:
    -      hasown: 2.0.3
    -
    -  es-to-primitive@1.3.0:
    -    dependencies:
    -      is-callable: 1.2.7
    -      is-date-object: 1.1.0
    -      is-symbol: 1.1.1
    -
       es-toolkit@1.47.0: {}
     
       esast-util-from-estree@2.0.0:
    @@ -16667,7 +12009,7 @@ snapshots:
       esast-util-from-js@2.0.1:
         dependencies:
           '@types/estree-jsx': 1.0.5
    -      acorn: 8.16.0
    +      acorn: 8.17.0
           esast-util-from-estree: 2.0.0
           vfile-message: 4.0.3
     
    @@ -16713,373 +12055,47 @@ snapshots:
           '@esbuild/linux-arm': 0.28.1
           '@esbuild/linux-arm64': 0.28.1
           '@esbuild/linux-ia32': 0.28.1
    -      '@esbuild/linux-loong64': 0.28.1
    -      '@esbuild/linux-mips64el': 0.28.1
    -      '@esbuild/linux-ppc64': 0.28.1
    -      '@esbuild/linux-riscv64': 0.28.1
    -      '@esbuild/linux-s390x': 0.28.1
    -      '@esbuild/linux-x64': 0.28.1
    -      '@esbuild/netbsd-arm64': 0.28.1
    -      '@esbuild/netbsd-x64': 0.28.1
    -      '@esbuild/openbsd-arm64': 0.28.1
    -      '@esbuild/openbsd-x64': 0.28.1
    -      '@esbuild/openharmony-arm64': 0.28.1
    -      '@esbuild/sunos-x64': 0.28.1
    -      '@esbuild/win32-arm64': 0.28.1
    -      '@esbuild/win32-ia32': 0.28.1
    -      '@esbuild/win32-x64': 0.28.1
    -
    -  escalade@3.2.0: {}
    -
    -  escape-html@1.0.3: {}
    -
    -  escape-string-regexp@1.0.5: {}
    -
    -  escape-string-regexp@2.0.0: {}
    -
    -  escape-string-regexp@4.0.0: {}
    -
    -  escape-string-regexp@5.0.0: {}
    -
    -  escodegen@2.1.0:
    -    dependencies:
    -      esprima: 4.0.1
    -      estraverse: 5.3.0
    -      esutils: 2.0.3
    -    optionalDependencies:
    -      source-map: 0.6.1
    -
    -  eslint-config-standard-jsx@11.0.0(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1):
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-plugin-react: 7.37.5(eslint@8.57.1)
    -
    -  eslint-config-standard-with-typescript@23.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)(typescript@6.0.3):
    -    dependencies:
    -      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3)
    -      '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      eslint: 8.57.1
    -      eslint-config-standard: 17.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)
    -      eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)
    -      eslint-plugin-n: 15.7.0(eslint@8.57.1)
    -      eslint-plugin-promise: 6.6.0(eslint@8.57.1)
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  eslint-config-standard@17.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1):
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)
    -      eslint-plugin-n: 15.7.0(eslint@8.57.1)
    -      eslint-plugin-promise: 6.6.0(eslint@8.57.1)
    -
    -  eslint-config-standard@17.1.0(eslint-plugin-import@2.32.0(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1):
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-plugin-import: 2.32.0(eslint@10.5.0)
    -      eslint-plugin-n: 15.7.0(eslint@10.5.0)
    -      eslint-plugin-promise: 6.6.0(eslint@10.5.0)
    -
    -  eslint-import-resolver-node@0.3.10:
    -    dependencies:
    -      debug: 3.2.7
    -      is-core-module: 2.16.2
    -      resolve: 2.0.0-next.7
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1):
    -    dependencies:
    -      debug: 3.2.7
    -    optionalDependencies:
    -      '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      eslint: 8.57.1
    -      eslint-import-resolver-node: 0.3.10
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  eslint-plugin-es@4.1.0(eslint@10.5.0):
    -    dependencies:
    -      eslint: 10.5.0
    -      eslint-utils: 2.1.0
    -      regexpp: 3.2.0
    -
    -  eslint-plugin-es@4.1.0(eslint@8.57.1):
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-utils: 2.1.0
    -      regexpp: 3.2.0
    -
    -  eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1):
    -    dependencies:
    -      '@rtsao/scc': 1.1.0
    -      array-includes: 3.1.9
    -      array.prototype.findlastindex: 1.2.6
    -      array.prototype.flat: 1.3.3
    -      array.prototype.flatmap: 1.3.3
    -      debug: 3.2.7
    -      doctrine: 2.1.0
    -      eslint: 8.57.1
    -      eslint-import-resolver-node: 0.3.10
    -      eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1)
    -      hasown: 2.0.3
    -      is-core-module: 2.16.2
    -      is-glob: 4.0.3
    -      minimatch: 3.1.5
    -      object.fromentries: 2.0.8
    -      object.groupby: 1.0.3
    -      object.values: 1.2.1
    -      semver: 6.3.1
    -      string.prototype.trimend: 1.0.9
    -      tsconfig-paths: 3.15.0
    -    optionalDependencies:
    -      '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -    transitivePeerDependencies:
    -      - eslint-import-resolver-typescript
    -      - eslint-import-resolver-webpack
    -      - supports-color
    -
    -  eslint-plugin-import@2.32.0(eslint@10.5.0):
    -    dependencies:
    -      '@rtsao/scc': 1.1.0
    -      array-includes: 3.1.9
    -      array.prototype.findlastindex: 1.2.6
    -      array.prototype.flat: 1.3.3
    -      array.prototype.flatmap: 1.3.3
    -      debug: 3.2.7
    -      doctrine: 2.1.0
    -      eslint: 10.5.0
    -      eslint-import-resolver-node: 0.3.10
    -      eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1)
    -      hasown: 2.0.3
    -      is-core-module: 2.16.2
    -      is-glob: 4.0.3
    -      minimatch: 3.1.5
    -      object.fromentries: 2.0.8
    -      object.groupby: 1.0.3
    -      object.values: 1.2.1
    -      semver: 6.3.1
    -      string.prototype.trimend: 1.0.9
    -      tsconfig-paths: 3.15.0
    -    transitivePeerDependencies:
    -      - eslint-import-resolver-typescript
    -      - eslint-import-resolver-webpack
    -      - supports-color
    +      '@esbuild/linux-loong64': 0.28.1
    +      '@esbuild/linux-mips64el': 0.28.1
    +      '@esbuild/linux-ppc64': 0.28.1
    +      '@esbuild/linux-riscv64': 0.28.1
    +      '@esbuild/linux-s390x': 0.28.1
    +      '@esbuild/linux-x64': 0.28.1
    +      '@esbuild/netbsd-arm64': 0.28.1
    +      '@esbuild/netbsd-x64': 0.28.1
    +      '@esbuild/openbsd-arm64': 0.28.1
    +      '@esbuild/openbsd-x64': 0.28.1
    +      '@esbuild/openharmony-arm64': 0.28.1
    +      '@esbuild/sunos-x64': 0.28.1
    +      '@esbuild/win32-arm64': 0.28.1
    +      '@esbuild/win32-ia32': 0.28.1
    +      '@esbuild/win32-x64': 0.28.1
     
    -  eslint-plugin-n@15.7.0(eslint@10.5.0):
    -    dependencies:
    -      builtins: 5.1.0
    -      eslint: 10.5.0
    -      eslint-plugin-es: 4.1.0(eslint@10.5.0)
    -      eslint-utils: 3.0.0(eslint@10.5.0)
    -      ignore: 5.3.2
    -      is-core-module: 2.16.2
    -      minimatch: 3.1.5
    -      resolve: 1.22.12
    -      semver: 7.8.5
    +  escalade@3.2.0: {}
     
    -  eslint-plugin-n@15.7.0(eslint@8.57.1):
    -    dependencies:
    -      builtins: 5.1.0
    -      eslint: 8.57.1
    -      eslint-plugin-es: 4.1.0(eslint@8.57.1)
    -      eslint-utils: 3.0.0(eslint@8.57.1)
    -      ignore: 5.3.2
    -      is-core-module: 2.16.2
    -      minimatch: 3.1.5
    -      resolve: 1.22.12
    -      semver: 7.8.5
    +  escape-html@1.0.3: {}
     
    -  eslint-plugin-promise@6.6.0(eslint@10.5.0):
    -    dependencies:
    -      eslint: 10.5.0
    +  escape-string-regexp@2.0.0: {}
     
    -  eslint-plugin-promise@6.6.0(eslint@8.57.1):
    -    dependencies:
    -      eslint: 8.57.1
    +  escape-string-regexp@5.0.0: {}
     
    -  eslint-plugin-react@7.37.5(eslint@10.5.0):
    +  escodegen@2.1.0:
         dependencies:
    -      array-includes: 3.1.9
    -      array.prototype.findlast: 1.2.5
    -      array.prototype.flatmap: 1.3.3
    -      array.prototype.tosorted: 1.1.4
    -      doctrine: 2.1.0
    -      es-iterator-helpers: 1.3.2
    -      eslint: 10.5.0
    -      estraverse: 5.3.0
    -      hasown: 2.0.3
    -      jsx-ast-utils: 3.3.5
    -      minimatch: 3.1.5
    -      object.entries: 1.1.9
    -      object.fromentries: 2.0.8
    -      object.values: 1.2.1
    -      prop-types: 15.8.1
    -      resolve: 2.0.0-next.6
    -      semver: 6.3.1
    -      string.prototype.matchall: 4.0.12
    -      string.prototype.repeat: 1.0.0
    -
    -  eslint-plugin-react@7.37.5(eslint@8.57.1):
    -    dependencies:
    -      array-includes: 3.1.9
    -      array.prototype.findlast: 1.2.5
    -      array.prototype.flatmap: 1.3.3
    -      array.prototype.tosorted: 1.1.4
    -      doctrine: 2.1.0
    -      es-iterator-helpers: 1.3.2
    -      eslint: 8.57.1
    +      esprima: 4.0.1
           estraverse: 5.3.0
    -      hasown: 2.0.3
    -      jsx-ast-utils: 3.3.5
    -      minimatch: 3.1.5
    -      object.entries: 1.1.9
    -      object.fromentries: 2.0.8
    -      object.values: 1.2.1
    -      prop-types: 15.8.1
    -      resolve: 2.0.0-next.6
    -      semver: 6.3.1
    -      string.prototype.matchall: 4.0.12
    -      string.prototype.repeat: 1.0.0
    +      esutils: 2.0.3
    +    optionalDependencies:
    +      source-map: 0.6.1
     
       eslint-scope@5.1.1:
         dependencies:
           esrecurse: 4.3.0
           estraverse: 4.3.0
     
    -  eslint-scope@7.2.2:
    -    dependencies:
    -      esrecurse: 4.3.0
    -      estraverse: 5.3.0
    -
    -  eslint-scope@9.1.2:
    -    dependencies:
    -      '@types/esrecurse': 4.3.1
    -      '@types/estree': 1.0.9
    -      esrecurse: 4.3.0
    -      estraverse: 5.3.0
    -
    -  eslint-utils@2.1.0:
    -    dependencies:
    -      eslint-visitor-keys: 1.3.0
    -
    -  eslint-utils@3.0.0(eslint@10.5.0):
    -    dependencies:
    -      eslint: 10.5.0
    -      eslint-visitor-keys: 2.1.0
    -
    -  eslint-utils@3.0.0(eslint@8.57.1):
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-visitor-keys: 2.1.0
    -
    -  eslint-visitor-keys@1.3.0: {}
    -
    -  eslint-visitor-keys@2.1.0: {}
    -
    -  eslint-visitor-keys@3.4.3: {}
    -
    -  eslint-visitor-keys@5.0.1: {}
    -
    -  eslint@10.5.0:
    -    dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0)
    -      '@eslint-community/regexpp': 4.12.2
    -      '@eslint/config-array': 0.23.5
    -      '@eslint/config-helpers': 0.6.0
    -      '@eslint/core': 1.2.1
    -      '@eslint/plugin-kit': 0.7.2
    -      '@humanfs/node': 0.16.8
    -      '@humanwhocodes/module-importer': 1.0.1
    -      '@humanwhocodes/retry': 0.4.3
    -      '@types/estree': 1.0.9
    -      ajv: 6.15.0
    -      cross-spawn: 7.0.6
    -      debug: 4.4.3
    -      escape-string-regexp: 4.0.0
    -      eslint-scope: 9.1.2
    -      eslint-visitor-keys: 5.0.1
    -      espree: 11.2.0
    -      esquery: 1.7.0
    -      esutils: 2.0.3
    -      fast-deep-equal: 3.1.3
    -      file-entry-cache: 8.0.0
    -      find-up: 5.0.0
    -      glob-parent: 6.0.2
    -      ignore: 5.3.2
    -      imurmurhash: 0.1.4
    -      is-glob: 4.0.3
    -      json-stable-stringify-without-jsonify: 1.0.1
    -      minimatch: 10.2.5
    -      natural-compare: 1.4.0
    -      optionator: 0.9.4
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  eslint@8.57.1:
    -    dependencies:
    -      '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1)
    -      '@eslint-community/regexpp': 4.12.2
    -      '@eslint/eslintrc': 2.1.4
    -      '@eslint/js': 8.57.1
    -      '@humanwhocodes/config-array': 0.13.0
    -      '@humanwhocodes/module-importer': 1.0.1
    -      '@nodelib/fs.walk': 1.2.8
    -      '@ungap/structured-clone': 1.3.1
    -      ajv: 6.15.0
    -      chalk: 4.1.2
    -      cross-spawn: 7.0.6
    -      debug: 4.4.3
    -      doctrine: 3.0.0
    -      escape-string-regexp: 4.0.0
    -      eslint-scope: 7.2.2
    -      eslint-visitor-keys: 3.4.3
    -      espree: 9.6.1
    -      esquery: 1.7.0
    -      esutils: 2.0.3
    -      fast-deep-equal: 3.1.3
    -      file-entry-cache: 6.0.1
    -      find-up: 5.0.0
    -      glob-parent: 6.0.2
    -      globals: 13.24.0
    -      graphemer: 1.4.0
    -      ignore: 5.3.2
    -      imurmurhash: 0.1.4
    -      is-glob: 4.0.3
    -      is-path-inside: 3.0.3
    -      js-yaml: 4.3.0
    -      json-stable-stringify-without-jsonify: 1.0.1
    -      levn: 0.4.1
    -      lodash.merge: 4.6.2
    -      minimatch: 3.1.5
    -      natural-compare: 1.4.0
    -      optionator: 0.9.4
    -      strip-ansi: 6.0.1
    -      text-table: 0.2.0
    -    transitivePeerDependencies:
    -      - supports-color
    -
       esm@3.2.25: {}
     
    -  espree@11.2.0:
    -    dependencies:
    -      acorn: 8.16.0
    -      acorn-jsx: 5.3.2(acorn@8.16.0)
    -      eslint-visitor-keys: 5.0.1
    -
    -  espree@9.6.1:
    -    dependencies:
    -      acorn: 8.16.0
    -      acorn-jsx: 5.3.2(acorn@8.16.0)
    -      eslint-visitor-keys: 3.4.3
    -
       esprima@4.0.1: {}
     
    -  esquery@1.7.0:
    -    dependencies:
    -      estraverse: 5.3.0
    -
       esrecurse@4.3.0:
         dependencies:
           estraverse: 5.3.0
    @@ -17121,8 +12137,6 @@ snapshots:
           '@types/estree-jsx': 1.0.5
           '@types/unist': 3.0.3
     
    -  estree-walker@1.0.1: {}
    -
       estree-walker@2.0.2: {}
     
       estree-walker@3.0.3:
    @@ -17133,8 +12147,6 @@ snapshots:
     
       etag@1.8.1: {}
     
    -  event-target-shim@5.0.1: {}
    -
       eventemitter3@4.0.7: {}
     
       eventemitter3@5.0.4: {}
    @@ -17174,9 +12186,8 @@ snapshots:
           jest-mock: 30.4.1
           jest-util: 30.4.1
     
    -  exponential-backoff@3.1.3: {}
    -
    -  expr-eval-fork@3.0.3: {}
    +  exponential-backoff@3.1.3:
    +    optional: true
     
       express-rate-limit@8.6.0(express@5.2.1):
         dependencies:
    @@ -17190,7 +12201,7 @@ snapshots:
         dependencies:
           accepts: 1.3.8
           array-flatten: 1.1.1
    -      body-parser: 1.20.5
    +      body-parser: 1.20.6
           content-disposition: 0.5.4
           content-type: 1.0.5
           cookie: 0.7.2
    @@ -17273,52 +12284,16 @@ snapshots:
     
       fake-indexeddb@6.2.5: {}
     
    -  fast-deep-equal@1.1.0: {}
    -
    -  fast-deep-equal@2.0.1: {}
    -
       fast-deep-equal@3.1.3: {}
     
       fast-fifo@1.3.2: {}
     
    -  fast-glob@3.3.3:
    -    dependencies:
    -      '@nodelib/fs.stat': 2.0.5
    -      '@nodelib/fs.walk': 1.2.8
    -      glob-parent: 5.1.2
    -      merge2: 1.4.1
    -      micromatch: 4.0.8
    -
       fast-json-stable-stringify@2.1.0: {}
     
    -  fast-levenshtein@2.0.6: {}
    -
    -  fast-memoize@2.5.2: {}
    -
       fast-safe-stringify@2.1.1: {}
     
       fast-uri@3.1.4: {}
     
    -  fast-xml-builder@1.2.0:
    -    dependencies:
    -      path-expression-matcher: 1.6.2
    -      xml-naming: 0.1.0
    -
    -  fast-xml-parser@5.10.1:
    -    dependencies:
    -      '@nodable/entities': 3.0.0
    -      fast-xml-builder: 1.2.0
    -      is-unsafe: 2.0.0
    -      path-expression-matcher: 1.6.2
    -      strnum: 2.4.1
    -      xml-naming: 0.3.0
    -
    -  fastest-stable-stringify@2.0.2: {}
    -
    -  fastq@1.20.1:
    -    dependencies:
    -      reusify: 1.1.0
    -
       fault@2.0.1:
         dependencies:
           format: 0.2.2
    @@ -17335,33 +12310,17 @@ snapshots:
         dependencies:
           pend: 1.2.0
     
    -  fdir@6.5.0(picomatch@4.0.4):
    +  fdir@6.5.0(picomatch@4.0.5):
         optionalDependencies:
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
     
       fetch-blob@3.2.0:
         dependencies:
           node-domexception: 1.0.0
           web-streams-polyfill: 3.3.3
     
    -  file-entry-cache@6.0.1:
    -    dependencies:
    -      flat-cache: 3.2.0
    -
    -  file-entry-cache@8.0.0:
    -    dependencies:
    -      flat-cache: 4.0.1
    -
       file-uri-to-path@1.0.0: {}
     
    -  filename-reserved-regex@2.0.0: {}
    -
    -  filenamify@4.3.0:
    -    dependencies:
    -      filename-reserved-regex: 2.0.0
    -      strip-outer: 1.0.1
    -      trim-repeated: 1.0.0
    -
       fill-range@7.1.1:
         dependencies:
           to-regex-range: 5.0.1
    @@ -17395,58 +12354,23 @@ snapshots:
           make-dir: 3.1.0
           pkg-dir: 4.2.0
     
    -  find-up@3.0.0:
    -    dependencies:
    -      locate-path: 3.0.0
    -
       find-up@4.1.0:
         dependencies:
           locate-path: 5.0.0
           path-exists: 4.0.0
     
    -  find-up@5.0.0:
    -    dependencies:
    -      locate-path: 6.0.0
    -      path-exists: 4.0.0
    -
    -  find-up@6.3.0:
    -    dependencies:
    -      locate-path: 7.2.0
    -      path-exists: 5.0.0
    -
       fix-dts-default-cjs-exports@1.0.1:
         dependencies:
           magic-string: 0.30.21
           mlly: 1.8.2
           rollup: 4.60.2
     
    -  flat-cache@3.2.0:
    -    dependencies:
    -      flatted: 3.4.2
    -      keyv: 4.5.4
    -      rimraf: 3.0.2
    -
    -  flat-cache@4.0.1:
    -    dependencies:
    -      flatted: 3.4.2
    -      keyv: 4.5.4
    -
       flat@5.0.2: {}
     
    -  flatted@3.4.2: {}
    -
       follow-redirects@1.16.0(debug@4.4.3):
         optionalDependencies:
           debug: 4.4.3
     
    -  for-each@0.3.5:
    -    dependencies:
    -      is-callable: 1.2.7
    -
    -  foreach@2.0.6: {}
    -
    -  foreachasync@3.0.0: {}
    -
       foreground-child@3.3.1:
         dependencies:
           cross-spawn: 7.0.6
    @@ -17480,35 +12404,18 @@ snapshots:
     
       fs-constants@1.0.0: {}
     
    -  fs-extra@0.6.4:
    -    dependencies:
    -      jsonfile: 1.0.1
    -      mkdirp: 0.3.5
    -      ncp: 0.4.2
    -      rimraf: 2.2.8
    -
    -  fs-extra@11.3.4:
    +  fs-extra@11.3.5:
         dependencies:
           graceful-fs: 4.2.11
           jsonfile: 6.2.1
           universalify: 2.0.1
     
    -  fs-extra@11.3.5:
    +  fs-extra@11.4.0:
         dependencies:
           graceful-fs: 4.2.11
           jsonfile: 6.2.1
           universalify: 2.0.1
     
    -  fs-minipass@3.0.3:
    -    dependencies:
    -      minipass: 7.1.3
    -
    -  fs.extra@1.3.2:
    -    dependencies:
    -      fs-extra: 0.6.4
    -      mkdirp: 0.3.5
    -      walk: 2.3.15
    -
       fs.realpath@1.0.0: {}
     
       fsevents@2.3.3:
    @@ -17516,23 +12423,10 @@ snapshots:
     
       function-bind@1.1.2: {}
     
    -  function.prototype.name@1.1.8:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      functions-have-names: 1.2.3
    -      hasown: 2.0.3
    -      is-callable: 1.2.7
    -
    -  functions-have-names@1.2.3: {}
    -
       generate-function@2.3.1:
         dependencies:
           is-property: 1.0.2
     
    -  generator-function@2.0.1: {}
    -
       gensync@1.0.0-beta.2: {}
     
       get-caller-file@2.0.5: {}
    @@ -17557,9 +12451,7 @@ snapshots:
       get-proto@1.0.1:
         dependencies:
           dunder-proto: 1.0.1
    -      es-object-atoms: 1.1.1
    -
    -  get-stdin@8.0.0: {}
    +      es-object-atoms: 1.1.2
     
       get-stream@5.2.0:
         dependencies:
    @@ -17567,12 +12459,6 @@ snapshots:
     
       get-stream@6.0.1: {}
     
    -  get-symbol-description@1.1.0:
    -    dependencies:
    -      call-bound: 1.0.4
    -      es-errors: 1.3.0
    -      get-intrinsic: 1.3.0
    -
       get-uri@6.0.5:
         dependencies:
           basic-ftp: 5.3.1
    @@ -17591,16 +12477,10 @@ snapshots:
         dependencies:
           is-glob: 4.0.3
     
    -  glob-parent@6.0.2:
    -    dependencies:
    -      is-glob: 4.0.3
    -
       glob-to-regex.js@1.2.0(tslib@2.8.1):
         dependencies:
           tslib: 2.8.1
     
    -  glob-to-regexp@0.4.1: {}
    -
       glob@10.5.0:
         dependencies:
           foreground-child: 3.3.1
    @@ -17610,12 +12490,6 @@ snapshots:
           package-json-from-dist: 1.0.1
           path-scurry: 1.11.1
     
    -  glob@13.0.6:
    -    dependencies:
    -      minimatch: 10.2.5
    -      minipass: 7.1.3
    -      path-scurry: 2.0.2
    -
       glob@7.2.3:
         dependencies:
           fs.realpath: 1.0.0
    @@ -17625,36 +12499,10 @@ snapshots:
           once: 1.4.0
           path-is-absolute: 1.0.1
     
    -  global-dirs@3.0.1:
    -    dependencies:
    -      ini: 2.0.0
    -
    -  globals@13.24.0:
    -    dependencies:
    -      type-fest: 0.20.2
    -
    -  globals@17.6.0: {}
    -
    -  globalthis@1.0.4:
    -    dependencies:
    -      define-properties: 1.2.1
    -      gopd: 1.2.0
    -
    -  globby@11.1.0:
    -    dependencies:
    -      array-union: 2.1.0
    -      dir-glob: 3.0.1
    -      fast-glob: 3.3.3
    -      ignore: 5.3.2
    -      merge2: 1.4.1
    -      slash: 3.0.0
    -
       gopd@1.2.0: {}
     
       graceful-fs@4.2.11: {}
     
    -  graphemer@1.4.0: {}
    -
       gray-matter@4.0.3:
         dependencies:
           js-yaml: 3.15.0
    @@ -17678,18 +12526,8 @@ snapshots:
         optionalDependencies:
           uglify-js: 3.19.3
     
    -  has-bigints@1.1.0: {}
    -
       has-flag@4.0.0: {}
     
    -  has-property-descriptors@1.0.2:
    -    dependencies:
    -      es-define-property: 1.0.1
    -
    -  has-proto@1.2.0:
    -    dependencies:
    -      dunder-proto: 1.0.1
    -
       has-symbols@1.1.0: {}
     
       has-tostringtag@1.0.2:
    @@ -17779,21 +12617,6 @@ snapshots:
         dependencies:
           '@types/hast': 3.0.4
     
    -  header-case@2.0.4:
    -    dependencies:
    -      capital-case: 1.0.4
    -      tslib: 2.8.1
    -
    -  highlight.js@10.7.3: {}
    -
    -  hosted-git-info@7.0.2:
    -    dependencies:
    -      lru-cache: 10.4.3
    -
    -  hosted-git-info@9.0.3:
    -    dependencies:
    -      lru-cache: 11.5.1
    -
       hpack.js@2.1.6:
         dependencies:
           inherits: 2.0.4
    @@ -17810,6 +12633,7 @@ snapshots:
           '@exodus/bytes': 1.15.0(@noble/hashes@2.2.0)
         transitivePeerDependencies:
           - '@noble/hashes'
    +    optional: true
     
       html-escaper@2.0.2: {}
     
    @@ -17821,8 +12645,6 @@ snapshots:
         dependencies:
           tslib: 2.8.1
     
    -  http-cache-semantics@4.2.0: {}
    -
       http-deceiver@1.2.7: {}
     
       http-errors@1.8.1:
    @@ -17897,16 +12719,6 @@ snapshots:
     
       ieee754@1.2.1: {}
     
    -  ignore-walk@8.0.0:
    -    dependencies:
    -      minimatch: 10.2.5
    -
    -  ignore@5.3.2: {}
    -
    -  ignore@7.0.5: {}
    -
    -  immer@9.0.21: {}
    -
       immutable@5.1.9:
         optional: true
     
    @@ -17914,6 +12726,7 @@ snapshots:
         dependencies:
           parent-module: 1.0.1
           resolve-from: 4.0.0
    +    optional: true
     
       import-local@3.2.0:
         dependencies:
    @@ -17935,12 +12748,6 @@ snapshots:
     
       ini@1.3.8: {}
     
    -  ini@2.0.0: {}
    -
    -  ini@4.1.3: {}
    -
    -  ini@6.0.0: {}
    -
       inline-style-parser@0.2.7: {}
     
       interface-datastore@10.0.1:
    @@ -17960,12 +12767,6 @@ snapshots:
         dependencies:
           abort-error: 1.0.2
     
    -  internal-slot@1.1.0:
    -    dependencies:
    -      es-errors: 1.3.0
    -      hasown: 2.0.3
    -      side-channel: 1.1.1
    -
       internmap@1.0.1: {}
     
       internmap@2.0.3: {}
    @@ -17993,51 +12794,15 @@ snapshots:
           is-alphabetical: 2.0.1
           is-decimal: 2.0.1
     
    -  is-array-buffer@3.0.5:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      get-intrinsic: 1.3.0
    -
       is-arrayish@0.2.1: {}
     
    -  is-async-function@2.1.1:
    -    dependencies:
    -      async-function: 1.0.0
    -      call-bound: 1.0.4
    -      get-proto: 1.0.1
    -      has-tostringtag: 1.0.2
    -      safe-regex-test: 1.1.0
    -
    -  is-bigint@1.1.0:
    -    dependencies:
    -      has-bigints: 1.1.0
    -
       is-binary-path@2.1.0:
         dependencies:
           binary-extensions: 2.3.0
     
    -  is-boolean-object@1.2.2:
    -    dependencies:
    -      call-bound: 1.0.4
    -      has-tostringtag: 1.0.2
    -
    -  is-callable@1.2.7: {}
    -
       is-core-module@2.16.2:
         dependencies:
    -      hasown: 2.0.3
    -
    -  is-data-view@1.0.2:
    -    dependencies:
    -      call-bound: 1.0.4
    -      get-intrinsic: 1.3.0
    -      is-typed-array: 1.1.15
    -
    -  is-date-object@1.1.0:
    -    dependencies:
    -      call-bound: 1.0.4
    -      has-tostringtag: 1.0.2
    +      hasown: 2.0.4
     
       is-decimal@2.0.1: {}
     
    @@ -18052,22 +12817,10 @@ snapshots:
     
       is-extglob@2.1.1: {}
     
    -  is-finalizationregistry@1.1.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -
       is-fullwidth-code-point@3.0.0: {}
     
       is-generator-fn@2.1.0: {}
     
    -  is-generator-function@1.1.2:
    -    dependencies:
    -      call-bound: 1.0.4
    -      generator-function: 2.0.1
    -      get-proto: 1.0.1
    -      has-tostringtag: 1.0.2
    -      safe-regex-test: 1.1.0
    -
       is-glob@4.0.3:
         dependencies:
           is-extglob: 2.1.1
    @@ -18078,23 +12831,12 @@ snapshots:
         dependencies:
           is-docker: 3.0.0
     
    -  is-loopback-addr@2.0.2: {}
    -
    -  is-map@2.0.3: {}
    -
    -  is-negative-zero@2.0.3: {}
    +  is-loopback-addr@2.0.2: {}
     
       is-network-error@1.3.2: {}
     
    -  is-number-object@1.1.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -      has-tostringtag: 1.0.2
    -
       is-number@7.0.0: {}
     
    -  is-path-inside@3.0.3: {}
    -
       is-plain-obj@3.0.0: {}
     
       is-plain-obj@4.1.0: {}
    @@ -18109,49 +12851,8 @@ snapshots:
     
       is-property@1.0.2: {}
     
    -  is-regex@1.2.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -      gopd: 1.2.0
    -      has-tostringtag: 1.0.2
    -      hasown: 2.0.3
    -
    -  is-set@2.0.3: {}
    -
    -  is-shared-array-buffer@1.0.4:
    -    dependencies:
    -      call-bound: 1.0.4
    -
       is-stream@2.0.1: {}
     
    -  is-string@1.1.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -      has-tostringtag: 1.0.2
    -
    -  is-symbol@1.1.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -      has-symbols: 1.1.0
    -      safe-regex-test: 1.1.0
    -
    -  is-typed-array@1.1.15:
    -    dependencies:
    -      which-typed-array: 1.1.20
    -
    -  is-unsafe@2.0.0: {}
    -
    -  is-weakmap@2.0.2: {}
    -
    -  is-weakref@1.1.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -
    -  is-weakset@2.0.4:
    -    dependencies:
    -      call-bound: 1.0.4
    -      get-intrinsic: 1.3.0
    -
       is-wsl@2.2.0:
         dependencies:
           is-docker: 2.2.1
    @@ -18163,25 +12864,13 @@ snapshots:
     
       isarray@1.0.0: {}
     
    -  isarray@2.0.5: {}
    -
       isexe@2.0.0: {}
     
    -  isexe@3.1.5: {}
    -
    -  isexe@4.0.0: {}
    +  isexe@4.0.0:
    +    optional: true
     
       isobject@3.0.1: {}
     
    -  isomorphic-dompurify@2.36.0(@noble/hashes@2.2.0):
    -    dependencies:
    -      dompurify: 3.4.12
    -      jsdom: 28.1.0(@noble/hashes@2.2.0)
    -    transitivePeerDependencies:
    -      - '@noble/hashes'
    -      - canvas
    -      - supports-color
    -
       istanbul-lib-coverage@3.2.2: {}
     
       istanbul-lib-instrument@6.0.3:
    @@ -18279,7 +12968,7 @@ snapshots:
         dependencies:
           p-defer: 4.0.1
     
    -  it-queue@1.1.3:
    +  it-queue@1.1.4:
         dependencies:
           abort-error: 1.0.2
           it-pushable: 3.2.4
    @@ -18311,15 +13000,6 @@ snapshots:
     
       it-take@3.0.11: {}
     
    -  iterator.prototype@1.1.5:
    -    dependencies:
    -      define-data-property: 1.1.4
    -      es-object-atoms: 1.1.1
    -      get-intrinsic: 1.3.0
    -      get-proto: 1.0.1
    -      has-symbols: 1.1.0
    -      set-function-name: 2.0.2
    -
       jackspeak@3.4.3:
         dependencies:
           '@isaacs/cliui': 8.0.2
    @@ -18338,7 +13018,7 @@ snapshots:
           '@jest/expect': 30.4.1
           '@jest/test-result': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           chalk: 4.1.2
           co: 4.6.0
           dedent: 1.7.2(babel-plugin-macros@3.1.0)
    @@ -18358,18 +13038,18 @@ snapshots:
           - babel-plugin-macros
           - supports-color
     
    -  jest-cli@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)):
    +  jest-cli@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)):
         dependencies:
    -      '@jest/core': 30.4.2(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      '@jest/core': 30.4.2(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           '@jest/test-result': 30.4.1
           '@jest/types': 30.4.1
           chalk: 4.1.2
           exit-x: 0.2.2
           import-local: 3.2.0
    -      jest-config: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      jest-config: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           jest-util: 30.4.1
           jest-validate: 30.4.1
    -      yargs: 17.7.2
    +      yargs: 17.7.3
         optionalDependencies:
           node-notifier: 8.0.2
         transitivePeerDependencies:
    @@ -18379,7 +13059,7 @@ snapshots:
           - supports-color
           - ts-node
     
    -  jest-config@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)):
    +  jest-config@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)):
         dependencies:
           '@babel/core': 7.29.7
           '@jest/get-type': 30.1.0
    @@ -18405,8 +13085,8 @@ snapshots:
           slash: 3.0.0
           strip-json-comments: 3.1.1
         optionalDependencies:
    -      '@types/node': 26.0.0
    -      ts-node: 10.9.2(@types/node@26.0.0)(typescript@6.0.3)
    +      '@types/node': 26.1.1
    +      ts-node: 10.9.2(@types/node@26.1.1)(typescript@6.0.3)
         transitivePeerDependencies:
           - babel-plugin-macros
           - supports-color
    @@ -18445,29 +13125,29 @@ snapshots:
           '@jest/environment': 30.4.1
           '@jest/fake-timers': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jest-mock: 30.4.1
           jest-util: 30.4.1
           jest-validate: 30.4.1
     
    -  jest-fetch-mock@3.0.3(encoding@0.1.13):
    +  jest-fetch-mock@3.2.0(encoding@0.1.13):
         dependencies:
           cross-fetch: 3.2.0(encoding@0.1.13)
    -      promise-polyfill: 8.3.0
    +      domexception: 4.0.0
         transitivePeerDependencies:
           - encoding
     
       jest-haste-map@30.4.1:
         dependencies:
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           anymatch: 3.1.3
           fb-watchman: 2.0.2
           graceful-fs: 4.2.11
           jest-regex-util: 30.4.0
           jest-util: 30.4.1
           jest-worker: 30.4.1
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
           walker: 1.0.8
         optionalDependencies:
           fsevents: 2.3.3
    @@ -18492,7 +13172,7 @@ snapshots:
           chalk: 4.1.2
           graceful-fs: 4.2.11
           jest-util: 30.4.1
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
           pretty-format: 30.4.1
           slash: 3.0.0
           stack-utils: 2.0.6
    @@ -18500,7 +13180,7 @@ snapshots:
       jest-mock@30.4.1:
         dependencies:
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jest-util: 30.4.1
     
       jest-pnp-resolver@1.2.3(jest-resolve@30.4.1):
    @@ -18534,7 +13214,7 @@ snapshots:
           '@jest/test-result': 30.4.1
           '@jest/transform': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           chalk: 4.1.2
           emittery: 0.13.1
           exit-x: 0.2.2
    @@ -18563,7 +13243,7 @@ snapshots:
           '@jest/test-result': 30.4.1
           '@jest/transform': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           chalk: 4.1.2
           cjs-module-lexer: 2.2.0
           collect-v8-coverage: 1.0.3
    @@ -18581,10 +13261,6 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  jest-simple-summary@1.0.2:
    -    dependencies:
    -      xml2js: 0.5.0
    -
       jest-snapshot@30.4.1:
         dependencies:
           '@babel/core': 7.29.7
    @@ -18607,18 +13283,18 @@ snapshots:
           jest-util: 30.4.1
           pretty-format: 30.4.1
           semver: 7.8.5
    -      synckit: 0.11.12
    +      synckit: 0.11.13
         transitivePeerDependencies:
           - supports-color
     
       jest-util@30.4.1:
         dependencies:
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           chalk: 4.1.2
           ci-info: 4.4.0
           graceful-fs: 4.2.11
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
     
       jest-validate@30.4.1:
         dependencies:
    @@ -18633,7 +13309,7 @@ snapshots:
         dependencies:
           '@jest/test-result': 30.4.1
           '@jest/types': 30.4.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           ansi-escapes: 4.3.2
           chalk: 4.1.2
           emittery: 0.13.1
    @@ -18642,24 +13318,24 @@ snapshots:
     
       jest-worker@27.5.1:
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           merge-stream: 2.0.0
           supports-color: 8.1.1
     
       jest-worker@30.4.1:
         dependencies:
    -      '@types/node': 26.0.0
    -      '@ungap/structured-clone': 1.3.1
    +      '@types/node': 26.1.1
    +      '@ungap/structured-clone': 1.3.3
           jest-util: 30.4.1
           merge-stream: 2.0.0
           supports-color: 8.1.1
     
    -  jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)):
    +  jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)):
         dependencies:
    -      '@jest/core': 30.4.2(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      '@jest/core': 30.4.2(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           '@jest/types': 30.4.1
           import-local: 3.2.0
    -      jest-cli: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      jest-cli: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
         optionalDependencies:
           node-notifier: 8.0.2
         transitivePeerDependencies:
    @@ -18669,8 +13345,6 @@ snapshots:
           - supports-color
           - ts-node
     
    -  jmespath@0.15.0: {}
    -
       joi@18.2.3:
         dependencies:
           '@hapi/address': 5.1.1
    @@ -18693,6 +13367,7 @@ snapshots:
       js-yaml@4.3.0:
         dependencies:
           argparse: 2.0.1
    +    optional: true
     
       jsdom@24.1.3:
         dependencies:
    @@ -18715,7 +13390,7 @@ snapshots:
           whatwg-encoding: 3.1.1
           whatwg-mimetype: 4.0.0
           whatwg-url: 14.2.0
    -      ws: 8.21.0
    +      ws: 8.21.1
           xml-name-validator: 5.0.0
         transitivePeerDependencies:
           - bufferutil
    @@ -18731,7 +13406,7 @@ snapshots:
           http-proxy-agent: 7.0.2
           https-proxy-agent: 7.0.6
           is-potential-custom-element-name: 1.0.1
    -      nwsapi: 2.2.23
    +      nwsapi: 2.2.24
           parse5: 7.3.0
           rrweb-cssom: 0.8.0
           saxes: 6.0.0
    @@ -18742,7 +13417,7 @@ snapshots:
           whatwg-encoding: 3.1.1
           whatwg-mimetype: 4.0.0
           whatwg-url: 14.2.0
    -      ws: 8.21.0
    +      ws: 8.21.1
           xml-name-validator: 5.0.0
         transitivePeerDependencies:
           - bufferutil
    @@ -18775,99 +13450,33 @@ snapshots:
         transitivePeerDependencies:
           - '@noble/hashes'
           - supports-color
    -
    -  jsep@1.4.0: {}
    +    optional: true
     
       jsesc@3.1.0: {}
     
    -  json-buffer@3.0.1: {}
    -
    -  json-e@4.8.2:
    -    dependencies:
    -      json-stable-stringify-without-jsonify: 1.0.1
    -
    -  json-parse-better-errors@1.0.2: {}
    -
       json-parse-even-better-errors@2.3.1: {}
     
    -  json-parse-even-better-errors@3.0.2: {}
    -
    -  json-parse-even-better-errors@5.0.0: {}
    -
    -  json-pointer@0.6.2:
    -    dependencies:
    -      foreach: 2.0.6
    -
    -  json-schema-migrate@0.2.0:
    -    dependencies:
    -      ajv: 5.5.2
    -
    -  json-schema-traverse@0.3.1: {}
    -
    -  json-schema-traverse@0.4.1: {}
    -
       json-schema-traverse@1.0.0: {}
     
    -  json-stable-stringify-without-jsonify@1.0.1: {}
    -
    -  json-stringify-nice@1.1.4: {}
    -
    -  json5@1.0.2:
    -    dependencies:
    -      minimist: 1.2.8
    -
       json5@2.2.3: {}
     
    -  jsonc-parser@2.2.1: {}
    -
    -  jsonfile@1.0.1: {}
    -
       jsonfile@6.2.1:
         dependencies:
           universalify: 2.0.1
         optionalDependencies:
           graceful-fs: 4.2.11
     
    -  jsonparse@1.3.1: {}
    -
    -  jsonpath-plus@10.4.0:
    -    dependencies:
    -      '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0)
    -      '@jsep-plugin/regex': 1.0.4(jsep@1.4.0)
    -      jsep: 1.4.0
    -
    -  jsonpointer@5.0.1: {}
    -
    -  jsx-ast-utils@3.3.5:
    -    dependencies:
    -      array-includes: 3.1.9
    -      array.prototype.flat: 1.3.3
    -      object.assign: 4.1.7
    -      object.values: 1.2.1
    -
    -  just-curry-it@3.2.1: {}
    -
    -  just-curry-it@5.3.0: {}
    -
    -  just-diff-apply@5.5.0: {}
    -
    -  just-diff@6.0.2: {}
    -
       jwt-simple@0.5.6: {}
     
       katex@0.16.47:
         dependencies:
           commander: 8.3.0
     
    -  keyv@4.5.4:
    -    dependencies:
    -      json-buffer: 3.0.1
    -
       khroma@2.1.0: {}
     
       kind-of@6.0.3: {}
     
    -  knex@3.2.10(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.0.0))(sqlite3@6.0.1):
    +  knex@3.3.0(better-sqlite3@12.11.1)(mysql2@3.23.1(@types/node@26.1.1)):
         dependencies:
           colorette: 2.0.19
           commander: 10.0.1
    @@ -18881,12 +13490,11 @@ snapshots:
           pg-connection-string: 2.6.2
           rechoir: 0.8.0
           resolve-from: 5.0.0
    -      tarn: 3.0.2
    +      tarn: 3.1.2
           tildify: 2.0.0
         optionalDependencies:
           better-sqlite3: 12.11.1
    -      mysql2: 3.23.1(@types/node@26.0.0)
    -      sqlite3: 6.0.1
    +      mysql2: 3.23.1(@types/node@26.1.1)
         transitivePeerDependencies:
           - supports-color
     
    @@ -18903,26 +13511,19 @@ snapshots:
     
       leven@3.1.0: {}
     
    -  levenshtein-edit-distance@2.0.5: {}
    -
    -  levn@0.4.1:
    -    dependencies:
    -      prelude-ls: 1.2.1
    -      type-check: 0.4.0
    -
    -  libp2p@3.3.4:
    +  libp2p@3.3.6:
         dependencies:
           '@chainsafe/is-ip': 2.1.0
           '@chainsafe/netmask': 2.0.0
    -      '@libp2p/crypto': 5.1.20
    -      '@libp2p/interface': 3.2.4
    -      '@libp2p/interface-internal': 3.1.7
    -      '@libp2p/logger': 6.2.9
    -      '@libp2p/multistream-select': 7.0.22
    -      '@libp2p/peer-collections': 7.0.22
    -      '@libp2p/peer-id': 6.0.11
    -      '@libp2p/peer-store': 12.0.22
    -      '@libp2p/utils': 7.2.3
    +      '@libp2p/crypto': 5.1.21
    +      '@libp2p/interface': 3.2.5
    +      '@libp2p/interface-internal': 3.1.9
    +      '@libp2p/logger': 6.2.10
    +      '@libp2p/multistream-select': 7.0.24
    +      '@libp2p/peer-collections': 7.0.24
    +      '@libp2p/peer-id': 6.0.12
    +      '@libp2p/peer-store': 12.0.24
    +      '@libp2p/utils': 7.3.0
           '@multiformats/dns': 1.0.13
           '@multiformats/multiaddr': 13.0.3
           '@multiformats/multiaddr-matcher': 3.0.2
    @@ -18993,51 +13594,18 @@ snapshots:
     
       lines-and-columns@1.2.4: {}
     
    -  load-json-file@5.3.0:
    -    dependencies:
    -      graceful-fs: 4.2.11
    -      parse-json: 4.0.0
    -      pify: 4.0.1
    -      strip-bom: 3.0.0
    -      type-fest: 0.3.1
    -
    -  load-json-file@7.0.1: {}
    -
       load-tsconfig@0.2.5: {}
     
    -  loader-runner@4.3.2: {}
    -
    -  locate-path@3.0.0:
    -    dependencies:
    -      p-locate: 3.0.0
    -      path-exists: 3.0.0
    -
       locate-path@5.0.0:
         dependencies:
           p-locate: 4.1.0
     
    -  locate-path@6.0.0:
    -    dependencies:
    -      p-locate: 5.0.0
    -
    -  locate-path@7.2.0:
    -    dependencies:
    -      p-locate: 6.0.0
    -
       lodash-es@4.18.1: {}
     
    -  lodash.debounce@4.0.8: {}
    -
       lodash.memoize@4.1.2: {}
     
    -  lodash.merge@4.6.2: {}
    -
    -  lodash.topath@4.5.2: {}
    -
       lodash@4.18.1: {}
     
    -  loglevel@1.9.2: {}
    -
       long@5.3.2: {}
     
       longest-streak@3.1.0: {}
    @@ -19046,13 +13614,10 @@ snapshots:
         dependencies:
           js-tokens: 4.0.0
     
    -  lower-case@2.0.2:
    -    dependencies:
    -      tslib: 2.8.1
    -
       lru-cache@10.4.3: {}
     
    -  lru-cache@11.5.1: {}
    +  lru-cache@11.5.1:
    +    optional: true
     
       lru-cache@5.1.1:
         dependencies:
    @@ -19080,23 +13645,6 @@ snapshots:
     
       make-error@1.3.6: {}
     
    -  make-fetch-happen@15.0.6:
    -    dependencies:
    -      '@gar/promise-retry': 1.0.3
    -      '@npmcli/agent': 4.0.2
    -      '@npmcli/redact': 4.0.0
    -      cacache: 20.0.4
    -      http-cache-semantics: 4.2.0
    -      minipass: 7.1.3
    -      minipass-fetch: 5.0.2
    -      minipass-flush: 1.0.7
    -      minipass-pipeline: 1.2.4
    -      negotiator: 1.0.0
    -      proc-log: 6.1.0
    -      ssri: 13.0.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
       makeerror@1.0.12:
         dependencies:
           tmpl: 1.0.5
    @@ -19107,8 +13655,6 @@ snapshots:
     
       marked@16.4.2: {}
     
    -  marked@4.3.0: {}
    -
       math-intrinsics@1.1.0: {}
     
       mdast-util-find-and-replace@3.0.2:
    @@ -19261,7 +13807,7 @@ snapshots:
         dependencies:
           '@types/hast': 3.0.4
           '@types/mdast': 4.0.4
    -      '@ungap/structured-clone': 1.3.1
    +      '@ungap/structured-clone': 1.3.3
           devlop: 1.1.0
           micromark-util-sanitize-uri: 2.0.1
           trim-lines: 3.0.1
    @@ -19285,7 +13831,8 @@ snapshots:
         dependencies:
           '@types/mdast': 4.0.4
     
    -  mdn-data@2.27.1: {}
    +  mdn-data@2.27.1:
    +    optional: true
     
       media-typer@0.3.0: {}
     
    @@ -19316,13 +13863,11 @@ snapshots:
     
       merge-stream@2.0.0: {}
     
    -  merge2@1.4.1: {}
    -
    -  mermaid@11.15.0:
    +  mermaid@11.16.0:
         dependencies:
           '@braintree/sanitize-url': 7.1.2
           '@iconify/utils': 3.1.3
    -      '@mermaid-js/parser': 1.1.1
    +      '@mermaid-js/parser': 1.2.0
           '@types/d3': 7.4.3
           '@upsetjs/venn.js': 2.0.0
           cytoscape: 3.33.4
    @@ -19470,8 +14015,8 @@ snapshots:
     
       micromark-extension-mdxjs@3.0.0:
         dependencies:
    -      acorn: 8.16.0
    -      acorn-jsx: 5.3.2(acorn@8.16.0)
    +      acorn: 8.17.0
    +      acorn-jsx: 5.3.2(acorn@8.17.0)
           micromark-extension-mdx-expression: 3.0.1
           micromark-extension-mdx-jsx: 3.0.2
           micromark-extension-mdx-md: 2.0.0
    @@ -19644,10 +14189,6 @@ snapshots:
     
       minimalistic-assert@1.0.1: {}
     
    -  minimatch@10.2.5:
    -    dependencies:
    -      brace-expansion: 5.0.8
    -
       minimatch@3.1.5:
         dependencies:
           brace-expansion: 5.0.8
    @@ -19658,33 +14199,23 @@ snapshots:
     
       minimist@1.2.8: {}
     
    -  minipass-collect@2.0.1:
    -    dependencies:
    -      minipass: 7.1.3
    -
    -  minipass-fetch@5.0.2:
    +  minimizer-webpack-plugin@5.6.1(esbuild@0.28.1)(webpack@5.109.0(esbuild@0.28.1)):
         dependencies:
    -      minipass: 7.1.3
    -      minipass-sized: 2.0.0
    -      minizlib: 3.1.0
    +      '@jridgewell/trace-mapping': 0.3.31
    +      jest-worker: 27.5.1
    +      schema-utils: 4.3.3
    +      terser: 5.49.0
    +      webpack: 5.109.0(esbuild@0.28.1)
         optionalDependencies:
    -      iconv-lite: 0.7.2
    -
    -  minipass-flush@1.0.7:
    -    dependencies:
    -      minipass: 3.3.6
    -
    -  minipass-pipeline@1.2.4:
    -    dependencies:
    -      minipass: 3.3.6
    -
    -  minipass-sized@2.0.0:
    -    dependencies:
    -      minipass: 7.1.3
    +      esbuild: 0.28.1
     
    -  minipass@3.3.6:
    +  minimizer-webpack-plugin@5.6.1(webpack@5.109.0):
         dependencies:
    -      yallist: 4.0.0
    +      '@jridgewell/trace-mapping': 0.3.31
    +      jest-worker: 27.5.1
    +      schema-utils: 4.3.3
    +      terser: 5.49.0
    +      webpack: 5.109.0(webpack-cli@7.2.1)
     
       minipass@7.1.3: {}
     
    @@ -19696,11 +14227,9 @@ snapshots:
     
       mkdirp-classic@0.5.3: {}
     
    -  mkdirp@0.3.5: {}
    -
       mlly@1.8.2:
         dependencies:
    -      acorn: 8.16.0
    +      acorn: 8.17.0
           pathe: 2.0.3
           pkg-types: 1.3.1
           ufo: 1.6.3
    @@ -19718,7 +14247,7 @@ snapshots:
           find-cache-dir: 3.3.2
           follow-redirects: 1.16.0(debug@4.4.3)
           https-proxy-agent: 7.0.6
    -      mongodb: 7.3.0(socks@2.8.7)
    +      mongodb: 7.5.0(socks@2.8.7)
           new-find-package-json: 2.0.0
           semver: 7.8.5
           tar-stream: 3.2.0
    @@ -19754,20 +14283,18 @@ snapshots:
           - socks
           - supports-color
     
    -  mongodb@7.3.0(socks@2.8.7):
    +  mongodb@7.5.0(socks@2.8.7):
         dependencies:
    -      '@mongodb-js/saslprep': 1.4.9
    +      '@mongodb-js/saslprep': 1.4.12
           bson: 7.2.0
           mongodb-connection-string-url: 7.0.1
         optionalDependencies:
           socks: 2.8.7
     
    -  moo@0.5.3: {}
    -
       mortice@3.3.1:
         dependencies:
           abort-error: 1.0.2
    -      it-queue: 1.1.3
    +      it-queue: 1.1.4
           main-event: 1.0.4
     
       mrmime@2.0.1: {}
    @@ -19789,9 +14316,11 @@ snapshots:
     
       multiformats@14.0.0: {}
     
    -  mysql2@3.23.1(@types/node@26.0.0):
    +  multiformats@14.0.5: {}
    +
    +  mysql2@3.23.1(@types/node@26.1.1):
         dependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           aws-ssl-profiles: 1.1.2
           denque: 2.1.0
           generate-function: 2.3.1
    @@ -19817,12 +14346,8 @@ snapshots:
     
       napi-postinstall@0.3.4: {}
     
    -  natural-compare-lite@1.4.0: {}
    -
       natural-compare@1.4.0: {}
     
    -  ncp@0.4.2: {}
    -
       negotiator@0.6.3: {}
     
       negotiator@0.6.4: {}
    @@ -19831,8 +14356,6 @@ snapshots:
     
       neo-async@2.6.2: {}
     
    -  nested-error-stacks@2.0.1: {}
    -
       netmask@2.1.1: {}
     
       new-find-package-json@2.0.0:
    @@ -19841,21 +14364,6 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  nimma@0.2.3:
    -    dependencies:
    -      '@jsep-plugin/regex': 1.0.4(jsep@1.4.0)
    -      '@jsep-plugin/ternary': 1.1.4(jsep@1.4.0)
    -      astring: 1.9.0
    -      jsep: 1.4.0
    -    optionalDependencies:
    -      jsonpath-plus: 10.4.0
    -      lodash.topath: 4.5.2
    -
    -  no-case@3.0.4:
    -    dependencies:
    -      lower-case: 2.0.2
    -      tslib: 2.8.1
    -
       node-abi@3.92.0:
         dependencies:
           semver: 7.8.5
    @@ -19867,19 +14375,6 @@ snapshots:
     
       node-domexception@1.0.0: {}
     
    -  node-exports-info@1.6.0:
    -    dependencies:
    -      array.prototype.flatmap: 1.3.3
    -      es-errors: 1.3.0
    -      object.entries: 1.1.9
    -      semver: 6.3.1
    -
    -  node-fetch@2.6.7(encoding@0.1.13):
    -    dependencies:
    -      whatwg-url: 5.0.0
    -    optionalDependencies:
    -      encoding: 0.1.13
    -
       node-fetch@2.7.0(encoding@0.1.13):
         dependencies:
           whatwg-url: 5.0.0
    @@ -19906,19 +14401,6 @@ snapshots:
           which: 6.0.1
         optional: true
     
    -  node-gyp@12.4.0:
    -    dependencies:
    -      env-paths: 2.2.1
    -      exponential-backoff: 3.1.3
    -      graceful-fs: 4.2.11
    -      nopt: 9.0.0
    -      proc-log: 6.1.0
    -      semver: 7.8.5
    -      tar: 7.5.21
    -      tinyglobby: 0.2.17
    -      undici: 6.27.0
    -      which: 6.0.1
    -
       node-int64@0.4.0: {}
     
       node-notifier@8.0.2:
    @@ -19933,133 +14415,26 @@ snapshots:
     
       node-releases@2.0.46: {}
     
    -  nopt@7.2.1:
    -    dependencies:
    -      abbrev: 2.0.0
    +  node-releases@2.0.51: {}
     
       nopt@9.0.0:
         dependencies:
           abbrev: 4.0.0
    -
    -  normalize-package-data@6.0.2:
    -    dependencies:
    -      hosted-git-info: 7.0.2
    -      semver: 7.8.5
    -      validate-npm-package-license: 3.0.4
    +    optional: true
     
       normalize-path@3.0.0: {}
     
    -  npm-bundled@5.0.0:
    -    dependencies:
    -      npm-normalize-package-bin: 5.0.0
    -
    -  npm-install-checks@6.3.0:
    -    dependencies:
    -      semver: 7.8.5
    -
    -  npm-install-checks@8.0.0:
    -    dependencies:
    -      semver: 7.8.5
    -
    -  npm-normalize-package-bin@3.0.1: {}
    -
    -  npm-normalize-package-bin@5.0.0: {}
    -
    -  npm-package-arg@11.0.3:
    -    dependencies:
    -      hosted-git-info: 7.0.2
    -      proc-log: 4.2.0
    -      semver: 7.8.5
    -      validate-npm-package-name: 5.0.1
    -
    -  npm-package-arg@13.0.2:
    -    dependencies:
    -      hosted-git-info: 9.0.3
    -      proc-log: 6.1.0
    -      semver: 7.8.5
    -      validate-npm-package-name: 7.0.2
    -
    -  npm-packlist@10.0.4:
    -    dependencies:
    -      ignore-walk: 8.0.0
    -      proc-log: 6.1.0
    -
    -  npm-pick-manifest@11.0.3:
    -    dependencies:
    -      npm-install-checks: 8.0.0
    -      npm-normalize-package-bin: 5.0.0
    -      npm-package-arg: 13.0.2
    -      semver: 7.8.5
    -
    -  npm-pick-manifest@9.1.0:
    -    dependencies:
    -      npm-install-checks: 6.3.0
    -      npm-normalize-package-bin: 3.0.1
    -      npm-package-arg: 11.0.3
    -      semver: 7.8.5
    -
    -  npm-registry-fetch@19.1.1:
    -    dependencies:
    -      '@npmcli/redact': 4.0.0
    -      jsonparse: 1.3.1
    -      make-fetch-happen: 15.0.6
    -      minipass: 7.1.3
    -      minipass-fetch: 5.0.2
    -      minizlib: 3.1.0
    -      npm-package-arg: 13.0.2
    -      proc-log: 6.1.0
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  npm-run-path@4.0.1:
    -    dependencies:
    -      path-key: 3.1.1
    -
    -  nwsapi@2.2.23: {}
    -
    -  object-assign@4.1.1: {}
    -
    -  object-hash@3.0.0: {}
    -
    -  object-inspect@1.13.4: {}
    -
    -  object-keys@1.1.1: {}
    -
    -  object.assign@4.1.7:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-object-atoms: 1.1.1
    -      has-symbols: 1.1.0
    -      object-keys: 1.1.1
    -
    -  object.entries@1.1.9:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-object-atoms: 1.1.1
    -
    -  object.fromentries@2.0.8:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-object-atoms: 1.1.1
    -
    -  object.groupby@1.0.3:
    +  npm-run-path@4.0.1:
         dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    +      path-key: 3.1.1
     
    -  object.values@1.2.1:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-object-atoms: 1.1.1
    +  nwsapi@2.2.23: {}
    +
    +  nwsapi@2.2.24: {}
    +
    +  object-assign@4.1.1: {}
    +
    +  object-inspect@1.13.4: {}
     
       obuf@1.1.2: {}
     
    @@ -20094,30 +14469,29 @@ snapshots:
           is-inside-container: 1.0.0
           wsl-utils: 0.1.0
     
    -  openapi-sampler@1.7.2:
    -    dependencies:
    -      '@types/json-schema': 7.0.15
    -      fast-xml-parser: 5.10.1
    -      json-pointer: 0.6.2
    -
    -  openapi-types@12.1.3: {}
    -
       opener@1.5.2: {}
     
    -  optionator@0.9.4:
    -    dependencies:
    -      deep-is: 0.1.4
    -      fast-levenshtein: 2.0.6
    -      levn: 0.4.1
    -      prelude-ls: 1.2.1
    -      type-check: 0.4.0
    -      word-wrap: 1.2.5
    -
    -  own-keys@1.0.1:
    -    dependencies:
    -      get-intrinsic: 1.3.0
    -      object-keys: 1.1.1
    -      safe-push-apply: 1.0.0
    +  oxlint@1.75.0:
    +    optionalDependencies:
    +      '@oxlint/binding-android-arm-eabi': 1.75.0
    +      '@oxlint/binding-android-arm64': 1.75.0
    +      '@oxlint/binding-darwin-arm64': 1.75.0
    +      '@oxlint/binding-darwin-x64': 1.75.0
    +      '@oxlint/binding-freebsd-x64': 1.75.0
    +      '@oxlint/binding-linux-arm-gnueabihf': 1.75.0
    +      '@oxlint/binding-linux-arm-musleabihf': 1.75.0
    +      '@oxlint/binding-linux-arm64-gnu': 1.75.0
    +      '@oxlint/binding-linux-arm64-musl': 1.75.0
    +      '@oxlint/binding-linux-ppc64-gnu': 1.75.0
    +      '@oxlint/binding-linux-riscv64-gnu': 1.75.0
    +      '@oxlint/binding-linux-riscv64-musl': 1.75.0
    +      '@oxlint/binding-linux-s390x-gnu': 1.75.0
    +      '@oxlint/binding-linux-x64-gnu': 1.75.0
    +      '@oxlint/binding-linux-x64-musl': 1.75.0
    +      '@oxlint/binding-openharmony-arm64': 1.75.0
    +      '@oxlint/binding-win32-arm64-msvc': 1.75.0
    +      '@oxlint/binding-win32-ia32-msvc': 1.75.0
    +      '@oxlint/binding-win32-x64-msvc': 1.75.0
     
       p-defer@4.0.1: {}
     
    @@ -20133,38 +14507,15 @@ snapshots:
         dependencies:
           yocto-queue: 0.1.0
     
    -  p-limit@4.0.0:
    -    dependencies:
    -      yocto-queue: 1.2.2
    -
    -  p-locate@3.0.0:
    -    dependencies:
    -      p-limit: 2.3.0
    -
       p-locate@4.1.0:
         dependencies:
           p-limit: 2.3.0
     
    -  p-locate@5.0.0:
    -    dependencies:
    -      p-limit: 3.1.0
    -
    -  p-locate@6.0.0:
    -    dependencies:
    -      p-limit: 4.0.0
    -
    -  p-map@7.0.4: {}
    -
       p-queue@8.1.1:
         dependencies:
           eventemitter3: 5.0.4
           p-timeout: 6.1.4
     
    -  p-queue@9.1.2:
    -    dependencies:
    -      eventemitter3: 5.0.4
    -      p-timeout: 7.0.1
    -
       p-queue@9.3.0:
         dependencies:
           eventemitter3: 5.0.4
    @@ -20208,28 +14559,6 @@ snapshots:
     
       package-manager-detector@1.6.0: {}
     
    -  pacote@21.5.1:
    -    dependencies:
    -      '@gar/promise-retry': 1.0.3
    -      '@npmcli/git': 7.0.2
    -      '@npmcli/installed-package-contents': 4.0.0
    -      '@npmcli/package-json': 7.0.5
    -      '@npmcli/promise-spawn': 9.0.1
    -      '@npmcli/run-script': 10.0.4
    -      cacache: 20.0.4
    -      fs-minipass: 3.0.3
    -      minipass: 7.1.3
    -      npm-package-arg: 13.0.2
    -      npm-packlist: 10.0.4
    -      npm-pick-manifest: 11.0.3
    -      npm-registry-fetch: 19.1.1
    -      proc-log: 6.1.0
    -      sigstore: 4.1.1
    -      ssri: 13.0.1
    -      tar: 7.5.21
    -    transitivePeerDependencies:
    -      - supports-color
    -
       pagefind@1.5.2:
         optionalDependencies:
           '@pagefind/darwin-arm64': 1.5.2
    @@ -20240,20 +14569,10 @@ snapshots:
           '@pagefind/windows-arm64': 1.5.2
           '@pagefind/windows-x64': 1.5.2
     
    -  param-case@3.0.4:
    -    dependencies:
    -      dot-case: 3.0.4
    -      tslib: 2.8.1
    -
       parent-module@1.0.1:
         dependencies:
           callsites: 3.1.0
    -
    -  parse-conflict-json@5.0.1:
    -    dependencies:
    -      json-parse-even-better-errors: 5.0.0
    -      just-diff: 6.0.2
    -      just-diff-apply: 5.5.0
    +    optional: true
     
       parse-entities@4.0.2:
         dependencies:
    @@ -20265,11 +14584,6 @@ snapshots:
           is-decimal: 2.0.1
           is-hexadecimal: 2.0.1
     
    -  parse-json@4.0.0:
    -    dependencies:
    -      error-ex: 1.3.4
    -      json-parse-better-errors: 1.0.2
    -
       parse-json@5.2.0:
         dependencies:
           '@babel/code-frame': 7.29.7
    @@ -20284,31 +14598,14 @@ snapshots:
       parse5@8.0.1:
         dependencies:
           entities: 8.0.0
    +    optional: true
     
       parseurl@1.3.3: {}
     
    -  pascal-case@3.1.2:
    -    dependencies:
    -      no-case: 3.0.4
    -      tslib: 2.8.1
    -
    -  path-case@3.0.4:
    -    dependencies:
    -      dot-case: 3.0.4
    -      tslib: 2.8.1
    -
       path-data-parser@0.1.0: {}
     
    -  path-equal@1.2.5: {}
    -
    -  path-exists@3.0.0: {}
    -
       path-exists@4.0.0: {}
     
    -  path-exists@5.0.0: {}
    -
    -  path-expression-matcher@1.6.2: {}
    -
       path-is-absolute@1.0.1: {}
     
       path-key@3.1.1: {}
    @@ -20320,16 +14617,12 @@ snapshots:
           lru-cache: 10.4.3
           minipass: 7.1.3
     
    -  path-scurry@2.0.2:
    -    dependencies:
    -      lru-cache: 11.5.1
    -      minipass: 7.1.3
    -
       path-to-regexp@0.1.13: {}
     
       path-to-regexp@8.4.2: {}
     
    -  path-type@4.0.0: {}
    +  path-type@4.0.0:
    +    optional: true
     
       pathe@2.0.3: {}
     
    @@ -20343,20 +14636,10 @@ snapshots:
     
       picomatch@4.0.4: {}
     
    -  pify@4.0.1: {}
    +  picomatch@4.0.5: {}
     
       pirates@4.0.7: {}
     
    -  pkg-conf@3.1.0:
    -    dependencies:
    -      find-up: 3.0.0
    -      load-json-file: 5.3.0
    -
    -  pkg-conf@4.0.0:
    -    dependencies:
    -      find-up: 6.3.0
    -      load-json-file: 7.0.1
    -
       pkg-dir@4.2.0:
         dependencies:
           find-up: 4.1.0
    @@ -20385,22 +14668,13 @@ snapshots:
           path-data-parser: 0.1.0
           points-on-curve: 0.2.0
     
    -  pony-cause@1.1.1: {}
    -
    -  possible-typed-array-names@1.1.0: {}
    -
    -  postcss-load-config@6.0.1(postcss@8.5.18)(tsx@4.22.4)(yaml@2.8.3):
    +  postcss-load-config@6.0.1(postcss@8.5.18)(tsx@4.23.1)(yaml@2.9.0):
         dependencies:
           lilconfig: 3.1.3
         optionalDependencies:
           postcss: 8.5.18
    -      tsx: 4.22.4
    -      yaml: 2.8.3
    -
    -  postcss-selector-parser@7.1.4:
    -    dependencies:
    -      cssesc: 3.0.0
    -      util-deprecate: 1.0.2
    +      tsx: 4.23.1
    +      yaml: 2.9.0
     
       postcss@8.5.18:
         dependencies:
    @@ -20423,11 +14697,7 @@ snapshots:
           tar-fs: 2.1.4
           tunnel-agent: 0.6.0
     
    -  prelude-ls@1.2.1: {}
    -
    -  prettier@3.8.3: {}
    -
    -  prettier@3.8.4: {}
    +  prettier@3.9.6: {}
     
       pretty-format@27.5.1:
         dependencies:
    @@ -20440,33 +14710,17 @@ snapshots:
           '@jest/schemas': 30.4.1
           ansi-styles: 5.2.0
           react-is-18: react-is@18.3.1
    -      react-is-19: react-is@19.2.7
    +      react-is-19: react-is@19.2.8
     
    -  proc-log@4.2.0: {}
    -
    -  proc-log@6.1.0: {}
    +  proc-log@6.1.0:
    +    optional: true
     
       process-nextick-args@2.0.1: {}
     
    -  proggy@4.0.0: {}
    -
       progress-events@1.1.0: {}
     
       progress@2.0.3: {}
     
    -  promise-all-reject-late@1.0.1: {}
    -
    -  promise-call-limit@3.0.2: {}
    -
    -  promise-inflight@1.0.1: {}
    -
    -  promise-polyfill@8.3.0: {}
    -
    -  promise-retry@2.0.1:
    -    dependencies:
    -      err-code: 2.0.3
    -      retry: 0.12.0
    -
       prop-types@15.8.1:
         dependencies:
           loose-envify: 1.4.0
    @@ -20477,20 +14731,6 @@ snapshots:
     
       property-information@7.2.0: {}
     
    -  protobufjs@7.6.5:
    -    dependencies:
    -      '@protobufjs/aspromise': 1.1.2
    -      '@protobufjs/base64': 1.1.2
    -      '@protobufjs/codegen': 2.0.5
    -      '@protobufjs/eventemitter': 1.1.1
    -      '@protobufjs/fetch': 1.1.1
    -      '@protobufjs/float': 1.0.2
    -      '@protobufjs/path': 1.1.2
    -      '@protobufjs/pool': 1.1.0
    -      '@protobufjs/utf8': 1.1.1
    -      '@types/node': 26.0.0
    -      long: 5.3.2
    -
       protons-runtime@5.6.0:
         dependencies:
           uint8-varint: 2.0.5
    @@ -20527,8 +14767,6 @@ snapshots:
         dependencies:
           punycode: 2.3.1
     
    -  pubsub-js@1.9.5: {}
    -
       pump@3.0.4:
         dependencies:
           end-of-stream: 1.4.5
    @@ -20536,12 +14774,12 @@ snapshots:
     
       punycode@2.3.1: {}
     
    -  puppeteer-core@24.42.0:
    +  puppeteer-core@24.43.1:
         dependencies:
    -      '@puppeteer/browsers': 2.13.0
    -      chromium-bidi: 14.0.0(devtools-protocol@0.0.1595872)
    +      '@puppeteer/browsers': 2.13.2
    +      chromium-bidi: 14.0.0(devtools-protocol@0.0.1608973)
           debug: 4.4.3
    -      devtools-protocol: 0.0.1595872
    +      devtools-protocol: 0.0.1608973
           typed-query-selector: 2.12.2
           webdriver-bidi-protocol: 0.4.1
           ws: 8.21.0
    @@ -20553,23 +14791,6 @@ snapshots:
           - supports-color
           - utf-8-validate
     
    -  puppeteer@24.42.0(typescript@4.9.5):
    -    dependencies:
    -      '@puppeteer/browsers': 2.13.0
    -      chromium-bidi: 14.0.0(devtools-protocol@0.0.1595872)
    -      cosmiconfig: 9.0.1(typescript@4.9.5)
    -      devtools-protocol: 0.0.1595872
    -      puppeteer-core: 24.42.0
    -      typed-query-selector: 2.12.2
    -    transitivePeerDependencies:
    -      - bare-abort-controller
    -      - bare-buffer
    -      - bufferutil
    -      - react-native-b4a
    -      - supports-color
    -      - typescript
    -      - utf-8-validate
    -
       pure-rand@7.0.1: {}
     
       pvtsutils@1.3.6:
    @@ -20590,8 +14811,6 @@ snapshots:
     
       querystringify@2.2.0: {}
     
    -  queue-microtask@1.2.3: {}
    -
       race-event@1.6.1:
         dependencies:
           abort-error: 1.0.2
    @@ -20600,13 +14819,6 @@ snapshots:
     
       race-signal@2.0.0: {}
     
    -  ramldt2jsonschema@1.2.3:
    -    dependencies:
    -      commander: 5.1.0
    -      js-yaml: 3.15.0
    -      json-schema-migrate: 0.2.0
    -      webapi-parser: 0.5.0
    -
       random-int@3.1.0: {}
     
       range-parser@1.2.1: {}
    @@ -20632,31 +14844,20 @@ snapshots:
           minimist: 1.2.8
           strip-json-comments: 2.0.1
     
    -  react-dom@18.3.1(react@18.3.1):
    -    dependencies:
    -      loose-envify: 1.4.0
    -      react: 18.3.1
    -      scheduler: 0.23.2
    -
    -  react-dom@19.2.7(react@19.2.7):
    +  react-dom@19.2.8(react@19.2.8):
         dependencies:
    -      react: 19.2.7
    +      react: 19.2.8
           scheduler: 0.27.0
     
    -  react-error-boundary@4.1.2(react@18.3.1):
    -    dependencies:
    -      '@babel/runtime': 7.29.2
    -      react: 18.3.1
    -
       react-fast-compare@3.2.2: {}
     
    -  react-helmet-async@1.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
    +  react-helmet-async@1.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
         dependencies:
    -      '@babel/runtime': 7.29.2
    +      '@babel/runtime': 7.29.7
           invariant: 2.2.4
           prop-types: 15.8.1
    -      react: 19.2.7
    -      react-dom: 19.2.7(react@19.2.7)
    +      react: 19.2.8
    +      react-dom: 19.2.8(react@19.2.8)
           react-fast-compare: 3.2.2
           shallowequal: 1.1.0
     
    @@ -20666,37 +14867,21 @@ snapshots:
     
       react-is@18.3.1: {}
     
    -  react-is@19.2.7: {}
    +  react-is@19.2.8: {}
     
    -  react-router-dom@6.30.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
    +  react-router-dom@6.30.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
         dependencies:
           '@remix-run/router': 1.23.3
    -      react: 19.2.7
    -      react-dom: 19.2.7(react@19.2.7)
    -      react-router: 6.30.4(react@19.2.7)
    +      react: 19.2.8
    +      react-dom: 19.2.8(react@19.2.8)
    +      react-router: 6.30.4(react@19.2.8)
     
    -  react-router@6.30.4(react@19.2.7):
    +  react-router@6.30.4(react@19.2.8):
         dependencies:
           '@remix-run/router': 1.23.3
    -      react: 19.2.7
    -
    -  react@17.0.2:
    -    dependencies:
    -      loose-envify: 1.4.0
    -      object-assign: 4.1.1
    -
    -  react@18.3.1:
    -    dependencies:
    -      loose-envify: 1.4.0
    -
    -  react@19.2.7: {}
    -
    -  read-cmd-shim@6.0.0: {}
    +      react: 19.2.8
     
    -  read-package-json-fast@3.0.2:
    -    dependencies:
    -      json-parse-even-better-errors: 3.0.2
    -      npm-normalize-package-bin: 3.0.1
    +  react@19.2.8: {}
     
       readable-stream@2.3.8:
         dependencies:
    @@ -20720,8 +14905,6 @@ snapshots:
     
       readdirp@4.1.2: {}
     
    -  readline@1.3.0: {}
    -
       rechoir@0.8.0:
         dependencies:
           resolve: 1.22.12
    @@ -20762,23 +14945,6 @@ snapshots:
     
       reflect-metadata@0.2.2: {}
     
    -  reflect.getprototypeof@1.0.10:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      es-object-atoms: 1.1.1
    -      get-intrinsic: 1.3.0
    -      get-proto: 1.0.1
    -      which-builtin-type: 1.2.1
    -
    -  regenerate-unicode-properties@10.2.2:
    -    dependencies:
    -      regenerate: 1.4.2
    -
    -  regenerate@1.4.2: {}
    -
       regex-recursion@6.0.2:
         dependencies:
           regex-utilities: 2.3.0
    @@ -20789,32 +14955,6 @@ snapshots:
         dependencies:
           regex-utilities: 2.3.0
     
    -  regexp.prototype.flags@1.5.4:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-errors: 1.3.0
    -      get-proto: 1.0.1
    -      gopd: 1.2.0
    -      set-function-name: 2.0.2
    -
    -  regexpp@3.2.0: {}
    -
    -  regexpu-core@6.4.0:
    -    dependencies:
    -      regenerate: 1.4.2
    -      regenerate-unicode-properties: 10.2.2
    -      regjsgen: 0.8.0
    -      regjsparser: 0.13.2
    -      unicode-match-property-ecmascript: 2.0.0
    -      unicode-match-property-value-ecmascript: 2.2.1
    -
    -  regjsgen@0.8.0: {}
    -
    -  regjsparser@0.13.2:
    -    dependencies:
    -      jsesc: 3.1.0
    -
       rehype-autolink-headings@7.1.0:
         dependencies:
           '@types/hast': 3.0.4
    @@ -20905,26 +15045,17 @@ snapshots:
     
       require-main-filename@2.0.0: {}
     
    -  requireg@0.2.2:
    -    dependencies:
    -      nested-error-stacks: 2.0.1
    -      rc: 1.2.8
    -      resolve: 1.7.1
    -
       requires-port@1.0.0: {}
     
       resolve-cwd@3.0.0:
         dependencies:
           resolve-from: 5.0.0
     
    -  resolve-from@4.0.0: {}
    +  resolve-from@4.0.0:
    +    optional: true
     
       resolve-from@5.0.0: {}
     
    -  resolve-pkg@2.0.0:
    -    dependencies:
    -      resolve-from: 5.0.0
    -
       resolve-tsconfig@1.3.0(typescript@6.0.3):
         dependencies:
           typescript: 6.0.3
    @@ -20936,66 +15067,30 @@ snapshots:
           path-parse: 1.0.7
           supports-preserve-symlinks-flag: 1.0.0
     
    -  resolve@1.7.1:
    -    dependencies:
    -      path-parse: 1.0.7
    -
    -  resolve@2.0.0-next.6:
    -    dependencies:
    -      es-errors: 1.3.0
    -      is-core-module: 2.16.2
    -      node-exports-info: 1.6.0
    -      object-keys: 1.1.1
    -      path-parse: 1.0.7
    -      supports-preserve-symlinks-flag: 1.0.0
    -
    -  resolve@2.0.0-next.7:
    -    dependencies:
    -      es-errors: 1.3.0
    -      is-core-module: 2.16.2
    -      node-exports-info: 1.6.0
    -      object-keys: 1.1.1
    -      path-parse: 1.0.7
    -      supports-preserve-symlinks-flag: 1.0.0
    -
    -  retry@0.12.0: {}
    -
       retry@0.13.1: {}
     
    -  reusify@1.1.0: {}
    -
    -  rimraf@2.2.8: {}
    -
    -  rimraf@3.0.2:
    -    dependencies:
    -      glob: 7.2.3
    -
       robust-predicates@3.0.3: {}
     
    -  rolldown@1.0.3:
    +  rolldown@1.1.5:
         dependencies:
    -      '@oxc-project/types': 0.133.0
    +      '@oxc-project/types': 0.139.0
           '@rolldown/pluginutils': 1.0.1
         optionalDependencies:
    -      '@rolldown/binding-android-arm64': 1.0.3
    -      '@rolldown/binding-darwin-arm64': 1.0.3
    -      '@rolldown/binding-darwin-x64': 1.0.3
    -      '@rolldown/binding-freebsd-x64': 1.0.3
    -      '@rolldown/binding-linux-arm-gnueabihf': 1.0.3
    -      '@rolldown/binding-linux-arm64-gnu': 1.0.3
    -      '@rolldown/binding-linux-arm64-musl': 1.0.3
    -      '@rolldown/binding-linux-ppc64-gnu': 1.0.3
    -      '@rolldown/binding-linux-s390x-gnu': 1.0.3
    -      '@rolldown/binding-linux-x64-gnu': 1.0.3
    -      '@rolldown/binding-linux-x64-musl': 1.0.3
    -      '@rolldown/binding-openharmony-arm64': 1.0.3
    -      '@rolldown/binding-wasm32-wasi': 1.0.3
    -      '@rolldown/binding-win32-arm64-msvc': 1.0.3
    -      '@rolldown/binding-win32-x64-msvc': 1.0.3
    -
    -  rollup@2.80.0:
    -    optionalDependencies:
    -      fsevents: 2.3.3
    +      '@rolldown/binding-android-arm64': 1.1.5
    +      '@rolldown/binding-darwin-arm64': 1.1.5
    +      '@rolldown/binding-darwin-x64': 1.1.5
    +      '@rolldown/binding-freebsd-x64': 1.1.5
    +      '@rolldown/binding-linux-arm-gnueabihf': 1.1.5
    +      '@rolldown/binding-linux-arm64-gnu': 1.1.5
    +      '@rolldown/binding-linux-arm64-musl': 1.1.5
    +      '@rolldown/binding-linux-ppc64-gnu': 1.1.5
    +      '@rolldown/binding-linux-s390x-gnu': 1.1.5
    +      '@rolldown/binding-linux-x64-gnu': 1.1.5
    +      '@rolldown/binding-linux-x64-musl': 1.1.5
    +      '@rolldown/binding-openharmony-arm64': 1.1.5
    +      '@rolldown/binding-wasm32-wasi': 1.1.5
    +      '@rolldown/binding-win32-arm64-msvc': 1.1.5
    +      '@rolldown/binding-win32-x64-msvc': 1.1.5
     
       rollup@4.60.2:
         dependencies:
    @@ -21051,39 +15146,12 @@ snapshots:
     
       run-applescript@7.1.0: {}
     
    -  run-parallel@1.2.0:
    -    dependencies:
    -      queue-microtask: 1.2.3
    -
       rw@1.3.3: {}
     
    -  safe-array-concat@1.1.4:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      get-intrinsic: 1.3.0
    -      has-symbols: 1.1.0
    -      isarray: 2.0.5
    -
       safe-buffer@5.1.2: {}
     
       safe-buffer@5.2.1: {}
     
    -  safe-push-apply@1.0.0:
    -    dependencies:
    -      es-errors: 1.3.0
    -      isarray: 2.0.5
    -
    -  safe-regex-test@1.1.0:
    -    dependencies:
    -      call-bound: 1.0.4
    -      es-errors: 1.3.0
    -      is-regex: 1.2.1
    -
    -  safe-stable-stringify@1.1.1: {}
    -
    -  safe-stable-stringify@2.5.0: {}
    -
       safer-buffer@2.1.2: {}
     
       sass@1.99.0:
    @@ -21092,19 +15160,13 @@ snapshots:
           immutable: 5.1.9
           source-map-js: 1.2.1
         optionalDependencies:
    -      '@parcel/watcher': 2.5.6
    +      '@parcel/watcher': 2.6.0
         optional: true
     
    -  sax@1.6.0: {}
    -
       saxes@6.0.0:
         dependencies:
           xmlchars: 2.2.0
     
    -  scheduler@0.23.2:
    -    dependencies:
    -      loose-envify: 1.4.0
    -
       scheduler@0.27.0: {}
     
       schema-utils@4.3.3:
    @@ -21126,12 +15188,8 @@ snapshots:
           '@peculiar/x509': 1.14.3
           pkijs: 3.4.0
     
    -  semver@5.7.2: {}
    -
       semver@6.3.1: {}
     
    -  semver@7.8.1: {}
    -
       semver@7.8.5: {}
     
       send@0.19.2:
    @@ -21168,12 +15226,6 @@ snapshots:
         transitivePeerDependencies:
           - supports-color
     
    -  sentence-case@3.0.4:
    -    dependencies:
    -      no-case: 3.0.4
    -      tslib: 2.8.1
    -      upper-case-first: 2.0.2
    -
       serve-index@1.9.2:
         dependencies:
           accepts: 1.3.8
    @@ -21206,28 +15258,6 @@ snapshots:
     
       set-blocking@2.0.0: {}
     
    -  set-function-length@1.2.2:
    -    dependencies:
    -      define-data-property: 1.1.4
    -      es-errors: 1.3.0
    -      function-bind: 1.1.2
    -      get-intrinsic: 1.3.0
    -      gopd: 1.2.0
    -      has-property-descriptors: 1.0.2
    -
    -  set-function-name@2.0.2:
    -    dependencies:
    -      define-data-property: 1.1.4
    -      es-errors: 1.3.0
    -      functions-have-names: 1.2.3
    -      has-property-descriptors: 1.0.2
    -
    -  set-proto@1.0.0:
    -    dependencies:
    -      dunder-proto: 1.0.1
    -      es-errors: 1.3.0
    -      es-object-atoms: 1.1.1
    -
       setprototypeof@1.2.0: {}
     
       shallow-clone@3.0.1:
    @@ -21247,14 +15277,14 @@ snapshots:
       shellwords@0.1.1:
         optional: true
     
    -  shiki@4.2.0:
    +  shiki@4.3.1:
         dependencies:
    -      '@shikijs/core': 4.2.0
    -      '@shikijs/engine-javascript': 4.2.0
    -      '@shikijs/engine-oniguruma': 4.2.0
    -      '@shikijs/langs': 4.2.0
    -      '@shikijs/themes': 4.2.0
    -      '@shikijs/types': 4.2.0
    +      '@shikijs/core': 4.3.1
    +      '@shikijs/engine-javascript': 4.3.1
    +      '@shikijs/engine-oniguruma': 4.3.1
    +      '@shikijs/langs': 4.3.1
    +      '@shikijs/themes': 4.3.1
    +      '@shikijs/types': 4.3.1
           '@shikijs/vscode-textmate': 10.0.2
           '@types/hast': 3.0.4
     
    @@ -21278,14 +15308,6 @@ snapshots:
           object-inspect: 1.13.4
           side-channel-map: 1.0.1
     
    -  side-channel@1.1.0:
    -    dependencies:
    -      es-errors: 1.3.0
    -      object-inspect: 1.13.4
    -      side-channel-list: 1.0.1
    -      side-channel-map: 1.0.1
    -      side-channel-weakmap: 1.0.2
    -
       side-channel@1.1.1:
         dependencies:
           es-errors: 1.3.0
    @@ -21300,17 +15322,6 @@ snapshots:
     
       signal-exit@4.1.0: {}
     
    -  sigstore@4.1.1:
    -    dependencies:
    -      '@sigstore/bundle': 4.0.0
    -      '@sigstore/core': 3.2.1
    -      '@sigstore/protobuf-specs': 0.5.1
    -      '@sigstore/sign': 4.1.1
    -      '@sigstore/tuf': 4.0.2
    -      '@sigstore/verify': 3.1.1
    -    transitivePeerDependencies:
    -      - supports-color
    -
       simple-concat@1.0.1: {}
     
       simple-get@4.0.1:
    @@ -21319,16 +15330,6 @@ snapshots:
           once: 1.4.0
           simple-concat: 1.0.1
     
    -  simple-git@3.36.0:
    -    dependencies:
    -      '@kwsites/file-exists': 1.1.1
    -      '@kwsites/promise-deferred': 1.1.1
    -      '@simple-git/args-pathspec': 1.0.3
    -      '@simple-git/argv-parser': 1.1.1
    -      debug: 4.4.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
       sirv@3.0.2:
         dependencies:
           '@polka/url': 1.0.0-next.29
    @@ -21341,15 +15342,10 @@ snapshots:
     
       smart-buffer@4.2.0: {}
     
    -  snake-case@3.0.4:
    -    dependencies:
    -      dot-case: 3.0.4
    -      tslib: 2.8.1
    -
    -  socket.io-adapter@2.5.6:
    +  socket.io-adapter@2.5.8:
         dependencies:
           debug: 4.4.3
    -      ws: 8.21.0
    +      ws: 8.21.1
         transitivePeerDependencies:
           - bufferutil
           - supports-color
    @@ -21359,14 +15355,14 @@ snapshots:
         dependencies:
           '@socket.io/component-emitter': 3.1.2
           debug: 4.4.3
    -      engine.io-client: 6.6.4
    -      socket.io-parser: 4.2.6
    +      engine.io-client: 6.6.6
    +      socket.io-parser: 4.2.7
         transitivePeerDependencies:
           - bufferutil
           - supports-color
           - utf-8-validate
     
    -  socket.io-parser@4.2.6:
    +  socket.io-parser@4.2.7:
         dependencies:
           '@socket.io/component-emitter': 3.1.2
           debug: 4.4.3
    @@ -21379,9 +15375,9 @@ snapshots:
           base64id: 2.0.0
           cors: 2.8.6
           debug: 4.4.3
    -      engine.io: 6.6.7
    -      socket.io-adapter: 2.5.6
    -      socket.io-parser: 4.2.6
    +      engine.io: 6.6.9
    +      socket.io-adapter: 2.5.8
    +      socket.io-parser: 4.2.7
         transitivePeerDependencies:
           - bufferutil
           - supports-color
    @@ -21418,8 +15414,6 @@ snapshots:
           buffer-from: 1.1.2
           source-map: 0.6.1
     
    -  source-map@0.5.7: {}
    -
       source-map@0.6.1: {}
     
       source-map@0.7.6: {}
    @@ -21430,25 +15424,6 @@ snapshots:
         dependencies:
           memory-pager: 1.5.0
     
    -  spdx-correct@3.2.0:
    -    dependencies:
    -      spdx-expression-parse: 3.0.1
    -      spdx-license-ids: 3.0.23
    -
    -  spdx-exceptions@2.5.0: {}
    -
    -  spdx-expression-parse@3.0.1:
    -    dependencies:
    -      spdx-exceptions: 2.5.0
    -      spdx-license-ids: 3.0.23
    -
    -  spdx-expression-parse@4.0.0:
    -    dependencies:
    -      spdx-exceptions: 2.5.0
    -      spdx-license-ids: 3.0.23
    -
    -  spdx-license-ids@3.0.23: {}
    -
       spdy-transport@3.0.0:
         dependencies:
           debug: 4.4.3
    @@ -21483,52 +15458,28 @@ snapshots:
         optionalDependencies:
           node-gyp: 12.3.0
     
    -  ssri@13.0.1:
    -    dependencies:
    -      minipass: 7.1.3
    -
       stack-utils@2.0.6:
         dependencies:
           escape-string-regexp: 2.0.0
     
       stackback@0.0.2: {}
     
    -  standard-engine@15.1.0:
    -    dependencies:
    -      get-stdin: 8.0.0
    -      minimist: 1.2.8
    -      pkg-conf: 3.1.0
    -      xdg-basedir: 4.0.0
    -
    -  standard@17.1.2:
    -    dependencies:
    -      eslint: 8.57.1
    -      eslint-config-standard: 17.1.0(eslint-plugin-import@2.32.0(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)
    -      eslint-config-standard-jsx: 11.0.0(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1)
    -      eslint-plugin-import: 2.32.0(eslint@10.5.0)
    -      eslint-plugin-n: 15.7.0(eslint@10.5.0)
    -      eslint-plugin-promise: 6.6.0(eslint@10.5.0)
    -      eslint-plugin-react: 7.37.5(eslint@10.5.0)
    -      standard-engine: 15.1.0
    -      version-guard: 1.1.3
    -    transitivePeerDependencies:
    -      - '@typescript-eslint/parser'
    -      - eslint-import-resolver-typescript
    -      - eslint-import-resolver-webpack
    -      - supports-color
    -
       statuses@1.5.0: {}
     
       statuses@2.0.2: {}
     
       std-env@4.1.0: {}
     
    -  stop-iteration-iterator@1.1.0:
    +  streamx@2.25.0:
         dependencies:
    -      es-errors: 1.3.0
    -      internal-slot: 1.1.0
    +      events-universal: 1.0.1
    +      fast-fifo: 1.3.2
    +      text-decoder: 1.2.7
    +    transitivePeerDependencies:
    +      - bare-abort-controller
    +      - react-native-b4a
     
    -  streamx@2.25.0:
    +  streamx@2.28.0:
         dependencies:
           events-universal: 1.0.1
           fast-fifo: 1.3.2
    @@ -21536,6 +15487,7 @@ snapshots:
         transitivePeerDependencies:
           - bare-abort-controller
           - react-native-b4a
    +    optional: true
     
       string-length@4.0.2:
         dependencies:
    @@ -21554,50 +15506,6 @@ snapshots:
           emoji-regex: 9.2.2
           strip-ansi: 7.2.0
     
    -  string.prototype.matchall@4.0.12:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-errors: 1.3.0
    -      es-object-atoms: 1.1.1
    -      get-intrinsic: 1.3.0
    -      gopd: 1.2.0
    -      has-symbols: 1.1.0
    -      internal-slot: 1.1.0
    -      regexp.prototype.flags: 1.5.4
    -      set-function-name: 2.0.2
    -      side-channel: 1.1.0
    -
    -  string.prototype.repeat@1.0.0:
    -    dependencies:
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -
    -  string.prototype.trim@1.2.10:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-data-property: 1.1.4
    -      define-properties: 1.2.1
    -      es-abstract: 1.24.2
    -      es-object-atoms: 1.1.1
    -      has-property-descriptors: 1.0.2
    -
    -  string.prototype.trimend@1.0.9:
    -    dependencies:
    -      call-bind: 1.0.9
    -      call-bound: 1.0.4
    -      define-properties: 1.2.1
    -      es-object-atoms: 1.1.1
    -
    -  string.prototype.trimstart@1.0.8:
    -    dependencies:
    -      call-bind: 1.0.9
    -      define-properties: 1.2.1
    -      es-object-atoms: 1.1.1
    -
       string_decoder@1.1.1:
         dependencies:
           safe-buffer: 5.1.2
    @@ -21621,8 +15529,6 @@ snapshots:
     
       strip-bom-string@1.0.0: {}
     
    -  strip-bom@3.0.0: {}
    -
       strip-bom@4.0.0: {}
     
       strip-final-newline@2.0.0: {}
    @@ -21635,14 +15541,6 @@ snapshots:
     
       strip-json-comments@3.1.1: {}
     
    -  strip-outer@1.0.1:
    -    dependencies:
    -      escape-string-regexp: 1.0.5
    -
    -  strnum@2.4.1:
    -    dependencies:
    -      anynum: 1.0.1
    -
       style-to-js@1.1.21:
         dependencies:
           style-to-object: 1.0.14
    @@ -21699,15 +15597,9 @@ snapshots:
     
       symbol-tree@3.2.4: {}
     
    -  sync-fetch@0.5.2(encoding@0.1.13):
    -    dependencies:
    -      node-fetch: 2.7.0(encoding@0.1.13)
    -    transitivePeerDependencies:
    -      - encoding
    -
    -  synckit@0.11.12:
    +  synckit@0.11.13:
         dependencies:
    -      '@pkgr/core': 0.2.9
    +      '@pkgr/core': 0.3.6
     
       tapable@2.3.3: {}
     
    @@ -21718,13 +15610,13 @@ snapshots:
           pump: 3.0.4
           tar-stream: 2.2.0
     
    -  tar-fs@3.1.2:
    +  tar-fs@3.1.3:
         dependencies:
           pump: 3.0.4
           tar-stream: 3.2.0
         optionalDependencies:
    -      bare-fs: 4.7.1
    -      bare-path: 3.0.0
    +      bare-fs: 4.7.4
    +      bare-path: 3.1.1
         transitivePeerDependencies:
           - bare-abort-controller
           - bare-buffer
    @@ -21757,7 +15649,7 @@ snapshots:
           minizlib: 3.1.0
           yallist: 5.0.0
     
    -  tarn@3.0.2: {}
    +  tarn@3.1.2: {}
     
       teex@1.0.1:
         dependencies:
    @@ -21766,28 +15658,10 @@ snapshots:
           - bare-abort-controller
           - react-native-b4a
     
    -  terser-webpack-plugin@5.6.0(esbuild@0.28.1)(webpack@5.107.2(esbuild@0.28.1)):
    -    dependencies:
    -      '@jridgewell/trace-mapping': 0.3.31
    -      jest-worker: 27.5.1
    -      schema-utils: 4.3.3
    -      terser: 5.48.0
    -      webpack: 5.107.2(esbuild@0.28.1)
    -    optionalDependencies:
    -      esbuild: 0.28.1
    -
    -  terser-webpack-plugin@5.6.0(webpack@5.107.2):
    -    dependencies:
    -      '@jridgewell/trace-mapping': 0.3.31
    -      jest-worker: 27.5.1
    -      schema-utils: 4.3.3
    -      terser: 5.48.0
    -      webpack: 5.107.2(webpack-cli@7.0.3)
    -
    -  terser@5.48.0:
    +  terser@5.49.0:
         dependencies:
           '@jridgewell/source-map': 0.3.11
    -      acorn: 8.16.0
    +      acorn: 8.17.0
           commander: 2.20.3
           source-map-support: 0.5.21
     
    @@ -21803,8 +15677,6 @@ snapshots:
         transitivePeerDependencies:
           - react-native-b4a
     
    -  text-table@0.2.0: {}
    -
       thenify-all@1.6.0:
         dependencies:
           thenify: 3.3.1
    @@ -21829,19 +15701,20 @@ snapshots:
     
       tinyglobby@0.2.16:
         dependencies:
    -      fdir: 6.5.0(picomatch@4.0.4)
    -      picomatch: 4.0.4
    +      fdir: 6.5.0(picomatch@4.0.5)
    +      picomatch: 4.0.5
     
       tinyglobby@0.2.17:
         dependencies:
    -      fdir: 6.5.0(picomatch@4.0.4)
    -      picomatch: 4.0.4
    +      fdir: 6.5.0(picomatch@4.0.5)
    +      picomatch: 4.0.5
     
       tinyrainbow@3.1.0: {}
     
       tldts-core@6.1.86: {}
     
    -  tldts-core@7.4.0: {}
    +  tldts-core@7.4.0:
    +    optional: true
     
       tldts@6.1.86:
         dependencies:
    @@ -21850,6 +15723,7 @@ snapshots:
       tldts@7.4.0:
         dependencies:
           tldts-core: 7.4.0
    +    optional: true
     
       tmpl@1.0.5: {}
     
    @@ -21877,6 +15751,7 @@ snapshots:
       tough-cookie@6.0.1:
         dependencies:
           tldts: 7.4.0
    +    optional: true
     
       tr46@0.0.3: {}
     
    @@ -21887,6 +15762,7 @@ snapshots:
       tr46@6.0.0:
         dependencies:
           punycode: 2.3.1
    +    optional: true
     
       tree-dump@1.1.0(tslib@2.8.1):
         dependencies:
    @@ -21894,34 +15770,24 @@ snapshots:
     
       tree-kill@1.2.2: {}
     
    -  treeverse@3.0.0: {}
    -
       trim-lines@3.0.1: {}
     
    -  trim-repeated@1.0.0:
    -    dependencies:
    -      escape-string-regexp: 1.0.5
    -
       trough@2.2.0: {}
     
    -  ts-api-utils@2.5.0(typescript@6.0.3):
    -    dependencies:
    -      typescript: 6.0.3
    -
       ts-dedent@2.2.0: {}
     
       ts-interface-checker@0.1.13: {}
     
    -  ts-jest@29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3):
    +  ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.27.7)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3):
         dependencies:
           bs-logger: 0.2.6
           fast-json-stable-stringify: 2.1.0
           handlebars: 4.7.9
    -      jest: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      jest: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           json5: 2.2.3
           lodash.memoize: 4.1.2
           make-error: 1.3.6
    -      semver: 7.8.1
    +      semver: 7.8.5
           type-fest: 4.41.0
           typescript: 6.0.3
           yargs-parser: 21.1.1
    @@ -21933,33 +15799,12 @@ snapshots:
           esbuild: 0.27.7
           jest-util: 30.4.1
     
    -  ts-jest@29.4.11(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3):
    -    dependencies:
    -      bs-logger: 0.2.6
    -      fast-json-stable-stringify: 2.1.0
    -      handlebars: 4.7.9
    -      jest: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    -      json5: 2.2.3
    -      lodash.memoize: 4.1.2
    -      make-error: 1.3.6
    -      semver: 7.8.1
    -      type-fest: 4.41.0
    -      typescript: 6.0.3
    -      yargs-parser: 21.1.1
    -    optionalDependencies:
    -      '@babel/core': 7.29.7
    -      '@jest/transform': 30.4.1
    -      '@jest/types': 30.4.1
    -      babel-jest: 30.4.1(@babel/core@7.29.7)
    -      esbuild: 0.28.1
    -      jest-util: 30.4.1
    -
    -  ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(jest-util@30.4.1)(jest@30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3)))(typescript@6.0.3):
    +  ts-jest@29.4.12(@babel/core@7.29.7)(@jest/transform@30.4.1)(@jest/types@30.4.1)(babel-jest@30.4.1(@babel/core@7.29.7))(esbuild@0.28.1)(jest-util@30.4.1)(jest@30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3)))(typescript@6.0.3):
         dependencies:
           bs-logger: 0.2.6
           fast-json-stable-stringify: 2.1.0
           handlebars: 4.7.9
    -      jest: 30.4.2(@types/node@26.0.0)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3))
    +      jest: 30.4.2(@types/node@26.1.1)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3))
           json5: 2.2.3
           lodash.memoize: 4.1.2
           make-error: 1.3.6
    @@ -21972,68 +15817,33 @@ snapshots:
           '@jest/transform': 30.4.1
           '@jest/types': 30.4.1
           babel-jest: 30.4.1(@babel/core@7.29.7)
    +      esbuild: 0.28.1
           jest-util: 30.4.1
     
    -  ts-loader@9.6.2(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.1)):
    +  ts-loader@9.6.2(typescript@6.0.3)(webpack@5.109.0(esbuild@0.28.1)):
         dependencies:
           chalk: 4.1.2
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
           source-map: 0.7.6
           typescript: 6.0.3
    -      webpack: 5.107.2(esbuild@0.28.1)
    +      webpack: 5.109.0(esbuild@0.28.1)
     
    -  ts-loader@9.6.2(typescript@6.0.3)(webpack@5.107.2):
    +  ts-loader@9.6.2(typescript@6.0.3)(webpack@5.109.0):
         dependencies:
           chalk: 4.1.2
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
           source-map: 0.7.6
           typescript: 6.0.3
    -      webpack: 5.107.2(webpack-cli@7.0.3)
    -
    -  ts-node@10.9.2(@types/node@16.18.126)(typescript@4.9.5):
    -    dependencies:
    -      '@cspotcode/source-map-support': 0.8.1
    -      '@tsconfig/node10': 1.0.12
    -      '@tsconfig/node12': 1.0.11
    -      '@tsconfig/node14': 1.0.3
    -      '@tsconfig/node16': 1.0.4
    -      '@types/node': 16.18.126
    -      acorn: 8.16.0
    -      acorn-walk: 8.3.5
    -      arg: 4.1.3
    -      create-require: 1.1.1
    -      diff: 4.0.4
    -      make-error: 1.3.6
    -      typescript: 4.9.5
    -      v8-compile-cache-lib: 3.0.1
    -      yn: 3.1.1
    -
    -  ts-node@10.9.2(@types/node@26.0.0)(typescript@4.9.5):
    -    dependencies:
    -      '@cspotcode/source-map-support': 0.8.1
    -      '@tsconfig/node10': 1.0.12
    -      '@tsconfig/node12': 1.0.11
    -      '@tsconfig/node14': 1.0.3
    -      '@tsconfig/node16': 1.0.4
    -      '@types/node': 26.0.0
    -      acorn: 8.16.0
    -      acorn-walk: 8.3.5
    -      arg: 4.1.3
    -      create-require: 1.1.1
    -      diff: 4.0.4
    -      make-error: 1.3.6
    -      typescript: 4.9.5
    -      v8-compile-cache-lib: 3.0.1
    -      yn: 3.1.1
    +      webpack: 5.109.0(webpack-cli@7.2.1)
     
    -  ts-node@10.9.2(@types/node@26.0.0)(typescript@6.0.3):
    +  ts-node@10.9.2(@types/node@26.1.1)(typescript@6.0.3):
         dependencies:
           '@cspotcode/source-map-support': 0.8.1
           '@tsconfig/node10': 1.0.12
           '@tsconfig/node12': 1.0.11
           '@tsconfig/node14': 1.0.3
           '@tsconfig/node16': 1.0.4
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           acorn: 8.16.0
           acorn-walk: 8.3.5
           arg: 4.1.3
    @@ -22044,38 +15854,11 @@ snapshots:
           v8-compile-cache-lib: 3.0.1
           yn: 3.1.1
     
    -  ts-standard@12.0.2(typescript@6.0.3):
    -    dependencies:
    -      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3)
    -      '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3)
    -      eslint: 8.57.1
    -      eslint-config-standard-jsx: 11.0.0(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1)
    -      eslint-config-standard-with-typescript: 23.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)(typescript@6.0.3)
    -      eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)
    -      eslint-plugin-n: 15.7.0(eslint@8.57.1)
    -      eslint-plugin-promise: 6.6.0(eslint@8.57.1)
    -      eslint-plugin-react: 7.37.5(eslint@8.57.1)
    -      minimist: 1.2.8
    -      pkg-conf: 4.0.0
    -      standard-engine: 15.1.0
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - eslint-import-resolver-typescript
    -      - eslint-import-resolver-webpack
    -      - supports-color
    -
       ts2md@0.2.8:
         dependencies:
    -      prettier: 3.8.3
    +      prettier: 3.9.6
           typescript: 5.9.3
     
    -  tsconfig-paths@3.15.0:
    -    dependencies:
    -      '@types/json5': 0.0.29
    -      json5: 1.0.2
    -      minimist: 1.2.8
    -      strip-bom: 3.0.0
    -
       tsconfig-to-dual-package@1.2.0(typescript@6.0.3):
         dependencies:
           resolve-tsconfig: 1.3.0(typescript@6.0.3)
    @@ -22085,7 +15868,7 @@ snapshots:
     
       tslib@2.8.1: {}
     
    -  tsup@8.5.1(postcss@8.5.18)(tsx@4.22.4)(typescript@6.0.3)(yaml@2.8.3):
    +  tsup@8.5.1(postcss@8.5.18)(tsx@4.23.1)(typescript@6.0.3)(yaml@2.9.0):
         dependencies:
           bundle-require: 5.1.0(esbuild@0.27.7)
           cac: 6.7.14
    @@ -22096,7 +15879,7 @@ snapshots:
           fix-dts-default-cjs-exports: 1.0.1
           joycon: 3.1.1
           picocolors: 1.1.1
    -      postcss-load-config: 6.0.1(postcss@8.5.18)(tsx@4.22.4)(yaml@2.8.3)
    +      postcss-load-config: 6.0.1(postcss@8.5.18)(tsx@4.23.1)(yaml@2.9.0)
           resolve-from: 5.0.0
           rollup: 4.60.2
           source-map: 0.7.6
    @@ -22113,12 +15896,7 @@ snapshots:
           - tsx
           - yaml
     
    -  tsutils@3.21.0(typescript@6.0.3):
    -    dependencies:
    -      tslib: 1.14.1
    -      typescript: 6.0.3
    -
    -  tsx@4.22.4:
    +  tsx@4.23.1:
         dependencies:
           esbuild: 0.28.1
         optionalDependencies:
    @@ -22128,30 +15906,14 @@ snapshots:
         dependencies:
           tslib: 1.14.1
     
    -  tuf-js@4.1.0:
    -    dependencies:
    -      '@tufjs/models': 4.1.0
    -      debug: 4.4.3
    -      make-fetch-happen: 15.0.6
    -    transitivePeerDependencies:
    -      - supports-color
    -
       tunnel-agent@0.6.0:
         dependencies:
           safe-buffer: 5.2.1
     
    -  type-check@0.4.0:
    -    dependencies:
    -      prelude-ls: 1.2.1
    -
       type-detect@4.0.8: {}
     
    -  type-fest@0.20.2: {}
    -
       type-fest@0.21.3: {}
     
    -  type-fest@0.3.1: {}
    -
       type-fest@4.41.0: {}
     
       type-is@1.6.18:
    @@ -22165,68 +15927,8 @@ snapshots:
           media-typer: 1.1.0
           mime-types: 3.0.2
     
    -  typed-array-buffer@1.0.3:
    -    dependencies:
    -      call-bound: 1.0.4
    -      es-errors: 1.3.0
    -      is-typed-array: 1.1.15
    -
    -  typed-array-byte-length@1.0.3:
    -    dependencies:
    -      call-bind: 1.0.9
    -      for-each: 0.3.5
    -      gopd: 1.2.0
    -      has-proto: 1.2.0
    -      is-typed-array: 1.1.15
    -
    -  typed-array-byte-offset@1.0.4:
    -    dependencies:
    -      available-typed-arrays: 1.0.7
    -      call-bind: 1.0.9
    -      for-each: 0.3.5
    -      gopd: 1.2.0
    -      has-proto: 1.2.0
    -      is-typed-array: 1.1.15
    -      reflect.getprototypeof: 1.0.10
    -
    -  typed-array-length@1.0.7:
    -    dependencies:
    -      call-bind: 1.0.9
    -      for-each: 0.3.5
    -      gopd: 1.2.0
    -      is-typed-array: 1.1.15
    -      possible-typed-array-names: 1.1.0
    -      reflect.getprototypeof: 1.0.10
    -
       typed-query-selector@2.12.2: {}
     
    -  typescript-eslint@8.61.1(eslint@10.5.0)(typescript@6.0.3):
    -    dependencies:
    -      '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)
    -      '@typescript-eslint/parser': 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    -      '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3)
    -      '@typescript-eslint/utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3)
    -      eslint: 10.5.0
    -      typescript: 6.0.3
    -    transitivePeerDependencies:
    -      - supports-color
    -
    -  typescript-json-schema@0.58.1:
    -    dependencies:
    -      '@types/json-schema': 7.0.15
    -      '@types/node': 16.18.126
    -      glob: 7.2.3
    -      path-equal: 1.2.5
    -      safe-stable-stringify: 2.5.0
    -      ts-node: 10.9.2(@types/node@16.18.126)(typescript@4.9.5)
    -      typescript: 4.9.5
    -      yargs: 17.7.3
    -    transitivePeerDependencies:
    -      - '@swc/core'
    -      - '@swc/wasm'
    -
    -  typescript@4.9.5: {}
    -
       typescript@5.9.3: {}
     
       typescript@6.0.3: {}
    @@ -22262,29 +15964,13 @@ snapshots:
         dependencies:
           multiformats: 14.0.0
     
    -  unbox-primitive@1.1.0:
    -    dependencies:
    -      call-bound: 1.0.4
    -      has-bigints: 1.1.0
    -      has-symbols: 1.1.0
    -      which-boxed-primitive: 1.1.1
    -
       undici-types@8.3.0: {}
     
    -  undici@6.27.0: {}
    -
    -  undici@7.28.0: {}
    -
    -  unicode-canonical-property-names-ecmascript@2.0.1: {}
    -
    -  unicode-match-property-ecmascript@2.0.0:
    -    dependencies:
    -      unicode-canonical-property-names-ecmascript: 2.0.1
    -      unicode-property-aliases-ecmascript: 2.2.0
    -
    -  unicode-match-property-value-ecmascript@2.2.1: {}
    +  undici@6.27.0:
    +    optional: true
     
    -  unicode-property-aliases-ecmascript@2.2.0: {}
    +  undici@7.28.0:
    +    optional: true
     
       unified@11.0.5:
         dependencies:
    @@ -22374,37 +16060,21 @@ snapshots:
           escalade: 3.2.0
           picocolors: 1.1.1
     
    -  upper-case-first@2.0.2:
    -    dependencies:
    -      tslib: 2.8.1
    -
    -  upper-case@2.0.2:
    -    dependencies:
    -      tslib: 2.8.1
    -
    -  uri-js@4.4.1:
    +  update-browserslist-db@1.2.3(browserslist@4.28.7):
         dependencies:
    -      punycode: 2.3.1
    -
    -  urijs@1.19.11: {}
    +      browserslist: 4.28.7
    +      escalade: 3.2.0
    +      picocolors: 1.1.1
     
       url-parse@1.5.10:
         dependencies:
           querystringify: 2.2.0
           requires-port: 1.0.0
     
    -  use-resize-observer@9.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
    -    dependencies:
    -      '@juggle/resize-observer': 3.4.0
    -      react: 18.3.1
    -      react-dom: 18.3.1(react@18.3.1)
    -
       utf8-codec@1.0.0: {}
     
       util-deprecate@1.0.2: {}
     
    -  utility-types@3.11.0: {}
    -
       utils-merge@1.0.1: {}
     
       uuid@14.0.0: {}
    @@ -22421,19 +16091,8 @@ snapshots:
           '@types/istanbul-lib-coverage': 2.0.6
           convert-source-map: 2.0.0
     
    -  validate-npm-package-license@3.0.4:
    -    dependencies:
    -      spdx-correct: 3.2.0
    -      spdx-expression-parse: 3.0.1
    -
    -  validate-npm-package-name@5.0.1: {}
    -
    -  validate-npm-package-name@7.0.2: {}
    -
       vary@1.1.2: {}
     
    -  version-guard@1.1.3: {}
    -
       vfile-message@4.0.3:
         dependencies:
           '@types/unist': 3.0.3
    @@ -22444,52 +16103,52 @@ snapshots:
           '@types/unist': 3.0.3
           vfile-message: 4.0.3
     
    -  vite-react-ssg@0.9.0(prettier@3.8.4)(react-dom@19.2.7(react@19.2.7))(react-router-dom@6.30.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)):
    +  vite-react-ssg@0.9.2(prettier@3.9.6)(react-dom@19.2.8(react@19.2.8))(react-router-dom@6.30.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)):
         dependencies:
    -      fs-extra: 11.3.4
    +      fs-extra: 11.3.5
           html5parser: 2.0.2
           jsdom: 24.1.3
           kolorist: 1.8.0
    -      p-queue: 9.1.2
    -      react: 19.2.7
    -      react-dom: 19.2.7(react@19.2.7)
    -      react-helmet-async: 1.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
    -      vite: 8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)
    -      yargs: 17.7.2
    +      p-queue: 9.3.0
    +      react: 19.2.8
    +      react-dom: 19.2.8(react@19.2.8)
    +      react-helmet-async: 1.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
    +      vite: 8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)
    +      yargs: 17.7.3
         optionalDependencies:
    -      prettier: 3.8.4
    -      react-router-dom: 6.30.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
    +      prettier: 3.9.6
    +      react-router-dom: 6.30.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
         transitivePeerDependencies:
           - bufferutil
           - canvas
           - supports-color
           - utf-8-validate
     
    -  vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3):
    +  vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0):
         dependencies:
           lightningcss: 1.32.0
    -      picomatch: 4.0.4
    +      picomatch: 4.0.5
           postcss: 8.5.18
    -      rolldown: 1.0.3
    +      rolldown: 1.1.5
           tinyglobby: 0.2.17
         optionalDependencies:
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           esbuild: 0.28.1
           fsevents: 2.3.3
           sass: 1.99.0
    -      terser: 5.48.0
    -      tsx: 4.22.4
    -      yaml: 2.8.3
    -
    -  vitest@4.1.9(@opentelemetry/api@1.9.1)(@types/node@26.0.0)(jsdom@28.1.0(@noble/hashes@2.2.0))(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)):
    -    dependencies:
    -      '@vitest/expect': 4.1.9
    -      '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3))
    -      '@vitest/pretty-format': 4.1.9
    -      '@vitest/runner': 4.1.9
    -      '@vitest/snapshot': 4.1.9
    -      '@vitest/spy': 4.1.9
    -      '@vitest/utils': 4.1.9
    +      terser: 5.49.0
    +      tsx: 4.23.1
    +      yaml: 2.9.0
    +
    +  vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@26.1.1)(jsdom@28.1.0(@noble/hashes@2.2.0))(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)):
    +    dependencies:
    +      '@vitest/expect': 4.1.10
    +      '@vitest/mocker': 4.1.10(vite@8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0))
    +      '@vitest/pretty-format': 4.1.10
    +      '@vitest/runner': 4.1.10
    +      '@vitest/snapshot': 4.1.10
    +      '@vitest/spy': 4.1.10
    +      '@vitest/utils': 4.1.10
           es-module-lexer: 2.1.0
           expect-type: 1.3.0
           magic-string: 0.30.21
    @@ -22501,11 +16160,11 @@ snapshots:
           tinyexec: 1.2.2
           tinyglobby: 0.2.16
           tinyrainbow: 3.1.0
    -      vite: 8.0.16(@types/node@26.0.0)(esbuild@0.28.1)(sass@1.99.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.8.3)
    +      vite: 8.1.5(@types/node@26.1.1)(esbuild@0.28.1)(sass@1.99.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)
           why-is-node-running: 2.3.0
         optionalDependencies:
           '@opentelemetry/api': 1.9.1
    -      '@types/node': 26.0.0
    +      '@types/node': 26.1.1
           jsdom: 28.1.0(@noble/hashes@2.2.0)
         transitivePeerDependencies:
           - msw
    @@ -22514,21 +16173,12 @@ snapshots:
         dependencies:
           xml-name-validator: 5.0.0
     
    -  walk-up-path@3.0.1: {}
    -
    -  walk-up-path@4.0.0: {}
    -
    -  walk@2.3.15:
    -    dependencies:
    -      foreachasync: 3.0.0
    -
       walker@1.0.8:
         dependencies:
           makeerror: 1.0.12
     
    -  watchpack@2.5.1:
    +  watchpack@2.5.2:
         dependencies:
    -      glob-to-regexp: 0.4.1
           graceful-fs: 4.2.11
     
       wbuf@1.7.3:
    @@ -22542,19 +16192,16 @@ snapshots:
     
       web-streams-polyfill@3.3.3: {}
     
    -  webapi-parser@0.5.0:
    -    dependencies:
    -      ajv: 6.5.2
    -
       webdriver-bidi-protocol@0.4.1: {}
     
       webidl-conversions@3.0.1: {}
     
       webidl-conversions@7.0.0: {}
     
    -  webidl-conversions@8.0.1: {}
    +  webidl-conversions@8.0.1:
    +    optional: true
     
    -  webpack-bundle-analyzer@5.3.0:
    +  webpack-bundle-analyzer@5.3.1:
         dependencies:
           '@discoveryjs/json-ext': 0.6.3
           acorn: 8.16.0
    @@ -22570,7 +16217,7 @@ snapshots:
           - bufferutil
           - utf-8-validate
     
    -  webpack-cli@7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2):
    +  webpack-cli@7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0):
         dependencies:
           '@discoveryjs/json-ext': 1.1.0
           commander: 14.0.3
    @@ -22579,13 +16226,16 @@ snapshots:
           import-local: 3.2.0
           interpret: 3.1.1
           rechoir: 0.8.0
    -      webpack: 5.107.2(webpack-cli@7.0.3)
    +      webpack: 5.109.0(webpack-cli@7.2.1)
           webpack-merge: 6.0.1
         optionalDependencies:
    -      webpack-bundle-analyzer: 5.3.0
    -      webpack-dev-server: 5.2.6(tslib@2.8.1)(webpack-cli@7.0.3)(webpack@5.107.2)
    +      js-yaml: 4.3.0
    +      json5: 2.2.3
    +      toml: 3.0.0
    +      webpack-bundle-analyzer: 5.3.1
    +      webpack-dev-server: 5.2.6(tslib@2.8.1)(webpack-cli@7.2.1)(webpack@5.109.0)
     
    -  webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2):
    +  webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.109.0):
         dependencies:
           colorette: 2.0.20
           memfs: 4.57.2(tslib@2.8.1)
    @@ -22594,11 +16244,11 @@ snapshots:
           range-parser: 1.2.1
           schema-utils: 4.3.3
         optionalDependencies:
    -      webpack: 5.107.2(webpack-cli@7.0.3)
    +      webpack: 5.109.0(webpack-cli@7.2.1)
         transitivePeerDependencies:
           - tslib
     
    -  webpack-dev-server@5.2.6(tslib@2.8.1)(webpack-cli@7.0.3)(webpack@5.107.2):
    +  webpack-dev-server@5.2.6(tslib@2.8.1)(webpack-cli@7.2.1)(webpack@5.109.0):
         dependencies:
           '@types/bonjour': 3.5.13
           '@types/connect-history-api-fallback': 1.5.4
    @@ -22626,11 +16276,11 @@ snapshots:
           serve-index: 1.9.2
           sockjs: 0.3.24
           spdy: 4.0.2
    -      webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2)
    +      webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.109.0)
           ws: 8.21.0
         optionalDependencies:
    -      webpack: 5.107.2(webpack-cli@7.0.3)
    -      webpack-cli: 7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2)
    +      webpack: 5.109.0(webpack-cli@7.2.1)
    +      webpack-cli: 7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0)
         transitivePeerDependencies:
           - bufferutil
           - debug
    @@ -22644,9 +16294,9 @@ snapshots:
           flat: 5.0.2
           wildcard: 2.0.1
     
    -  webpack-sources@3.5.0: {}
    +  webpack-sources@3.5.1: {}
     
    -  webpack@5.107.2(esbuild@0.28.1):
    +  webpack@5.109.0(esbuild@0.28.1):
         dependencies:
           '@types/estree': 1.0.9
           '@types/json-schema': 7.0.15
    @@ -22654,23 +16304,20 @@ snapshots:
           '@webassemblyjs/wasm-edit': 1.14.1
           '@webassemblyjs/wasm-parser': 1.14.1
           acorn: 8.16.0
    -      acorn-import-phases: 1.0.4(acorn@8.16.0)
           browserslist: 4.28.2
           chrome-trace-event: 1.0.4
    -      enhanced-resolve: 5.22.0
    +      enhanced-resolve: 5.24.3
           es-module-lexer: 2.1.0
           eslint-scope: 5.1.1
           events: 3.3.0
    -      glob-to-regexp: 0.4.1
           graceful-fs: 4.2.11
    -      loader-runner: 4.3.2
           mime-db: 1.54.0
    +      minimizer-webpack-plugin: 5.6.1(esbuild@0.28.1)(webpack@5.109.0(esbuild@0.28.1))
           neo-async: 2.6.2
           schema-utils: 4.3.3
           tapable: 2.3.3
    -      terser-webpack-plugin: 5.6.0(esbuild@0.28.1)(webpack@5.107.2(esbuild@0.28.1))
    -      watchpack: 2.5.1
    -      webpack-sources: 3.5.0
    +      watchpack: 2.5.2
    +      webpack-sources: 3.5.1
         transitivePeerDependencies:
           - '@minify-html/node'
           - '@swc/core'
    @@ -22685,7 +16332,7 @@ snapshots:
           - postcss
           - uglify-js
     
    -  webpack@5.107.2(webpack-cli@7.0.3):
    +  webpack@5.109.0(webpack-cli@7.2.1):
         dependencies:
           '@types/estree': 1.0.9
           '@types/json-schema': 7.0.15
    @@ -22693,25 +16340,22 @@ snapshots:
           '@webassemblyjs/wasm-edit': 1.14.1
           '@webassemblyjs/wasm-parser': 1.14.1
           acorn: 8.16.0
    -      acorn-import-phases: 1.0.4(acorn@8.16.0)
           browserslist: 4.28.2
           chrome-trace-event: 1.0.4
    -      enhanced-resolve: 5.22.0
    +      enhanced-resolve: 5.24.3
           es-module-lexer: 2.1.0
           eslint-scope: 5.1.1
           events: 3.3.0
    -      glob-to-regexp: 0.4.1
           graceful-fs: 4.2.11
    -      loader-runner: 4.3.2
           mime-db: 1.54.0
    +      minimizer-webpack-plugin: 5.6.1(webpack@5.109.0)
           neo-async: 2.6.2
           schema-utils: 4.3.3
           tapable: 2.3.3
    -      terser-webpack-plugin: 5.6.0(webpack@5.107.2)
    -      watchpack: 2.5.1
    -      webpack-sources: 3.5.0
    +      watchpack: 2.5.2
    +      webpack-sources: 3.5.1
         optionalDependencies:
    -      webpack-cli: 7.0.3(webpack-bundle-analyzer@5.3.0)(webpack-dev-server@5.2.6)(webpack@5.107.2)
    +      webpack-cli: 7.2.1(js-yaml@4.3.0)(json5@2.2.3)(toml@3.0.0)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.0)
         transitivePeerDependencies:
           - '@minify-html/node'
           - '@swc/core'
    @@ -22740,7 +16384,8 @@ snapshots:
     
       whatwg-mimetype@4.0.0: {}
     
    -  whatwg-mimetype@5.0.0: {}
    +  whatwg-mimetype@5.0.0:
    +    optional: true
     
       whatwg-url@14.2.0:
         dependencies:
    @@ -22754,6 +16399,7 @@ snapshots:
           webidl-conversions: 8.0.1
         transitivePeerDependencies:
           - '@noble/hashes'
    +    optional: true
     
       whatwg-url@5.0.0:
         dependencies:
    @@ -22764,60 +16410,16 @@ snapshots:
         dependencies:
           is-electron: 2.2.2
     
    -  which-boxed-primitive@1.1.1:
    -    dependencies:
    -      is-bigint: 1.1.0
    -      is-boolean-object: 1.2.2
    -      is-number-object: 1.1.1
    -      is-string: 1.1.1
    -      is-symbol: 1.1.1
    -
    -  which-builtin-type@1.2.1:
    -    dependencies:
    -      call-bound: 1.0.4
    -      function.prototype.name: 1.1.8
    -      has-tostringtag: 1.0.2
    -      is-async-function: 2.1.1
    -      is-date-object: 1.1.0
    -      is-finalizationregistry: 1.1.1
    -      is-generator-function: 1.1.2
    -      is-regex: 1.2.1
    -      is-weakref: 1.1.1
    -      isarray: 2.0.5
    -      which-boxed-primitive: 1.1.1
    -      which-collection: 1.0.2
    -      which-typed-array: 1.1.20
    -
    -  which-collection@1.0.2:
    -    dependencies:
    -      is-map: 2.0.3
    -      is-set: 2.0.3
    -      is-weakmap: 2.0.2
    -      is-weakset: 2.0.4
    -
       which-module@2.0.1: {}
     
    -  which-typed-array@1.1.20:
    -    dependencies:
    -      available-typed-arrays: 1.0.7
    -      call-bind: 1.0.9
    -      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.2:
         dependencies:
           isexe: 2.0.0
     
    -  which@4.0.0:
    -    dependencies:
    -      isexe: 3.1.5
    -
       which@6.0.1:
         dependencies:
           isexe: 4.0.0
    +    optional: true
     
       why-is-node-running@2.3.0:
         dependencies:
    @@ -22826,8 +16428,6 @@ snapshots:
     
       wildcard@2.0.1: {}
     
    -  word-wrap@1.2.5: {}
    -
       wordwrap@1.0.0: {}
     
       wrap-ansi@6.2.0:
    @@ -22855,31 +16455,16 @@ snapshots:
           imurmurhash: 0.1.4
           signal-exit: 4.1.0
     
    -  write-file-atomic@7.0.1:
    -    dependencies:
    -      signal-exit: 4.1.0
    -
       ws@8.21.0: {}
     
    +  ws@8.21.1: {}
    +
       wsl-utils@0.1.0:
         dependencies:
           is-wsl: 3.1.1
     
    -  xdg-basedir@4.0.0: {}
    -
       xml-name-validator@5.0.0: {}
     
    -  xml-naming@0.1.0: {}
    -
    -  xml-naming@0.3.0: {}
    -
    -  xml2js@0.5.0:
    -    dependencies:
    -      sax: 1.6.0
    -      xmlbuilder: 11.0.1
    -
    -  xmlbuilder@11.0.1: {}
    -
       xmlchars@2.2.0: {}
     
       xmlhttprequest-ssl@2.1.2: {}
    @@ -22892,8 +16477,6 @@ snapshots:
     
       yallist@3.1.1: {}
     
    -  yallist@4.0.0: {}
    -
       yallist@5.0.0: {}
     
       yaml@1.10.3:
    @@ -22901,6 +16484,8 @@ snapshots:
     
       yaml@2.8.3: {}
     
    +  yaml@2.9.0: {}
    +
       yargs-parser@18.1.3:
         dependencies:
           camelcase: 5.3.1
    @@ -22922,16 +16507,6 @@ snapshots:
           y18n: 4.0.3
           yargs-parser: 18.1.3
     
    -  yargs@17.7.2:
    -    dependencies:
    -      cliui: 8.0.1
    -      escalade: 3.2.0
    -      get-caller-file: 2.0.5
    -      require-directory: 2.1.1
    -      string-width: 4.2.3
    -      y18n: 5.0.8
    -      yargs-parser: 21.1.1
    -
       yargs@17.7.3:
         dependencies:
           cliui: 8.0.1
    @@ -22956,8 +16531,6 @@ snapshots:
     
       yocto-queue@0.1.0: {}
     
    -  yocto-queue@1.2.2: {}
    -
       zod@3.25.76: {}
     
       zwitch@2.0.4: {}
    diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
    index 26417a3d5..0dc900b61 100644
    --- a/pnpm-workspace.yaml
    +++ b/pnpm-workspace.yaml
    @@ -12,16 +12,11 @@ packages:
     # downgrades. First-party @bsv/* releases are exempt from the delay so a
     # coordinated stack release can consume freshly published siblings.
     allowBuilds:
    -  '@hyperjump/json-pointer': false
    -  '@hyperjump/json-schema': false
    -  '@hyperjump/json-schema-core': false
    -  '@hyperjump/pact': false
       '@parcel/watcher': true
    +  '@scarf/scarf': false
       better-sqlite3: true
       esbuild: true
       mongodb-memory-server: true
    -  protobufjs: false
    -  puppeteer: false
       sqlite3: true
       unrs-resolver: true
     strictDepBuilds: true
    @@ -34,34 +29,8 @@ trustPolicy: no-downgrade
     # false positives (for example chokidar 4.0.3 in pnpm's own documentation).
     trustPolicyIgnoreAfter: 525600
     
    -# Temporary transitive floors for upstream security advisories. Selectors are
    -# limited to vulnerable ranges; Dependabot should remove them once every parent
    -# range resolves safely. brace-expansion has no patched 1.x/2.x release, so the
    -# audited build-tooling graph is explicitly moved to its patched 5.x line.
     overrides:
    -  '@babel/plugin-transform-modules-systemjs@<7.29.4': '7.29.4'
    +  # Jest 30 still reaches brace-expansion 1.x/2.x through minimatch 3/9, and
    +  # those major lines have no patched release. Remove this final override when
    +  # Jest's glob/test-exclude dependency graph accepts brace-expansion >=5.0.8.
       'brace-expansion@<=5.0.7': '5.0.8'
    -  'dompurify@<=3.4.11': '3.4.12'
    -  'engine.io@>=6.0.0 <6.6.7': '6.6.7'
    -  'fast-uri@>=3.0.0 <=3.1.3': '3.1.4'
    -  'fast-xml-builder@<=1.1.6': '1.1.7'
    -  'fast-xml-parser@>=5.9.3 <5.10.1': '5.10.1'
    -  'form-data@>=4.0.0 <4.0.6': '4.0.6'
    -  'http-proxy-middleware@>=2.0.0 <2.0.10': '2.0.10'
    -  'immutable@>=5.0.0-beta.1 <5.1.8': '5.1.9'
    -  'js-yaml@^3.0.0': '3.15.0'
    -  'js-yaml@^4.0.0': '4.3.0'
    -  'jsonpath-plus@<10.3.0': '10.4.0'
    -  'launch-editor@<=2.14.0': '2.14.1'
    -  'postcss@<=8.5.17': '8.5.18'
    -  'protobufjs@>=7.5.0 <=7.6.4': '7.6.5'
    -  'qs@<6.15.2': '6.15.2'
    -  'shell-quote@<=1.8.4': '1.9.0'
    -  'tar@<=7.5.20': '7.5.21'
    -  'undici@^6.0.0': '6.27.0'
    -  'undici@^7.0.0': '7.28.0'
    -  'websocket-driver@<0.7.5': '0.7.5'
    -  'webpack-dev-server@<=5.2.5': '5.2.6'
    -  'ws@>=8.0.0 <8.21.0': '8.21.0'
    -  'ip-address@>=10.0.0 <10.1.1': '10.1.1'
    -  'xml2js@<0.5.0': '0.5.0'
    diff --git a/scripts/check-versions.mjs b/scripts/check-versions.mjs
    index 30414018a..a7f4c8f76 100644
    --- a/scripts/check-versions.mjs
    +++ b/scripts/check-versions.mjs
    @@ -51,11 +51,8 @@ function caretUpperBound (version) {
       return { major: 0, minor: 0, patch: version.patch + 1 }
     }
     
    -function acceptsWorkspaceVersion (range, wsVersion) {
    -  // workspace:^ is the only `workspace:` form we allow — it publishes as `^X.Y.Z`,
    -  // letting downstream consumers dedupe. `workspace:*` publishes as an exact pin
    -  // and causes duplicate-install bugs across infra components, so reject it here.
    -  if (range === 'workspace:^' || range === `^${wsVersion}`) return true
    +function acceptsPeerVersion (range, wsVersion) {
    +  if (range === `^${wsVersion}`) return true
       if (!range.startsWith('^')) return false
     
       const min = parseVersion(range.slice(1))
    @@ -77,12 +74,15 @@ for (const pkg of pkgList) {
         continue
       }
       const d = JSON.parse(raw)
    -  for (const field of ['dependencies', 'devDependencies', 'peerDependencies']) {
    +  for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
         if (!d[field]) continue
         for (const [dep, range] of Object.entries(d[field])) {
           const wsVersion = workspaceMap[dep]
           if (!wsVersion) continue
    -      if (!acceptsWorkspaceVersion(range, wsVersion)) {
    +      const valid = field === 'peerDependencies'
    +        ? acceptsPeerVersion(range, wsVersion)
    +        : range === 'workspace:^'
    +      if (!valid) {
             console.log(`STALE  ${d.name}  ${dep}  ${range}  (current: ${wsVersion})`)
             stale++
           }
    @@ -132,7 +132,7 @@ for (const child of located) {
     if (stale === 0 && mismatched === 0) {
       console.log('All cross-package version references up to date.')
     } else {
    -  if (stale > 0) console.error(`\n${stale} stale references. Run: node scripts/sync-versions.mjs`)
    +  if (stale > 0) console.error(`\n${stale} stale references. Run: node scripts/sync-versions.mjs --workspace-only`)
       if (mismatched > 0) console.error(`\n${mismatched} nested package(s) out of lockstep with their enclosing package. Bump them to match.`)
       process.exit(1)
     }
    diff --git a/scripts/generate-asyncapi-html.mjs b/scripts/generate-asyncapi-html.mjs
    index d4a0f46ff..b2b1c589b 100644
    --- a/scripts/generate-asyncapi-html.mjs
    +++ b/scripts/generate-asyncapi-html.mjs
    @@ -1,133 +1,216 @@
     #!/usr/bin/env node
     /**
    - * Generate AsyncAPI HTML visualizations for all AsyncAPI spec files.
    - *
    - * Uses @asyncapi/generator + @asyncapi/html-template to produce a single-file
    - * self-contained HTML app for each spec, output to docs/assets/asyncapi//.
    - *
    - * Run via:  pnpm docs:asyncapi
    - *       or: node scripts/generate-asyncapi-html.mjs
    - *
    - * Dependencies (@asyncapi/generator and @asyncapi/html-template) are installed
    - * as devDependencies via pnpm.  The html-template requires generator >=2.0.0.
    + * Generate deterministic, self-contained HTML references for the repository's
    + * AsyncAPI specifications. The renderer intentionally uses only the maintained
    + * `yaml` parser so documentation builds do not inherit a package generator,
    + * template engine, browser runtime, or their legacy parser chains.
      */
     
    -import { resolve, dirname } from 'path';
    -import { fileURLToPath } from 'url';
    -import { createRequire } from 'module';
    -import { readFileSync, writeFileSync } from 'fs';
    +import { dirname, resolve } from 'node:path'
    +import { fileURLToPath } from 'node:url'
    +import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
    +import { parse } from 'yaml'
     
    -const __dirname = dirname(fileURLToPath(import.meta.url));
    -const ROOT = resolve(__dirname, '..');
    +const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
     
    -// Use createRequire so we can load CJS modules from node_modules
    -const require = createRequire(import.meta.url);
    -const Generator = require('@asyncapi/generator/lib/generator.js');
    -
    -// ---------------------------------------------------------------------------
    -// Spec → output mapping
    -// ---------------------------------------------------------------------------
     const SPECS = [
       {
         spec: 'specs/payments/brc29-payment-protocol.yaml',
    -    out:  'docs-site/public/assets/asyncapi/brc29',
    +    out: 'docs-site/public/assets/asyncapi/brc29'
       },
       {
         spec: 'specs/auth/brc103-mutual-auth.yaml',
    -    out:  'docs-site/public/assets/asyncapi/brc31',
    +    out: 'docs-site/public/assets/asyncapi/brc31'
       },
       {
         spec: 'specs/messaging/authsocket-asyncapi.yaml',
    -    out:  'docs-site/public/assets/asyncapi/authsocket',
    +    out: 'docs-site/public/assets/asyncapi/authsocket'
       },
       {
         spec: 'specs/sync/gasp-asyncapi.yaml',
    -    out:  'docs-site/public/assets/asyncapi/gasp',
    -  },
    -];
    -
    -// ---------------------------------------------------------------------------
    -// Dark theme CSS injected into generated HTML (template has no dark mode param)
    -// ---------------------------------------------------------------------------
    -const DARK_CSS = ``;
    -
    -function injectDarkTheme(htmlPath) {
    -  const html = readFileSync(htmlPath, 'utf-8');
    -  if (html.includes('DARK_CSS_INJECTED')) return;
    -  writeFileSync(htmlPath, html.replace('', `` + DARK_CSS + '\n'));
    +    out: 'docs-site/public/assets/asyncapi/gasp'
    +  }
    +]
    +
    +function escapeHtml (value) {
    +  return String(value)
    +    .replaceAll('&', '&')
    +    .replaceAll('<', '<')
    +    .replaceAll('>', '>')
    +    .replaceAll('"', '"')
    +    .replaceAll("'", ''')
    +}
    +
    +function identifier (value) {
    +  return String(value)
    +    .toLowerCase()
    +    .replace(/[^a-z0-9]+/g, '-')
    +    .replace(/(^-|-$)/g, '')
    +}
    +
    +function description (value) {
    +  if (value == null || value === '') return ''
    +  return `
    ${escapeHtml(value)}
    ` } -// --------------------------------------------------------------------------- -// Generate all specs -// --------------------------------------------------------------------------- -async function main() { - let ok = 0; - let fail = 0; - - for (const { spec, out } of SPECS) { - const specAbs = resolve(ROOT, spec); - const outAbs = resolve(ROOT, out); - console.log(`Generating: ${spec}`); - console.log(` to: ${out}/index.html`); - - try { - const g = new Generator('@asyncapi/html-template', outAbs, { - forceWrite: true, - // singleFile=true bundles all CSS + JS inline — truly self-contained - templateParams: { singleFile: 'true' }, - }); - await g.generateFromFile(specAbs); - injectDarkTheme(resolve(outAbs, 'index.html')); - console.log(' done.\n'); - ok++; - } catch (err) { - console.error(` FAILED: ${err.message}\n`); - fail++; +function scalar (value) { + if (value === null) return 'null' + if (typeof value === 'string') { + const className = value.startsWith('#/') ? 'ref' : 'string' + return `${escapeHtml(value)}` + } + return `${escapeHtml(JSON.stringify(value))}` +} + +function renderValue (value, depth = 0) { + if (value == null || typeof value !== 'object') return scalar(value) + + if (Array.isArray(value)) { + if (value.length === 0) return 'empty list' + return `
      ${value.map(item => `
    1. ${renderValue(item, depth + 1)}
    2. `).join('')}
    ` + } + + const entries = Object.entries(value) + if (entries.length === 0) return 'empty object' + + return `
    ${entries.map(([key, child]) => { + const nested = child != null && typeof child === 'object' + if (!nested) { + return `
    ${escapeHtml(key)}
    ${scalar(child)}
    ` } + + const open = depth < 1 ? ' open' : '' + return `
    ${escapeHtml(key)}
    ${Array.isArray(child) ? `${child.length} item${child.length === 1 ? '' : 's'}` : `${Object.keys(child).length} field${Object.keys(child).length === 1 ? '' : 's'}`}${renderValue(child, depth + 1)}
    ` + }).join('')}
    ` +} + +function renderEntries (title, sectionId, entries, renderSummary) { + const values = Object.entries(entries ?? {}) + if (values.length === 0) return '' + + return `
    +

    ${escapeHtml(title)}

    ${values.length}
    +
    ${values.map(([name, value]) => { + const summary = renderSummary?.(value) ?? '' + return `
    +

    ${escapeHtml(name)}

    + ${summary} + ${description(value?.description ?? value?.summary)} + ${renderValue(value)} +
    ` + }).join('')}
    +
    ` +} + +function renderSpec (document, source, specPath) { + const info = document.info + const components = document.components ?? {} + const counts = [ + ['Servers', Object.keys(document.servers ?? {}).length], + ['Channels', Object.keys(document.channels ?? {}).length], + ['Operations', Object.keys(document.operations ?? {}).length], + ['Messages', Object.keys(components.messages ?? {}).length], + ['Schemas', Object.keys(components.schemas ?? {}).length] + ] + + const nav = counts + .filter(([, count]) => count > 0) + .map(([name]) => `${name}`) + .join('') + + const body = [ + renderEntries('Servers', 'servers', document.servers, server => { + const endpoint = [server.protocol, server.host].filter(Boolean).join('://') + return endpoint === '' ? '' : `

    ${escapeHtml(endpoint)}${escapeHtml(server.pathname ?? '')}

    ` + }), + renderEntries('Channels', 'channels', document.channels, channel => { + return channel.address == null ? '' : `

    ${escapeHtml(channel.address)}

    ` + }), + renderEntries('Operations', 'operations', document.operations, operation => { + return operation.action == null ? '' : `${escapeHtml(operation.action)}` + }), + renderEntries('Messages', 'messages', components.messages), + renderEntries('Schemas', 'schemas', components.schemas) + ].join('') + + return ` + + + + + + ${escapeHtml(info.title)} · AsyncAPI + + + +
    +
    AsyncAPI ${escapeHtml(document.asyncapi)} · ${escapeHtml(specPath)}
    +

    ${escapeHtml(info.title)}

    v${escapeHtml(info.version)}
    + ${description(info.description)} +
    ${counts.map(([name, count]) => `${count}${name}`).join('')}
    +
    + +
    + ${body} +
    + Raw YAML source +
    ${escapeHtml(source)}
    +
    +
    +
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    + + +`.replace(/[ \t]+$/gm, '') +} + +function validate (document, specPath) { + if (document == null || typeof document !== 'object') { + throw new Error(`${specPath} must contain a YAML object`) + } + if (typeof document.asyncapi !== 'string' || !document.asyncapi.startsWith('3.')) { + throw new Error(`${specPath} must declare AsyncAPI 3.x`) + } + if (typeof document.info?.title !== 'string' || typeof document.info?.version !== 'string') { + throw new Error(`${specPath} must declare info.title and info.version`) } +} + +let failures = 0 +for (const { spec, out } of SPECS) { + try { + const source = readFileSync(resolve(ROOT, spec), 'utf8') + .split('\n') + .map(line => line.trimEnd()) + .join('\n') + const document = parse(source, { prettyErrors: true, uniqueKeys: true }) + validate(document, spec) - console.log(`AsyncAPI HTML generation complete: ${ok} succeeded, ${fail} failed.`); - if (fail > 0) process.exit(1); + const outputDirectory = resolve(ROOT, out) + mkdirSync(outputDirectory, { recursive: true }) + writeFileSync(resolve(outputDirectory, 'index.html'), renderSpec(document, source, spec)) + console.log(`generated ${out}/index.html`) + } catch (error) { + failures += 1 + console.error(`failed ${spec}: ${error instanceof Error ? error.message : String(error)}`) + } } -main().catch((err) => { - console.error('Fatal error:', err); - process.exit(1); -}); +if (failures > 0) process.exit(1) +console.log(`AsyncAPI HTML generation complete: ${SPECS.length} succeeded, 0 failed.`) diff --git a/scripts/sync-versions.mjs b/scripts/sync-versions.mjs index 06417d8bc..78671c3d9 100644 --- a/scripts/sync-versions.mjs +++ b/scripts/sync-versions.mjs @@ -27,6 +27,7 @@ import { execSync } from 'node:child_process' const __dirname = dirname(fileURLToPath(import.meta.url)) const ROOT = resolve(__dirname, '..') const DRY_RUN = process.argv.includes('--dry-run') +const WORKSPACE_ONLY = process.argv.includes('--workspace-only') // --- 1. Collect all workspace package.json paths --- const output = execSync('pnpm -r ls --json --depth 0', { cwd: ROOT }).toString() @@ -40,6 +41,35 @@ for (const pkg of pkgList) { } } +function parseVersion (version) { + const match = version.match(/^(\d+)\.(\d+)\.(\d+)/) + if (!match) return null + return { + major: Number(match[1]), + minor: Number(match[2]), + patch: Number(match[3]) + } +} + +function compareVersion (a, b) { + return a.major - b.major || a.minor - b.minor || a.patch - b.patch +} + +function caretUpperBound (version) { + if (version.major > 0) return { major: version.major + 1, minor: 0, patch: 0 } + if (version.minor > 0) return { major: 0, minor: version.minor + 1, patch: 0 } + return { major: 0, minor: 0, patch: version.patch + 1 } +} + +function acceptsPeerVersion (range, wsVersion) { + if (!range.startsWith('^')) return false + const minimum = parseVersion(range.slice(1)) + const current = parseVersion(wsVersion) + if (!minimum || !current) return false + return compareVersion(current, minimum) >= 0 && + compareVersion(current, caretUpperBound(minimum)) < 0 +} + console.log(`Found ${Object.keys(workspaceMap).length} workspace packages`) // --- 2. Rewrite cross-references --- @@ -62,18 +92,15 @@ for (const [, { path: pkgPath }] of Object.entries(workspaceMap)) { for (const [dep, range] of Object.entries(pkg[field])) { const ws = workspaceMap[dep] if (!ws) continue - const target = `^${ws.version}` - // `workspace:^` is the canonical form for cross-workspace deps in this repo — - // publishes as `^X.Y.Z` so downstream installs dedupe. `workspace:*` publishes - // as an exact pin and causes duplicate-install bugs; rewrite it to `workspace:^`. - if (range === 'workspace:*') { - console.log(` ${pkg.name}: ${dep} workspace:* → workspace:^`) - pkg[field][dep] = 'workspace:^' - changed = true - totalChanges++ - continue - } - if (range !== target && range !== 'workspace:^') { + // Runtime, development, and optional workspace edges must link to the + // local package. pnpm rewrites workspace:^ to ^X.Y.Z during publish. + // Peer ranges remain ordinary semver because they express the public + // compatibility contract rather than an installation edge. + const target = field === 'peerDependencies' ? `^${ws.version}` : 'workspace:^' + const valid = field === 'peerDependencies' + ? acceptsPeerVersion(range, ws.version) + : range === target + if (!valid) { console.log(` ${pkg.name}: ${dep} ${range} → ${target}`) pkg[field][dep] = target changed = true @@ -136,7 +163,7 @@ const bumpPatch = (version) => { return `${major}.${minor}.${patch + 1}${suffix}` } -if (existsSync(INFRA_DIR)) { +if (!WORKSPACE_ONLY && existsSync(INFRA_DIR)) { const entries = readdirSync(INFRA_DIR) for (const entry of entries) { const componentDir = join(INFRA_DIR, entry) diff --git a/specs/reliability/message-box-server.md b/specs/reliability/message-box-server.md index 14d3240c1..cb8634124 100644 --- a/specs/reliability/message-box-server.md +++ b/specs/reliability/message-box-server.md @@ -13,7 +13,7 @@ ## Build and Test - Build command: `npm run build` (tsc; prebuild: rimraf dist) - Test command: `npm test` (node --experimental-vm-modules jest --config=jest.config.mjs) -- Lint command: `npm run lint` (ts-standard --fix .; no lint:ci target) +- Lint command: `npm run lint` (oxlint .; no lint:ci target) - Coverage command: `npm run test:coverage` - Benchmark command: None defined - Last baseline date: 2026-04-24 @@ -81,7 +81,7 @@ Date: 2026-04-24 - Coverage: Available via `npm run test:coverage`; no enforced threshold ## Lint -- Lint command: `npm run lint` (ts-standard --fix .) +- Lint command: `npm run lint` (oxlint .) - Result: Unknown — lint applies auto-fixes; no separate lint:ci (check-only) command defined ## Dependencies diff --git a/specs/reliability/overlay-express.md b/specs/reliability/overlay-express.md index eca8908e4..f93b8e8ec 100644 --- a/specs/reliability/overlay-express.md +++ b/specs/reliability/overlay-express.md @@ -13,7 +13,7 @@ ## Build and Test - Build command: `npm run build` (tsc -b + tsconfig-to-dual-package) - Test command: `npm test` (jest — no build step required before tests) -- Lint command: `npm run lint:ci` (ts-standard src/**/*.ts) +- Lint command: `npm run lint:ci` (oxlint src) - Coverage command: `npm run test:coverage` - Benchmark command: None defined - Last baseline date: 2026-04-24 @@ -81,7 +81,7 @@ Date: 2026-04-24 - Coverage: Available via `npm run test:coverage` (lcov to coverage/); uploaded to Codecov; no enforced threshold ## Lint -- Lint command: `npm run lint:ci` (ts-standard src/**/*.ts) +- Lint command: `npm run lint:ci` (oxlint src) - Result: pass (run in CI on every push/PR) ## Dependencies diff --git a/specs/reliability/ts-sdk.md b/specs/reliability/ts-sdk.md index 84c7c4ca8..31c98230f 100644 --- a/specs/reliability/ts-sdk.md +++ b/specs/reliability/ts-sdk.md @@ -13,7 +13,7 @@ ## Build and Test - Build command: `npm run build` (tsc -b + rspack UMD bundle) - Test command: `npm test` (build + jest) -- Lint command: `npm run lint:ci` (ts-standard) +- Lint command: `npm run lint:ci` (Oxlint) - Coverage command: `npm run test:coverage` - Benchmark command: None defined (benchmarks/ directory exists but no npm script) - Last baseline date: 2026-04-24 @@ -81,7 +81,7 @@ Date: 2026-04-24 - Coverage: Available via `npm run test:coverage` (lcov output to coverage/); no enforced threshold ## Lint -- Lint command: `npm run lint:ci` (ts-standard src/**/*.ts) +- Lint command: `npm run lint:ci` (oxlint src) - Result: pass (run in CI on every push/PR) ## Dependencies diff --git a/specs/reliability/wallet-toolbox.md b/specs/reliability/wallet-toolbox.md index cdbe49faa..15ea82665 100644 --- a/specs/reliability/wallet-toolbox.md +++ b/specs/reliability/wallet-toolbox.md @@ -13,7 +13,7 @@ ## Build and Test - Build command: `npm run build` (tsc --build) - Test command: `npm test` (build + jest, excludes man.test.ts) -- Lint command: `npm run lint` (prettier --write; no ts-standard lint:ci target) +- Lint command: `npm run lint` (Oxlint over `src` and `benchmarks`) - Coverage command: `npm run test:coverage` - Benchmark command: None defined - Last baseline date: 2026-04-24 From 63a1eab117065bd20428671829e740cb3a521f9c Mon Sep 17 00:00:00 2001 From: Ty J Everett Date: Fri, 24 Jul 2026 18:55:52 -0700 Subject: [PATCH 2/6] fix security and analysis gates --- .../assets/asyncapi/authsocket/index.html | 1070 +--------------- .../public/assets/asyncapi/brc29/index.html | 530 +------- .../public/assets/asyncapi/brc31/index.html | 1076 +---------------- .../public/assets/asyncapi/gasp/index.html | 863 +------------ packages/sdk/src/primitives/utils.ts | 6 +- scripts/generate-asyncapi-html.mjs | 29 +- 6 files changed, 28 insertions(+), 3546 deletions(-) diff --git a/docs-site/public/assets/asyncapi/authsocket/index.html b/docs-site/public/assets/asyncapi/authsocket/index.html index 6df0e2af0..e348268bd 100644 --- a/docs-site/public/assets/asyncapi/authsocket/index.html +++ b/docs-site/public/assets/asyncapi/authsocket/index.html @@ -1,1069 +1 @@ - - - - - - - AuthSocket WebSocket Protocol · AsyncAPI - - - -
    -
    AsyncAPI 3.1.0 · specs/messaging/authsocket-asyncapi.yaml
    -

    AuthSocket WebSocket Protocol

    v1.0.0
    -
    AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket` -WebSocket channel used by the BSV MessageBox Server. - -## Transport layer - -`AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server. -All Socket.IO events are standard Socket.IO framing; this spec describes -the *application-level* event names and payload shapes that flow over the -Socket.IO connection. - -## BRC-103 mutual authentication - -Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before -application events are exchanged. The handshake is carried on the -**`authMessage`** event using the `AuthMessage` envelope defined in the -`@bsv/sdk` `Transport` interface. - -Once the handshake succeeds the peer's `identityKey` (compressed secp256k1 -public key, 66-char hex) is known server-side and stored in memory for the -lifetime of the connection. - -## Application events - -After authentication the server emits and listens for the events described -below. All application payloads are serialized as JSON inside the -BRC-103 `general` message (`Peer.toPeer`). The transport layer -(`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope -before signing. - -Source of truth: -- `packages/messaging/authsocket/src/AuthSocketServer.ts` -- `packages/messaging/authsocket/src/SocketServerTransport.ts` -- `packages/messaging/message-box-server/src/index.ts` -
    -
    2Servers16Channels17Operations0Messages18Schemas
    -
    - -
    -
    -

    Servers

    2
    -
    -

    production

    -

    wss://messagebox.babbage.systems/

    -
    Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    -
    host
    messagebox.babbage.systems
    pathname
    /
    protocol
    wss
    description
    Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    -
    -

    local

    -

    ws://localhost:{port}/

    -
    Local development Socket.IO server.
    -
    host
    localhost:{port}
    pathname
    /
    protocol
    ws
    description
    Local development Socket.IO server.
    variables
    1 field
    port
    2 fields
    default
    5001
    description
    HTTP port the MessageBox Server listens on.
    -
    -
    -

    Channels

    16
    -
    -

    authMessage

    -

    authMessage

    -
    Low-level Socket.IO event used by `SocketServerTransport` to carry -BRC-103 `AuthMessage` frames. This event is NOT an application event; -it is emitted and received transparently by the `Peer` class from -`@bsv/sdk`. Application developers do not interact with this channel -directly — they use the typed events below. - -See `packages/messaging/authsocket/src/SocketServerTransport.ts`. -
    -
    address
    authMessage
    description
    Low-level Socket.IO event used by `SocketServerTransport` to carry -BRC-103 `AuthMessage` frames. This event is NOT an application event; -it is emitted and received transparently by the `Peer` class from -`@bsv/sdk`. Application developers do not interact with this channel -directly — they use the typed events below. - -See `packages/messaging/authsocket/src/SocketServerTransport.ts`. -
    messages
    1 field
    authMessageFrame
    3 fields
    name
    authMessageFrame
    summary
    BRC-103 auth frame (both directions — client and server).
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage
    -
    -

    authenticated

    -

    authenticated

    -
    Fallback authentication event. The client emits this when its identity -key was not included in the Socket.IO handshake. The server validates -the key, updates its in-memory `authenticatedSockets` map, and emits -`authenticationSuccess` or `authenticationFailed` in response. -
    -
    address
    authenticated
    description
    Fallback authentication event. The client emits this when its identity -key was not included in the Socket.IO handshake. The server validates -the key, updates its in-memory `authenticatedSockets` map, and emits -`authenticationSuccess` or `authenticationFailed` in response. -
    messages
    1 field
    authenticateMessage
    3 fields
    name
    authenticateMessage
    summary
    Client sends its identity key for post-connection auth.
    payload
    1 field
    $ref
    #/components/schemas/AuthenticatePayload
    -
    -

    authenticationSuccess

    -

    authenticationSuccess

    -
    Emitted by the server after successful identity key validation.
    -
    address
    authenticationSuccess
    description
    Emitted by the server after successful identity key validation.
    messages
    1 field
    authSuccessMessage
    2 fields
    name
    authSuccessMessage
    payload
    1 field
    $ref
    #/components/schemas/AuthSuccessPayload
    -
    -

    authenticationFailed

    -

    authenticationFailed

    -
    Emitted by the server when identity key validation fails.
    -
    address
    authenticationFailed
    description
    Emitted by the server when identity key validation fails.
    messages
    1 field
    authFailedMessage
    2 fields
    name
    authFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/AuthFailedPayload
    -
    -

    joinRoom

    -

    joinRoom

    -
    Client requests to subscribe to a room. Only authenticated sockets may -join rooms. The server responds with `joinedRoom` on success or -`joinFailed` on error. - -Room ID convention: `<recipientIdentityKey>-<messageBoxType>`. -
    -
    address
    joinRoom
    description
    Client requests to subscribe to a room. Only authenticated sockets may -join rooms. The server responds with `joinedRoom` on success or -`joinFailed` on error. - -Room ID convention: `<recipientIdentityKey>-<messageBoxType>`. -
    messages
    1 field
    joinRoomMessage
    3 fields
    name
    joinRoomMessage
    summary
    Room ID string to join.
    payload
    1 field
    $ref
    #/components/schemas/JoinRoomPayload
    -
    -

    joinedRoom

    -

    joinedRoom

    -
    Server confirms the client has joined the specified room.
    -
    address
    joinedRoom
    description
    Server confirms the client has joined the specified room.
    messages
    1 field
    joinedRoomMessage
    2 fields
    name
    joinedRoomMessage
    payload
    1 field
    $ref
    #/components/schemas/JoinedRoomPayload
    -
    -

    joinFailed

    -

    joinFailed

    -
    Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    -
    address
    joinFailed
    description
    Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    messages
    1 field
    joinFailedMessage
    2 fields
    name
    joinFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/JoinFailedPayload
    -
    -

    leaveRoom

    -

    leaveRoom

    -
    Client requests to leave a room.
    -
    address
    leaveRoom
    description
    Client requests to leave a room.
    messages
    1 field
    leaveRoomMessage
    3 fields
    name
    leaveRoomMessage
    summary
    Room ID string to leave.
    payload
    1 field
    $ref
    #/components/schemas/LeaveRoomPayload
    -
    -

    leftRoom

    -

    leftRoom

    -
    Server confirms the client has left the room.
    -
    address
    leftRoom
    description
    Server confirms the client has left the room.
    messages
    1 field
    leftRoomMessage
    2 fields
    name
    leftRoomMessage
    payload
    1 field
    $ref
    #/components/schemas/LeftRoomPayload
    -
    -

    leaveFailed

    -

    leaveFailed

    -
    Emitted when `leaveRoom` fails.
    -
    address
    leaveFailed
    description
    Emitted when `leaveRoom` fails.
    messages
    1 field
    leaveFailedMessage
    2 fields
    name
    leaveFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/LeaveFailedPayload
    -
    -

    sendMessage

    -

    sendMessage

    -
    Client sends a message to a recipient via WebSocket. The server: -1. Validates the sender is authenticated. -2. Validates `roomId` and `message`. -3. Creates the message box if it does not exist. -4. Inserts the message into the database (with ON CONFLICT IGNORE dedup). -5. Emits `sendMessageAck-{roomId}` back to the sender. -6. Broadcasts `sendMessage-{roomId}` to all connections in the room. -
    -
    address
    sendMessage
    description
    Client sends a message to a recipient via WebSocket. The server: -1. Validates the sender is authenticated. -2. Validates `roomId` and `message`. -3. Creates the message box if it does not exist. -4. Inserts the message into the database (with ON CONFLICT IGNORE dedup). -5. Emits `sendMessageAck-{roomId}` back to the sender. -6. Broadcasts `sendMessage-{roomId}` to all connections in the room. -
    messages
    1 field
    sendMessageMessage
    2 fields
    name
    sendMessageMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessagePayload
    -
    -

    sendMessageAck

    -

    sendMessageAck-{roomId}

    -
    Per-room acknowledgement emitted to the sender only after the message -is stored. The event name is `sendMessageAck-<roomId>` where `roomId` -matches the value in the originating `sendMessage` payload. -
    -
    address
    sendMessageAck-{roomId}
    description
    Per-room acknowledgement emitted to the sender only after the message -is stored. The event name is `sendMessageAck-<roomId>` where `roomId` -matches the value in the originating `sendMessage` payload. -
    parameters
    1 field
    roomId
    1 field
    description
    The room ID from the originating sendMessage request.
    messages
    1 field
    sendMessageAckMessage
    2 fields
    name
    sendMessageAckMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessageAckPayload
    -
    -

    sendMessageBroadcast

    -

    sendMessage-{roomId}

    -
    Broadcast emitted to all connections subscribed to `roomId` after a -successful `sendMessage`. The event name is `sendMessage-<roomId>`. -
    -
    address
    sendMessage-{roomId}
    description
    Broadcast emitted to all connections subscribed to `roomId` after a -successful `sendMessage`. The event name is `sendMessage-<roomId>`. -
    parameters
    1 field
    roomId
    1 field
    description
    The target room ID.
    messages
    1 field
    sendMessageBroadcastMessage
    2 fields
    name
    sendMessageBroadcastMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessageBroadcastPayload
    -
    -

    messageFailed

    -

    messageFailed

    -
    Emitted to the sender when `sendMessage` processing fails.
    -
    address
    messageFailed
    description
    Emitted to the sender when `sendMessage` processing fails.
    messages
    1 field
    messageFailedMessage
    2 fields
    name
    messageFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/MessageFailedPayload
    -
    -

    paymentFailed

    -

    paymentFailed

    -
    Emitted to unauthenticated sockets that attempt to send a message -(same event name reused from older payment-gate logic). -
    -
    address
    paymentFailed
    description
    Emitted to unauthenticated sockets that attempt to send a message -(same event name reused from older payment-gate logic). -
    messages
    1 field
    paymentFailedMessage
    2 fields
    name
    paymentFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/PaymentFailedPayload
    -
    -

    disconnect

    -

    disconnect

    -
    Standard Socket.IO disconnect event. The server removes the socket from -the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`. -
    -
    address
    disconnect
    description
    Standard Socket.IO disconnect event. The server removes the socket from -the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`. -
    messages
    1 field
    disconnectMessage
    2 fields
    name
    disconnectMessage
    payload
    1 field
    $ref
    #/components/schemas/DisconnectPayload
    -
    -
    -

    Operations

    17
    -
    -

    receiveAuthMessage

    - receive -
    Server receives an AuthMessage frame from the client during BRC-103 handshake.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/authMessage
    summary
    Server receives an AuthMessage frame from the client during BRC-103 handshake.
    messages
    1 item
    1. $ref
      #/channels/authMessage/messages/authMessageFrame
    -
    -

    sendAuthMessage

    - send -
    Server sends an AuthMessage frame to the client during BRC-103 handshake.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/authMessage
    summary
    Server sends an AuthMessage frame to the client during BRC-103 handshake.
    messages
    1 item
    1. $ref
      #/channels/authMessage/messages/authMessageFrame
    -
    -

    receiveAuthenticated

    - receive -
    Server receives the client's identity key on the 'authenticated' event.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/authenticated
    summary
    Server receives the client's identity key on the 'authenticated' event.
    messages
    1 item
    1. $ref
      #/channels/authenticated/messages/authenticateMessage
    -
    -

    sendAuthenticationSuccess

    - send -
    Server confirms successful identity key validation.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/authenticationSuccess
    summary
    Server confirms successful identity key validation.
    messages
    1 item
    1. $ref
      #/channels/authenticationSuccess/messages/authSuccessMessage
    -
    -

    sendAuthenticationFailed

    - send -
    Server rejects an invalid identity key.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/authenticationFailed
    summary
    Server rejects an invalid identity key.
    messages
    1 item
    1. $ref
      #/channels/authenticationFailed/messages/authFailedMessage
    -
    -

    receiveJoinRoom

    - receive -
    Server receives a room join request.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/joinRoom
    summary
    Server receives a room join request.
    messages
    1 item
    1. $ref
      #/channels/joinRoom/messages/joinRoomMessage
    -
    -

    sendJoinedRoom

    - send -
    Server confirms room join.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/joinedRoom
    summary
    Server confirms room join.
    messages
    1 item
    1. $ref
      #/channels/joinedRoom/messages/joinedRoomMessage
    -
    -

    sendJoinFailed

    - send -
    Server signals room join failure.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/joinFailed
    summary
    Server signals room join failure.
    messages
    1 item
    1. $ref
      #/channels/joinFailed/messages/joinFailedMessage
    -
    -

    receiveLeaveRoom

    - receive -
    Server receives a room leave request.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/leaveRoom
    summary
    Server receives a room leave request.
    messages
    1 item
    1. $ref
      #/channels/leaveRoom/messages/leaveRoomMessage
    -
    -

    sendLeftRoom

    - send -
    Server confirms room leave.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/leftRoom
    summary
    Server confirms room leave.
    messages
    1 item
    1. $ref
      #/channels/leftRoom/messages/leftRoomMessage
    -
    -

    sendLeaveFailed

    - send -
    Server signals room leave failure.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/leaveFailed
    summary
    Server signals room leave failure.
    messages
    1 item
    1. $ref
      #/channels/leaveFailed/messages/leaveFailedMessage
    -
    -

    receiveSendMessage

    - receive -
    Server receives a message from the client to deliver to a recipient.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/sendMessage
    summary
    Server receives a message from the client to deliver to a recipient.
    messages
    1 item
    1. $ref
      #/channels/sendMessage/messages/sendMessageMessage
    -
    -

    sendSendMessageAck

    - send -
    Server acknowledges delivery of a message to the sender.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/sendMessageAck
    summary
    Server acknowledges delivery of a message to the sender.
    messages
    1 item
    1. $ref
      #/channels/sendMessageAck/messages/sendMessageAckMessage
    -
    -

    sendSendMessageBroadcast

    - send -
    Server broadcasts a new message to all room subscribers.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/sendMessageBroadcast
    summary
    Server broadcasts a new message to all room subscribers.
    messages
    1 item
    1. $ref
      #/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage
    -
    -

    sendMessageFailed

    - send -
    Server signals message delivery failure.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/messageFailed
    summary
    Server signals message delivery failure.
    messages
    1 item
    1. $ref
      #/channels/messageFailed/messages/messageFailedMessage
    -
    -

    sendPaymentFailed

    - send -
    Server signals auth/payment gate rejection.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/paymentFailed
    summary
    Server signals auth/payment gate rejection.
    messages
    1 item
    1. $ref
      #/channels/paymentFailed/messages/paymentFailedMessage
    -
    -

    receiveDisconnect

    - receive -
    Client disconnects; server cleans up in-memory state.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/disconnect
    summary
    Client disconnects; server cleans up in-memory state.
    messages
    1 item
    1. $ref
      #/channels/disconnect/messages/disconnectMessage
    -
    -
    -

    Schemas

    18
    -
    -

    PubKeyHex

    - -
    Compressed secp256k1 public key, 66 hex characters.
    -
    type
    string
    pattern
    ^0[23][0-9a-fA-F]{64}$
    description
    Compressed secp256k1 public key, 66 hex characters.
    -
    -

    AuthMessage

    - -
    BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the -low-level `authMessage` Socket.IO event. Not an application-level event. -
    -
    type
    object
    description
    BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the -low-level `authMessage` Socket.IO event. Not an application-level event. -
    required
    3 items
    1. messageType
    2. version
    3. identityKey
    properties
    9 fields
    messageType
    3 fields
    type
    string
    enum
    3 items
    1. initialRequest
    2. initialResponse
    3. general
    description
    - `initialRequest` — first handshake message from initiating peer -- `initialResponse` — server's challenge response (includes nonce, signature) -- `general` — signed application payload after handshake -
    version
    2 fields
    type
    string
    description
    Auth protocol version string.
    identityKey
    1 field
    $ref
    #/components/schemas/PubKeyHex
    nonce
    2 fields
    type
    string
    description
    Fresh random nonce (base64) generated by the sender.
    yourNonce
    2 fields
    type
    string
    description
    Echo of the peer's nonce from the previous message.
    initialNonce
    2 fields
    type
    string
    description
    Present in `initialRequest`; absent in subsequent messages.
    payload
    3 fields
    type
    array
    items
    1 field
    type
    integer
    description
    Signed application payload (byte array). Empty for handshake messages.
    signature
    3 fields
    type
    array
    items
    1 field
    type
    integer
    description
    DER-encoded ECDSA signature over the payload.
    requestedCertificates
    3 fields
    type
    object
    description
    Optional certificate request set (BRC-52 format).
    additionalProperties
    true
    -
    -

    EventEnvelope

    - -
    Application-level wrapper JSON-encoded inside the BRC-103 `general` -message payload. The `SocketServerTransport` encodes/decodes this -transparently; application code only sees `eventName` and `data`. -
    -
    type
    object
    description
    Application-level wrapper JSON-encoded inside the BRC-103 `general` -message payload. The `SocketServerTransport` encodes/decodes this -transparently; application code only sees `eventName` and `data`. -
    required
    2 items
    1. eventName
    2. data
    properties
    2 fields
    eventName
    2 fields
    type
    string
    description
    The Socket.IO event name.
    data
    1 field
    description
    The event-specific payload.
    -
    -

    AuthenticatePayload

    - -
    Sent by the client on the `authenticated` event when the identity key -was not available at connection time (fallback path). The server validates -the key and responds with `authenticationSuccess` or `authenticationFailed`. -
    -
    type
    object
    description
    Sent by the client on the `authenticated` event when the identity key -was not available at connection time (fallback path). The server validates -the key and responds with `authenticationSuccess` or `authenticationFailed`. -
    properties
    1 field
    identityKey
    1 field
    $ref
    #/components/schemas/PubKeyHex
    -
    -

    AuthSuccessPayload

    - - -
    type
    object
    required
    1 item
    1. status
    properties
    1 field
    status
    2 fields
    type
    string
    enum
    1 item
    1. success
    -
    -

    AuthFailedPayload

    - - -
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    2 fields
    type
    string
    description
    Human-readable reason for failure.
    -
    -

    JoinRoomPayload

    - -
    The room ID string sent by the client on the `joinRoom` event. -Room IDs use the convention `<recipientKey>-<messageBoxType>`. -Example: `028d37b9...-payment_inbox`. -
    -
    type
    string
    description
    The room ID string sent by the client on the `joinRoom` event. -Room IDs use the convention `<recipientKey>-<messageBoxType>`. -Example: `028d37b9...-payment_inbox`. -
    -
    -

    JoinedRoomPayload

    - - -
    type
    object
    required
    1 item
    1. roomId
    properties
    1 field
    roomId
    1 field
    type
    string
    -
    -

    JoinFailedPayload

    - - -
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string
    -
    -

    LeaveRoomPayload

    - -
    The room ID string sent by the client on the `leaveRoom` event.
    -
    type
    string
    description
    The room ID string sent by the client on the `leaveRoom` event.
    -
    -

    LeftRoomPayload

    - - -
    type
    object
    required
    1 item
    1. roomId
    properties
    1 field
    roomId
    1 field
    type
    string
    -
    -

    LeaveFailedPayload

    - - -
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string
    -
    -

    WsSendMessagePayload

    - -
    Payload for the client-to-server `sendMessage` event.
    -
    type
    object
    description
    Payload for the client-to-server `sendMessage` event.
    required
    2 items
    1. roomId
    2. message
    properties
    2 fields
    roomId
    2 fields
    type
    string
    description
    Target room. Format: `<recipientKey>-<messageBoxType>`. -The server extracts the `messageBoxType` by splitting on `-` and -taking the second part; it uses the authenticated sender key from -`authenticatedSockets`. -
    message
    3 fields
    type
    object
    required
    3 items
    1. messageId
    2. recipient
    3. body
    properties
    3 fields
    messageId
    2 fields
    type
    string
    description
    Unique identifier for this message (deduplication key).
    recipient
    1 field
    $ref
    #/components/schemas/PubKeyHex
    body
    2 fields
    type
    string
    description
    Message body string.
    -
    -

    WsSendMessageAckPayload

    - -
    Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after -a successful `sendMessage`. Note: the event name is dynamic and includes -the room ID used in the originating request. -
    -
    type
    object
    description
    Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after -a successful `sendMessage`. Note: the event name is dynamic and includes -the room ID used in the originating request. -
    required
    2 items
    1. status
    2. messageId
    properties
    2 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. success
    messageId
    1 field
    type
    string
    -
    -

    WsSendMessageBroadcastPayload

    - -
    Broadcast emitted by the server on `sendMessage-{roomId}` to all -connections in the room (including the sender). Note: the event name -is dynamic. -
    -
    type
    object
    description
    Broadcast emitted by the server on `sendMessage-{roomId}` to all -connections in the room (including the sender). Note: the event name -is dynamic. -
    required
    3 items
    1. sender
    2. messageId
    3. body
    properties
    3 fields
    sender
    1 field
    $ref
    #/components/schemas/PubKeyHex
    messageId
    1 field
    type
    string
    body
    1 field
    type
    string
    -
    -

    MessageFailedPayload

    - - -
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string
    -
    -

    PaymentFailedPayload

    - - -
    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string
    -
    -

    DisconnectPayload

    - -
    The Socket.IO disconnect reason string (e.g. `transport close`, -`server namespace disconnect`). -
    -
    type
    string
    description
    The Socket.IO disconnect reason string (e.g. `transport close`, -`server namespace disconnect`). -
    -
    -
    -
    - Raw YAML source -
    asyncapi: "3.1.0"
    -
    -info:
    -  title: AuthSocket WebSocket Protocol
    -  version: "1.0.0"
    -  description: |
    -    AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket`
    -    WebSocket channel used by the BSV MessageBox Server.
    -
    -    ## Transport layer
    -
    -    `AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server.
    -    All Socket.IO events are standard Socket.IO framing; this spec describes
    -    the *application-level* event names and payload shapes that flow over the
    -    Socket.IO connection.
    -
    -    ## BRC-103 mutual authentication
    -
    -    Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before
    -    application events are exchanged. The handshake is carried on the
    -    **`authMessage`** event using the `AuthMessage` envelope defined in the
    -    `@bsv/sdk` `Transport` interface.
    -
    -    Once the handshake succeeds the peer's `identityKey` (compressed secp256k1
    -    public key, 66-char hex) is known server-side and stored in memory for the
    -    lifetime of the connection.
    -
    -    ## Application events
    -
    -    After authentication the server emits and listens for the events described
    -    below. All application payloads are serialized as JSON inside the
    -    BRC-103 `general` message (`Peer.toPeer`). The transport layer
    -    (`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope
    -    before signing.
    -
    -    Source of truth:
    -    - `packages/messaging/authsocket/src/AuthSocketServer.ts`
    -    - `packages/messaging/authsocket/src/SocketServerTransport.ts`
    -    - `packages/messaging/message-box-server/src/index.ts`
    -
    -servers:
    -  production:
    -    host: "messagebox.babbage.systems"
    -    pathname: "/"
    -    protocol: wss
    -    description: Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    -  local:
    -    host: "localhost:{port}"
    -    pathname: "/"
    -    protocol: ws
    -    description: Local development Socket.IO server.
    -    variables:
    -      port:
    -        default: "5001"
    -        description: HTTP port the MessageBox Server listens on.
    -
    -# ---------------------------------------------------------------------------
    -# Components
    -# ---------------------------------------------------------------------------
    -components:
    -  schemas:
    -    PubKeyHex:
    -      type: string
    -      pattern: "^0[23][0-9a-fA-F]{64}$"
    -      description: Compressed secp256k1 public key, 66 hex characters.
    -
    -    AuthMessage:
    -      type: object
    -      description: |
    -        BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the
    -        low-level `authMessage` Socket.IO event. Not an application-level event.
    -      required: [messageType, version, identityKey]
    -      properties:
    -        messageType:
    -          type: string
    -          enum: [initialRequest, initialResponse, general]
    -          description: |
    -            - `initialRequest`  — first handshake message from initiating peer
    -            - `initialResponse` — server's challenge response (includes nonce, signature)
    -            - `general`         — signed application payload after handshake
    -        version:
    -          type: string
    -          description: Auth protocol version string.
    -        identityKey:
    -          $ref: "#/components/schemas/PubKeyHex"
    -        nonce:
    -          type: string
    -          description: Fresh random nonce (base64) generated by the sender.
    -        yourNonce:
    -          type: string
    -          description: Echo of the peer's nonce from the previous message.
    -        initialNonce:
    -          type: string
    -          description: Present in `initialRequest`; absent in subsequent messages.
    -        payload:
    -          type: array
    -          items:
    -            type: integer
    -          description: Signed application payload (byte array). Empty for handshake messages.
    -        signature:
    -          type: array
    -          items:
    -            type: integer
    -          description: DER-encoded ECDSA signature over the payload.
    -        requestedCertificates:
    -          type: object
    -          description: Optional certificate request set (BRC-52 format).
    -          additionalProperties: true
    -
    -    EventEnvelope:
    -      type: object
    -      description: |
    -        Application-level wrapper JSON-encoded inside the BRC-103 `general`
    -        message payload. The `SocketServerTransport` encodes/decodes this
    -        transparently; application code only sees `eventName` and `data`.
    -      required: [eventName, data]
    -      properties:
    -        eventName:
    -          type: string
    -          description: The Socket.IO event name.
    -        data:
    -          description: The event-specific payload.
    -
    -    # ----- Authentication flow -----
    -    AuthenticatePayload:
    -      type: object
    -      description: |
    -        Sent by the client on the `authenticated` event when the identity key
    -        was not available at connection time (fallback path). The server validates
    -        the key and responds with `authenticationSuccess` or `authenticationFailed`.
    -      properties:
    -        identityKey:
    -          $ref: "#/components/schemas/PubKeyHex"
    -
    -    AuthSuccessPayload:
    -      type: object
    -      required: [status]
    -      properties:
    -        status:
    -          type: string
    -          enum: [success]
    -
    -    AuthFailedPayload:
    -      type: object
    -      required: [reason]
    -      properties:
    -        reason:
    -          type: string
    -          description: Human-readable reason for failure.
    -
    -    # ----- Room management -----
    -    JoinRoomPayload:
    -      type: string
    -      description: |
    -        The room ID string sent by the client on the `joinRoom` event.
    -        Room IDs use the convention `<recipientKey>-<messageBoxType>`.
    -        Example: `028d37b9...-payment_inbox`.
    -
    -    JoinedRoomPayload:
    -      type: object
    -      required: [roomId]
    -      properties:
    -        roomId:
    -          type: string
    -
    -    JoinFailedPayload:
    -      type: object
    -      required: [reason]
    -      properties:
    -        reason:
    -          type: string
    -
    -    LeaveRoomPayload:
    -      type: string
    -      description: The room ID string sent by the client on the `leaveRoom` event.
    -
    -    LeftRoomPayload:
    -      type: object
    -      required: [roomId]
    -      properties:
    -        roomId:
    -          type: string
    -
    -    LeaveFailedPayload:
    -      type: object
    -      required: [reason]
    -      properties:
    -        reason:
    -          type: string
    -
    -    # ----- Message sending -----
    -    WsSendMessagePayload:
    -      type: object
    -      description: Payload for the client-to-server `sendMessage` event.
    -      required: [roomId, message]
    -      properties:
    -        roomId:
    -          type: string
    -          description: |
    -            Target room. Format: `<recipientKey>-<messageBoxType>`.
    -            The server extracts the `messageBoxType` by splitting on `-` and
    -            taking the second part; it uses the authenticated sender key from
    -            `authenticatedSockets`.
    -        message:
    -          type: object
    -          required: [messageId, recipient, body]
    -          properties:
    -            messageId:
    -              type: string
    -              description: Unique identifier for this message (deduplication key).
    -            recipient:
    -              $ref: "#/components/schemas/PubKeyHex"
    -            body:
    -              type: string
    -              description: Message body string.
    -
    -    WsSendMessageAckPayload:
    -      type: object
    -      description: |
    -        Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after
    -        a successful `sendMessage`. Note: the event name is dynamic and includes
    -        the room ID used in the originating request.
    -      required: [status, messageId]
    -      properties:
    -        status:
    -          type: string
    -          enum: [success]
    -        messageId:
    -          type: string
    -
    -    WsSendMessageBroadcastPayload:
    -      type: object
    -      description: |
    -        Broadcast emitted by the server on `sendMessage-{roomId}` to all
    -        connections in the room (including the sender). Note: the event name
    -        is dynamic.
    -      required: [sender, messageId, body]
    -      properties:
    -        sender:
    -          $ref: "#/components/schemas/PubKeyHex"
    -        messageId:
    -          type: string
    -        body:
    -          type: string
    -
    -    MessageFailedPayload:
    -      type: object
    -      required: [reason]
    -      properties:
    -        reason:
    -          type: string
    -
    -    PaymentFailedPayload:
    -      type: object
    -      required: [reason]
    -      properties:
    -        reason:
    -          type: string
    -
    -    DisconnectPayload:
    -      type: string
    -      description: |
    -        The Socket.IO disconnect reason string (e.g. `transport close`,
    -        `server namespace disconnect`).
    -
    -# ---------------------------------------------------------------------------
    -# Channels
    -# ---------------------------------------------------------------------------
    -channels:
    -
    -  # -------- Low-level auth handshake (BRC-103 / Peer transport) --------
    -  authMessage:
    -    address: authMessage
    -    description: |
    -      Low-level Socket.IO event used by `SocketServerTransport` to carry
    -      BRC-103 `AuthMessage` frames. This event is NOT an application event;
    -      it is emitted and received transparently by the `Peer` class from
    -      `@bsv/sdk`. Application developers do not interact with this channel
    -      directly — they use the typed events below.
    -
    -      See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
    -    messages:
    -      authMessageFrame:
    -        name: authMessageFrame
    -        summary: BRC-103 auth frame (both directions — client and server).
    -        payload:
    -          $ref: "#/components/schemas/AuthMessage"
    -
    -  # -------- Application authentication --------
    -  authenticated:
    -    address: authenticated
    -    description: |
    -      Fallback authentication event. The client emits this when its identity
    -      key was not included in the Socket.IO handshake. The server validates
    -      the key, updates its in-memory `authenticatedSockets` map, and emits
    -      `authenticationSuccess` or `authenticationFailed` in response.
    -    messages:
    -      authenticateMessage:
    -        name: authenticateMessage
    -        summary: Client sends its identity key for post-connection auth.
    -        payload:
    -          $ref: "#/components/schemas/AuthenticatePayload"
    -
    -  authenticationSuccess:
    -    address: authenticationSuccess
    -    description: Emitted by the server after successful identity key validation.
    -    messages:
    -      authSuccessMessage:
    -        name: authSuccessMessage
    -        payload:
    -          $ref: "#/components/schemas/AuthSuccessPayload"
    -
    -  authenticationFailed:
    -    address: authenticationFailed
    -    description: Emitted by the server when identity key validation fails.
    -    messages:
    -      authFailedMessage:
    -        name: authFailedMessage
    -        payload:
    -          $ref: "#/components/schemas/AuthFailedPayload"
    -
    -  # -------- Room management --------
    -  joinRoom:
    -    address: joinRoom
    -    description: |
    -      Client requests to subscribe to a room. Only authenticated sockets may
    -      join rooms. The server responds with `joinedRoom` on success or
    -      `joinFailed` on error.
    -
    -      Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
    -    messages:
    -      joinRoomMessage:
    -        name: joinRoomMessage
    -        summary: Room ID string to join.
    -        payload:
    -          $ref: "#/components/schemas/JoinRoomPayload"
    -
    -  joinedRoom:
    -    address: joinedRoom
    -    description: Server confirms the client has joined the specified room.
    -    messages:
    -      joinedRoomMessage:
    -        name: joinedRoomMessage
    -        payload:
    -          $ref: "#/components/schemas/JoinedRoomPayload"
    -
    -  joinFailed:
    -    address: joinFailed
    -    description: Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    -    messages:
    -      joinFailedMessage:
    -        name: joinFailedMessage
    -        payload:
    -          $ref: "#/components/schemas/JoinFailedPayload"
    -
    -  leaveRoom:
    -    address: leaveRoom
    -    description: Client requests to leave a room.
    -    messages:
    -      leaveRoomMessage:
    -        name: leaveRoomMessage
    -        summary: Room ID string to leave.
    -        payload:
    -          $ref: "#/components/schemas/LeaveRoomPayload"
    -
    -  leftRoom:
    -    address: leftRoom
    -    description: Server confirms the client has left the room.
    -    messages:
    -      leftRoomMessage:
    -        name: leftRoomMessage
    -        payload:
    -          $ref: "#/components/schemas/LeftRoomPayload"
    -
    -  leaveFailed:
    -    address: leaveFailed
    -    description: Emitted when `leaveRoom` fails.
    -    messages:
    -      leaveFailedMessage:
    -        name: leaveFailedMessage
    -        payload:
    -          $ref: "#/components/schemas/LeaveFailedPayload"
    -
    -  # -------- Message sending --------
    -  sendMessage:
    -    address: sendMessage
    -    description: |
    -      Client sends a message to a recipient via WebSocket. The server:
    -      1. Validates the sender is authenticated.
    -      2. Validates `roomId` and `message`.
    -      3. Creates the message box if it does not exist.
    -      4. Inserts the message into the database (with ON CONFLICT IGNORE dedup).
    -      5. Emits `sendMessageAck-{roomId}` back to the sender.
    -      6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
    -    messages:
    -      sendMessageMessage:
    -        name: sendMessageMessage
    -        payload:
    -          $ref: "#/components/schemas/WsSendMessagePayload"
    -
    -  sendMessageAck:
    -    address: "sendMessageAck-{roomId}"
    -    description: |
    -      Per-room acknowledgement emitted to the sender only after the message
    -      is stored. The event name is `sendMessageAck-<roomId>` where `roomId`
    -      matches the value in the originating `sendMessage` payload.
    -    parameters:
    -      roomId:
    -        description: The room ID from the originating sendMessage request.
    -    messages:
    -      sendMessageAckMessage:
    -        name: sendMessageAckMessage
    -        payload:
    -          $ref: "#/components/schemas/WsSendMessageAckPayload"
    -
    -  sendMessageBroadcast:
    -    address: "sendMessage-{roomId}"
    -    description: |
    -      Broadcast emitted to all connections subscribed to `roomId` after a
    -      successful `sendMessage`. The event name is `sendMessage-<roomId>`.
    -    parameters:
    -      roomId:
    -        description: The target room ID.
    -    messages:
    -      sendMessageBroadcastMessage:
    -        name: sendMessageBroadcastMessage
    -        payload:
    -          $ref: "#/components/schemas/WsSendMessageBroadcastPayload"
    -
    -  messageFailed:
    -    address: messageFailed
    -    description: Emitted to the sender when `sendMessage` processing fails.
    -    messages:
    -      messageFailedMessage:
    -        name: messageFailedMessage
    -        payload:
    -          $ref: "#/components/schemas/MessageFailedPayload"
    -
    -  paymentFailed:
    -    address: paymentFailed
    -    description: |
    -      Emitted to unauthenticated sockets that attempt to send a message
    -      (same event name reused from older payment-gate logic).
    -    messages:
    -      paymentFailedMessage:
    -        name: paymentFailedMessage
    -        payload:
    -          $ref: "#/components/schemas/PaymentFailedPayload"
    -
    -  # -------- Lifecycle --------
    -  disconnect:
    -    address: disconnect
    -    description: |
    -      Standard Socket.IO disconnect event. The server removes the socket from
    -      the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
    -    messages:
    -      disconnectMessage:
    -        name: disconnectMessage
    -        payload:
    -          $ref: "#/components/schemas/DisconnectPayload"
    -
    -# ---------------------------------------------------------------------------
    -# Operations
    -# ---------------------------------------------------------------------------
    -operations:
    -
    -  # --- Auth handshake (transport-level, both directions) ---
    -  receiveAuthMessage:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/authMessage"
    -    summary: Server receives an AuthMessage frame from the client during BRC-103 handshake.
    -    messages:
    -      - $ref: "#/channels/authMessage/messages/authMessageFrame"
    -
    -  sendAuthMessage:
    -    action: send
    -    channel:
    -      $ref: "#/channels/authMessage"
    -    summary: Server sends an AuthMessage frame to the client during BRC-103 handshake.
    -    messages:
    -      - $ref: "#/channels/authMessage/messages/authMessageFrame"
    -
    -  # --- Client authentication ---
    -  receiveAuthenticated:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/authenticated"
    -    summary: Server receives the client's identity key on the 'authenticated' event.
    -    messages:
    -      - $ref: "#/channels/authenticated/messages/authenticateMessage"
    -
    -  sendAuthenticationSuccess:
    -    action: send
    -    channel:
    -      $ref: "#/channels/authenticationSuccess"
    -    summary: Server confirms successful identity key validation.
    -    messages:
    -      - $ref: "#/channels/authenticationSuccess/messages/authSuccessMessage"
    -
    -  sendAuthenticationFailed:
    -    action: send
    -    channel:
    -      $ref: "#/channels/authenticationFailed"
    -    summary: Server rejects an invalid identity key.
    -    messages:
    -      - $ref: "#/channels/authenticationFailed/messages/authFailedMessage"
    -
    -  # --- Room management ---
    -  receiveJoinRoom:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/joinRoom"
    -    summary: Server receives a room join request.
    -    messages:
    -      - $ref: "#/channels/joinRoom/messages/joinRoomMessage"
    -
    -  sendJoinedRoom:
    -    action: send
    -    channel:
    -      $ref: "#/channels/joinedRoom"
    -    summary: Server confirms room join.
    -    messages:
    -      - $ref: "#/channels/joinedRoom/messages/joinedRoomMessage"
    -
    -  sendJoinFailed:
    -    action: send
    -    channel:
    -      $ref: "#/channels/joinFailed"
    -    summary: Server signals room join failure.
    -    messages:
    -      - $ref: "#/channels/joinFailed/messages/joinFailedMessage"
    -
    -  receiveLeaveRoom:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/leaveRoom"
    -    summary: Server receives a room leave request.
    -    messages:
    -      - $ref: "#/channels/leaveRoom/messages/leaveRoomMessage"
    -
    -  sendLeftRoom:
    -    action: send
    -    channel:
    -      $ref: "#/channels/leftRoom"
    -    summary: Server confirms room leave.
    -    messages:
    -      - $ref: "#/channels/leftRoom/messages/leftRoomMessage"
    -
    -  sendLeaveFailed:
    -    action: send
    -    channel:
    -      $ref: "#/channels/leaveFailed"
    -    summary: Server signals room leave failure.
    -    messages:
    -      - $ref: "#/channels/leaveFailed/messages/leaveFailedMessage"
    -
    -  # --- Message sending ---
    -  receiveSendMessage:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/sendMessage"
    -    summary: Server receives a message from the client to deliver to a recipient.
    -    messages:
    -      - $ref: "#/channels/sendMessage/messages/sendMessageMessage"
    -
    -  sendSendMessageAck:
    -    action: send
    -    channel:
    -      $ref: "#/channels/sendMessageAck"
    -    summary: Server acknowledges delivery of a message to the sender.
    -    messages:
    -      - $ref: "#/channels/sendMessageAck/messages/sendMessageAckMessage"
    -
    -  sendSendMessageBroadcast:
    -    action: send
    -    channel:
    -      $ref: "#/channels/sendMessageBroadcast"
    -    summary: Server broadcasts a new message to all room subscribers.
    -    messages:
    -      - $ref: "#/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage"
    -
    -  sendMessageFailed:
    -    action: send
    -    channel:
    -      $ref: "#/channels/messageFailed"
    -    summary: Server signals message delivery failure.
    -    messages:
    -      - $ref: "#/channels/messageFailed/messages/messageFailedMessage"
    -
    -  sendPaymentFailed:
    -    action: send
    -    channel:
    -      $ref: "#/channels/paymentFailed"
    -    summary: Server signals auth/payment gate rejection.
    -    messages:
    -      - $ref: "#/channels/paymentFailed/messages/paymentFailedMessage"
    -
    -  # --- Lifecycle ---
    -  receiveDisconnect:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/disconnect"
    -    summary: Client disconnects; server cleans up in-memory state.
    -    messages:
    -      - $ref: "#/channels/disconnect/messages/disconnectMessage"
    -
    -
    -
    -
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    - - +AuthSocket WebSocket Protocol · AsyncAPI
    AsyncAPI 3.1.0 · specs/messaging/authsocket-asyncapi.yaml

    AuthSocket WebSocket Protocol

    v1.0.0
    AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket` WebSocket channel used by the BSV MessageBox Server. ## Transport layer `AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server. All Socket.IO events are standard Socket.IO framing; this spec describes the *application-level* event names and payload shapes that flow over the Socket.IO connection. ## BRC-103 mutual authentication Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before application events are exchanged. The handshake is carried on the **`authMessage`** event using the `AuthMessage` envelope defined in the `@bsv/sdk` `Transport` interface. Once the handshake succeeds the peer's `identityKey` (compressed secp256k1 public key, 66-char hex) is known server-side and stored in memory for the lifetime of the connection. ## Application events After authentication the server emits and listens for the events described below. All application payloads are serialized as JSON inside the BRC-103 `general` message (`Peer.toPeer`). The transport layer (`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope before signing. Source of truth: - `packages/messaging/authsocket/src/AuthSocketServer.ts` - `packages/messaging/authsocket/src/SocketServerTransport.ts` - `packages/messaging/message-box-server/src/index.ts`
    2Servers16Channels17Operations0Messages18Schemas

    Servers

    2

    production

    wss://messagebox.babbage.systems/

    Production MessageBox WebSocket endpoint (Socket.IO over WSS).
    host
    messagebox.babbage.systems
    pathname
    /
    protocol
    wss
    description
    Production MessageBox WebSocket endpoint (Socket.IO over WSS).

    local

    ws://localhost:{port}/

    Local development Socket.IO server.
    host
    localhost:{port}
    pathname
    /
    protocol
    ws
    description
    Local development Socket.IO server.
    variables
    1 field
    port
    2 fields
    default
    5001
    description
    HTTP port the MessageBox Server listens on.

    Channels

    16

    authMessage

    authMessage

    Low-level Socket.IO event used by `SocketServerTransport` to carry BRC-103 `AuthMessage` frames. This event is NOT an application event; it is emitted and received transparently by the `Peer` class from `@bsv/sdk`. Application developers do not interact with this channel directly — they use the typed events below. See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
    address
    authMessage
    description
    Low-level Socket.IO event used by `SocketServerTransport` to carry BRC-103 `AuthMessage` frames. This event is NOT an application event; it is emitted and received transparently by the `Peer` class from `@bsv/sdk`. Application developers do not interact with this channel directly — they use the typed events below. See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
    messages
    1 field
    authMessageFrame
    3 fields
    name
    authMessageFrame
    summary
    BRC-103 auth frame (both directions — client and server).
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage

    authenticated

    authenticated

    Fallback authentication event. The client emits this when its identity key was not included in the Socket.IO handshake. The server validates the key, updates its in-memory `authenticatedSockets` map, and emits `authenticationSuccess` or `authenticationFailed` in response.
    address
    authenticated
    description
    Fallback authentication event. The client emits this when its identity key was not included in the Socket.IO handshake. The server validates the key, updates its in-memory `authenticatedSockets` map, and emits `authenticationSuccess` or `authenticationFailed` in response.
    messages
    1 field
    authenticateMessage
    3 fields
    name
    authenticateMessage
    summary
    Client sends its identity key for post-connection auth.
    payload
    1 field
    $ref
    #/components/schemas/AuthenticatePayload

    authenticationSuccess

    authenticationSuccess

    Emitted by the server after successful identity key validation.
    address
    authenticationSuccess
    description
    Emitted by the server after successful identity key validation.
    messages
    1 field
    authSuccessMessage
    2 fields
    name
    authSuccessMessage
    payload
    1 field
    $ref
    #/components/schemas/AuthSuccessPayload

    authenticationFailed

    authenticationFailed

    Emitted by the server when identity key validation fails.
    address
    authenticationFailed
    description
    Emitted by the server when identity key validation fails.
    messages
    1 field
    authFailedMessage
    2 fields
    name
    authFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/AuthFailedPayload

    joinRoom

    joinRoom

    Client requests to subscribe to a room. Only authenticated sockets may join rooms. The server responds with `joinedRoom` on success or `joinFailed` on error. Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
    address
    joinRoom
    description
    Client requests to subscribe to a room. Only authenticated sockets may join rooms. The server responds with `joinedRoom` on success or `joinFailed` on error. Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
    messages
    1 field
    joinRoomMessage
    3 fields
    name
    joinRoomMessage
    summary
    Room ID string to join.
    payload
    1 field
    $ref
    #/components/schemas/JoinRoomPayload

    joinedRoom

    joinedRoom

    Server confirms the client has joined the specified room.
    address
    joinedRoom
    description
    Server confirms the client has joined the specified room.
    messages
    1 field
    joinedRoomMessage
    2 fields
    name
    joinedRoomMessage
    payload
    1 field
    $ref
    #/components/schemas/JoinedRoomPayload

    joinFailed

    joinFailed

    Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    address
    joinFailed
    description
    Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
    messages
    1 field
    joinFailedMessage
    2 fields
    name
    joinFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/JoinFailedPayload

    leaveRoom

    leaveRoom

    Client requests to leave a room.
    address
    leaveRoom
    description
    Client requests to leave a room.
    messages
    1 field
    leaveRoomMessage
    3 fields
    name
    leaveRoomMessage
    summary
    Room ID string to leave.
    payload
    1 field
    $ref
    #/components/schemas/LeaveRoomPayload

    leftRoom

    leftRoom

    Server confirms the client has left the room.
    address
    leftRoom
    description
    Server confirms the client has left the room.
    messages
    1 field
    leftRoomMessage
    2 fields
    name
    leftRoomMessage
    payload
    1 field
    $ref
    #/components/schemas/LeftRoomPayload

    leaveFailed

    leaveFailed

    Emitted when `leaveRoom` fails.
    address
    leaveFailed
    description
    Emitted when `leaveRoom` fails.
    messages
    1 field
    leaveFailedMessage
    2 fields
    name
    leaveFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/LeaveFailedPayload

    sendMessage

    sendMessage

    Client sends a message to a recipient via WebSocket. The server: 1. Validates the sender is authenticated. 2. Validates `roomId` and `message`. 3. Creates the message box if it does not exist. 4. Inserts the message into the database (with ON CONFLICT IGNORE dedup). 5. Emits `sendMessageAck-{roomId}` back to the sender. 6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
    address
    sendMessage
    description
    Client sends a message to a recipient via WebSocket. The server: 1. Validates the sender is authenticated. 2. Validates `roomId` and `message`. 3. Creates the message box if it does not exist. 4. Inserts the message into the database (with ON CONFLICT IGNORE dedup). 5. Emits `sendMessageAck-{roomId}` back to the sender. 6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
    messages
    1 field
    sendMessageMessage
    2 fields
    name
    sendMessageMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessagePayload

    sendMessageAck

    sendMessageAck-{roomId}

    Per-room acknowledgement emitted to the sender only after the message is stored. The event name is `sendMessageAck-<roomId>` where `roomId` matches the value in the originating `sendMessage` payload.
    address
    sendMessageAck-{roomId}
    description
    Per-room acknowledgement emitted to the sender only after the message is stored. The event name is `sendMessageAck-<roomId>` where `roomId` matches the value in the originating `sendMessage` payload.
    parameters
    1 field
    roomId
    1 field
    description
    The room ID from the originating sendMessage request.
    messages
    1 field
    sendMessageAckMessage
    2 fields
    name
    sendMessageAckMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessageAckPayload

    sendMessageBroadcast

    sendMessage-{roomId}

    Broadcast emitted to all connections subscribed to `roomId` after a successful `sendMessage`. The event name is `sendMessage-<roomId>`.
    address
    sendMessage-{roomId}
    description
    Broadcast emitted to all connections subscribed to `roomId` after a successful `sendMessage`. The event name is `sendMessage-<roomId>`.
    parameters
    1 field
    roomId
    1 field
    description
    The target room ID.
    messages
    1 field
    sendMessageBroadcastMessage
    2 fields
    name
    sendMessageBroadcastMessage
    payload
    1 field
    $ref
    #/components/schemas/WsSendMessageBroadcastPayload

    messageFailed

    messageFailed

    Emitted to the sender when `sendMessage` processing fails.
    address
    messageFailed
    description
    Emitted to the sender when `sendMessage` processing fails.
    messages
    1 field
    messageFailedMessage
    2 fields
    name
    messageFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/MessageFailedPayload

    paymentFailed

    paymentFailed

    Emitted to unauthenticated sockets that attempt to send a message (same event name reused from older payment-gate logic).
    address
    paymentFailed
    description
    Emitted to unauthenticated sockets that attempt to send a message (same event name reused from older payment-gate logic).
    messages
    1 field
    paymentFailedMessage
    2 fields
    name
    paymentFailedMessage
    payload
    1 field
    $ref
    #/components/schemas/PaymentFailedPayload

    disconnect

    disconnect

    Standard Socket.IO disconnect event. The server removes the socket from the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
    address
    disconnect
    description
    Standard Socket.IO disconnect event. The server removes the socket from the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
    messages
    1 field
    disconnectMessage
    2 fields
    name
    disconnectMessage
    payload
    1 field
    $ref
    #/components/schemas/DisconnectPayload

    Operations

    17

    receiveAuthMessage

    receive
    Server receives an AuthMessage frame from the client during BRC-103 handshake.
    action
    receive
    channel
    1 field
    $ref
    #/channels/authMessage
    summary
    Server receives an AuthMessage frame from the client during BRC-103 handshake.
    messages
    1 item
    1. $ref
      #/channels/authMessage/messages/authMessageFrame

    sendAuthMessage

    send
    Server sends an AuthMessage frame to the client during BRC-103 handshake.
    action
    send
    channel
    1 field
    $ref
    #/channels/authMessage
    summary
    Server sends an AuthMessage frame to the client during BRC-103 handshake.
    messages
    1 item
    1. $ref
      #/channels/authMessage/messages/authMessageFrame

    receiveAuthenticated

    receive
    Server receives the client's identity key on the 'authenticated' event.
    action
    receive
    channel
    1 field
    $ref
    #/channels/authenticated
    summary
    Server receives the client's identity key on the 'authenticated' event.
    messages
    1 item
    1. $ref
      #/channels/authenticated/messages/authenticateMessage

    sendAuthenticationSuccess

    send
    Server confirms successful identity key validation.
    action
    send
    channel
    1 field
    $ref
    #/channels/authenticationSuccess
    summary
    Server confirms successful identity key validation.
    messages
    1 item
    1. $ref
      #/channels/authenticationSuccess/messages/authSuccessMessage

    sendAuthenticationFailed

    send
    Server rejects an invalid identity key.
    action
    send
    channel
    1 field
    $ref
    #/channels/authenticationFailed
    summary
    Server rejects an invalid identity key.
    messages
    1 item
    1. $ref
      #/channels/authenticationFailed/messages/authFailedMessage

    receiveJoinRoom

    receive
    Server receives a room join request.
    action
    receive
    channel
    1 field
    $ref
    #/channels/joinRoom
    summary
    Server receives a room join request.
    messages
    1 item
    1. $ref
      #/channels/joinRoom/messages/joinRoomMessage

    sendJoinedRoom

    send
    Server confirms room join.
    action
    send
    channel
    1 field
    $ref
    #/channels/joinedRoom
    summary
    Server confirms room join.
    messages
    1 item
    1. $ref
      #/channels/joinedRoom/messages/joinedRoomMessage

    sendJoinFailed

    send
    Server signals room join failure.
    action
    send
    channel
    1 field
    $ref
    #/channels/joinFailed
    summary
    Server signals room join failure.
    messages
    1 item
    1. $ref
      #/channels/joinFailed/messages/joinFailedMessage

    receiveLeaveRoom

    receive
    Server receives a room leave request.
    action
    receive
    channel
    1 field
    $ref
    #/channels/leaveRoom
    summary
    Server receives a room leave request.
    messages
    1 item
    1. $ref
      #/channels/leaveRoom/messages/leaveRoomMessage

    sendLeftRoom

    send
    Server confirms room leave.
    action
    send
    channel
    1 field
    $ref
    #/channels/leftRoom
    summary
    Server confirms room leave.
    messages
    1 item
    1. $ref
      #/channels/leftRoom/messages/leftRoomMessage

    sendLeaveFailed

    send
    Server signals room leave failure.
    action
    send
    channel
    1 field
    $ref
    #/channels/leaveFailed
    summary
    Server signals room leave failure.
    messages
    1 item
    1. $ref
      #/channels/leaveFailed/messages/leaveFailedMessage

    receiveSendMessage

    receive
    Server receives a message from the client to deliver to a recipient.
    action
    receive
    channel
    1 field
    $ref
    #/channels/sendMessage
    summary
    Server receives a message from the client to deliver to a recipient.
    messages
    1 item
    1. $ref
      #/channels/sendMessage/messages/sendMessageMessage

    sendSendMessageAck

    send
    Server acknowledges delivery of a message to the sender.
    action
    send
    channel
    1 field
    $ref
    #/channels/sendMessageAck
    summary
    Server acknowledges delivery of a message to the sender.
    messages
    1 item
    1. $ref
      #/channels/sendMessageAck/messages/sendMessageAckMessage

    sendSendMessageBroadcast

    send
    Server broadcasts a new message to all room subscribers.
    action
    send
    channel
    1 field
    $ref
    #/channels/sendMessageBroadcast
    summary
    Server broadcasts a new message to all room subscribers.
    messages
    1 item
    1. $ref
      #/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage

    sendMessageFailed

    send
    Server signals message delivery failure.
    action
    send
    channel
    1 field
    $ref
    #/channels/messageFailed
    summary
    Server signals message delivery failure.
    messages
    1 item
    1. $ref
      #/channels/messageFailed/messages/messageFailedMessage

    sendPaymentFailed

    send
    Server signals auth/payment gate rejection.
    action
    send
    channel
    1 field
    $ref
    #/channels/paymentFailed
    summary
    Server signals auth/payment gate rejection.
    messages
    1 item
    1. $ref
      #/channels/paymentFailed/messages/paymentFailedMessage

    receiveDisconnect

    receive
    Client disconnects; server cleans up in-memory state.
    action
    receive
    channel
    1 field
    $ref
    #/channels/disconnect
    summary
    Client disconnects; server cleans up in-memory state.
    messages
    1 item
    1. $ref
      #/channels/disconnect/messages/disconnectMessage

    Schemas

    18

    PubKeyHex

    Compressed secp256k1 public key, 66 hex characters.
    type
    string
    pattern
    ^0[23][0-9a-fA-F]{64}$
    description
    Compressed secp256k1 public key, 66 hex characters.

    AuthMessage

    BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the low-level `authMessage` Socket.IO event. Not an application-level event.
    type
    object
    description
    BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the low-level `authMessage` Socket.IO event. Not an application-level event.
    required
    3 items
    1. messageType
    2. version
    3. identityKey
    properties
    9 fields
    messageType
    3 fields
    type
    string
    enum
    3 items
    1. initialRequest
    2. initialResponse
    3. general
    description
    - `initialRequest` — first handshake message from initiating peer - `initialResponse` — server's challenge response (includes nonce, signature) - `general` — signed application payload after handshake
    version
    2 fields
    type
    string
    description
    Auth protocol version string.
    identityKey
    1 field
    $ref
    #/components/schemas/PubKeyHex
    nonce
    2 fields
    type
    string
    description
    Fresh random nonce (base64) generated by the sender.
    yourNonce
    2 fields
    type
    string
    description
    Echo of the peer's nonce from the previous message.
    initialNonce
    2 fields
    type
    string
    description
    Present in `initialRequest`; absent in subsequent messages.
    payload
    3 fields
    type
    array
    items
    1 field
    type
    integer
    description
    Signed application payload (byte array). Empty for handshake messages.
    signature
    3 fields
    type
    array
    items
    1 field
    type
    integer
    description
    DER-encoded ECDSA signature over the payload.
    requestedCertificates
    3 fields
    type
    object
    description
    Optional certificate request set (BRC-52 format).
    additionalProperties
    true

    EventEnvelope

    Application-level wrapper JSON-encoded inside the BRC-103 `general` message payload. The `SocketServerTransport` encodes/decodes this transparently; application code only sees `eventName` and `data`.
    type
    object
    description
    Application-level wrapper JSON-encoded inside the BRC-103 `general` message payload. The `SocketServerTransport` encodes/decodes this transparently; application code only sees `eventName` and `data`.
    required
    2 items
    1. eventName
    2. data
    properties
    2 fields
    eventName
    2 fields
    type
    string
    description
    The Socket.IO event name.
    data
    1 field
    description
    The event-specific payload.

    AuthenticatePayload

    Sent by the client on the `authenticated` event when the identity key was not available at connection time (fallback path). The server validates the key and responds with `authenticationSuccess` or `authenticationFailed`.
    type
    object
    description
    Sent by the client on the `authenticated` event when the identity key was not available at connection time (fallback path). The server validates the key and responds with `authenticationSuccess` or `authenticationFailed`.
    properties
    1 field
    identityKey
    1 field
    $ref
    #/components/schemas/PubKeyHex

    AuthSuccessPayload

    type
    object
    required
    1 item
    1. status
    properties
    1 field
    status
    2 fields
    type
    string
    enum
    1 item
    1. success

    AuthFailedPayload

    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    2 fields
    type
    string
    description
    Human-readable reason for failure.

    JoinRoomPayload

    The room ID string sent by the client on the `joinRoom` event. Room IDs use the convention `<recipientKey>-<messageBoxType>`. Example: `028d37b9...-payment_inbox`.
    type
    string
    description
    The room ID string sent by the client on the `joinRoom` event. Room IDs use the convention `<recipientKey>-<messageBoxType>`. Example: `028d37b9...-payment_inbox`.

    JoinedRoomPayload

    type
    object
    required
    1 item
    1. roomId
    properties
    1 field
    roomId
    1 field
    type
    string

    JoinFailedPayload

    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string

    LeaveRoomPayload

    The room ID string sent by the client on the `leaveRoom` event.
    type
    string
    description
    The room ID string sent by the client on the `leaveRoom` event.

    LeftRoomPayload

    type
    object
    required
    1 item
    1. roomId
    properties
    1 field
    roomId
    1 field
    type
    string

    LeaveFailedPayload

    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string

    WsSendMessagePayload

    Payload for the client-to-server `sendMessage` event.
    type
    object
    description
    Payload for the client-to-server `sendMessage` event.
    required
    2 items
    1. roomId
    2. message
    properties
    2 fields
    roomId
    2 fields
    type
    string
    description
    Target room. Format: `<recipientKey>-<messageBoxType>`. The server extracts the `messageBoxType` by splitting on `-` and taking the second part; it uses the authenticated sender key from `authenticatedSockets`.
    message
    3 fields
    type
    object
    required
    3 items
    1. messageId
    2. recipient
    3. body
    properties
    3 fields
    messageId
    2 fields
    type
    string
    description
    Unique identifier for this message (deduplication key).
    recipient
    1 field
    $ref
    #/components/schemas/PubKeyHex
    body
    2 fields
    type
    string
    description
    Message body string.

    WsSendMessageAckPayload

    Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after a successful `sendMessage`. Note: the event name is dynamic and includes the room ID used in the originating request.
    type
    object
    description
    Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after a successful `sendMessage`. Note: the event name is dynamic and includes the room ID used in the originating request.
    required
    2 items
    1. status
    2. messageId
    properties
    2 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. success
    messageId
    1 field
    type
    string

    WsSendMessageBroadcastPayload

    Broadcast emitted by the server on `sendMessage-{roomId}` to all connections in the room (including the sender). Note: the event name is dynamic.
    type
    object
    description
    Broadcast emitted by the server on `sendMessage-{roomId}` to all connections in the room (including the sender). Note: the event name is dynamic.
    required
    3 items
    1. sender
    2. messageId
    3. body
    properties
    3 fields
    sender
    1 field
    $ref
    #/components/schemas/PubKeyHex
    messageId
    1 field
    type
    string
    body
    1 field
    type
    string

    MessageFailedPayload

    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string

    PaymentFailedPayload

    type
    object
    required
    1 item
    1. reason
    properties
    1 field
    reason
    1 field
    type
    string

    DisconnectPayload

    The Socket.IO disconnect reason string (e.g. `transport close`, `server namespace disconnect`).
    type
    string
    description
    The Socket.IO disconnect reason string (e.g. `transport close`, `server namespace disconnect`).
    Raw YAML source
    asyncapi: "3.1.0"
    
    info:
      title: AuthSocket WebSocket Protocol
      version: "1.0.0"
      description: |
        AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket`
        WebSocket channel used by the BSV MessageBox Server.
    
        ## Transport layer
    
        `AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server.
        All Socket.IO events are standard Socket.IO framing; this spec describes
        the *application-level* event names and payload shapes that flow over the
        Socket.IO connection.
    
        ## BRC-103 mutual authentication
    
        Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before
        application events are exchanged. The handshake is carried on the
        **`authMessage`** event using the `AuthMessage` envelope defined in the
        `@bsv/sdk` `Transport` interface.
    
        Once the handshake succeeds the peer's `identityKey` (compressed secp256k1
        public key, 66-char hex) is known server-side and stored in memory for the
        lifetime of the connection.
    
        ## Application events
    
        After authentication the server emits and listens for the events described
        below. All application payloads are serialized as JSON inside the
        BRC-103 `general` message (`Peer.toPeer`). The transport layer
        (`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope
        before signing.
    
        Source of truth:
        - `packages/messaging/authsocket/src/AuthSocketServer.ts`
        - `packages/messaging/authsocket/src/SocketServerTransport.ts`
        - `packages/messaging/message-box-server/src/index.ts`
    
    servers:
      production:
        host: "messagebox.babbage.systems"
        pathname: "/"
        protocol: wss
        description: Production MessageBox WebSocket endpoint (Socket.IO over WSS).
      local:
        host: "localhost:{port}"
        pathname: "/"
        protocol: ws
        description: Local development Socket.IO server.
        variables:
          port:
            default: "5001"
            description: HTTP port the MessageBox Server listens on.
    
    # ---------------------------------------------------------------------------
    # Components
    # ---------------------------------------------------------------------------
    components:
      schemas:
        PubKeyHex:
          type: string
          pattern: "^0[23][0-9a-fA-F]{64}$"
          description: Compressed secp256k1 public key, 66 hex characters.
    
        AuthMessage:
          type: object
          description: |
            BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the
            low-level `authMessage` Socket.IO event. Not an application-level event.
          required: [messageType, version, identityKey]
          properties:
            messageType:
              type: string
              enum: [initialRequest, initialResponse, general]
              description: |
                - `initialRequest`  — first handshake message from initiating peer
                - `initialResponse` — server's challenge response (includes nonce, signature)
                - `general`         — signed application payload after handshake
            version:
              type: string
              description: Auth protocol version string.
            identityKey:
              $ref: "#/components/schemas/PubKeyHex"
            nonce:
              type: string
              description: Fresh random nonce (base64) generated by the sender.
            yourNonce:
              type: string
              description: Echo of the peer's nonce from the previous message.
            initialNonce:
              type: string
              description: Present in `initialRequest`; absent in subsequent messages.
            payload:
              type: array
              items:
                type: integer
              description: Signed application payload (byte array). Empty for handshake messages.
            signature:
              type: array
              items:
                type: integer
              description: DER-encoded ECDSA signature over the payload.
            requestedCertificates:
              type: object
              description: Optional certificate request set (BRC-52 format).
              additionalProperties: true
    
        EventEnvelope:
          type: object
          description: |
            Application-level wrapper JSON-encoded inside the BRC-103 `general`
            message payload. The `SocketServerTransport` encodes/decodes this
            transparently; application code only sees `eventName` and `data`.
          required: [eventName, data]
          properties:
            eventName:
              type: string
              description: The Socket.IO event name.
            data:
              description: The event-specific payload.
    
        # ----- Authentication flow -----
        AuthenticatePayload:
          type: object
          description: |
            Sent by the client on the `authenticated` event when the identity key
            was not available at connection time (fallback path). The server validates
            the key and responds with `authenticationSuccess` or `authenticationFailed`.
          properties:
            identityKey:
              $ref: "#/components/schemas/PubKeyHex"
    
        AuthSuccessPayload:
          type: object
          required: [status]
          properties:
            status:
              type: string
              enum: [success]
    
        AuthFailedPayload:
          type: object
          required: [reason]
          properties:
            reason:
              type: string
              description: Human-readable reason for failure.
    
        # ----- Room management -----
        JoinRoomPayload:
          type: string
          description: |
            The room ID string sent by the client on the `joinRoom` event.
            Room IDs use the convention `<recipientKey>-<messageBoxType>`.
            Example: `028d37b9...-payment_inbox`.
    
        JoinedRoomPayload:
          type: object
          required: [roomId]
          properties:
            roomId:
              type: string
    
        JoinFailedPayload:
          type: object
          required: [reason]
          properties:
            reason:
              type: string
    
        LeaveRoomPayload:
          type: string
          description: The room ID string sent by the client on the `leaveRoom` event.
    
        LeftRoomPayload:
          type: object
          required: [roomId]
          properties:
            roomId:
              type: string
    
        LeaveFailedPayload:
          type: object
          required: [reason]
          properties:
            reason:
              type: string
    
        # ----- Message sending -----
        WsSendMessagePayload:
          type: object
          description: Payload for the client-to-server `sendMessage` event.
          required: [roomId, message]
          properties:
            roomId:
              type: string
              description: |
                Target room. Format: `<recipientKey>-<messageBoxType>`.
                The server extracts the `messageBoxType` by splitting on `-` and
                taking the second part; it uses the authenticated sender key from
                `authenticatedSockets`.
            message:
              type: object
              required: [messageId, recipient, body]
              properties:
                messageId:
                  type: string
                  description: Unique identifier for this message (deduplication key).
                recipient:
                  $ref: "#/components/schemas/PubKeyHex"
                body:
                  type: string
                  description: Message body string.
    
        WsSendMessageAckPayload:
          type: object
          description: |
            Acknowledgement emitted by the server on `sendMessageAck-{roomId}` after
            a successful `sendMessage`. Note: the event name is dynamic and includes
            the room ID used in the originating request.
          required: [status, messageId]
          properties:
            status:
              type: string
              enum: [success]
            messageId:
              type: string
    
        WsSendMessageBroadcastPayload:
          type: object
          description: |
            Broadcast emitted by the server on `sendMessage-{roomId}` to all
            connections in the room (including the sender). Note: the event name
            is dynamic.
          required: [sender, messageId, body]
          properties:
            sender:
              $ref: "#/components/schemas/PubKeyHex"
            messageId:
              type: string
            body:
              type: string
    
        MessageFailedPayload:
          type: object
          required: [reason]
          properties:
            reason:
              type: string
    
        PaymentFailedPayload:
          type: object
          required: [reason]
          properties:
            reason:
              type: string
    
        DisconnectPayload:
          type: string
          description: |
            The Socket.IO disconnect reason string (e.g. `transport close`,
            `server namespace disconnect`).
    
    # ---------------------------------------------------------------------------
    # Channels
    # ---------------------------------------------------------------------------
    channels:
    
      # -------- Low-level auth handshake (BRC-103 / Peer transport) --------
      authMessage:
        address: authMessage
        description: |
          Low-level Socket.IO event used by `SocketServerTransport` to carry
          BRC-103 `AuthMessage` frames. This event is NOT an application event;
          it is emitted and received transparently by the `Peer` class from
          `@bsv/sdk`. Application developers do not interact with this channel
          directly — they use the typed events below.
    
          See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
        messages:
          authMessageFrame:
            name: authMessageFrame
            summary: BRC-103 auth frame (both directions — client and server).
            payload:
              $ref: "#/components/schemas/AuthMessage"
    
      # -------- Application authentication --------
      authenticated:
        address: authenticated
        description: |
          Fallback authentication event. The client emits this when its identity
          key was not included in the Socket.IO handshake. The server validates
          the key, updates its in-memory `authenticatedSockets` map, and emits
          `authenticationSuccess` or `authenticationFailed` in response.
        messages:
          authenticateMessage:
            name: authenticateMessage
            summary: Client sends its identity key for post-connection auth.
            payload:
              $ref: "#/components/schemas/AuthenticatePayload"
    
      authenticationSuccess:
        address: authenticationSuccess
        description: Emitted by the server after successful identity key validation.
        messages:
          authSuccessMessage:
            name: authSuccessMessage
            payload:
              $ref: "#/components/schemas/AuthSuccessPayload"
    
      authenticationFailed:
        address: authenticationFailed
        description: Emitted by the server when identity key validation fails.
        messages:
          authFailedMessage:
            name: authFailedMessage
            payload:
              $ref: "#/components/schemas/AuthFailedPayload"
    
      # -------- Room management --------
      joinRoom:
        address: joinRoom
        description: |
          Client requests to subscribe to a room. Only authenticated sockets may
          join rooms. The server responds with `joinedRoom` on success or
          `joinFailed` on error.
    
          Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
        messages:
          joinRoomMessage:
            name: joinRoomMessage
            summary: Room ID string to join.
            payload:
              $ref: "#/components/schemas/JoinRoomPayload"
    
      joinedRoom:
        address: joinedRoom
        description: Server confirms the client has joined the specified room.
        messages:
          joinedRoomMessage:
            name: joinedRoomMessage
            payload:
              $ref: "#/components/schemas/JoinedRoomPayload"
    
      joinFailed:
        address: joinFailed
        description: Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
        messages:
          joinFailedMessage:
            name: joinFailedMessage
            payload:
              $ref: "#/components/schemas/JoinFailedPayload"
    
      leaveRoom:
        address: leaveRoom
        description: Client requests to leave a room.
        messages:
          leaveRoomMessage:
            name: leaveRoomMessage
            summary: Room ID string to leave.
            payload:
              $ref: "#/components/schemas/LeaveRoomPayload"
    
      leftRoom:
        address: leftRoom
        description: Server confirms the client has left the room.
        messages:
          leftRoomMessage:
            name: leftRoomMessage
            payload:
              $ref: "#/components/schemas/LeftRoomPayload"
    
      leaveFailed:
        address: leaveFailed
        description: Emitted when `leaveRoom` fails.
        messages:
          leaveFailedMessage:
            name: leaveFailedMessage
            payload:
              $ref: "#/components/schemas/LeaveFailedPayload"
    
      # -------- Message sending --------
      sendMessage:
        address: sendMessage
        description: |
          Client sends a message to a recipient via WebSocket. The server:
          1. Validates the sender is authenticated.
          2. Validates `roomId` and `message`.
          3. Creates the message box if it does not exist.
          4. Inserts the message into the database (with ON CONFLICT IGNORE dedup).
          5. Emits `sendMessageAck-{roomId}` back to the sender.
          6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
        messages:
          sendMessageMessage:
            name: sendMessageMessage
            payload:
              $ref: "#/components/schemas/WsSendMessagePayload"
    
      sendMessageAck:
        address: "sendMessageAck-{roomId}"
        description: |
          Per-room acknowledgement emitted to the sender only after the message
          is stored. The event name is `sendMessageAck-<roomId>` where `roomId`
          matches the value in the originating `sendMessage` payload.
        parameters:
          roomId:
            description: The room ID from the originating sendMessage request.
        messages:
          sendMessageAckMessage:
            name: sendMessageAckMessage
            payload:
              $ref: "#/components/schemas/WsSendMessageAckPayload"
    
      sendMessageBroadcast:
        address: "sendMessage-{roomId}"
        description: |
          Broadcast emitted to all connections subscribed to `roomId` after a
          successful `sendMessage`. The event name is `sendMessage-<roomId>`.
        parameters:
          roomId:
            description: The target room ID.
        messages:
          sendMessageBroadcastMessage:
            name: sendMessageBroadcastMessage
            payload:
              $ref: "#/components/schemas/WsSendMessageBroadcastPayload"
    
      messageFailed:
        address: messageFailed
        description: Emitted to the sender when `sendMessage` processing fails.
        messages:
          messageFailedMessage:
            name: messageFailedMessage
            payload:
              $ref: "#/components/schemas/MessageFailedPayload"
    
      paymentFailed:
        address: paymentFailed
        description: |
          Emitted to unauthenticated sockets that attempt to send a message
          (same event name reused from older payment-gate logic).
        messages:
          paymentFailedMessage:
            name: paymentFailedMessage
            payload:
              $ref: "#/components/schemas/PaymentFailedPayload"
    
      # -------- Lifecycle --------
      disconnect:
        address: disconnect
        description: |
          Standard Socket.IO disconnect event. The server removes the socket from
          the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
        messages:
          disconnectMessage:
            name: disconnectMessage
            payload:
              $ref: "#/components/schemas/DisconnectPayload"
    
    # ---------------------------------------------------------------------------
    # Operations
    # ---------------------------------------------------------------------------
    operations:
    
      # --- Auth handshake (transport-level, both directions) ---
      receiveAuthMessage:
        action: receive
        channel:
          $ref: "#/channels/authMessage"
        summary: Server receives an AuthMessage frame from the client during BRC-103 handshake.
        messages:
          - $ref: "#/channels/authMessage/messages/authMessageFrame"
    
      sendAuthMessage:
        action: send
        channel:
          $ref: "#/channels/authMessage"
        summary: Server sends an AuthMessage frame to the client during BRC-103 handshake.
        messages:
          - $ref: "#/channels/authMessage/messages/authMessageFrame"
    
      # --- Client authentication ---
      receiveAuthenticated:
        action: receive
        channel:
          $ref: "#/channels/authenticated"
        summary: Server receives the client's identity key on the 'authenticated' event.
        messages:
          - $ref: "#/channels/authenticated/messages/authenticateMessage"
    
      sendAuthenticationSuccess:
        action: send
        channel:
          $ref: "#/channels/authenticationSuccess"
        summary: Server confirms successful identity key validation.
        messages:
          - $ref: "#/channels/authenticationSuccess/messages/authSuccessMessage"
    
      sendAuthenticationFailed:
        action: send
        channel:
          $ref: "#/channels/authenticationFailed"
        summary: Server rejects an invalid identity key.
        messages:
          - $ref: "#/channels/authenticationFailed/messages/authFailedMessage"
    
      # --- Room management ---
      receiveJoinRoom:
        action: receive
        channel:
          $ref: "#/channels/joinRoom"
        summary: Server receives a room join request.
        messages:
          - $ref: "#/channels/joinRoom/messages/joinRoomMessage"
    
      sendJoinedRoom:
        action: send
        channel:
          $ref: "#/channels/joinedRoom"
        summary: Server confirms room join.
        messages:
          - $ref: "#/channels/joinedRoom/messages/joinedRoomMessage"
    
      sendJoinFailed:
        action: send
        channel:
          $ref: "#/channels/joinFailed"
        summary: Server signals room join failure.
        messages:
          - $ref: "#/channels/joinFailed/messages/joinFailedMessage"
    
      receiveLeaveRoom:
        action: receive
        channel:
          $ref: "#/channels/leaveRoom"
        summary: Server receives a room leave request.
        messages:
          - $ref: "#/channels/leaveRoom/messages/leaveRoomMessage"
    
      sendLeftRoom:
        action: send
        channel:
          $ref: "#/channels/leftRoom"
        summary: Server confirms room leave.
        messages:
          - $ref: "#/channels/leftRoom/messages/leftRoomMessage"
    
      sendLeaveFailed:
        action: send
        channel:
          $ref: "#/channels/leaveFailed"
        summary: Server signals room leave failure.
        messages:
          - $ref: "#/channels/leaveFailed/messages/leaveFailedMessage"
    
      # --- Message sending ---
      receiveSendMessage:
        action: receive
        channel:
          $ref: "#/channels/sendMessage"
        summary: Server receives a message from the client to deliver to a recipient.
        messages:
          - $ref: "#/channels/sendMessage/messages/sendMessageMessage"
    
      sendSendMessageAck:
        action: send
        channel:
          $ref: "#/channels/sendMessageAck"
        summary: Server acknowledges delivery of a message to the sender.
        messages:
          - $ref: "#/channels/sendMessageAck/messages/sendMessageAckMessage"
    
      sendSendMessageBroadcast:
        action: send
        channel:
          $ref: "#/channels/sendMessageBroadcast"
        summary: Server broadcasts a new message to all room subscribers.
        messages:
          - $ref: "#/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage"
    
      sendMessageFailed:
        action: send
        channel:
          $ref: "#/channels/messageFailed"
        summary: Server signals message delivery failure.
        messages:
          - $ref: "#/channels/messageFailed/messages/messageFailedMessage"
    
      sendPaymentFailed:
        action: send
        channel:
          $ref: "#/channels/paymentFailed"
        summary: Server signals auth/payment gate rejection.
        messages:
          - $ref: "#/channels/paymentFailed/messages/paymentFailedMessage"
    
      # --- Lifecycle ---
      receiveDisconnect:
        action: receive
        channel:
          $ref: "#/channels/disconnect"
        summary: Client disconnects; server cleans up in-memory state.
        messages:
          - $ref: "#/channels/disconnect/messages/disconnectMessage"
    
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    \ No newline at end of file diff --git a/docs-site/public/assets/asyncapi/brc29/index.html b/docs-site/public/assets/asyncapi/brc29/index.html index 94a49e174..596c8deaa 100644 --- a/docs-site/public/assets/asyncapi/brc29/index.html +++ b/docs-site/public/assets/asyncapi/brc29/index.html @@ -1,529 +1 @@ - - - - - - - BRC-29 Simple Authenticated BSV P2PKH Payment Protocol · AsyncAPI - - - -
    -
    AsyncAPI 3.1.0 · specs/payments/brc29-payment-protocol.yaml
    -

    BRC-29 Simple Authenticated BSV P2PKH Payment Protocol

    v1.0.0
    -
    Specifies the peer-to-peer payment flow defined in BRC-29, including -BRC-42 key derivation prefix/suffix negotiation, the current Atomic BEEF -payment message, and the BRC-100 internalizeAction remittance envelope. - -The older BRC-8 extended-envelope format (the `transactions` array) is -deprecated for new integrations; only the current BRC-100 / Atomic BEEF -transport is modelled here. - -Source of truth: /docs/BRCs/payments/0029.md -
    -
    0Servers2Channels2Operations2Messages8Schemas
    -
    - -
    -
    -

    Channels

    2
    -
    -

    paymentSend

    -

    payment/send

    -
    Logical channel representing a sender delivering a BRC-29 payment message -to a recipient. In practice this is carried over whatever higher-level -transport the application chooses (HTTP POST, WebSocket, BRC-104 message -box, etc.). The channel models the one-way delivery of the payment. -
    -
    address
    payment/send
    description
    Logical channel representing a sender delivering a BRC-29 payment message -to a recipient. In practice this is carried over whatever higher-level -transport the application chooses (HTTP POST, WebSocket, BRC-104 message -box, etc.). The channel models the one-way delivery of the payment. -
    messages
    1 field
    paymentMessage
    1 field
    $ref
    #/components/messages/PaymentMessage
    -
    -

    paymentAcknowledge

    -

    payment/acknowledge

    -
    Logical channel representing the recipient acknowledging acceptance or -rejection of the incoming payment after calling internalizeAction. -
    -
    address
    payment/acknowledge
    description
    Logical channel representing the recipient acknowledging acceptance or -rejection of the incoming payment after calling internalizeAction. -
    messages
    1 field
    paymentAck
    1 field
    $ref
    #/components/messages/PaymentAck
    -
    -
    -

    Operations

    2
    -
    -

    sendPayment

    - send -
    Sender delivers a BRC-29 payment message to the recipient.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/paymentSend
    summary
    Sender delivers a BRC-29 payment message to the recipient.
    messages
    1 item
    1. $ref
      #/channels/paymentSend/messages/paymentMessage
    -
    -

    receiveAck

    - receive -
    Sender receives payment acceptance or rejection from the recipient.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/paymentAcknowledge
    summary
    Sender receives payment acceptance or rejection from the recipient.
    messages
    1 item
    1. $ref
      #/channels/paymentAcknowledge/messages/paymentAck
    -
    -
    -

    Messages

    2
    -
    -

    PaymentMessage

    - -
    Current (BRC-100 / Atomic BEEF) payment message sent from the payer to -the payee. Carries one transaction with one or more P2PKH outputs -derived via BRC-42 key derivation using the invoice number format -`2-3241645161d8-<derivationPrefix> <derivationSuffix>`. -
    -
    name
    PaymentMessage
    title
    BRC-29 Payment Message
    summary
    Current (BRC-100 / Atomic BEEF) payment message sent from the payer to -the payee. Carries one transaction with one or more P2PKH outputs -derived via BRC-42 key derivation using the invoice number format -`2-3241645161d8-<derivationPrefix> <derivationSuffix>`. -
    payload
    1 field
    $ref
    #/components/schemas/PaymentMessage
    -
    -

    PaymentAck

    - -
    Informal acknowledgement returned by the recipient after calling -BRC-100 internalizeAction. No mandatory wire format is defined by -BRC-29; the shape below is the conventional minimal envelope. -
    -
    name
    PaymentAck
    title
    Payment Acknowledgement
    summary
    Informal acknowledgement returned by the recipient after calling -BRC-100 internalizeAction. No mandatory wire format is defined by -BRC-29; the shape below is the conventional minimal envelope. -
    payload
    1 field
    $ref
    #/components/schemas/PaymentAck
    -
    -
    -

    Schemas

    8
    -
    -

    PaymentMessage

    - -
    Payment message delivered from sender to recipient. The `transaction` -field carries a base64-encoded Atomic BEEF blob (BRC-95). For payments -containing multiple outputs each output MUST carry its own -derivationSuffix and outputIndex so the recipient can recover the -correct P2PKH private key for each UTXO. -
    -
    type
    object
    description
    Payment message delivered from sender to recipient. The `transaction` -field carries a base64-encoded Atomic BEEF blob (BRC-95). For payments -containing multiple outputs each output MUST carry its own -derivationSuffix and outputIndex so the recipient can recover the -correct P2PKH private key for each UTXO. -
    required
    3 items
    1. derivationPrefix
    2. derivationSuffix
    3. transaction
    properties
    5 fields
    derivationPrefix
    3 fields
    type
    string
    description
    Payment-wide random nonce (base64-encoded, BRC-29 §3). -Uniquely identifies this payment across all outputs. -
    example
    3q2+7w==
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific random nonce (base64-encoded). -Uniquely identifies a single output within this payment. -For multi-output payments, use the `outputs` array instead. -
    example
    iMba2Q==
    transaction
    3 fields
    type
    string
    description
    Base64-encoded Atomic BEEF (BRC-95) containing the signed BSV -transaction with one or more P2PKH outputs for the recipient. -
    example
    <base64-encoded-BEEF>
    outputs
    3 fields
    type
    array
    description
    Present when multiple outputs belong to the same payment. Each -element describes one P2PKH output intended for the recipient. -When this array is absent, `derivationSuffix` at the top level -refers to output index 0. -
    items
    1 field
    $ref
    #/components/schemas/PaymentOutputDescriptor
    senderIdentityKey
    3 fields
    type
    string
    description
    Hex-encoded compressed secp256k1 identity public key of the sender. -SHOULD be included so the recipient can verify key derivation and -include it in the internalizeAction remittance. -
    example
    02abc123...
    -
    -

    PaymentOutputDescriptor

    - -
    Describes one P2PKH output within a multi-output BRC-29 payment.
    -
    type
    object
    description
    Describes one P2PKH output within a multi-output BRC-29 payment.
    required
    2 items
    1. outputIndex
    2. derivationSuffix
    properties
    2 fields
    outputIndex
    3 fields
    type
    integer
    minimum
    0
    description
    Zero-based output index within the transaction.
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific nonce for this output (base64-encoded).
    example
    X9k4LA==
    -
    -

    Brc42InvoiceNumber

    - -
    BRC-42 invoice number used to derive the recipient's P2PKH key for each -output. Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>` -where: - - `2` = security level (BRC-43) - - `3241645161d8` = BRC-29 magic number - - derivationPrefix / derivationSuffix are the values from the message -
    -
    type
    string
    description
    BRC-42 invoice number used to derive the recipient's P2PKH key for each -output. Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>` -where: - - `2` = security level (BRC-43) - - `3241645161d8` = BRC-29 magic number - - derivationPrefix / derivationSuffix are the values from the message -
    pattern
    ^2-3241645161d8-[A-Za-z0-9+/=]+ [A-Za-z0-9+/=]+$
    example
    2-3241645161d8-3q2+7w== iMba2Q==
    -
    -

    PaymentRemittance

    - -
    Remittance object passed to BRC-100 `internalizeAction` for each -payment output. The recipient's wallet uses these fields to derive -the private key and credit the UTXO. -
    -
    type
    object
    description
    Remittance object passed to BRC-100 `internalizeAction` for each -payment output. The recipient's wallet uses these fields to derive -the private key and credit the UTXO. -
    required
    3 items
    1. derivationPrefix
    2. derivationSuffix
    3. senderIdentityKey
    properties
    3 fields
    derivationPrefix
    3 fields
    type
    string
    description
    Payment-wide derivation prefix (base64-encoded).
    example
    3q2+7w==
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific derivation suffix (base64-encoded).
    example
    iMba2Q==
    senderIdentityKey
    3 fields
    type
    string
    description
    Hex-encoded compressed secp256k1 identity public key of the sender.
    example
    02abc123...
    -
    -

    InternalizeActionArgs

    - -
    Arguments passed to the BRC-100 `internalizeAction` wallet method by -the recipient when processing an incoming BRC-29 payment. -
    -
    type
    object
    description
    Arguments passed to the BRC-100 `internalizeAction` wallet method by -the recipient when processing an incoming BRC-29 payment. -
    required
    3 items
    1. tx
    2. outputs
    3. description
    properties
    3 fields
    tx
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    Raw Atomic BEEF bytes of the payment transaction.
    outputs
    4 fields
    type
    array
    minItems
    1
    items
    1 field
    $ref
    #/components/schemas/InternalizeOutput
    description
    One entry per P2PKH output intended for this recipient.
    description
    3 fields
    type
    string
    description
    Human-readable description of the payment.
    example
    Incoming BRC-29 payment
    -
    -

    InternalizeOutput

    - - -
    type
    object
    required
    3 items
    1. outputIndex
    2. protocol
    3. paymentRemittance
    properties
    3 fields
    outputIndex
    3 fields
    type
    integer
    minimum
    0
    description
    Zero-based output index within the transaction.
    protocol
    3 fields
    type
    string
    enum
    1 item
    1. wallet payment
    description
    Protocol identifier understood by BRC-100 wallets.
    paymentRemittance
    1 field
    $ref
    #/components/schemas/PaymentRemittance
    -
    -

    PaymentAck

    - -
    Minimal response returned to the sender after the recipient has called -`internalizeAction`. BRC-29 does not mandate a wire format; this is -the conventional shape used by ts-sdk integrations. -
    -
    type
    object
    description
    Minimal response returned to the sender after the recipient has called -`internalizeAction`. BRC-29 does not mandate a wire format; this is -the conventional shape used by ts-sdk integrations. -
    required
    1 item
    1. accepted
    properties
    3 fields
    accepted
    2 fields
    type
    boolean
    description
    true if internalizeAction succeeded and the payment was credited.
    txid
    3 fields
    type
    string
    description
    Txid of the accepted transaction (hex, 64 characters).
    pattern
    ^[0-9a-fA-F]{64}$
    error
    2 fields
    type
    string
    description
    Human-readable error message if `accepted` is false. Only present -on rejection. -
    -
    -

    LegacyPaymentEnvelope

    - -
    **Deprecated.** The original BRC-8 extended-envelope format. New -integrations MUST NOT use this format; use `PaymentMessage` instead. -Documented here only for backwards-compatibility reference. -
    -
    type
    object
    deprecated
    true
    description
    **Deprecated.** The original BRC-8 extended-envelope format. New -integrations MUST NOT use this format; use `PaymentMessage` instead. -Documented here only for backwards-compatibility reference. -
    required
    4 items
    1. protocol
    2. senderIdentityKey
    3. derivationPrefix
    4. transactions
    properties
    4 fields
    protocol
    2 fields
    type
    string
    enum
    1 item
    1. 3241645161d8
    senderIdentityKey
    2 fields
    type
    string
    description
    Hex-encoded sender identity public key.
    derivationPrefix
    2 fields
    type
    string
    description
    Payment-wide derivation prefix.
    transactions
    3 fields
    type
    array
    description
    Array of extended BRC-8 transaction envelopes.
    items
    2 fields
    type
    object
    description
    Extended BRC-8 transaction envelope (schema omitted — deprecated).
    -
    -
    -
    - Raw YAML source -
    asyncapi: "3.1.0"
    -
    -info:
    -  title: BRC-29 Simple Authenticated BSV P2PKH Payment Protocol
    -  version: "1.0.0"
    -  description: |
    -    Specifies the peer-to-peer payment flow defined in BRC-29, including
    -    BRC-42 key derivation prefix/suffix negotiation, the current Atomic BEEF
    -    payment message, and the BRC-100 internalizeAction remittance envelope.
    -
    -    The older BRC-8 extended-envelope format (the `transactions` array) is
    -    deprecated for new integrations; only the current BRC-100 / Atomic BEEF
    -    transport is modelled here.
    -
    -    Source of truth: /docs/BRCs/payments/0029.md
    -  license:
    -    name: Open BSV Licence
    -
    -defaultContentType: application/json
    -
    -# ---------------------------------------------------------------------------
    -# Channels
    -# ---------------------------------------------------------------------------
    -channels:
    -  paymentSend:
    -    address: payment/send
    -    description: |
    -      Logical channel representing a sender delivering a BRC-29 payment message
    -      to a recipient.  In practice this is carried over whatever higher-level
    -      transport the application chooses (HTTP POST, WebSocket, BRC-104 message
    -      box, etc.).  The channel models the one-way delivery of the payment.
    -    messages:
    -      paymentMessage:
    -        $ref: "#/components/messages/PaymentMessage"
    -
    -  paymentAcknowledge:
    -    address: payment/acknowledge
    -    description: |
    -      Logical channel representing the recipient acknowledging acceptance or
    -      rejection of the incoming payment after calling internalizeAction.
    -    messages:
    -      paymentAck:
    -        $ref: "#/components/messages/PaymentAck"
    -
    -# ---------------------------------------------------------------------------
    -# Operations
    -# ---------------------------------------------------------------------------
    -operations:
    -  sendPayment:
    -    action: send
    -    channel:
    -      $ref: "#/channels/paymentSend"
    -    summary: Sender delivers a BRC-29 payment message to the recipient.
    -    messages:
    -      - $ref: "#/channels/paymentSend/messages/paymentMessage"
    -
    -  receiveAck:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/paymentAcknowledge"
    -    summary: Sender receives payment acceptance or rejection from the recipient.
    -    messages:
    -      - $ref: "#/channels/paymentAcknowledge/messages/paymentAck"
    -
    -# ---------------------------------------------------------------------------
    -# Components
    -# ---------------------------------------------------------------------------
    -components:
    -  messages:
    -    PaymentMessage:
    -      name: PaymentMessage
    -      title: BRC-29 Payment Message
    -      summary: |
    -        Current (BRC-100 / Atomic BEEF) payment message sent from the payer to
    -        the payee.  Carries one transaction with one or more P2PKH outputs
    -        derived via BRC-42 key derivation using the invoice number format
    -        `2-3241645161d8-<derivationPrefix> <derivationSuffix>`.
    -      payload:
    -        $ref: "#/components/schemas/PaymentMessage"
    -
    -    PaymentAck:
    -      name: PaymentAck
    -      title: Payment Acknowledgement
    -      summary: |
    -        Informal acknowledgement returned by the recipient after calling
    -        BRC-100 internalizeAction.  No mandatory wire format is defined by
    -        BRC-29; the shape below is the conventional minimal envelope.
    -      payload:
    -        $ref: "#/components/schemas/PaymentAck"
    -
    -  schemas:
    -    # -----------------------------------------------------------------------
    -    # PaymentMessage — single-output form (multi-output uses array variant)
    -    # -----------------------------------------------------------------------
    -    PaymentMessage:
    -      type: object
    -      description: |
    -        Payment message delivered from sender to recipient.  The `transaction`
    -        field carries a base64-encoded Atomic BEEF blob (BRC-95).  For payments
    -        containing multiple outputs each output MUST carry its own
    -        derivationSuffix and outputIndex so the recipient can recover the
    -        correct P2PKH private key for each UTXO.
    -      required:
    -        - derivationPrefix
    -        - derivationSuffix
    -        - transaction
    -      properties:
    -        derivationPrefix:
    -          type: string
    -          description: |
    -            Payment-wide random nonce (base64-encoded, BRC-29 §3).
    -            Uniquely identifies this payment across all outputs.
    -          example: "3q2+7w=="
    -        derivationSuffix:
    -          type: string
    -          description: |
    -            UTXO-specific random nonce (base64-encoded).
    -            Uniquely identifies a single output within this payment.
    -            For multi-output payments, use the `outputs` array instead.
    -          example: "iMba2Q=="
    -        transaction:
    -          type: string
    -          description: |
    -            Base64-encoded Atomic BEEF (BRC-95) containing the signed BSV
    -            transaction with one or more P2PKH outputs for the recipient.
    -          example: "<base64-encoded-BEEF>"
    -        outputs:
    -          type: array
    -          description: |
    -            Present when multiple outputs belong to the same payment.  Each
    -            element describes one P2PKH output intended for the recipient.
    -            When this array is absent, `derivationSuffix` at the top level
    -            refers to output index 0.
    -          items:
    -            $ref: "#/components/schemas/PaymentOutputDescriptor"
    -        senderIdentityKey:
    -          type: string
    -          description: |
    -            Hex-encoded compressed secp256k1 identity public key of the sender.
    -            SHOULD be included so the recipient can verify key derivation and
    -            include it in the internalizeAction remittance.
    -          example: "02abc123..."
    -
    -    PaymentOutputDescriptor:
    -      type: object
    -      description: Describes one P2PKH output within a multi-output BRC-29 payment.
    -      required:
    -        - outputIndex
    -        - derivationSuffix
    -      properties:
    -        outputIndex:
    -          type: integer
    -          minimum: 0
    -          description: Zero-based output index within the transaction.
    -        derivationSuffix:
    -          type: string
    -          description: UTXO-specific nonce for this output (base64-encoded).
    -          example: "X9k4LA=="
    -
    -    # -----------------------------------------------------------------------
    -    # Key-derivation invoice number (informational)
    -    # -----------------------------------------------------------------------
    -    Brc42InvoiceNumber:
    -      type: string
    -      description: |
    -        BRC-42 invoice number used to derive the recipient's P2PKH key for each
    -        output.  Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>`
    -        where:
    -          - `2`             = security level (BRC-43)
    -          - `3241645161d8`  = BRC-29 magic number
    -          - derivationPrefix / derivationSuffix are the values from the message
    -      pattern: "^2-3241645161d8-[A-Za-z0-9+/=]+ [A-Za-z0-9+/=]+$"
    -      example: "2-3241645161d8-3q2+7w== iMba2Q=="
    -
    -    # -----------------------------------------------------------------------
    -    # internalizeAction remittance (as passed by the recipient's wallet)
    -    # -----------------------------------------------------------------------
    -    PaymentRemittance:
    -      type: object
    -      description: |
    -        Remittance object passed to BRC-100 `internalizeAction` for each
    -        payment output.  The recipient's wallet uses these fields to derive
    -        the private key and credit the UTXO.
    -      required:
    -        - derivationPrefix
    -        - derivationSuffix
    -        - senderIdentityKey
    -      properties:
    -        derivationPrefix:
    -          type: string
    -          description: Payment-wide derivation prefix (base64-encoded).
    -          example: "3q2+7w=="
    -        derivationSuffix:
    -          type: string
    -          description: UTXO-specific derivation suffix (base64-encoded).
    -          example: "iMba2Q=="
    -        senderIdentityKey:
    -          type: string
    -          description: Hex-encoded compressed secp256k1 identity public key of the sender.
    -          example: "02abc123..."
    -
    -    # -----------------------------------------------------------------------
    -    # Full internalizeAction args shape (BRC-100)
    -    # -----------------------------------------------------------------------
    -    InternalizeActionArgs:
    -      type: object
    -      description: |
    -        Arguments passed to the BRC-100 `internalizeAction` wallet method by
    -        the recipient when processing an incoming BRC-29 payment.
    -      required:
    -        - tx
    -        - outputs
    -        - description
    -      properties:
    -        tx:
    -          type: array
    -          items:
    -            type: integer
    -            minimum: 0
    -            maximum: 255
    -          description: Raw Atomic BEEF bytes of the payment transaction.
    -        outputs:
    -          type: array
    -          minItems: 1
    -          items:
    -            $ref: "#/components/schemas/InternalizeOutput"
    -          description: One entry per P2PKH output intended for this recipient.
    -        description:
    -          type: string
    -          description: Human-readable description of the payment.
    -          example: "Incoming BRC-29 payment"
    -
    -    InternalizeOutput:
    -      type: object
    -      required:
    -        - outputIndex
    -        - protocol
    -        - paymentRemittance
    -      properties:
    -        outputIndex:
    -          type: integer
    -          minimum: 0
    -          description: Zero-based output index within the transaction.
    -        protocol:
    -          type: string
    -          enum:
    -            - "wallet payment"
    -          description: Protocol identifier understood by BRC-100 wallets.
    -        paymentRemittance:
    -          $ref: "#/components/schemas/PaymentRemittance"
    -
    -    # -----------------------------------------------------------------------
    -    # Acknowledgement
    -    # -----------------------------------------------------------------------
    -    PaymentAck:
    -      type: object
    -      description: |
    -        Minimal response returned to the sender after the recipient has called
    -        `internalizeAction`.  BRC-29 does not mandate a wire format; this is
    -        the conventional shape used by ts-sdk integrations.
    -      required:
    -        - accepted
    -      properties:
    -        accepted:
    -          type: boolean
    -          description: true if internalizeAction succeeded and the payment was credited.
    -        txid:
    -          type: string
    -          description: Txid of the accepted transaction (hex, 64 characters).
    -          pattern: "^[0-9a-fA-F]{64}$"
    -        error:
    -          type: string
    -          description: |
    -            Human-readable error message if `accepted` is false.  Only present
    -            on rejection.
    -
    -    # -----------------------------------------------------------------------
    -    # Legacy (deprecated) payment envelope — documented for compatibility only
    -    # -----------------------------------------------------------------------
    -    LegacyPaymentEnvelope:
    -      type: object
    -      deprecated: true
    -      description: |
    -        **Deprecated.** The original BRC-8 extended-envelope format.  New
    -        integrations MUST NOT use this format; use `PaymentMessage` instead.
    -        Documented here only for backwards-compatibility reference.
    -      required:
    -        - protocol
    -        - senderIdentityKey
    -        - derivationPrefix
    -        - transactions
    -      properties:
    -        protocol:
    -          type: string
    -          enum:
    -            - "3241645161d8"
    -        senderIdentityKey:
    -          type: string
    -          description: Hex-encoded sender identity public key.
    -        derivationPrefix:
    -          type: string
    -          description: Payment-wide derivation prefix.
    -        transactions:
    -          type: array
    -          description: Array of extended BRC-8 transaction envelopes.
    -          items:
    -            type: object
    -            description: Extended BRC-8 transaction envelope (schema omitted — deprecated).
    -
    -
    -
    -
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    - - +BRC-29 Simple Authenticated BSV P2PKH Payment Protocol · AsyncAPI
    AsyncAPI 3.1.0 · specs/payments/brc29-payment-protocol.yaml

    BRC-29 Simple Authenticated BSV P2PKH Payment Protocol

    v1.0.0
    Specifies the peer-to-peer payment flow defined in BRC-29, including BRC-42 key derivation prefix/suffix negotiation, the current Atomic BEEF payment message, and the BRC-100 internalizeAction remittance envelope. The older BRC-8 extended-envelope format (the `transactions` array) is deprecated for new integrations; only the current BRC-100 / Atomic BEEF transport is modelled here. Source of truth: /docs/BRCs/payments/0029.md
    0Servers2Channels2Operations2Messages8Schemas

    Channels

    2

    paymentSend

    payment/send

    Logical channel representing a sender delivering a BRC-29 payment message to a recipient. In practice this is carried over whatever higher-level transport the application chooses (HTTP POST, WebSocket, BRC-104 message box, etc.). The channel models the one-way delivery of the payment.
    address
    payment/send
    description
    Logical channel representing a sender delivering a BRC-29 payment message to a recipient. In practice this is carried over whatever higher-level transport the application chooses (HTTP POST, WebSocket, BRC-104 message box, etc.). The channel models the one-way delivery of the payment.
    messages
    1 field
    paymentMessage
    1 field
    $ref
    #/components/messages/PaymentMessage

    paymentAcknowledge

    payment/acknowledge

    Logical channel representing the recipient acknowledging acceptance or rejection of the incoming payment after calling internalizeAction.
    address
    payment/acknowledge
    description
    Logical channel representing the recipient acknowledging acceptance or rejection of the incoming payment after calling internalizeAction.
    messages
    1 field
    paymentAck
    1 field
    $ref
    #/components/messages/PaymentAck

    Operations

    2

    sendPayment

    send
    Sender delivers a BRC-29 payment message to the recipient.
    action
    send
    channel
    1 field
    $ref
    #/channels/paymentSend
    summary
    Sender delivers a BRC-29 payment message to the recipient.
    messages
    1 item
    1. $ref
      #/channels/paymentSend/messages/paymentMessage

    receiveAck

    receive
    Sender receives payment acceptance or rejection from the recipient.
    action
    receive
    channel
    1 field
    $ref
    #/channels/paymentAcknowledge
    summary
    Sender receives payment acceptance or rejection from the recipient.
    messages
    1 item
    1. $ref
      #/channels/paymentAcknowledge/messages/paymentAck

    Messages

    2

    PaymentMessage

    Current (BRC-100 / Atomic BEEF) payment message sent from the payer to the payee. Carries one transaction with one or more P2PKH outputs derived via BRC-42 key derivation using the invoice number format `2-3241645161d8-<derivationPrefix> <derivationSuffix>`.
    name
    PaymentMessage
    title
    BRC-29 Payment Message
    summary
    Current (BRC-100 / Atomic BEEF) payment message sent from the payer to the payee. Carries one transaction with one or more P2PKH outputs derived via BRC-42 key derivation using the invoice number format `2-3241645161d8-<derivationPrefix> <derivationSuffix>`.
    payload
    1 field
    $ref
    #/components/schemas/PaymentMessage

    PaymentAck

    Informal acknowledgement returned by the recipient after calling BRC-100 internalizeAction. No mandatory wire format is defined by BRC-29; the shape below is the conventional minimal envelope.
    name
    PaymentAck
    title
    Payment Acknowledgement
    summary
    Informal acknowledgement returned by the recipient after calling BRC-100 internalizeAction. No mandatory wire format is defined by BRC-29; the shape below is the conventional minimal envelope.
    payload
    1 field
    $ref
    #/components/schemas/PaymentAck

    Schemas

    8

    PaymentMessage

    Payment message delivered from sender to recipient. The `transaction` field carries a base64-encoded Atomic BEEF blob (BRC-95). For payments containing multiple outputs each output MUST carry its own derivationSuffix and outputIndex so the recipient can recover the correct P2PKH private key for each UTXO.
    type
    object
    description
    Payment message delivered from sender to recipient. The `transaction` field carries a base64-encoded Atomic BEEF blob (BRC-95). For payments containing multiple outputs each output MUST carry its own derivationSuffix and outputIndex so the recipient can recover the correct P2PKH private key for each UTXO.
    required
    3 items
    1. derivationPrefix
    2. derivationSuffix
    3. transaction
    properties
    5 fields
    derivationPrefix
    3 fields
    type
    string
    description
    Payment-wide random nonce (base64-encoded, BRC-29 §3). Uniquely identifies this payment across all outputs.
    example
    3q2+7w==
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific random nonce (base64-encoded). Uniquely identifies a single output within this payment. For multi-output payments, use the `outputs` array instead.
    example
    iMba2Q==
    transaction
    3 fields
    type
    string
    description
    Base64-encoded Atomic BEEF (BRC-95) containing the signed BSV transaction with one or more P2PKH outputs for the recipient.
    example
    <base64-encoded-BEEF>
    outputs
    3 fields
    type
    array
    description
    Present when multiple outputs belong to the same payment. Each element describes one P2PKH output intended for the recipient. When this array is absent, `derivationSuffix` at the top level refers to output index 0.
    items
    1 field
    $ref
    #/components/schemas/PaymentOutputDescriptor
    senderIdentityKey
    3 fields
    type
    string
    description
    Hex-encoded compressed secp256k1 identity public key of the sender. SHOULD be included so the recipient can verify key derivation and include it in the internalizeAction remittance.
    example
    02abc123...

    PaymentOutputDescriptor

    Describes one P2PKH output within a multi-output BRC-29 payment.
    type
    object
    description
    Describes one P2PKH output within a multi-output BRC-29 payment.
    required
    2 items
    1. outputIndex
    2. derivationSuffix
    properties
    2 fields
    outputIndex
    3 fields
    type
    integer
    minimum
    0
    description
    Zero-based output index within the transaction.
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific nonce for this output (base64-encoded).
    example
    X9k4LA==

    Brc42InvoiceNumber

    BRC-42 invoice number used to derive the recipient's P2PKH key for each output. Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>` where: - `2` = security level (BRC-43) - `3241645161d8` = BRC-29 magic number - derivationPrefix / derivationSuffix are the values from the message
    type
    string
    description
    BRC-42 invoice number used to derive the recipient's P2PKH key for each output. Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>` where: - `2` = security level (BRC-43) - `3241645161d8` = BRC-29 magic number - derivationPrefix / derivationSuffix are the values from the message
    pattern
    ^2-3241645161d8-[A-Za-z0-9+/=]+ [A-Za-z0-9+/=]+$
    example
    2-3241645161d8-3q2+7w== iMba2Q==

    PaymentRemittance

    Remittance object passed to BRC-100 `internalizeAction` for each payment output. The recipient's wallet uses these fields to derive the private key and credit the UTXO.
    type
    object
    description
    Remittance object passed to BRC-100 `internalizeAction` for each payment output. The recipient's wallet uses these fields to derive the private key and credit the UTXO.
    required
    3 items
    1. derivationPrefix
    2. derivationSuffix
    3. senderIdentityKey
    properties
    3 fields
    derivationPrefix
    3 fields
    type
    string
    description
    Payment-wide derivation prefix (base64-encoded).
    example
    3q2+7w==
    derivationSuffix
    3 fields
    type
    string
    description
    UTXO-specific derivation suffix (base64-encoded).
    example
    iMba2Q==
    senderIdentityKey
    3 fields
    type
    string
    description
    Hex-encoded compressed secp256k1 identity public key of the sender.
    example
    02abc123...

    InternalizeActionArgs

    Arguments passed to the BRC-100 `internalizeAction` wallet method by the recipient when processing an incoming BRC-29 payment.
    type
    object
    description
    Arguments passed to the BRC-100 `internalizeAction` wallet method by the recipient when processing an incoming BRC-29 payment.
    required
    3 items
    1. tx
    2. outputs
    3. description
    properties
    3 fields
    tx
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    Raw Atomic BEEF bytes of the payment transaction.
    outputs
    4 fields
    type
    array
    minItems
    1
    items
    1 field
    $ref
    #/components/schemas/InternalizeOutput
    description
    One entry per P2PKH output intended for this recipient.
    description
    3 fields
    type
    string
    description
    Human-readable description of the payment.
    example
    Incoming BRC-29 payment

    InternalizeOutput

    type
    object
    required
    3 items
    1. outputIndex
    2. protocol
    3. paymentRemittance
    properties
    3 fields
    outputIndex
    3 fields
    type
    integer
    minimum
    0
    description
    Zero-based output index within the transaction.
    protocol
    3 fields
    type
    string
    enum
    1 item
    1. wallet payment
    description
    Protocol identifier understood by BRC-100 wallets.
    paymentRemittance
    1 field
    $ref
    #/components/schemas/PaymentRemittance

    PaymentAck

    Minimal response returned to the sender after the recipient has called `internalizeAction`. BRC-29 does not mandate a wire format; this is the conventional shape used by ts-sdk integrations.
    type
    object
    description
    Minimal response returned to the sender after the recipient has called `internalizeAction`. BRC-29 does not mandate a wire format; this is the conventional shape used by ts-sdk integrations.
    required
    1 item
    1. accepted
    properties
    3 fields
    accepted
    2 fields
    type
    boolean
    description
    true if internalizeAction succeeded and the payment was credited.
    txid
    3 fields
    type
    string
    description
    Txid of the accepted transaction (hex, 64 characters).
    pattern
    ^[0-9a-fA-F]{64}$
    error
    2 fields
    type
    string
    description
    Human-readable error message if `accepted` is false. Only present on rejection.

    LegacyPaymentEnvelope

    **Deprecated.** The original BRC-8 extended-envelope format. New integrations MUST NOT use this format; use `PaymentMessage` instead. Documented here only for backwards-compatibility reference.
    type
    object
    deprecated
    true
    description
    **Deprecated.** The original BRC-8 extended-envelope format. New integrations MUST NOT use this format; use `PaymentMessage` instead. Documented here only for backwards-compatibility reference.
    required
    4 items
    1. protocol
    2. senderIdentityKey
    3. derivationPrefix
    4. transactions
    properties
    4 fields
    protocol
    2 fields
    type
    string
    enum
    1 item
    1. 3241645161d8
    senderIdentityKey
    2 fields
    type
    string
    description
    Hex-encoded sender identity public key.
    derivationPrefix
    2 fields
    type
    string
    description
    Payment-wide derivation prefix.
    transactions
    3 fields
    type
    array
    description
    Array of extended BRC-8 transaction envelopes.
    items
    2 fields
    type
    object
    description
    Extended BRC-8 transaction envelope (schema omitted — deprecated).
    Raw YAML source
    asyncapi: "3.1.0"
    
    info:
      title: BRC-29 Simple Authenticated BSV P2PKH Payment Protocol
      version: "1.0.0"
      description: |
        Specifies the peer-to-peer payment flow defined in BRC-29, including
        BRC-42 key derivation prefix/suffix negotiation, the current Atomic BEEF
        payment message, and the BRC-100 internalizeAction remittance envelope.
    
        The older BRC-8 extended-envelope format (the `transactions` array) is
        deprecated for new integrations; only the current BRC-100 / Atomic BEEF
        transport is modelled here.
    
        Source of truth: /docs/BRCs/payments/0029.md
      license:
        name: Open BSV Licence
    
    defaultContentType: application/json
    
    # ---------------------------------------------------------------------------
    # Channels
    # ---------------------------------------------------------------------------
    channels:
      paymentSend:
        address: payment/send
        description: |
          Logical channel representing a sender delivering a BRC-29 payment message
          to a recipient.  In practice this is carried over whatever higher-level
          transport the application chooses (HTTP POST, WebSocket, BRC-104 message
          box, etc.).  The channel models the one-way delivery of the payment.
        messages:
          paymentMessage:
            $ref: "#/components/messages/PaymentMessage"
    
      paymentAcknowledge:
        address: payment/acknowledge
        description: |
          Logical channel representing the recipient acknowledging acceptance or
          rejection of the incoming payment after calling internalizeAction.
        messages:
          paymentAck:
            $ref: "#/components/messages/PaymentAck"
    
    # ---------------------------------------------------------------------------
    # Operations
    # ---------------------------------------------------------------------------
    operations:
      sendPayment:
        action: send
        channel:
          $ref: "#/channels/paymentSend"
        summary: Sender delivers a BRC-29 payment message to the recipient.
        messages:
          - $ref: "#/channels/paymentSend/messages/paymentMessage"
    
      receiveAck:
        action: receive
        channel:
          $ref: "#/channels/paymentAcknowledge"
        summary: Sender receives payment acceptance or rejection from the recipient.
        messages:
          - $ref: "#/channels/paymentAcknowledge/messages/paymentAck"
    
    # ---------------------------------------------------------------------------
    # Components
    # ---------------------------------------------------------------------------
    components:
      messages:
        PaymentMessage:
          name: PaymentMessage
          title: BRC-29 Payment Message
          summary: |
            Current (BRC-100 / Atomic BEEF) payment message sent from the payer to
            the payee.  Carries one transaction with one or more P2PKH outputs
            derived via BRC-42 key derivation using the invoice number format
            `2-3241645161d8-<derivationPrefix> <derivationSuffix>`.
          payload:
            $ref: "#/components/schemas/PaymentMessage"
    
        PaymentAck:
          name: PaymentAck
          title: Payment Acknowledgement
          summary: |
            Informal acknowledgement returned by the recipient after calling
            BRC-100 internalizeAction.  No mandatory wire format is defined by
            BRC-29; the shape below is the conventional minimal envelope.
          payload:
            $ref: "#/components/schemas/PaymentAck"
    
      schemas:
        # -----------------------------------------------------------------------
        # PaymentMessage — single-output form (multi-output uses array variant)
        # -----------------------------------------------------------------------
        PaymentMessage:
          type: object
          description: |
            Payment message delivered from sender to recipient.  The `transaction`
            field carries a base64-encoded Atomic BEEF blob (BRC-95).  For payments
            containing multiple outputs each output MUST carry its own
            derivationSuffix and outputIndex so the recipient can recover the
            correct P2PKH private key for each UTXO.
          required:
            - derivationPrefix
            - derivationSuffix
            - transaction
          properties:
            derivationPrefix:
              type: string
              description: |
                Payment-wide random nonce (base64-encoded, BRC-29 §3).
                Uniquely identifies this payment across all outputs.
              example: "3q2+7w=="
            derivationSuffix:
              type: string
              description: |
                UTXO-specific random nonce (base64-encoded).
                Uniquely identifies a single output within this payment.
                For multi-output payments, use the `outputs` array instead.
              example: "iMba2Q=="
            transaction:
              type: string
              description: |
                Base64-encoded Atomic BEEF (BRC-95) containing the signed BSV
                transaction with one or more P2PKH outputs for the recipient.
              example: "<base64-encoded-BEEF>"
            outputs:
              type: array
              description: |
                Present when multiple outputs belong to the same payment.  Each
                element describes one P2PKH output intended for the recipient.
                When this array is absent, `derivationSuffix` at the top level
                refers to output index 0.
              items:
                $ref: "#/components/schemas/PaymentOutputDescriptor"
            senderIdentityKey:
              type: string
              description: |
                Hex-encoded compressed secp256k1 identity public key of the sender.
                SHOULD be included so the recipient can verify key derivation and
                include it in the internalizeAction remittance.
              example: "02abc123..."
    
        PaymentOutputDescriptor:
          type: object
          description: Describes one P2PKH output within a multi-output BRC-29 payment.
          required:
            - outputIndex
            - derivationSuffix
          properties:
            outputIndex:
              type: integer
              minimum: 0
              description: Zero-based output index within the transaction.
            derivationSuffix:
              type: string
              description: UTXO-specific nonce for this output (base64-encoded).
              example: "X9k4LA=="
    
        # -----------------------------------------------------------------------
        # Key-derivation invoice number (informational)
        # -----------------------------------------------------------------------
        Brc42InvoiceNumber:
          type: string
          description: |
            BRC-42 invoice number used to derive the recipient's P2PKH key for each
            output.  Format: `2-3241645161d8-<derivationPrefix> <derivationSuffix>`
            where:
              - `2`             = security level (BRC-43)
              - `3241645161d8`  = BRC-29 magic number
              - derivationPrefix / derivationSuffix are the values from the message
          pattern: "^2-3241645161d8-[A-Za-z0-9+/=]+ [A-Za-z0-9+/=]+$"
          example: "2-3241645161d8-3q2+7w== iMba2Q=="
    
        # -----------------------------------------------------------------------
        # internalizeAction remittance (as passed by the recipient's wallet)
        # -----------------------------------------------------------------------
        PaymentRemittance:
          type: object
          description: |
            Remittance object passed to BRC-100 `internalizeAction` for each
            payment output.  The recipient's wallet uses these fields to derive
            the private key and credit the UTXO.
          required:
            - derivationPrefix
            - derivationSuffix
            - senderIdentityKey
          properties:
            derivationPrefix:
              type: string
              description: Payment-wide derivation prefix (base64-encoded).
              example: "3q2+7w=="
            derivationSuffix:
              type: string
              description: UTXO-specific derivation suffix (base64-encoded).
              example: "iMba2Q=="
            senderIdentityKey:
              type: string
              description: Hex-encoded compressed secp256k1 identity public key of the sender.
              example: "02abc123..."
    
        # -----------------------------------------------------------------------
        # Full internalizeAction args shape (BRC-100)
        # -----------------------------------------------------------------------
        InternalizeActionArgs:
          type: object
          description: |
            Arguments passed to the BRC-100 `internalizeAction` wallet method by
            the recipient when processing an incoming BRC-29 payment.
          required:
            - tx
            - outputs
            - description
          properties:
            tx:
              type: array
              items:
                type: integer
                minimum: 0
                maximum: 255
              description: Raw Atomic BEEF bytes of the payment transaction.
            outputs:
              type: array
              minItems: 1
              items:
                $ref: "#/components/schemas/InternalizeOutput"
              description: One entry per P2PKH output intended for this recipient.
            description:
              type: string
              description: Human-readable description of the payment.
              example: "Incoming BRC-29 payment"
    
        InternalizeOutput:
          type: object
          required:
            - outputIndex
            - protocol
            - paymentRemittance
          properties:
            outputIndex:
              type: integer
              minimum: 0
              description: Zero-based output index within the transaction.
            protocol:
              type: string
              enum:
                - "wallet payment"
              description: Protocol identifier understood by BRC-100 wallets.
            paymentRemittance:
              $ref: "#/components/schemas/PaymentRemittance"
    
        # -----------------------------------------------------------------------
        # Acknowledgement
        # -----------------------------------------------------------------------
        PaymentAck:
          type: object
          description: |
            Minimal response returned to the sender after the recipient has called
            `internalizeAction`.  BRC-29 does not mandate a wire format; this is
            the conventional shape used by ts-sdk integrations.
          required:
            - accepted
          properties:
            accepted:
              type: boolean
              description: true if internalizeAction succeeded and the payment was credited.
            txid:
              type: string
              description: Txid of the accepted transaction (hex, 64 characters).
              pattern: "^[0-9a-fA-F]{64}$"
            error:
              type: string
              description: |
                Human-readable error message if `accepted` is false.  Only present
                on rejection.
    
        # -----------------------------------------------------------------------
        # Legacy (deprecated) payment envelope — documented for compatibility only
        # -----------------------------------------------------------------------
        LegacyPaymentEnvelope:
          type: object
          deprecated: true
          description: |
            **Deprecated.** The original BRC-8 extended-envelope format.  New
            integrations MUST NOT use this format; use `PaymentMessage` instead.
            Documented here only for backwards-compatibility reference.
          required:
            - protocol
            - senderIdentityKey
            - derivationPrefix
            - transactions
          properties:
            protocol:
              type: string
              enum:
                - "3241645161d8"
            senderIdentityKey:
              type: string
              description: Hex-encoded sender identity public key.
            derivationPrefix:
              type: string
              description: Payment-wide derivation prefix.
            transactions:
              type: array
              description: Array of extended BRC-8 transaction envelopes.
              items:
                type: object
                description: Extended BRC-8 transaction envelope (schema omitted — deprecated).
    
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    \ No newline at end of file diff --git a/docs-site/public/assets/asyncapi/brc31/index.html b/docs-site/public/assets/asyncapi/brc31/index.html index 32d18a4fb..5842d04ec 100644 --- a/docs-site/public/assets/asyncapi/brc31/index.html +++ b/docs-site/public/assets/asyncapi/brc31/index.html @@ -1,1075 +1 @@ - - - - - - - BRC-103 Mutual Authentication Handshake · AsyncAPI - - - -
    -
    AsyncAPI 3.1.0 · specs/auth/brc103-mutual-auth.yaml
    -

    BRC-103 Mutual Authentication Handshake

    v1.0.0
    -
    AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual -authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as -implemented in: - -- `packages/middleware/auth-express-middleware/src/index.ts` - (`ExpressTransport`, `createAuthMiddleware`) — BRC-104 HTTP transport - (https://bsv.brc.dev/peer-to-peer/0104) -- `packages/messaging/authsocket/src/SocketServerTransport.ts` - (`SocketServerTransport`) — Socket.IO transport -- `@bsv/sdk` `Peer` and `Transport` interfaces - -Note: this file replaces the earlier `brc31-handshake.yaml`. BRC-31 was -the legacy identifier; the protocol is now standardised as BRC-103 with -BRC-104 covering the HTTP binding. - -## Protocol overview - -BRC-103 mutual authentication uses ECDH-derived key pairs to create a -shared, forward-secret session between two parties. Neither party trusts -the other's identity until the signed handshake is verified. - -### Two-phase handshake - -**Phase 1 — Non-general (initial exchange)** - -Carried over the special endpoint `POST /.well-known/auth` for HTTP -transports, or the `authMessage` Socket.IO event for WebSocket transports. - -1. **Client → Server** `initialRequest` - Client generates a fresh nonce, signs it with its identity key, and - sends the auth message. Headers on the HTTP path: - ``` - x-bsv-auth-version: <version> - x-bsv-auth-identity-key: <clientPubKeyHex> - x-bsv-auth-nonce: <base64Nonce> - ``` - Body (HTTP): the `AuthMessage` JSON object. - -2. **Server → Client** `initialResponse` - Server validates the client's nonce/signature, generates its own nonce, - signs the response, and returns the `AuthMessage`. HTTP response headers: - ``` - x-bsv-auth-version: <version> - x-bsv-auth-message-type: initialResponse - x-bsv-auth-identity-key: <serverPubKeyHex> - x-bsv-auth-nonce: <base64ServerNonce> - x-bsv-auth-your-nonce: <base64ClientNonce> - x-bsv-auth-signature: <hexDERSignature> - x-bsv-auth-requested-certificates: <JSON> (optional) - ``` - -**Phase 2 — General (authenticated request/response)** - -Once the session is established all subsequent HTTP requests carry: -``` -x-bsv-auth-version: <version> -x-bsv-auth-identity-key: <clientPubKeyHex> -x-bsv-auth-nonce: <base64Nonce> -x-bsv-auth-your-nonce: <base64ServerNonce> -x-bsv-auth-request-id: <base64RequestId> -x-bsv-auth-signature: <hexDERSignature> -``` - -The signed payload includes: `requestId || method || pathname || search -|| headers (sorted) || body`. - -The server responds with: -``` -x-bsv-auth-version: <version> -x-bsv-auth-identity-key: <serverPubKeyHex> -x-bsv-auth-nonce: <base64Nonce> -x-bsv-auth-your-nonce: <base64ClientNonce> -x-bsv-auth-request-id: <base64RequestId> -x-bsv-auth-signature: <hexDERSignature> -``` - -The signed response payload includes: `requestId || statusCode || -headers (sorted) || body`. - -### Certificate flow (optional) - -If the server declares `certificatesToRequest`, it embeds the request set -in the `x-bsv-auth-requested-certificates` header of the `initialResponse`. -The client then provides certificates in a follow-up `/.well-known/auth` -call before the `next()` middleware proceeds. The server waits up to -30 seconds; timeout returns 408. - -### Unauthenticated pass-through - -If `allowUnauthenticated: true` is set in middleware options, requests -without auth headers proceed with `req.auth.identityKey = 'unknown'`. - -## Implementation-specific notes - -- `ExpressTransport` intercepts `res.status`, `res.json`, `res.send`, - `res.set`, `res.end`, `res.sendFile`, and `res.text` to buffer the - response until after `Peer.toPeer` signs and re-emits it. Original - methods are saved as `res.__status`, `res.__json`, etc. -- The `RequestId` is a 32-byte random value encoded as base64. -- Nonces are single-use; the `SessionManager` stores seen nonces to - prevent replay. Deployments that run multiple server instances should - use a shared `AsyncSessionManager` store so every instance can resolve - the same nonce/session state during the handshake. -
    -
    1Servers4Channels5Operations0Messages14Schemas
    -
    - -
    -
    -

    Servers

    1
    -
    -

    httpServer

    -

    https://{host}/.well-known/auth

    -
    HTTP endpoint for BRC-103 non-general (initial handshake) messages. -General (authenticated) messages use normal application paths. -
    -
    host
    {host}
    pathname
    /.well-known/auth
    protocol
    https
    description
    HTTP endpoint for BRC-103 non-general (initial handshake) messages. -General (authenticated) messages use normal application paths. -
    variables
    1 field
    host
    1 field
    default
    messagebox.babbage.systems
    -
    -
    -

    Channels

    4
    -
    -

    wellKnownAuth

    -

    /.well-known/auth

    -
    HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. -The client POSTs an `AuthMessage` JSON body; the server replies with an -`AuthMessage` JSON body and the `x-bsv-auth-*` response headers. - -In Socket.IO transports the same exchange happens over the `authMessage` -Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP -endpoint. -
    -
    address
    /.well-known/auth
    description
    HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. -The client POSTs an `AuthMessage` JSON body; the server replies with an -`AuthMessage` JSON body and the `x-bsv-auth-*` response headers. - -In Socket.IO transports the same exchange happens over the `authMessage` -Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP -endpoint. -
    messages
    2 fields
    initialRequest
    6 fields
    name
    initialRequest
    summary
    Client initiates the BRC-103 handshake.
    description
    The client generates a nonce, signs it, and sends the -`initialRequest` AuthMessage as the POST body. -
    headers
    1 field
    $ref
    #/components/schemas/InitialRequestHeaders
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage
    examples
    1 item
    1. name
      example-initial-request
      payload
      7 fields
      messageType
      initialRequest
      version
      0.1
      identityKey
      028d37b941208cd6b8a4c28288eda5f2f16c2b3ab0fcb6d13c18b47fe37b971fc1
      nonce
      dGVzdE5vbmNlMTIzNA==
      initialNonce
      dGVzdE5vbmNlMTIzNA==
      payload
      0 itemsempty list
      signature
      0 itemsempty list
    initialResponse
    5 fields
    name
    initialResponse
    summary
    Server completes Phase 1 of the BRC-103 handshake.
    description
    The server validates the client's nonce/signature, generates its own -nonce, signs the response, and replies. The body is an `AuthMessage` -JSON object. Response headers carry the `x-bsv-auth-*` fields. - -If `certificatesToRequest` is configured, the -`x-bsv-auth-requested-certificates` header contains the JSON-encoded -request set. The client must supply certificates in a follow-up -POST before the session is fully established. -
    headers
    1 field
    $ref
    #/components/schemas/InitialResponseHeaders
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage
    -
    -

    generalRequest

    -

    {applicationPath}

    -
    Every authenticated application HTTP request (Phase 2). The path is -the actual application endpoint (e.g. `/sendMessage`, `/listMessages`). -The auth headers are attached alongside any application-specific headers. -
    -
    address
    {applicationPath}
    description
    Every authenticated application HTTP request (Phase 2). The path is -the actual application endpoint (e.g. `/sendMessage`, `/listMessages`). -The auth headers are attached alongside any application-specific headers. -
    parameters
    1 field
    applicationPath
    1 field
    description
    The application route path (e.g. /sendMessage).
    messages
    1 field
    generalRequestMessage
    5 fields
    name
    generalRequestMessage
    summary
    Authenticated application request.
    description
    The client sends application-level request headers and body, augmented -with `x-bsv-auth-*` mutual-auth headers. The `x-bsv-auth-signature` -covers the entire request (method, path, query string, signed headers, -and body) as described in `RequestAuthPayload`. -
    headers
    1 field
    $ref
    #/components/schemas/GeneralRequestHeaders
    payload
    1 field
    description
    Application-defined request body (any content type).
    -
    -

    generalResponse

    -

    {applicationPath}

    -
    Every authenticated application HTTP response (Phase 2). The server -signs the response status code, relevant headers, and body before sending. -
    -
    address
    {applicationPath}
    description
    Every authenticated application HTTP response (Phase 2). The server -signs the response status code, relevant headers, and body before sending. -
    parameters
    1 field
    applicationPath
    1 field
    description
    The application route path.
    messages
    1 field
    generalResponseMessage
    5 fields
    name
    generalResponseMessage
    summary
    Authenticated application response.
    description
    The server buffers the handler's response via `ResponseWriterWrapper`, -calls `Peer.toPeer` to sign it, and flushes the signed response -including `x-bsv-auth-*` response headers. The `x-bsv-auth-signature` -covers `requestId || statusCode || signed response headers || body`. -
    headers
    1 field
    $ref
    #/components/schemas/GeneralResponseHeaders
    payload
    1 field
    description
    Application-defined response body.
    -
    -

    authError

    -

    {applicationPath}

    -
    Error responses emitted by the auth middleware when authentication fails. -
    -
    address
    {applicationPath}
    description
    Error responses emitted by the auth middleware when authentication fails. -
    parameters
    1 field
    applicationPath
    1 field
    description
    The path at which the error was encountered.
    messages
    3 fields
    unauthorized
    3 fields
    name
    unauthorized
    summary
    401 — mutual auth failed (no or bad auth headers).
    payload
    1 field
    $ref
    #/components/schemas/AuthError401
    certificateTimeout
    3 fields
    name
    certificateTimeout
    summary
    408 — server waited 30 s for client certificates and timed out.
    payload
    1 field
    $ref
    #/components/schemas/AuthError408
    signingFailed
    3 fields
    name
    signingFailed
    summary
    500 — server failed to sign its response payload.
    payload
    1 field
    $ref
    #/components/schemas/AuthError500
    -
    -
    -

    Operations

    5
    -
    -

    sendInitialRequest

    - send -
    Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`. -The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`. -
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/wellKnownAuth
    summary
    Client initiates BRC-103 handshake (Phase 1, step 1).
    description
    Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`. -The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`. -
    messages
    1 item
    1. $ref
      #/channels/wellKnownAuth/messages/initialRequest
    -
    -

    receiveInitialResponse

    - receive -
    Server replies with `initialResponse`. If `requestedCertificates` is -non-empty the client must send a follow-up request with the required -certificates before proceeding to Phase 2. -
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/wellKnownAuth
    summary
    Client receives the server's Phase 1 challenge response.
    description
    Server replies with `initialResponse`. If `requestedCertificates` is -non-empty the client must send a follow-up request with the required -certificates before proceeding to Phase 2. -
    messages
    1 item
    1. $ref
      #/channels/wellKnownAuth/messages/initialResponse
    -
    -

    sendGeneralRequest

    - send -
    Any application HTTP request after the handshake. The client attaches -`x-bsv-auth-*` headers and a fresh signed payload covering the full -request. The server uses `buildAuthMessageFromRequest` to reconstruct -and verify the payload. -
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/generalRequest
    summary
    Client sends an authenticated application request (Phase 2).
    description
    Any application HTTP request after the handshake. The client attaches -`x-bsv-auth-*` headers and a fresh signed payload covering the full -request. The server uses `buildAuthMessageFromRequest` to reconstruct -and verify the payload. -
    messages
    1 item
    1. $ref
      #/channels/generalRequest/messages/generalRequestMessage
    -
    -

    receiveGeneralResponse

    - receive -
    The server's response includes `x-bsv-auth-*` headers and a signature -over the response payload. The client can verify the response origin -using `buildResponsePayload` semantics. -
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/generalResponse
    summary
    Client receives the server's authenticated application response (Phase 2).
    description
    The server's response includes `x-bsv-auth-*` headers and a signature -over the response payload. The client can verify the response origin -using `buildResponsePayload` semantics. -
    messages
    1 item
    1. $ref
      #/channels/generalResponse/messages/generalResponseMessage
    -
    -

    receiveAuthError

    - receive -
    Client receives an auth error from the middleware.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/authError
    summary
    Client receives an auth error from the middleware.
    messages
    3 items
    1. $ref
      #/channels/authError/messages/unauthorized
    2. $ref
      #/channels/authError/messages/certificateTimeout
    3. $ref
      #/channels/authError/messages/signingFailed
    -
    -
    -

    Schemas

    14
    -
    -

    PubKeyHex

    - -
    Compressed secp256k1 public key, 66 hex characters.
    -
    type
    string
    pattern
    ^0[23][0-9a-fA-F]{64}$
    description
    Compressed secp256k1 public key, 66 hex characters.
    -
    -

    Base64String

    - -
    Base64-encoded binary data.
    -
    type
    string
    description
    Base64-encoded binary data.
    -
    -

    HexString

    - -
    Hex-encoded binary data.
    -
    type
    string
    pattern
    ^[0-9a-fA-F]+$
    description
    Hex-encoded binary data.
    -
    -

    AuthMessageType

    - -
    - `initialRequest` — first message from the initiating party -- `initialResponse` — response from the receiving party completing Phase 1 -- `general` — signed application message (Phase 2) -
    -
    type
    string
    enum
    3 items
    1. initialRequest
    2. initialResponse
    3. general
    description
    - `initialRequest` — first message from the initiating party -- `initialResponse` — response from the receiving party completing Phase 1 -- `general` — signed application message (Phase 2) -
    -
    -

    AuthMessage

    - -
    The core BRC-103 message envelope. Transported over HTTP bodies -(at `/.well-known/auth`) or Socket.IO `authMessage` events. -
    -
    type
    object
    description
    The core BRC-103 message envelope. Transported over HTTP bodies -(at `/.well-known/auth`) or Socket.IO `authMessage` events. -
    required
    3 items
    1. messageType
    2. version
    3. identityKey
    properties
    9 fields
    messageType
    1 field
    $ref
    #/components/schemas/AuthMessageType
    version
    2 fields
    type
    string
    description
    Auth protocol version (e.g. "0.1").
    identityKey
    2 fields
    $ref
    #/components/schemas/PubKeyHex
    description
    Public identity key of the sender of this message.
    nonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Fresh single-use random value generated by the sender. -Stored in the `SessionManager` to prevent replay. Multi-instance -deployments should store it in a shared `AsyncSessionManager` -implementation. -
    yourNonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Echo of the peer's nonce from the previous message.
    initialNonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Present in `initialRequest` only. The very first nonce from the -initiating party before a session key is established. -
    payload
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    For `general` messages: the signed application payload. -Encoding: `requestId(32) || VarInt(statusCode) || VarInt(nHeaders) -|| [header pairs] || VarInt(bodyLength) || body`. -For handshake messages: empty or absent. -
    signature
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    DER-encoded ECDSA signature over the payload.
    requestedCertificates
    3 fields
    type
    object
    description
    BRC-52 certificate request set. Present in `initialResponse` when -the server requires certificates from the client. -
    additionalProperties
    true
    -
    -

    InitialRequestHeaders

    - -
    HTTP request headers sent by the client when initiating the BRC-103 -handshake at POST `/.well-known/auth`. -
    -
    type
    object
    description
    HTTP request headers sent by the client when initiating the BRC-103 -handshake at POST `/.well-known/auth`. -
    required
    3 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    properties
    3 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    -
    -

    InitialResponseHeaders

    - -
    HTTP response headers set by the server completing Phase 1 of the -BRC-103 handshake. -
    -
    type
    object
    description
    HTTP response headers set by the server completing Phase 1 of the -BRC-103 handshake. -
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-message-type
    3. x-bsv-auth-identity-key
    4. x-bsv-auth-nonce
    5. x-bsv-auth-your-nonce
    6. x-bsv-auth-signature
    properties
    7 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-message-type
    2 fields
    type
    string
    enum
    1 item
    1. initialResponse
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-signature
    1 field
    $ref
    #/components/schemas/HexString
    x-bsv-auth-requested-certificates
    2 fields
    type
    string
    description
    JSON-encoded BRC-52 certificate request set (optional).
    -
    -

    GeneralRequestHeaders

    - -
    HTTP request headers sent by the client for every authenticated -application request (Phase 2). -
    -
    type
    object
    description
    HTTP request headers sent by the client for every authenticated -application request (Phase 2). -
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    4. x-bsv-auth-your-nonce
    5. x-bsv-auth-request-id
    6. x-bsv-auth-signature
    properties
    6 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-request-id
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    32-byte random value, base64-encoded.
    x-bsv-auth-signature
    2 fields
    $ref
    #/components/schemas/HexString
    description
    ECDSA signature over: -`requestId(32B) || VarInt(method.length) || method -|| VarInt(pathname.length) || pathname -|| VarInt(search.length) || search (or -1 if empty) -|| VarInt(nHeaders) || [sorted header pairs] -|| VarInt(bodyLength) || body (or -1 if empty)`. -
    -
    -

    GeneralResponseHeaders

    - -
    HTTP response headers set by the server on every authenticated -application response (Phase 2). -
    -
    type
    object
    description
    HTTP response headers set by the server on every authenticated -application response (Phase 2). -
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    4. x-bsv-auth-your-nonce
    5. x-bsv-auth-request-id
    6. x-bsv-auth-signature
    properties
    6 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-request-id
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-signature
    2 fields
    $ref
    #/components/schemas/HexString
    description
    ECDSA signature over: -`requestId(32B) || VarInt(statusCode) -|| VarInt(nHeaders) || [sorted non-auth x-bsv header pairs] -|| VarInt(bodyLength) || body (or -1 if empty)`. -
    -
    -

    AuthError401

    - -
    Returned when mutual authentication fails (no or bad auth headers).
    -
    type
    object
    description
    Returned when mutual authentication fails (no or bad auth headers).
    required
    3 items
    1. status
    2. code
    3. message
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    2 items
    1. UNAUTHORIZED
    2. ERR_AUTH_FAILED
    message
    1 field
    type
    string
    -
    -

    AuthError408

    - -
    Returned when the server is waiting for client certificates -and the 30-second timeout elapses. -
    -
    type
    object
    description
    Returned when the server is waiting for client certificates -and the 30-second timeout elapses. -
    required
    3 items
    1. status
    2. code
    3. message
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    1 item
    1. CERTIFICATE_TIMEOUT
    message
    1 field
    type
    string
    -
    -

    AuthError500

    - -
    Returned when the server fails to sign its response payload -(`ERR_RESPONSE_SIGNING_FAILED`). -
    -
    type
    object
    description
    Returned when the server fails to sign its response payload -(`ERR_RESPONSE_SIGNING_FAILED`). -
    required
    3 items
    1. status
    2. code
    3. description
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    2 items
    1. ERR_RESPONSE_SIGNING_FAILED
    2. ERR_INTERNAL_SERVER_ERROR
    description
    1 field
    type
    string
    -
    -

    RequestAuthPayload

    - -
    Informational schema: the signed payload for a `general` REQUEST. -Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`. - -Wire encoding (binary, concatenated): -| Field | Encoding | -|------------------|------------------------------------------| -| requestId | 32 raw bytes (decoded from base64) | -| method | VarInt(len) + UTF-8 bytes | -| pathname | VarInt(len) + UTF-8 bytes | -| search | VarInt(len) + UTF-8 bytes, or VarInt(-1) | -| nHeaders | VarInt | -| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | -| bodyLength | VarInt(len) or VarInt(-1) | -| body | raw bytes | - -Only these headers are included (sorted, lowercase): -- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) -- `content-type` (normalized: type only, no parameters) -- `authorization` -
    -
    type
    object
    description
    Informational schema: the signed payload for a `general` REQUEST. -Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`. - -Wire encoding (binary, concatenated): -| Field | Encoding | -|------------------|------------------------------------------| -| requestId | 32 raw bytes (decoded from base64) | -| method | VarInt(len) + UTF-8 bytes | -| pathname | VarInt(len) + UTF-8 bytes | -| search | VarInt(len) + UTF-8 bytes, or VarInt(-1) | -| nHeaders | VarInt | -| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | -| bodyLength | VarInt(len) or VarInt(-1) | -| body | raw bytes | - -Only these headers are included (sorted, lowercase): -- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) -- `content-type` (normalized: type only, no parameters) -- `authorization` -
    -
    -

    ResponseAuthPayload

    - -
    Informational schema: the signed payload for a `general` RESPONSE. -Assembled by `buildResponsePayload` in `ExpressTransport`. - -Wire encoding (binary, concatenated): -| Field | Encoding | -|------------------|------------------------------------------| -| requestId | 32 raw bytes (decoded from base64) | -| statusCode | VarInt | -| nHeaders | VarInt | -| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | -| bodyLength | VarInt(len) or VarInt(-1) | -| body | raw bytes | - -Only these response headers are included (sorted, lowercase): -- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) -- `authorization` -
    -
    type
    object
    description
    Informational schema: the signed payload for a `general` RESPONSE. -Assembled by `buildResponsePayload` in `ExpressTransport`. - -Wire encoding (binary, concatenated): -| Field | Encoding | -|------------------|------------------------------------------| -| requestId | 32 raw bytes (decoded from base64) | -| statusCode | VarInt | -| nHeaders | VarInt | -| headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | -| bodyLength | VarInt(len) or VarInt(-1) | -| body | raw bytes | - -Only these response headers are included (sorted, lowercase): -- Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) -- `authorization` -
    -
    -
    -
    - Raw YAML source -
    asyncapi: "3.1.0"
    -
    -info:
    -  title: BRC-103 Mutual Authentication Handshake
    -  version: "1.0.0"
    -  description: |
    -    AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual
    -    authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as
    -    implemented in:
    -
    -    - `packages/middleware/auth-express-middleware/src/index.ts`
    -      (`ExpressTransport`, `createAuthMiddleware`) — BRC-104 HTTP transport
    -      (https://bsv.brc.dev/peer-to-peer/0104)
    -    - `packages/messaging/authsocket/src/SocketServerTransport.ts`
    -      (`SocketServerTransport`) — Socket.IO transport
    -    - `@bsv/sdk` `Peer` and `Transport` interfaces
    -
    -    Note: this file replaces the earlier `brc31-handshake.yaml`. BRC-31 was
    -    the legacy identifier; the protocol is now standardised as BRC-103 with
    -    BRC-104 covering the HTTP binding.
    -
    -    ## Protocol overview
    -
    -    BRC-103 mutual authentication uses ECDH-derived key pairs to create a
    -    shared, forward-secret session between two parties. Neither party trusts
    -    the other's identity until the signed handshake is verified.
    -
    -    ### Two-phase handshake
    -
    -    **Phase 1 — Non-general (initial exchange)**
    -
    -    Carried over the special endpoint `POST /.well-known/auth` for HTTP
    -    transports, or the `authMessage` Socket.IO event for WebSocket transports.
    -
    -    1. **Client → Server** `initialRequest`
    -       Client generates a fresh nonce, signs it with its identity key, and
    -       sends the auth message. Headers on the HTTP path:
    -       ```
    -       x-bsv-auth-version: <version>
    -       x-bsv-auth-identity-key: <clientPubKeyHex>
    -       x-bsv-auth-nonce: <base64Nonce>
    -       ```
    -       Body (HTTP): the `AuthMessage` JSON object.
    -
    -    2. **Server → Client** `initialResponse`
    -       Server validates the client's nonce/signature, generates its own nonce,
    -       signs the response, and returns the `AuthMessage`. HTTP response headers:
    -       ```
    -       x-bsv-auth-version: <version>
    -       x-bsv-auth-message-type: initialResponse
    -       x-bsv-auth-identity-key: <serverPubKeyHex>
    -       x-bsv-auth-nonce: <base64ServerNonce>
    -       x-bsv-auth-your-nonce: <base64ClientNonce>
    -       x-bsv-auth-signature: <hexDERSignature>
    -       x-bsv-auth-requested-certificates: <JSON> (optional)
    -       ```
    -
    -    **Phase 2 — General (authenticated request/response)**
    -
    -    Once the session is established all subsequent HTTP requests carry:
    -    ```
    -    x-bsv-auth-version: <version>
    -    x-bsv-auth-identity-key: <clientPubKeyHex>
    -    x-bsv-auth-nonce: <base64Nonce>
    -    x-bsv-auth-your-nonce: <base64ServerNonce>
    -    x-bsv-auth-request-id: <base64RequestId>
    -    x-bsv-auth-signature: <hexDERSignature>
    -    ```
    -
    -    The signed payload includes: `requestId || method || pathname || search
    -    || headers (sorted) || body`.
    -
    -    The server responds with:
    -    ```
    -    x-bsv-auth-version: <version>
    -    x-bsv-auth-identity-key: <serverPubKeyHex>
    -    x-bsv-auth-nonce: <base64Nonce>
    -    x-bsv-auth-your-nonce: <base64ClientNonce>
    -    x-bsv-auth-request-id: <base64RequestId>
    -    x-bsv-auth-signature: <hexDERSignature>
    -    ```
    -
    -    The signed response payload includes: `requestId || statusCode ||
    -    headers (sorted) || body`.
    -
    -    ### Certificate flow (optional)
    -
    -    If the server declares `certificatesToRequest`, it embeds the request set
    -    in the `x-bsv-auth-requested-certificates` header of the `initialResponse`.
    -    The client then provides certificates in a follow-up `/.well-known/auth`
    -    call before the `next()` middleware proceeds. The server waits up to
    -    30 seconds; timeout returns 408.
    -
    -    ### Unauthenticated pass-through
    -
    -    If `allowUnauthenticated: true` is set in middleware options, requests
    -    without auth headers proceed with `req.auth.identityKey = 'unknown'`.
    -
    -    ## Implementation-specific notes
    -
    -    - `ExpressTransport` intercepts `res.status`, `res.json`, `res.send`,
    -      `res.set`, `res.end`, `res.sendFile`, and `res.text` to buffer the
    -      response until after `Peer.toPeer` signs and re-emits it. Original
    -      methods are saved as `res.__status`, `res.__json`, etc.
    -    - The `RequestId` is a 32-byte random value encoded as base64.
    -    - Nonces are single-use; the `SessionManager` stores seen nonces to
    -      prevent replay. Deployments that run multiple server instances should
    -      use a shared `AsyncSessionManager` store so every instance can resolve
    -      the same nonce/session state during the handshake.
    -
    -servers:
    -  httpServer:
    -    host: "{host}"
    -    pathname: "/.well-known/auth"
    -    protocol: https
    -    description: |
    -      HTTP endpoint for BRC-103 non-general (initial handshake) messages.
    -      General (authenticated) messages use normal application paths.
    -    variables:
    -      host:
    -        default: messagebox.babbage.systems
    -
    -# ---------------------------------------------------------------------------
    -# Components
    -# ---------------------------------------------------------------------------
    -components:
    -  schemas:
    -    PubKeyHex:
    -      type: string
    -      pattern: "^0[23][0-9a-fA-F]{64}$"
    -      description: Compressed secp256k1 public key, 66 hex characters.
    -
    -    Base64String:
    -      type: string
    -      description: Base64-encoded binary data.
    -
    -    HexString:
    -      type: string
    -      pattern: "^[0-9a-fA-F]+$"
    -      description: Hex-encoded binary data.
    -
    -    AuthMessageType:
    -      type: string
    -      enum: [initialRequest, initialResponse, general]
    -      description: |
    -        - `initialRequest`  — first message from the initiating party
    -        - `initialResponse` — response from the receiving party completing Phase 1
    -        - `general`         — signed application message (Phase 2)
    -
    -    AuthMessage:
    -      type: object
    -      description: |
    -        The core BRC-103 message envelope. Transported over HTTP bodies
    -        (at `/.well-known/auth`) or Socket.IO `authMessage` events.
    -      required: [messageType, version, identityKey]
    -      properties:
    -        messageType:
    -          $ref: "#/components/schemas/AuthMessageType"
    -        version:
    -          type: string
    -          description: Auth protocol version (e.g. "0.1").
    -        identityKey:
    -          $ref: "#/components/schemas/PubKeyHex"
    -          description: Public identity key of the sender of this message.
    -        nonce:
    -          $ref: "#/components/schemas/Base64String"
    -          description: |
    -            Fresh single-use random value generated by the sender.
    -            Stored in the `SessionManager` to prevent replay. Multi-instance
    -            deployments should store it in a shared `AsyncSessionManager`
    -            implementation.
    -        yourNonce:
    -          $ref: "#/components/schemas/Base64String"
    -          description: Echo of the peer's nonce from the previous message.
    -        initialNonce:
    -          $ref: "#/components/schemas/Base64String"
    -          description: |
    -            Present in `initialRequest` only. The very first nonce from the
    -            initiating party before a session key is established.
    -        payload:
    -          type: array
    -          items:
    -            type: integer
    -            minimum: 0
    -            maximum: 255
    -          description: |
    -            For `general` messages: the signed application payload.
    -            Encoding: `requestId(32) || VarInt(statusCode) || VarInt(nHeaders)
    -            || [header pairs] || VarInt(bodyLength) || body`.
    -            For handshake messages: empty or absent.
    -        signature:
    -          type: array
    -          items:
    -            type: integer
    -            minimum: 0
    -            maximum: 255
    -          description: DER-encoded ECDSA signature over the payload.
    -        requestedCertificates:
    -          type: object
    -          description: |
    -            BRC-52 certificate request set. Present in `initialResponse` when
    -            the server requires certificates from the client.
    -          additionalProperties: true
    -
    -    # -------------------------------------------------------------------------
    -    # HTTP header shapes (informational — not AsyncAPI schema objects)
    -    # -------------------------------------------------------------------------
    -    InitialRequestHeaders:
    -      type: object
    -      description: |
    -        HTTP request headers sent by the client when initiating the BRC-103
    -        handshake at POST `/.well-known/auth`.
    -      required:
    -        - x-bsv-auth-version
    -        - x-bsv-auth-identity-key
    -        - x-bsv-auth-nonce
    -      properties:
    -        x-bsv-auth-version:
    -          type: string
    -        x-bsv-auth-identity-key:
    -          $ref: "#/components/schemas/PubKeyHex"
    -        x-bsv-auth-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -
    -    InitialResponseHeaders:
    -      type: object
    -      description: |
    -        HTTP response headers set by the server completing Phase 1 of the
    -        BRC-103 handshake.
    -      required:
    -        - x-bsv-auth-version
    -        - x-bsv-auth-message-type
    -        - x-bsv-auth-identity-key
    -        - x-bsv-auth-nonce
    -        - x-bsv-auth-your-nonce
    -        - x-bsv-auth-signature
    -      properties:
    -        x-bsv-auth-version:
    -          type: string
    -        x-bsv-auth-message-type:
    -          type: string
    -          enum: [initialResponse]
    -        x-bsv-auth-identity-key:
    -          $ref: "#/components/schemas/PubKeyHex"
    -        x-bsv-auth-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-your-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-signature:
    -          $ref: "#/components/schemas/HexString"
    -        x-bsv-auth-requested-certificates:
    -          type: string
    -          description: JSON-encoded BRC-52 certificate request set (optional).
    -
    -    GeneralRequestHeaders:
    -      type: object
    -      description: |
    -        HTTP request headers sent by the client for every authenticated
    -        application request (Phase 2).
    -      required:
    -        - x-bsv-auth-version
    -        - x-bsv-auth-identity-key
    -        - x-bsv-auth-nonce
    -        - x-bsv-auth-your-nonce
    -        - x-bsv-auth-request-id
    -        - x-bsv-auth-signature
    -      properties:
    -        x-bsv-auth-version:
    -          type: string
    -        x-bsv-auth-identity-key:
    -          $ref: "#/components/schemas/PubKeyHex"
    -        x-bsv-auth-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-your-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-request-id:
    -          $ref: "#/components/schemas/Base64String"
    -          description: 32-byte random value, base64-encoded.
    -        x-bsv-auth-signature:
    -          $ref: "#/components/schemas/HexString"
    -          description: |
    -            ECDSA signature over:
    -            `requestId(32B) || VarInt(method.length) || method
    -            || VarInt(pathname.length) || pathname
    -            || VarInt(search.length) || search (or -1 if empty)
    -            || VarInt(nHeaders) || [sorted header pairs]
    -            || VarInt(bodyLength) || body (or -1 if empty)`.
    -
    -    GeneralResponseHeaders:
    -      type: object
    -      description: |
    -        HTTP response headers set by the server on every authenticated
    -        application response (Phase 2).
    -      required:
    -        - x-bsv-auth-version
    -        - x-bsv-auth-identity-key
    -        - x-bsv-auth-nonce
    -        - x-bsv-auth-your-nonce
    -        - x-bsv-auth-request-id
    -        - x-bsv-auth-signature
    -      properties:
    -        x-bsv-auth-version:
    -          type: string
    -        x-bsv-auth-identity-key:
    -          $ref: "#/components/schemas/PubKeyHex"
    -        x-bsv-auth-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-your-nonce:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-request-id:
    -          $ref: "#/components/schemas/Base64String"
    -        x-bsv-auth-signature:
    -          $ref: "#/components/schemas/HexString"
    -          description: |
    -            ECDSA signature over:
    -            `requestId(32B) || VarInt(statusCode)
    -            || VarInt(nHeaders) || [sorted non-auth x-bsv header pairs]
    -            || VarInt(bodyLength) || body (or -1 if empty)`.
    -
    -    # -------------------------------------------------------------------------
    -    # Error shapes
    -    # -------------------------------------------------------------------------
    -    AuthError401:
    -      type: object
    -      description: Returned when mutual authentication fails (no or bad auth headers).
    -      required: [status, code, message]
    -      properties:
    -        status:
    -          type: string
    -          enum: [error]
    -        code:
    -          type: string
    -          enum: [UNAUTHORIZED, ERR_AUTH_FAILED]
    -        message:
    -          type: string
    -
    -    AuthError408:
    -      type: object
    -      description: |
    -        Returned when the server is waiting for client certificates
    -        and the 30-second timeout elapses.
    -      required: [status, code, message]
    -      properties:
    -        status:
    -          type: string
    -          enum: [error]
    -        code:
    -          type: string
    -          enum: [CERTIFICATE_TIMEOUT]
    -        message:
    -          type: string
    -
    -    AuthError500:
    -      type: object
    -      description: |
    -        Returned when the server fails to sign its response payload
    -        (`ERR_RESPONSE_SIGNING_FAILED`).
    -      required: [status, code, description]
    -      properties:
    -        status:
    -          type: string
    -          enum: [error]
    -        code:
    -          type: string
    -          enum: [ERR_RESPONSE_SIGNING_FAILED, ERR_INTERNAL_SERVER_ERROR]
    -        description:
    -          type: string
    -
    -    RequestAuthPayload:
    -      type: object
    -      description: |
    -        Informational schema: the signed payload for a `general` REQUEST.
    -        Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`.
    -
    -        Wire encoding (binary, concatenated):
    -        | Field            | Encoding                                 |
    -        |------------------|------------------------------------------|
    -        | requestId        | 32 raw bytes (decoded from base64)       |
    -        | method           | VarInt(len) + UTF-8 bytes                |
    -        | pathname         | VarInt(len) + UTF-8 bytes                |
    -        | search           | VarInt(len) + UTF-8 bytes, or VarInt(-1) |
    -        | nHeaders         | VarInt                                   |
    -        | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val  |
    -        | bodyLength       | VarInt(len) or VarInt(-1)                |
    -        | body             | raw bytes                                |
    -
    -        Only these headers are included (sorted, lowercase):
    -        - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`)
    -        - `content-type` (normalized: type only, no parameters)
    -        - `authorization`
    -
    -    ResponseAuthPayload:
    -      type: object
    -      description: |
    -        Informational schema: the signed payload for a `general` RESPONSE.
    -        Assembled by `buildResponsePayload` in `ExpressTransport`.
    -
    -        Wire encoding (binary, concatenated):
    -        | Field            | Encoding                                 |
    -        |------------------|------------------------------------------|
    -        | requestId        | 32 raw bytes (decoded from base64)       |
    -        | statusCode       | VarInt                                   |
    -        | nHeaders         | VarInt                                   |
    -        | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val  |
    -        | bodyLength       | VarInt(len) or VarInt(-1)                |
    -        | body             | raw bytes                                |
    -
    -        Only these response headers are included (sorted, lowercase):
    -        - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`)
    -        - `authorization`
    -
    -# ---------------------------------------------------------------------------
    -# Channels
    -# ---------------------------------------------------------------------------
    -channels:
    -
    -  wellKnownAuth:
    -    address: "/.well-known/auth"
    -    description: |
    -      HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages.
    -      The client POSTs an `AuthMessage` JSON body; the server replies with an
    -      `AuthMessage` JSON body and the `x-bsv-auth-*` response headers.
    -
    -      In Socket.IO transports the same exchange happens over the `authMessage`
    -      Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP
    -      endpoint.
    -    messages:
    -      initialRequest:
    -        name: initialRequest
    -        summary: Client initiates the BRC-103 handshake.
    -        description: |
    -          The client generates a nonce, signs it, and sends the
    -          `initialRequest` AuthMessage as the POST body.
    -        headers:
    -          $ref: "#/components/schemas/InitialRequestHeaders"
    -        payload:
    -          $ref: "#/components/schemas/AuthMessage"
    -        examples:
    -          - name: example-initial-request
    -            payload:
    -              messageType: initialRequest
    -              version: "0.1"
    -              identityKey: "028d37b941208cd6b8a4c28288eda5f2f16c2b3ab0fcb6d13c18b47fe37b971fc1"
    -              nonce: "dGVzdE5vbmNlMTIzNA=="
    -              initialNonce: "dGVzdE5vbmNlMTIzNA=="
    -              payload: []
    -              signature: []
    -
    -      initialResponse:
    -        name: initialResponse
    -        summary: Server completes Phase 1 of the BRC-103 handshake.
    -        description: |
    -          The server validates the client's nonce/signature, generates its own
    -          nonce, signs the response, and replies. The body is an `AuthMessage`
    -          JSON object. Response headers carry the `x-bsv-auth-*` fields.
    -
    -          If `certificatesToRequest` is configured, the
    -          `x-bsv-auth-requested-certificates` header contains the JSON-encoded
    -          request set. The client must supply certificates in a follow-up
    -          POST before the session is fully established.
    -        headers:
    -          $ref: "#/components/schemas/InitialResponseHeaders"
    -        payload:
    -          $ref: "#/components/schemas/AuthMessage"
    -
    -  generalRequest:
    -    address: "{applicationPath}"
    -    description: |
    -      Every authenticated application HTTP request (Phase 2). The path is
    -      the actual application endpoint (e.g. `/sendMessage`, `/listMessages`).
    -      The auth headers are attached alongside any application-specific headers.
    -    parameters:
    -      applicationPath:
    -        description: The application route path (e.g. /sendMessage).
    -    messages:
    -      generalRequestMessage:
    -        name: generalRequestMessage
    -        summary: Authenticated application request.
    -        description: |
    -          The client sends application-level request headers and body, augmented
    -          with `x-bsv-auth-*` mutual-auth headers. The `x-bsv-auth-signature`
    -          covers the entire request (method, path, query string, signed headers,
    -          and body) as described in `RequestAuthPayload`.
    -        headers:
    -          $ref: "#/components/schemas/GeneralRequestHeaders"
    -        payload:
    -          description: Application-defined request body (any content type).
    -
    -  generalResponse:
    -    address: "{applicationPath}"
    -    description: |
    -      Every authenticated application HTTP response (Phase 2). The server
    -      signs the response status code, relevant headers, and body before sending.
    -    parameters:
    -      applicationPath:
    -        description: The application route path.
    -    messages:
    -      generalResponseMessage:
    -        name: generalResponseMessage
    -        summary: Authenticated application response.
    -        description: |
    -          The server buffers the handler's response via `ResponseWriterWrapper`,
    -          calls `Peer.toPeer` to sign it, and flushes the signed response
    -          including `x-bsv-auth-*` response headers. The `x-bsv-auth-signature`
    -          covers `requestId || statusCode || signed response headers || body`.
    -        headers:
    -          $ref: "#/components/schemas/GeneralResponseHeaders"
    -        payload:
    -          description: Application-defined response body.
    -
    -  authError:
    -    address: "{applicationPath}"
    -    description: |
    -      Error responses emitted by the auth middleware when authentication fails.
    -    parameters:
    -      applicationPath:
    -        description: The path at which the error was encountered.
    -    messages:
    -      unauthorized:
    -        name: unauthorized
    -        summary: 401 — mutual auth failed (no or bad auth headers).
    -        payload:
    -          $ref: "#/components/schemas/AuthError401"
    -
    -      certificateTimeout:
    -        name: certificateTimeout
    -        summary: 408 — server waited 30 s for client certificates and timed out.
    -        payload:
    -          $ref: "#/components/schemas/AuthError408"
    -
    -      signingFailed:
    -        name: signingFailed
    -        summary: 500 — server failed to sign its response payload.
    -        payload:
    -          $ref: "#/components/schemas/AuthError500"
    -
    -# ---------------------------------------------------------------------------
    -# Operations
    -# ---------------------------------------------------------------------------
    -operations:
    -
    -  sendInitialRequest:
    -    action: send
    -    channel:
    -      $ref: "#/channels/wellKnownAuth"
    -    summary: Client initiates BRC-103 handshake (Phase 1, step 1).
    -    description: |
    -      Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`.
    -      The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`.
    -    messages:
    -      - $ref: "#/channels/wellKnownAuth/messages/initialRequest"
    -
    -  receiveInitialResponse:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/wellKnownAuth"
    -    summary: Client receives the server's Phase 1 challenge response.
    -    description: |
    -      Server replies with `initialResponse`. If `requestedCertificates` is
    -      non-empty the client must send a follow-up request with the required
    -      certificates before proceeding to Phase 2.
    -    messages:
    -      - $ref: "#/channels/wellKnownAuth/messages/initialResponse"
    -
    -  sendGeneralRequest:
    -    action: send
    -    channel:
    -      $ref: "#/channels/generalRequest"
    -    summary: Client sends an authenticated application request (Phase 2).
    -    description: |
    -      Any application HTTP request after the handshake. The client attaches
    -      `x-bsv-auth-*` headers and a fresh signed payload covering the full
    -      request. The server uses `buildAuthMessageFromRequest` to reconstruct
    -      and verify the payload.
    -    messages:
    -      - $ref: "#/channels/generalRequest/messages/generalRequestMessage"
    -
    -  receiveGeneralResponse:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/generalResponse"
    -    summary: Client receives the server's authenticated application response (Phase 2).
    -    description: |
    -      The server's response includes `x-bsv-auth-*` headers and a signature
    -      over the response payload. The client can verify the response origin
    -      using `buildResponsePayload` semantics.
    -    messages:
    -      - $ref: "#/channels/generalResponse/messages/generalResponseMessage"
    -
    -  receiveAuthError:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/authError"
    -    summary: Client receives an auth error from the middleware.
    -    messages:
    -      - $ref: "#/channels/authError/messages/unauthorized"
    -      - $ref: "#/channels/authError/messages/certificateTimeout"
    -      - $ref: "#/channels/authError/messages/signingFailed"
    -
    -
    -
    -
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    - - +BRC-103 Mutual Authentication Handshake · AsyncAPI
    AsyncAPI 3.1.0 · specs/auth/brc103-mutual-auth.yaml

    BRC-103 Mutual Authentication Handshake

    v1.0.0
    AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as implemented in: - `packages/middleware/auth-express-middleware/src/index.ts` (`ExpressTransport`, `createAuthMiddleware`) — BRC-104 HTTP transport (https://bsv.brc.dev/peer-to-peer/0104) - `packages/messaging/authsocket/src/SocketServerTransport.ts` (`SocketServerTransport`) — Socket.IO transport - `@bsv/sdk` `Peer` and `Transport` interfaces Note: this file replaces the earlier `brc31-handshake.yaml`. BRC-31 was the legacy identifier; the protocol is now standardised as BRC-103 with BRC-104 covering the HTTP binding. ## Protocol overview BRC-103 mutual authentication uses ECDH-derived key pairs to create a shared, forward-secret session between two parties. Neither party trusts the other's identity until the signed handshake is verified. ### Two-phase handshake **Phase 1 — Non-general (initial exchange)** Carried over the special endpoint `POST /.well-known/auth` for HTTP transports, or the `authMessage` Socket.IO event for WebSocket transports. 1. **Client → Server** `initialRequest` Client generates a fresh nonce, signs it with its identity key, and sends the auth message. Headers on the HTTP path: ``` x-bsv-auth-version: <version> x-bsv-auth-identity-key: <clientPubKeyHex> x-bsv-auth-nonce: <base64Nonce> ``` Body (HTTP): the `AuthMessage` JSON object. 2. **Server → Client** `initialResponse` Server validates the client's nonce/signature, generates its own nonce, signs the response, and returns the `AuthMessage`. HTTP response headers: ``` x-bsv-auth-version: <version> x-bsv-auth-message-type: initialResponse x-bsv-auth-identity-key: <serverPubKeyHex> x-bsv-auth-nonce: <base64ServerNonce> x-bsv-auth-your-nonce: <base64ClientNonce> x-bsv-auth-signature: <hexDERSignature> x-bsv-auth-requested-certificates: <JSON> (optional) ``` **Phase 2 — General (authenticated request/response)** Once the session is established all subsequent HTTP requests carry: ``` x-bsv-auth-version: <version> x-bsv-auth-identity-key: <clientPubKeyHex> x-bsv-auth-nonce: <base64Nonce> x-bsv-auth-your-nonce: <base64ServerNonce> x-bsv-auth-request-id: <base64RequestId> x-bsv-auth-signature: <hexDERSignature> ``` The signed payload includes: `requestId || method || pathname || search || headers (sorted) || body`. The server responds with: ``` x-bsv-auth-version: <version> x-bsv-auth-identity-key: <serverPubKeyHex> x-bsv-auth-nonce: <base64Nonce> x-bsv-auth-your-nonce: <base64ClientNonce> x-bsv-auth-request-id: <base64RequestId> x-bsv-auth-signature: <hexDERSignature> ``` The signed response payload includes: `requestId || statusCode || headers (sorted) || body`. ### Certificate flow (optional) If the server declares `certificatesToRequest`, it embeds the request set in the `x-bsv-auth-requested-certificates` header of the `initialResponse`. The client then provides certificates in a follow-up `/.well-known/auth` call before the `next()` middleware proceeds. The server waits up to 30 seconds; timeout returns 408. ### Unauthenticated pass-through If `allowUnauthenticated: true` is set in middleware options, requests without auth headers proceed with `req.auth.identityKey = 'unknown'`. ## Implementation-specific notes - `ExpressTransport` intercepts `res.status`, `res.json`, `res.send`, `res.set`, `res.end`, `res.sendFile`, and `res.text` to buffer the response until after `Peer.toPeer` signs and re-emits it. Original methods are saved as `res.__status`, `res.__json`, etc. - The `RequestId` is a 32-byte random value encoded as base64. - Nonces are single-use; the `SessionManager` stores seen nonces to prevent replay. Deployments that run multiple server instances should use a shared `AsyncSessionManager` store so every instance can resolve the same nonce/session state during the handshake.
    1Servers4Channels5Operations0Messages14Schemas

    Servers

    1

    httpServer

    https://{host}/.well-known/auth

    HTTP endpoint for BRC-103 non-general (initial handshake) messages. General (authenticated) messages use normal application paths.
    host
    {host}
    pathname
    /.well-known/auth
    protocol
    https
    description
    HTTP endpoint for BRC-103 non-general (initial handshake) messages. General (authenticated) messages use normal application paths.
    variables
    1 field
    host
    1 field
    default
    messagebox.babbage.systems

    Channels

    4

    wellKnownAuth

    /.well-known/auth

    HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. The client POSTs an `AuthMessage` JSON body; the server replies with an `AuthMessage` JSON body and the `x-bsv-auth-*` response headers. In Socket.IO transports the same exchange happens over the `authMessage` Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP endpoint.
    address
    /.well-known/auth
    description
    HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages. The client POSTs an `AuthMessage` JSON body; the server replies with an `AuthMessage` JSON body and the `x-bsv-auth-*` response headers. In Socket.IO transports the same exchange happens over the `authMessage` Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP endpoint.
    messages
    2 fields
    initialRequest
    6 fields
    name
    initialRequest
    summary
    Client initiates the BRC-103 handshake.
    description
    The client generates a nonce, signs it, and sends the `initialRequest` AuthMessage as the POST body.
    headers
    1 field
    $ref
    #/components/schemas/InitialRequestHeaders
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage
    examples
    1 item
    1. name
      example-initial-request
      payload
      7 fields
      messageType
      initialRequest
      version
      0.1
      identityKey
      028d37b941208cd6b8a4c28288eda5f2f16c2b3ab0fcb6d13c18b47fe37b971fc1
      nonce
      dGVzdE5vbmNlMTIzNA==
      initialNonce
      dGVzdE5vbmNlMTIzNA==
      payload
      0 itemsempty list
      signature
      0 itemsempty list
    initialResponse
    5 fields
    name
    initialResponse
    summary
    Server completes Phase 1 of the BRC-103 handshake.
    description
    The server validates the client's nonce/signature, generates its own nonce, signs the response, and replies. The body is an `AuthMessage` JSON object. Response headers carry the `x-bsv-auth-*` fields. If `certificatesToRequest` is configured, the `x-bsv-auth-requested-certificates` header contains the JSON-encoded request set. The client must supply certificates in a follow-up POST before the session is fully established.
    headers
    1 field
    $ref
    #/components/schemas/InitialResponseHeaders
    payload
    1 field
    $ref
    #/components/schemas/AuthMessage

    generalRequest

    {applicationPath}

    Every authenticated application HTTP request (Phase 2). The path is the actual application endpoint (e.g. `/sendMessage`, `/listMessages`). The auth headers are attached alongside any application-specific headers.
    address
    {applicationPath}
    description
    Every authenticated application HTTP request (Phase 2). The path is the actual application endpoint (e.g. `/sendMessage`, `/listMessages`). The auth headers are attached alongside any application-specific headers.
    parameters
    1 field
    applicationPath
    1 field
    description
    The application route path (e.g. /sendMessage).
    messages
    1 field
    generalRequestMessage
    5 fields
    name
    generalRequestMessage
    summary
    Authenticated application request.
    description
    The client sends application-level request headers and body, augmented with `x-bsv-auth-*` mutual-auth headers. The `x-bsv-auth-signature` covers the entire request (method, path, query string, signed headers, and body) as described in `RequestAuthPayload`.
    headers
    1 field
    $ref
    #/components/schemas/GeneralRequestHeaders
    payload
    1 field
    description
    Application-defined request body (any content type).

    generalResponse

    {applicationPath}

    Every authenticated application HTTP response (Phase 2). The server signs the response status code, relevant headers, and body before sending.
    address
    {applicationPath}
    description
    Every authenticated application HTTP response (Phase 2). The server signs the response status code, relevant headers, and body before sending.
    parameters
    1 field
    applicationPath
    1 field
    description
    The application route path.
    messages
    1 field
    generalResponseMessage
    5 fields
    name
    generalResponseMessage
    summary
    Authenticated application response.
    description
    The server buffers the handler's response via `ResponseWriterWrapper`, calls `Peer.toPeer` to sign it, and flushes the signed response including `x-bsv-auth-*` response headers. The `x-bsv-auth-signature` covers `requestId || statusCode || signed response headers || body`.
    headers
    1 field
    $ref
    #/components/schemas/GeneralResponseHeaders
    payload
    1 field
    description
    Application-defined response body.

    authError

    {applicationPath}

    Error responses emitted by the auth middleware when authentication fails.
    address
    {applicationPath}
    description
    Error responses emitted by the auth middleware when authentication fails.
    parameters
    1 field
    applicationPath
    1 field
    description
    The path at which the error was encountered.
    messages
    3 fields
    unauthorized
    3 fields
    name
    unauthorized
    summary
    401 — mutual auth failed (no or bad auth headers).
    payload
    1 field
    $ref
    #/components/schemas/AuthError401
    certificateTimeout
    3 fields
    name
    certificateTimeout
    summary
    408 — server waited 30 s for client certificates and timed out.
    payload
    1 field
    $ref
    #/components/schemas/AuthError408
    signingFailed
    3 fields
    name
    signingFailed
    summary
    500 — server failed to sign its response payload.
    payload
    1 field
    $ref
    #/components/schemas/AuthError500

    Operations

    5

    sendInitialRequest

    send
    Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`. The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`.
    action
    send
    channel
    1 field
    $ref
    #/channels/wellKnownAuth
    summary
    Client initiates BRC-103 handshake (Phase 1, step 1).
    description
    Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`. The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`.
    messages
    1 item
    1. $ref
      #/channels/wellKnownAuth/messages/initialRequest

    receiveInitialResponse

    receive
    Server replies with `initialResponse`. If `requestedCertificates` is non-empty the client must send a follow-up request with the required certificates before proceeding to Phase 2.
    action
    receive
    channel
    1 field
    $ref
    #/channels/wellKnownAuth
    summary
    Client receives the server's Phase 1 challenge response.
    description
    Server replies with `initialResponse`. If `requestedCertificates` is non-empty the client must send a follow-up request with the required certificates before proceeding to Phase 2.
    messages
    1 item
    1. $ref
      #/channels/wellKnownAuth/messages/initialResponse

    sendGeneralRequest

    send
    Any application HTTP request after the handshake. The client attaches `x-bsv-auth-*` headers and a fresh signed payload covering the full request. The server uses `buildAuthMessageFromRequest` to reconstruct and verify the payload.
    action
    send
    channel
    1 field
    $ref
    #/channels/generalRequest
    summary
    Client sends an authenticated application request (Phase 2).
    description
    Any application HTTP request after the handshake. The client attaches `x-bsv-auth-*` headers and a fresh signed payload covering the full request. The server uses `buildAuthMessageFromRequest` to reconstruct and verify the payload.
    messages
    1 item
    1. $ref
      #/channels/generalRequest/messages/generalRequestMessage

    receiveGeneralResponse

    receive
    The server's response includes `x-bsv-auth-*` headers and a signature over the response payload. The client can verify the response origin using `buildResponsePayload` semantics.
    action
    receive
    channel
    1 field
    $ref
    #/channels/generalResponse
    summary
    Client receives the server's authenticated application response (Phase 2).
    description
    The server's response includes `x-bsv-auth-*` headers and a signature over the response payload. The client can verify the response origin using `buildResponsePayload` semantics.
    messages
    1 item
    1. $ref
      #/channels/generalResponse/messages/generalResponseMessage

    receiveAuthError

    receive
    Client receives an auth error from the middleware.
    action
    receive
    channel
    1 field
    $ref
    #/channels/authError
    summary
    Client receives an auth error from the middleware.
    messages
    3 items
    1. $ref
      #/channels/authError/messages/unauthorized
    2. $ref
      #/channels/authError/messages/certificateTimeout
    3. $ref
      #/channels/authError/messages/signingFailed

    Schemas

    14

    PubKeyHex

    Compressed secp256k1 public key, 66 hex characters.
    type
    string
    pattern
    ^0[23][0-9a-fA-F]{64}$
    description
    Compressed secp256k1 public key, 66 hex characters.

    Base64String

    Base64-encoded binary data.
    type
    string
    description
    Base64-encoded binary data.

    HexString

    Hex-encoded binary data.
    type
    string
    pattern
    ^[0-9a-fA-F]+$
    description
    Hex-encoded binary data.

    AuthMessageType

    - `initialRequest` — first message from the initiating party - `initialResponse` — response from the receiving party completing Phase 1 - `general` — signed application message (Phase 2)
    type
    string
    enum
    3 items
    1. initialRequest
    2. initialResponse
    3. general
    description
    - `initialRequest` — first message from the initiating party - `initialResponse` — response from the receiving party completing Phase 1 - `general` — signed application message (Phase 2)

    AuthMessage

    The core BRC-103 message envelope. Transported over HTTP bodies (at `/.well-known/auth`) or Socket.IO `authMessage` events.
    type
    object
    description
    The core BRC-103 message envelope. Transported over HTTP bodies (at `/.well-known/auth`) or Socket.IO `authMessage` events.
    required
    3 items
    1. messageType
    2. version
    3. identityKey
    properties
    9 fields
    messageType
    1 field
    $ref
    #/components/schemas/AuthMessageType
    version
    2 fields
    type
    string
    description
    Auth protocol version (e.g. "0.1").
    identityKey
    2 fields
    $ref
    #/components/schemas/PubKeyHex
    description
    Public identity key of the sender of this message.
    nonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Fresh single-use random value generated by the sender. Stored in the `SessionManager` to prevent replay. Multi-instance deployments should store it in a shared `AsyncSessionManager` implementation.
    yourNonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Echo of the peer's nonce from the previous message.
    initialNonce
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    Present in `initialRequest` only. The very first nonce from the initiating party before a session key is established.
    payload
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    For `general` messages: the signed application payload. Encoding: `requestId(32) || VarInt(statusCode) || VarInt(nHeaders) || [header pairs] || VarInt(bodyLength) || body`. For handshake messages: empty or absent.
    signature
    3 fields
    type
    array
    items
    3 fields
    type
    integer
    minimum
    0
    maximum
    255
    description
    DER-encoded ECDSA signature over the payload.
    requestedCertificates
    3 fields
    type
    object
    description
    BRC-52 certificate request set. Present in `initialResponse` when the server requires certificates from the client.
    additionalProperties
    true

    InitialRequestHeaders

    HTTP request headers sent by the client when initiating the BRC-103 handshake at POST `/.well-known/auth`.
    type
    object
    description
    HTTP request headers sent by the client when initiating the BRC-103 handshake at POST `/.well-known/auth`.
    required
    3 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    properties
    3 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String

    InitialResponseHeaders

    HTTP response headers set by the server completing Phase 1 of the BRC-103 handshake.
    type
    object
    description
    HTTP response headers set by the server completing Phase 1 of the BRC-103 handshake.
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-message-type
    3. x-bsv-auth-identity-key
    4. x-bsv-auth-nonce
    5. x-bsv-auth-your-nonce
    6. x-bsv-auth-signature
    properties
    7 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-message-type
    2 fields
    type
    string
    enum
    1 item
    1. initialResponse
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-signature
    1 field
    $ref
    #/components/schemas/HexString
    x-bsv-auth-requested-certificates
    2 fields
    type
    string
    description
    JSON-encoded BRC-52 certificate request set (optional).

    GeneralRequestHeaders

    HTTP request headers sent by the client for every authenticated application request (Phase 2).
    type
    object
    description
    HTTP request headers sent by the client for every authenticated application request (Phase 2).
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    4. x-bsv-auth-your-nonce
    5. x-bsv-auth-request-id
    6. x-bsv-auth-signature
    properties
    6 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-request-id
    2 fields
    $ref
    #/components/schemas/Base64String
    description
    32-byte random value, base64-encoded.
    x-bsv-auth-signature
    2 fields
    $ref
    #/components/schemas/HexString
    description
    ECDSA signature over: `requestId(32B) || VarInt(method.length) || method || VarInt(pathname.length) || pathname || VarInt(search.length) || search (or -1 if empty) || VarInt(nHeaders) || [sorted header pairs] || VarInt(bodyLength) || body (or -1 if empty)`.

    GeneralResponseHeaders

    HTTP response headers set by the server on every authenticated application response (Phase 2).
    type
    object
    description
    HTTP response headers set by the server on every authenticated application response (Phase 2).
    required
    6 items
    1. x-bsv-auth-version
    2. x-bsv-auth-identity-key
    3. x-bsv-auth-nonce
    4. x-bsv-auth-your-nonce
    5. x-bsv-auth-request-id
    6. x-bsv-auth-signature
    properties
    6 fields
    x-bsv-auth-version
    1 field
    type
    string
    x-bsv-auth-identity-key
    1 field
    $ref
    #/components/schemas/PubKeyHex
    x-bsv-auth-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-your-nonce
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-request-id
    1 field
    $ref
    #/components/schemas/Base64String
    x-bsv-auth-signature
    2 fields
    $ref
    #/components/schemas/HexString
    description
    ECDSA signature over: `requestId(32B) || VarInt(statusCode) || VarInt(nHeaders) || [sorted non-auth x-bsv header pairs] || VarInt(bodyLength) || body (or -1 if empty)`.

    AuthError401

    Returned when mutual authentication fails (no or bad auth headers).
    type
    object
    description
    Returned when mutual authentication fails (no or bad auth headers).
    required
    3 items
    1. status
    2. code
    3. message
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    2 items
    1. UNAUTHORIZED
    2. ERR_AUTH_FAILED
    message
    1 field
    type
    string

    AuthError408

    Returned when the server is waiting for client certificates and the 30-second timeout elapses.
    type
    object
    description
    Returned when the server is waiting for client certificates and the 30-second timeout elapses.
    required
    3 items
    1. status
    2. code
    3. message
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    1 item
    1. CERTIFICATE_TIMEOUT
    message
    1 field
    type
    string

    AuthError500

    Returned when the server fails to sign its response payload (`ERR_RESPONSE_SIGNING_FAILED`).
    type
    object
    description
    Returned when the server fails to sign its response payload (`ERR_RESPONSE_SIGNING_FAILED`).
    required
    3 items
    1. status
    2. code
    3. description
    properties
    3 fields
    status
    2 fields
    type
    string
    enum
    1 item
    1. error
    code
    2 fields
    type
    string
    enum
    2 items
    1. ERR_RESPONSE_SIGNING_FAILED
    2. ERR_INTERNAL_SERVER_ERROR
    description
    1 field
    type
    string

    RequestAuthPayload

    Informational schema: the signed payload for a `general` REQUEST. Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`. Wire encoding (binary, concatenated): | Field | Encoding | |------------------|------------------------------------------| | requestId | 32 raw bytes (decoded from base64) | | method | VarInt(len) + UTF-8 bytes | | pathname | VarInt(len) + UTF-8 bytes | | search | VarInt(len) + UTF-8 bytes, or VarInt(-1) | | nHeaders | VarInt | | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | | bodyLength | VarInt(len) or VarInt(-1) | | body | raw bytes | Only these headers are included (sorted, lowercase): - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) - `content-type` (normalized: type only, no parameters) - `authorization`
    type
    object
    description
    Informational schema: the signed payload for a `general` REQUEST. Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`. Wire encoding (binary, concatenated): | Field | Encoding | |------------------|------------------------------------------| | requestId | 32 raw bytes (decoded from base64) | | method | VarInt(len) + UTF-8 bytes | | pathname | VarInt(len) + UTF-8 bytes | | search | VarInt(len) + UTF-8 bytes, or VarInt(-1) | | nHeaders | VarInt | | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | | bodyLength | VarInt(len) or VarInt(-1) | | body | raw bytes | Only these headers are included (sorted, lowercase): - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) - `content-type` (normalized: type only, no parameters) - `authorization`

    ResponseAuthPayload

    Informational schema: the signed payload for a `general` RESPONSE. Assembled by `buildResponsePayload` in `ExpressTransport`. Wire encoding (binary, concatenated): | Field | Encoding | |------------------|------------------------------------------| | requestId | 32 raw bytes (decoded from base64) | | statusCode | VarInt | | nHeaders | VarInt | | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | | bodyLength | VarInt(len) or VarInt(-1) | | body | raw bytes | Only these response headers are included (sorted, lowercase): - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) - `authorization`
    type
    object
    description
    Informational schema: the signed payload for a `general` RESPONSE. Assembled by `buildResponsePayload` in `ExpressTransport`. Wire encoding (binary, concatenated): | Field | Encoding | |------------------|------------------------------------------| | requestId | 32 raw bytes (decoded from base64) | | statusCode | VarInt | | nHeaders | VarInt | | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val | | bodyLength | VarInt(len) or VarInt(-1) | | body | raw bytes | Only these response headers are included (sorted, lowercase): - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`) - `authorization`
    Raw YAML source
    asyncapi: "3.1.0"
    
    info:
      title: BRC-103 Mutual Authentication Handshake
      version: "1.0.0"
      description: |
        AsyncAPI 3.0 specification for the BRC-103 peer-to-peer mutual
        authentication protocol (https://bsv.brc.dev/peer-to-peer/0103) as
        implemented in:
    
        - `packages/middleware/auth-express-middleware/src/index.ts`
          (`ExpressTransport`, `createAuthMiddleware`) — BRC-104 HTTP transport
          (https://bsv.brc.dev/peer-to-peer/0104)
        - `packages/messaging/authsocket/src/SocketServerTransport.ts`
          (`SocketServerTransport`) — Socket.IO transport
        - `@bsv/sdk` `Peer` and `Transport` interfaces
    
        Note: this file replaces the earlier `brc31-handshake.yaml`. BRC-31 was
        the legacy identifier; the protocol is now standardised as BRC-103 with
        BRC-104 covering the HTTP binding.
    
        ## Protocol overview
    
        BRC-103 mutual authentication uses ECDH-derived key pairs to create a
        shared, forward-secret session between two parties. Neither party trusts
        the other's identity until the signed handshake is verified.
    
        ### Two-phase handshake
    
        **Phase 1 — Non-general (initial exchange)**
    
        Carried over the special endpoint `POST /.well-known/auth` for HTTP
        transports, or the `authMessage` Socket.IO event for WebSocket transports.
    
        1. **Client → Server** `initialRequest`
           Client generates a fresh nonce, signs it with its identity key, and
           sends the auth message. Headers on the HTTP path:
           ```
           x-bsv-auth-version: <version>
           x-bsv-auth-identity-key: <clientPubKeyHex>
           x-bsv-auth-nonce: <base64Nonce>
           ```
           Body (HTTP): the `AuthMessage` JSON object.
    
        2. **Server → Client** `initialResponse`
           Server validates the client's nonce/signature, generates its own nonce,
           signs the response, and returns the `AuthMessage`. HTTP response headers:
           ```
           x-bsv-auth-version: <version>
           x-bsv-auth-message-type: initialResponse
           x-bsv-auth-identity-key: <serverPubKeyHex>
           x-bsv-auth-nonce: <base64ServerNonce>
           x-bsv-auth-your-nonce: <base64ClientNonce>
           x-bsv-auth-signature: <hexDERSignature>
           x-bsv-auth-requested-certificates: <JSON> (optional)
           ```
    
        **Phase 2 — General (authenticated request/response)**
    
        Once the session is established all subsequent HTTP requests carry:
        ```
        x-bsv-auth-version: <version>
        x-bsv-auth-identity-key: <clientPubKeyHex>
        x-bsv-auth-nonce: <base64Nonce>
        x-bsv-auth-your-nonce: <base64ServerNonce>
        x-bsv-auth-request-id: <base64RequestId>
        x-bsv-auth-signature: <hexDERSignature>
        ```
    
        The signed payload includes: `requestId || method || pathname || search
        || headers (sorted) || body`.
    
        The server responds with:
        ```
        x-bsv-auth-version: <version>
        x-bsv-auth-identity-key: <serverPubKeyHex>
        x-bsv-auth-nonce: <base64Nonce>
        x-bsv-auth-your-nonce: <base64ClientNonce>
        x-bsv-auth-request-id: <base64RequestId>
        x-bsv-auth-signature: <hexDERSignature>
        ```
    
        The signed response payload includes: `requestId || statusCode ||
        headers (sorted) || body`.
    
        ### Certificate flow (optional)
    
        If the server declares `certificatesToRequest`, it embeds the request set
        in the `x-bsv-auth-requested-certificates` header of the `initialResponse`.
        The client then provides certificates in a follow-up `/.well-known/auth`
        call before the `next()` middleware proceeds. The server waits up to
        30 seconds; timeout returns 408.
    
        ### Unauthenticated pass-through
    
        If `allowUnauthenticated: true` is set in middleware options, requests
        without auth headers proceed with `req.auth.identityKey = 'unknown'`.
    
        ## Implementation-specific notes
    
        - `ExpressTransport` intercepts `res.status`, `res.json`, `res.send`,
          `res.set`, `res.end`, `res.sendFile`, and `res.text` to buffer the
          response until after `Peer.toPeer` signs and re-emits it. Original
          methods are saved as `res.__status`, `res.__json`, etc.
        - The `RequestId` is a 32-byte random value encoded as base64.
        - Nonces are single-use; the `SessionManager` stores seen nonces to
          prevent replay. Deployments that run multiple server instances should
          use a shared `AsyncSessionManager` store so every instance can resolve
          the same nonce/session state during the handshake.
    
    servers:
      httpServer:
        host: "{host}"
        pathname: "/.well-known/auth"
        protocol: https
        description: |
          HTTP endpoint for BRC-103 non-general (initial handshake) messages.
          General (authenticated) messages use normal application paths.
        variables:
          host:
            default: messagebox.babbage.systems
    
    # ---------------------------------------------------------------------------
    # Components
    # ---------------------------------------------------------------------------
    components:
      schemas:
        PubKeyHex:
          type: string
          pattern: "^0[23][0-9a-fA-F]{64}$"
          description: Compressed secp256k1 public key, 66 hex characters.
    
        Base64String:
          type: string
          description: Base64-encoded binary data.
    
        HexString:
          type: string
          pattern: "^[0-9a-fA-F]+$"
          description: Hex-encoded binary data.
    
        AuthMessageType:
          type: string
          enum: [initialRequest, initialResponse, general]
          description: |
            - `initialRequest`  — first message from the initiating party
            - `initialResponse` — response from the receiving party completing Phase 1
            - `general`         — signed application message (Phase 2)
    
        AuthMessage:
          type: object
          description: |
            The core BRC-103 message envelope. Transported over HTTP bodies
            (at `/.well-known/auth`) or Socket.IO `authMessage` events.
          required: [messageType, version, identityKey]
          properties:
            messageType:
              $ref: "#/components/schemas/AuthMessageType"
            version:
              type: string
              description: Auth protocol version (e.g. "0.1").
            identityKey:
              $ref: "#/components/schemas/PubKeyHex"
              description: Public identity key of the sender of this message.
            nonce:
              $ref: "#/components/schemas/Base64String"
              description: |
                Fresh single-use random value generated by the sender.
                Stored in the `SessionManager` to prevent replay. Multi-instance
                deployments should store it in a shared `AsyncSessionManager`
                implementation.
            yourNonce:
              $ref: "#/components/schemas/Base64String"
              description: Echo of the peer's nonce from the previous message.
            initialNonce:
              $ref: "#/components/schemas/Base64String"
              description: |
                Present in `initialRequest` only. The very first nonce from the
                initiating party before a session key is established.
            payload:
              type: array
              items:
                type: integer
                minimum: 0
                maximum: 255
              description: |
                For `general` messages: the signed application payload.
                Encoding: `requestId(32) || VarInt(statusCode) || VarInt(nHeaders)
                || [header pairs] || VarInt(bodyLength) || body`.
                For handshake messages: empty or absent.
            signature:
              type: array
              items:
                type: integer
                minimum: 0
                maximum: 255
              description: DER-encoded ECDSA signature over the payload.
            requestedCertificates:
              type: object
              description: |
                BRC-52 certificate request set. Present in `initialResponse` when
                the server requires certificates from the client.
              additionalProperties: true
    
        # -------------------------------------------------------------------------
        # HTTP header shapes (informational — not AsyncAPI schema objects)
        # -------------------------------------------------------------------------
        InitialRequestHeaders:
          type: object
          description: |
            HTTP request headers sent by the client when initiating the BRC-103
            handshake at POST `/.well-known/auth`.
          required:
            - x-bsv-auth-version
            - x-bsv-auth-identity-key
            - x-bsv-auth-nonce
          properties:
            x-bsv-auth-version:
              type: string
            x-bsv-auth-identity-key:
              $ref: "#/components/schemas/PubKeyHex"
            x-bsv-auth-nonce:
              $ref: "#/components/schemas/Base64String"
    
        InitialResponseHeaders:
          type: object
          description: |
            HTTP response headers set by the server completing Phase 1 of the
            BRC-103 handshake.
          required:
            - x-bsv-auth-version
            - x-bsv-auth-message-type
            - x-bsv-auth-identity-key
            - x-bsv-auth-nonce
            - x-bsv-auth-your-nonce
            - x-bsv-auth-signature
          properties:
            x-bsv-auth-version:
              type: string
            x-bsv-auth-message-type:
              type: string
              enum: [initialResponse]
            x-bsv-auth-identity-key:
              $ref: "#/components/schemas/PubKeyHex"
            x-bsv-auth-nonce:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-your-nonce:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-signature:
              $ref: "#/components/schemas/HexString"
            x-bsv-auth-requested-certificates:
              type: string
              description: JSON-encoded BRC-52 certificate request set (optional).
    
        GeneralRequestHeaders:
          type: object
          description: |
            HTTP request headers sent by the client for every authenticated
            application request (Phase 2).
          required:
            - x-bsv-auth-version
            - x-bsv-auth-identity-key
            - x-bsv-auth-nonce
            - x-bsv-auth-your-nonce
            - x-bsv-auth-request-id
            - x-bsv-auth-signature
          properties:
            x-bsv-auth-version:
              type: string
            x-bsv-auth-identity-key:
              $ref: "#/components/schemas/PubKeyHex"
            x-bsv-auth-nonce:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-your-nonce:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-request-id:
              $ref: "#/components/schemas/Base64String"
              description: 32-byte random value, base64-encoded.
            x-bsv-auth-signature:
              $ref: "#/components/schemas/HexString"
              description: |
                ECDSA signature over:
                `requestId(32B) || VarInt(method.length) || method
                || VarInt(pathname.length) || pathname
                || VarInt(search.length) || search (or -1 if empty)
                || VarInt(nHeaders) || [sorted header pairs]
                || VarInt(bodyLength) || body (or -1 if empty)`.
    
        GeneralResponseHeaders:
          type: object
          description: |
            HTTP response headers set by the server on every authenticated
            application response (Phase 2).
          required:
            - x-bsv-auth-version
            - x-bsv-auth-identity-key
            - x-bsv-auth-nonce
            - x-bsv-auth-your-nonce
            - x-bsv-auth-request-id
            - x-bsv-auth-signature
          properties:
            x-bsv-auth-version:
              type: string
            x-bsv-auth-identity-key:
              $ref: "#/components/schemas/PubKeyHex"
            x-bsv-auth-nonce:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-your-nonce:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-request-id:
              $ref: "#/components/schemas/Base64String"
            x-bsv-auth-signature:
              $ref: "#/components/schemas/HexString"
              description: |
                ECDSA signature over:
                `requestId(32B) || VarInt(statusCode)
                || VarInt(nHeaders) || [sorted non-auth x-bsv header pairs]
                || VarInt(bodyLength) || body (or -1 if empty)`.
    
        # -------------------------------------------------------------------------
        # Error shapes
        # -------------------------------------------------------------------------
        AuthError401:
          type: object
          description: Returned when mutual authentication fails (no or bad auth headers).
          required: [status, code, message]
          properties:
            status:
              type: string
              enum: [error]
            code:
              type: string
              enum: [UNAUTHORIZED, ERR_AUTH_FAILED]
            message:
              type: string
    
        AuthError408:
          type: object
          description: |
            Returned when the server is waiting for client certificates
            and the 30-second timeout elapses.
          required: [status, code, message]
          properties:
            status:
              type: string
              enum: [error]
            code:
              type: string
              enum: [CERTIFICATE_TIMEOUT]
            message:
              type: string
    
        AuthError500:
          type: object
          description: |
            Returned when the server fails to sign its response payload
            (`ERR_RESPONSE_SIGNING_FAILED`).
          required: [status, code, description]
          properties:
            status:
              type: string
              enum: [error]
            code:
              type: string
              enum: [ERR_RESPONSE_SIGNING_FAILED, ERR_INTERNAL_SERVER_ERROR]
            description:
              type: string
    
        RequestAuthPayload:
          type: object
          description: |
            Informational schema: the signed payload for a `general` REQUEST.
            Assembled by `buildAuthMessageFromRequest` in `ExpressTransport`.
    
            Wire encoding (binary, concatenated):
            | Field            | Encoding                                 |
            |------------------|------------------------------------------|
            | requestId        | 32 raw bytes (decoded from base64)       |
            | method           | VarInt(len) + UTF-8 bytes                |
            | pathname         | VarInt(len) + UTF-8 bytes                |
            | search           | VarInt(len) + UTF-8 bytes, or VarInt(-1) |
            | nHeaders         | VarInt                                   |
            | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val  |
            | bodyLength       | VarInt(len) or VarInt(-1)                |
            | body             | raw bytes                                |
    
            Only these headers are included (sorted, lowercase):
            - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`)
            - `content-type` (normalized: type only, no parameters)
            - `authorization`
    
        ResponseAuthPayload:
          type: object
          description: |
            Informational schema: the signed payload for a `general` RESPONSE.
            Assembled by `buildResponsePayload` in `ExpressTransport`.
    
            Wire encoding (binary, concatenated):
            | Field            | Encoding                                 |
            |------------------|------------------------------------------|
            | requestId        | 32 raw bytes (decoded from base64)       |
            | statusCode       | VarInt                                   |
            | nHeaders         | VarInt                                   |
            | headers (sorted) | VarInt(keyLen)+key + VarInt(valLen)+val  |
            | bodyLength       | VarInt(len) or VarInt(-1)                |
            | body             | raw bytes                                |
    
            Only these response headers are included (sorted, lowercase):
            - Headers starting with `x-bsv-` (but NOT `x-bsv-auth-*`)
            - `authorization`
    
    # ---------------------------------------------------------------------------
    # Channels
    # ---------------------------------------------------------------------------
    channels:
    
      wellKnownAuth:
        address: "/.well-known/auth"
        description: |
          HTTP channel used for Phase 1 (non-general) BRC-103 handshake messages.
          The client POSTs an `AuthMessage` JSON body; the server replies with an
          `AuthMessage` JSON body and the `x-bsv-auth-*` response headers.
    
          In Socket.IO transports the same exchange happens over the `authMessage`
          Socket.IO event (see `authsocket-asyncapi.yaml`) rather than this HTTP
          endpoint.
        messages:
          initialRequest:
            name: initialRequest
            summary: Client initiates the BRC-103 handshake.
            description: |
              The client generates a nonce, signs it, and sends the
              `initialRequest` AuthMessage as the POST body.
            headers:
              $ref: "#/components/schemas/InitialRequestHeaders"
            payload:
              $ref: "#/components/schemas/AuthMessage"
            examples:
              - name: example-initial-request
                payload:
                  messageType: initialRequest
                  version: "0.1"
                  identityKey: "028d37b941208cd6b8a4c28288eda5f2f16c2b3ab0fcb6d13c18b47fe37b971fc1"
                  nonce: "dGVzdE5vbmNlMTIzNA=="
                  initialNonce: "dGVzdE5vbmNlMTIzNA=="
                  payload: []
                  signature: []
    
          initialResponse:
            name: initialResponse
            summary: Server completes Phase 1 of the BRC-103 handshake.
            description: |
              The server validates the client's nonce/signature, generates its own
              nonce, signs the response, and replies. The body is an `AuthMessage`
              JSON object. Response headers carry the `x-bsv-auth-*` fields.
    
              If `certificatesToRequest` is configured, the
              `x-bsv-auth-requested-certificates` header contains the JSON-encoded
              request set. The client must supply certificates in a follow-up
              POST before the session is fully established.
            headers:
              $ref: "#/components/schemas/InitialResponseHeaders"
            payload:
              $ref: "#/components/schemas/AuthMessage"
    
      generalRequest:
        address: "{applicationPath}"
        description: |
          Every authenticated application HTTP request (Phase 2). The path is
          the actual application endpoint (e.g. `/sendMessage`, `/listMessages`).
          The auth headers are attached alongside any application-specific headers.
        parameters:
          applicationPath:
            description: The application route path (e.g. /sendMessage).
        messages:
          generalRequestMessage:
            name: generalRequestMessage
            summary: Authenticated application request.
            description: |
              The client sends application-level request headers and body, augmented
              with `x-bsv-auth-*` mutual-auth headers. The `x-bsv-auth-signature`
              covers the entire request (method, path, query string, signed headers,
              and body) as described in `RequestAuthPayload`.
            headers:
              $ref: "#/components/schemas/GeneralRequestHeaders"
            payload:
              description: Application-defined request body (any content type).
    
      generalResponse:
        address: "{applicationPath}"
        description: |
          Every authenticated application HTTP response (Phase 2). The server
          signs the response status code, relevant headers, and body before sending.
        parameters:
          applicationPath:
            description: The application route path.
        messages:
          generalResponseMessage:
            name: generalResponseMessage
            summary: Authenticated application response.
            description: |
              The server buffers the handler's response via `ResponseWriterWrapper`,
              calls `Peer.toPeer` to sign it, and flushes the signed response
              including `x-bsv-auth-*` response headers. The `x-bsv-auth-signature`
              covers `requestId || statusCode || signed response headers || body`.
            headers:
              $ref: "#/components/schemas/GeneralResponseHeaders"
            payload:
              description: Application-defined response body.
    
      authError:
        address: "{applicationPath}"
        description: |
          Error responses emitted by the auth middleware when authentication fails.
        parameters:
          applicationPath:
            description: The path at which the error was encountered.
        messages:
          unauthorized:
            name: unauthorized
            summary: 401 — mutual auth failed (no or bad auth headers).
            payload:
              $ref: "#/components/schemas/AuthError401"
    
          certificateTimeout:
            name: certificateTimeout
            summary: 408 — server waited 30 s for client certificates and timed out.
            payload:
              $ref: "#/components/schemas/AuthError408"
    
          signingFailed:
            name: signingFailed
            summary: 500 — server failed to sign its response payload.
            payload:
              $ref: "#/components/schemas/AuthError500"
    
    # ---------------------------------------------------------------------------
    # Operations
    # ---------------------------------------------------------------------------
    operations:
    
      sendInitialRequest:
        action: send
        channel:
          $ref: "#/channels/wellKnownAuth"
        summary: Client initiates BRC-103 handshake (Phase 1, step 1).
        description: |
          Client POSTs an `initialRequest` AuthMessage to `/.well-known/auth`.
          The body is a JSON-serialized `AuthMessage` with `messageType: initialRequest`.
        messages:
          - $ref: "#/channels/wellKnownAuth/messages/initialRequest"
    
      receiveInitialResponse:
        action: receive
        channel:
          $ref: "#/channels/wellKnownAuth"
        summary: Client receives the server's Phase 1 challenge response.
        description: |
          Server replies with `initialResponse`. If `requestedCertificates` is
          non-empty the client must send a follow-up request with the required
          certificates before proceeding to Phase 2.
        messages:
          - $ref: "#/channels/wellKnownAuth/messages/initialResponse"
    
      sendGeneralRequest:
        action: send
        channel:
          $ref: "#/channels/generalRequest"
        summary: Client sends an authenticated application request (Phase 2).
        description: |
          Any application HTTP request after the handshake. The client attaches
          `x-bsv-auth-*` headers and a fresh signed payload covering the full
          request. The server uses `buildAuthMessageFromRequest` to reconstruct
          and verify the payload.
        messages:
          - $ref: "#/channels/generalRequest/messages/generalRequestMessage"
    
      receiveGeneralResponse:
        action: receive
        channel:
          $ref: "#/channels/generalResponse"
        summary: Client receives the server's authenticated application response (Phase 2).
        description: |
          The server's response includes `x-bsv-auth-*` headers and a signature
          over the response payload. The client can verify the response origin
          using `buildResponsePayload` semantics.
        messages:
          - $ref: "#/channels/generalResponse/messages/generalResponseMessage"
    
      receiveAuthError:
        action: receive
        channel:
          $ref: "#/channels/authError"
        summary: Client receives an auth error from the middleware.
        messages:
          - $ref: "#/channels/authError/messages/unauthorized"
          - $ref: "#/channels/authError/messages/certificateTimeout"
          - $ref: "#/channels/authError/messages/signingFailed"
    
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    \ No newline at end of file diff --git a/docs-site/public/assets/asyncapi/gasp/index.html b/docs-site/public/assets/asyncapi/gasp/index.html index 7f67491f4..40ca9bfcd 100644 --- a/docs-site/public/assets/asyncapi/gasp/index.html +++ b/docs-site/public/assets/asyncapi/gasp/index.html @@ -1,862 +1 @@ - - - - - - - GASP — Graph Aware Sync Protocol · AsyncAPI - - - -
    -
    AsyncAPI 3.1.0 · specs/sync/gasp-asyncapi.yaml
    -

    GASP — Graph Aware Sync Protocol

    v1.0.0
    -
    AsyncAPI specification for GASP (Graph Aware Sync Protocol), the -cross-node UTXO synchronisation protocol implemented in -`gasp-core` (`@bsv/gasp-core`). - -GASP is a bidirectional gossip/sync protocol between overlay nodes. -Two parties exchange UTXO lists (the "initial exchange") and then -walk the transaction graph in a request/response pattern to transfer -any UTXOs the counterparty does not yet hold. - -## Protocol flow (normal, bidirectional) - -``` -Initiator Responder - | | - |-- GASPInitialRequest ---------------------->| - |<- GASPInitialResponse -----------------------| - |-- GASPInitialReply ------------------------->| (if not unidirectional) - | | - | [for each UTXO the counterparty is missing] - |-- requestNode(graphID, txid, vout, meta) -->| - |<- GASPNode ---------------------------------| - | | - | [responder may request further inputs] - |<- submitNode(GASPNode) ---------------------| - |-- GASPNodeResponse ------------------------>| - | (repeat until graph is complete) - | | -``` - -Source of truth: /ts/gasp-core/src/GASP.ts -
    -
    0Servers7Channels7Operations6Messages8Schemas
    -
    - -
    -
    -

    Channels

    7
    -
    -

    gaspInitialRequest

    -

    gasp/initialRequest

    -
    Initiator sends its sync parameters. The responder replies on the -`gasp/initialResponse` channel. -
    -
    address
    gasp/initialRequest
    description
    Initiator sends its sync parameters. The responder replies on the -`gasp/initialResponse` channel. -
    messages
    1 field
    GASPInitialRequest
    1 field
    $ref
    #/components/messages/GASPInitialRequest
    -
    -

    gaspInitialResponse

    -

    gasp/initialResponse

    -
    Responder sends back its list of known UTXOs and the timestamp from -which it wants to receive UTXOs from the initiator. -
    -
    address
    gasp/initialResponse
    description
    Responder sends back its list of known UTXOs and the timestamp from -which it wants to receive UTXOs from the initiator. -
    messages
    1 field
    GASPInitialResponse
    1 field
    $ref
    #/components/messages/GASPInitialResponse
    -
    -

    gaspInitialReply

    -

    gasp/initialReply

    -
    Initiator (if operating in bidirectional mode) sends the set of UTXOs -it holds that the responder does not. Absent in unidirectional mode. -
    -
    address
    gasp/initialReply
    description
    Initiator (if operating in bidirectional mode) sends the set of UTXOs -it holds that the responder does not. Absent in unidirectional mode. -
    messages
    1 field
    GASPInitialReply
    1 field
    $ref
    #/components/messages/GASPInitialReply
    -
    -

    gaspRequestNode

    -

    gasp/requestNode

    -
    Either party requests a specific graph node (transaction + output) from -the other. Used when walking the transaction graph to hydrate UTXOs. -
    -
    address
    gasp/requestNode
    description
    Either party requests a specific graph node (transaction + output) from -the other. Used when walking the transaction graph to hydrate UTXOs. -
    messages
    1 field
    GASPNodeRequest
    1 field
    $ref
    #/components/messages/GASPNodeRequest
    -
    -

    gaspNode

    -

    gasp/node

    -
    The responding party delivers the requested GASPNode (raw transaction, -optional BUMP proof, optional metadata). -
    -
    address
    gasp/node
    description
    The responding party delivers the requested GASPNode (raw transaction, -optional BUMP proof, optional metadata). -
    messages
    1 field
    GASPNode
    1 field
    $ref
    #/components/messages/GASPNode
    -
    -

    gaspSubmitNode

    -

    gasp/submitNode

    -
    A party submits a node it is trying to push to the counterparty. -The counterparty appends it to the temporary graph and may respond -with a list of additional inputs it still needs. -
    -
    address
    gasp/submitNode
    description
    A party submits a node it is trying to push to the counterparty. -The counterparty appends it to the temporary graph and may respond -with a list of additional inputs it still needs. -
    messages
    1 field
    GASPNode
    1 field
    $ref
    #/components/messages/GASPNode
    -
    -

    gaspNodeResponse

    -

    gasp/nodeResponse

    -
    Response to a submitted node; specifies which additional input transactions -(if any) the recipient still needs to complete the graph. An empty / null -response means the graph is complete. -
    -
    address
    gasp/nodeResponse
    description
    Response to a submitted node; specifies which additional input transactions -(if any) the recipient still needs to complete the graph. An empty / null -response means the graph is complete. -
    messages
    1 field
    GASPNodeResponse
    1 field
    $ref
    #/components/messages/GASPNodeResponse
    -
    -
    -

    Operations

    7
    -
    -

    sendInitialRequest

    - send -
    Initiator sends sync parameters to the responder.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspInitialRequest
    summary
    Initiator sends sync parameters to the responder.
    messages
    1 item
    1. $ref
      #/channels/gaspInitialRequest/messages/GASPInitialRequest
    -
    -

    receiveInitialResponse

    - receive -
    Initiator receives the responder's UTXO list and since timestamp.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/gaspInitialResponse
    summary
    Initiator receives the responder's UTXO list and since timestamp.
    messages
    1 item
    1. $ref
      #/channels/gaspInitialResponse/messages/GASPInitialResponse
    -
    -

    sendInitialReply

    - send -
    Initiator (bidirectional mode only) sends UTXOs the responder is missing. -
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspInitialReply
    summary
    Initiator (bidirectional mode only) sends UTXOs the responder is missing. -
    messages
    1 item
    1. $ref
      #/channels/gaspInitialReply/messages/GASPInitialReply
    -
    -

    requestNode

    - send -
    Request a specific transaction node from the counterparty.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspRequestNode
    summary
    Request a specific transaction node from the counterparty.
    messages
    1 item
    1. $ref
      #/channels/gaspRequestNode/messages/GASPNodeRequest
    -
    -

    deliverNode

    - receive -
    Receive a requested graph node from the counterparty.
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/gaspNode
    summary
    Receive a requested graph node from the counterparty.
    messages
    1 item
    1. $ref
      #/channels/gaspNode/messages/GASPNode
    -
    -

    submitNode

    - send -
    Push a graph node to the counterparty for ingestion.
    -
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspSubmitNode
    summary
    Push a graph node to the counterparty for ingestion.
    messages
    1 item
    1. $ref
      #/channels/gaspSubmitNode/messages/GASPNode
    -
    -

    receiveNodeResponse

    - receive -
    Receive the counterparty's response to a submitted node, listing any -additional input transactions needed to complete the graph. -
    -
    action
    receive
    channel
    1 field
    $ref
    #/channels/gaspNodeResponse
    summary
    Receive the counterparty's response to a submitted node, listing any -additional input transactions needed to complete the graph. -
    messages
    1 item
    1. $ref
      #/channels/gaspNodeResponse/messages/GASPNodeResponse
    -
    -
    -

    Messages

    6
    -
    -

    GASPInitialRequest

    - -
    First message in a GASP sync session. The initiator declares its -protocol version, the timestamp of the last sync with this party, and -an optional page size limit. -
    -
    name
    GASPInitialRequest
    title
    GASP Initial Request
    summary
    First message in a GASP sync session. The initiator declares its -protocol version, the timestamp of the last sync with this party, and -an optional page size limit. -
    payload
    1 field
    $ref
    #/components/schemas/GASPInitialRequest
    -
    -

    GASPInitialResponse

    - -
    Responder's reply to GASPInitialRequest. Contains the list of UTXOs -the responder has seen since `request.since`, plus the timestamp from -which the responder wants UTXOs back from the initiator. -
    -
    name
    GASPInitialResponse
    title
    GASP Initial Response
    summary
    Responder's reply to GASPInitialRequest. Contains the list of UTXOs -the responder has seen since `request.since`, plus the timestamp from -which the responder wants UTXOs back from the initiator. -
    payload
    1 field
    $ref
    #/components/schemas/GASPInitialResponse
    -
    -

    GASPInitialReply

    - -
    Initiator's follow-up (bidirectional mode). UTXOs the initiator holds -that were not in the Initial Response — i.e. UTXOs the responder needs. -
    -
    name
    GASPInitialReply
    title
    GASP Initial Reply
    summary
    Initiator's follow-up (bidirectional mode). UTXOs the initiator holds -that were not in the Initial Response — i.e. UTXOs the responder needs. -
    payload
    1 field
    $ref
    #/components/schemas/GASPInitialReply
    -
    -

    GASPNodeRequest

    - -
    Request for a specific transaction node identified by graphID, txid, -outputIndex, and whether transaction/output metadata should be included. -
    -
    name
    GASPNodeRequest
    title
    GASP Node Request
    summary
    Request for a specific transaction node identified by graphID, txid, -outputIndex, and whether transaction/output metadata should be included. -
    payload
    1 field
    $ref
    #/components/schemas/GASPNodeRequest
    -
    -

    GASPNode

    - -
    A transaction node: the raw transaction, the output index, an optional -BUMP merkle proof, optional metadata strings, and a mapping of input -outpoints to metadata hashes so the receiver can request ancestors. -
    -
    name
    GASPNode
    title
    GASP Node
    summary
    A transaction node: the raw transaction, the output index, an optional -BUMP merkle proof, optional metadata strings, and a mapping of input -outpoints to metadata hashes so the receiver can request ancestors. -
    payload
    1 field
    $ref
    #/components/schemas/GASPNode
    -
    -

    GASPNodeResponse

    - -
    Response to a submitted GASPNode. Lists the input outpoints (in -36-byte `<txid>.<vout>` format) that the recipient still needs to -complete the graph. A null / absent response means no further inputs -are required and the graph is complete. -
    -
    name
    GASPNodeResponse
    title
    GASP Node Response
    summary
    Response to a submitted GASPNode. Lists the input outpoints (in -36-byte `<txid>.<vout>` format) that the recipient still needs to -complete the graph. A null / absent response means no further inputs -are required and the graph is complete. -
    payload
    1 field
    $ref
    #/components/schemas/GASPNodeResponse
    -
    -
    -

    Schemas

    8
    -
    -

    GASPInitialRequest

    - -
    Parameters sent by the initiator to start a GASP sync session. -Version mismatch (current version is 1) causes the responder to throw -GASPVersionMismatchError and abort the session. -
    -
    type
    object
    description
    Parameters sent by the initiator to start a GASP sync session. -Version mismatch (current version is 1) causes the responder to throw -GASPVersionMismatchError and abort the session. -
    required
    2 items
    1. version
    2. since
    properties
    3 fields
    version
    4 fields
    type
    integer
    description
    GASP protocol version. Currently always 1.
    enum
    1 item
    1. 1
    example
    1
    since
    4 fields
    type
    integer
    minimum
    0
    description
    UNIX timestamp (seconds since epoch) of the last successful sync -with this counterparty. Use 0 to request all UTXOs. -Must be a non-negative integer. -
    example
    1714000000
    limit
    4 fields
    type
    integer
    minimum
    1
    description
    Optional maximum number of UTXOs the responder should return per -page. When the response contains exactly `limit` items the -initiator MUST send another GASPInitialRequest to fetch the next -page. Absent means "return all". -
    example
    1000
    -
    -

    GASPInitialResponse

    - -
    Responder's answer to GASPInitialRequest. `UTXOList` contains all -UTXOs the responder has seen since `request.since`; unconfirmed -(non-timestamped) UTXOs are always included regardless of timestamp. -
    -
    type
    object
    description
    Responder's answer to GASPInitialRequest. `UTXOList` contains all -UTXOs the responder has seen since `request.since`; unconfirmed -(non-timestamped) UTXOs are always included regardless of timestamp. -
    required
    2 items
    1. UTXOList
    2. since
    properties
    2 fields
    UTXOList
    3 fields
    type
    array
    description
    UTXOs the responder knows about (after `request.since`). The -initiator will request any of these it does not already hold. -
    items
    1 field
    $ref
    #/components/schemas/GASPOutput
    since
    4 fields
    type
    integer
    minimum
    0
    description
    Timestamp from which the responder wants to receive UTXOs back -from the initiator (used in the GASPInitialReply filter step). -
    example
    1714001000
    -
    -

    GASPInitialReply

    - -
    Sent by the initiator in bidirectional mode. Contains UTXOs the -initiator holds that are newer than `response.since` AND were not -already present in the Initial Response (so the responder can ingest -them). -
    -
    type
    object
    description
    Sent by the initiator in bidirectional mode. Contains UTXOs the -initiator holds that are newer than `response.since` AND were not -already present in the Initial Response (so the responder can ingest -them). -
    required
    1 item
    1. UTXOList
    properties
    1 field
    UTXOList
    3 fields
    type
    array
    description
    UTXOs the responder needs from the initiator.
    items
    1 field
    $ref
    #/components/schemas/GASPOutput
    -
    -

    GASPOutput

    - -
    Minimal outpoint descriptor used in the initial exchange phases. -`score` is a sortable timestamp (seconds since epoch) assigned when -the UTXO was first confirmed; unconfirmed UTXOs may have score 0. -
    -
    type
    object
    description
    Minimal outpoint descriptor used in the initial exchange phases. -`score` is a sortable timestamp (seconds since epoch) assigned when -the UTXO was first confirmed; unconfirmed UTXOs may have score 0. -
    required
    3 items
    1. txid
    2. outputIndex
    3. score
    properties
    3 fields
    txid
    4 fields
    type
    string
    pattern
    ^[0-9a-fA-F]{64}$
    description
    Transaction ID (hex, 64 characters).
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    Output index (vout) within the transaction.
    example
    0
    score
    3 fields
    type
    number
    description
    Sortable confirmation timestamp (UNIX seconds). 0 for unconfirmed -outputs. Used to filter UTXOs by the `since` parameters. -
    example
    1714000000
    -
    -

    GASPNodeRequest

    - -
    Request for a specific graph node. `graphID` is the 36-byte outpoint -string (`<txid>.<vout>`) identifying the tip of the graph being walked. -
    -
    type
    object
    description
    Request for a specific graph node. `graphID` is the 36-byte outpoint -string (`<txid>.<vout>`) identifying the tip of the graph being walked. -
    required
    4 items
    1. graphID
    2. txid
    3. outputIndex
    4. metadata
    properties
    4 fields
    graphID
    3 fields
    type
    string
    description
    Graph identifier — the 36-byte outpoint string (`<txid>.<vout>`) -of the UTXO at the tip of this sync graph. -
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0
    txid
    4 fields
    type
    string
    pattern
    ^[0-9a-fA-F]{64}$
    description
    Transaction ID of the node being requested.
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    Output index within the requested transaction.
    example
    0
    metadata
    3 fields
    type
    boolean
    description
    Whether the responder should include transaction and output metadata -in the returned GASPNode. -
    example
    true
    -
    -

    GASPNode

    - -
    A fully-hydrated graph node. `rawTx` is the complete serialised -Bitcoin transaction in hex. `proof` is a hex-encoded BUMP (BRC-74) -merkle proof, only present for confirmed transactions. `inputs` maps -each input outpoint (`<txid>.<vout>`) to the hash of its metadata, -allowing the recipient to detect when it needs updated metadata. -
    -
    type
    object
    description
    A fully-hydrated graph node. `rawTx` is the complete serialised -Bitcoin transaction in hex. `proof` is a hex-encoded BUMP (BRC-74) -merkle proof, only present for confirmed transactions. `inputs` maps -each input outpoint (`<txid>.<vout>`) to the hash of its metadata, -allowing the recipient to detect when it needs updated metadata. -
    required
    3 items
    1. graphID
    2. rawTx
    3. outputIndex
    properties
    7 fields
    graphID
    3 fields
    type
    string
    description
    Outpoint string (`<txid>.<vout>`) of the UTXO at the graph tip. -
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0
    rawTx
    3 fields
    type
    string
    description
    Complete Bitcoin transaction serialised as a lowercase hex string.
    example
    0100000001...
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    The output index within rawTx that this node represents.
    example
    0
    proof
    2 fields
    type
    string
    description
    Hex-encoded BUMP merkle proof for the transaction. Present only -when the transaction is confirmed in a block. -
    txMetadata
    2 fields
    type
    string
    description
    Opaque string of transaction-level metadata. Present only when -the request set `metadata: true`. -
    outputMetadata
    2 fields
    type
    string
    description
    Opaque string of output-level metadata. Present only when the -request set `metadata: true`. -
    inputs
    3 fields
    type
    object
    description
    Mapping of input outpoints (`<txid>.<vout>`) to an object -containing the hash of their metadata. Present only when -`metadata: true` was requested. -
    additionalProperties
    3 fields
    type
    object
    required
    1 item
    1. hash
    properties
    1 field
    hash
    2 fields
    type
    string
    description
    Hash of the input's metadata (hex or base64).
    -
    -

    GASPNodeResponse

    - -
    Response to a submitted GASPNode. `requestedInputs` lists outpoints -the recipient still needs in order to complete the graph and whether -metadata is required for each. If null or omitted, the graph is -complete and will be validated and finalised. -
    -
    type
    object
    description
    Response to a submitted GASPNode. `requestedInputs` lists outpoints -the recipient still needs in order to complete the graph and whether -metadata is required for each. If null or omitted, the graph is -complete and will be validated and finalised. -
    properties
    1 field
    requestedInputs
    3 fields
    type
    object
    description
    Mapping of input outpoints (`<txid>.<vout>`) to their metadata -requirement. An empty object or absent field signals completion. -
    additionalProperties
    3 fields
    type
    object
    required
    1 item
    1. metadata
    properties
    1 field
    metadata
    2 fields
    type
    boolean
    description
    Whether the submitter should include metadata for this input.
    -
    -

    GASPVersionMismatchError

    - -
    Thrown (and serialised into the response) when the responder's GASP -version differs from the version declared in GASPInitialRequest. -
    -
    type
    object
    description
    Thrown (and serialised into the response) when the responder's GASP -version differs from the version declared in GASPInitialRequest. -
    required
    4 items
    1. code
    2. message
    3. currentVersion
    4. foreignVersion
    properties
    4 fields
    code
    2 fields
    type
    string
    enum
    1 item
    1. ERR_GASP_VERSION_MISMATCH
    message
    2 fields
    type
    string
    example
    GASP version mismatch. Current version: 1, foreign version: 2
    currentVersion
    3 fields
    type
    integer
    description
    The responder's supported GASP version.
    example
    1
    foreignVersion
    3 fields
    type
    integer
    description
    The version declared by the initiator.
    example
    2
    -
    -
    -
    - Raw YAML source -
    asyncapi: "3.1.0"
    -
    -info:
    -  title: GASP — Graph Aware Sync Protocol
    -  version: "1.0.0"
    -  description: |
    -    AsyncAPI specification for GASP (Graph Aware Sync Protocol), the
    -    cross-node UTXO synchronisation protocol implemented in
    -    `gasp-core` (`@bsv/gasp-core`).
    -
    -    GASP is a bidirectional gossip/sync protocol between overlay nodes.
    -    Two parties exchange UTXO lists (the "initial exchange") and then
    -    walk the transaction graph in a request/response pattern to transfer
    -    any UTXOs the counterparty does not yet hold.
    -
    -    ## Protocol flow (normal, bidirectional)
    -
    -    ```
    -    Initiator                                   Responder
    -       |                                             |
    -       |-- GASPInitialRequest ---------------------->|
    -       |<- GASPInitialResponse -----------------------|
    -       |-- GASPInitialReply ------------------------->|   (if not unidirectional)
    -       |                                             |
    -       |  [for each UTXO the counterparty is missing]
    -       |-- requestNode(graphID, txid, vout, meta) -->|
    -       |<- GASPNode ---------------------------------|
    -       |                                             |
    -       |  [responder may request further inputs]
    -       |<- submitNode(GASPNode) ---------------------|
    -       |-- GASPNodeResponse ------------------------>|
    -       |          (repeat until graph is complete)
    -       |                                             |
    -    ```
    -
    -    Source of truth: /ts/gasp-core/src/GASP.ts
    -  license:
    -    name: Open BSV Licence
    -
    -defaultContentType: application/json
    -
    -# ---------------------------------------------------------------------------
    -# Channels
    -# ---------------------------------------------------------------------------
    -channels:
    -  gaspInitialRequest:
    -    address: gasp/initialRequest
    -    description: |
    -      Initiator sends its sync parameters.  The responder replies on the
    -      `gasp/initialResponse` channel.
    -    messages:
    -      GASPInitialRequest:
    -        $ref: "#/components/messages/GASPInitialRequest"
    -
    -  gaspInitialResponse:
    -    address: gasp/initialResponse
    -    description: |
    -      Responder sends back its list of known UTXOs and the timestamp from
    -      which it wants to receive UTXOs from the initiator.
    -    messages:
    -      GASPInitialResponse:
    -        $ref: "#/components/messages/GASPInitialResponse"
    -
    -  gaspInitialReply:
    -    address: gasp/initialReply
    -    description: |
    -      Initiator (if operating in bidirectional mode) sends the set of UTXOs
    -      it holds that the responder does not.  Absent in unidirectional mode.
    -    messages:
    -      GASPInitialReply:
    -        $ref: "#/components/messages/GASPInitialReply"
    -
    -  gaspRequestNode:
    -    address: gasp/requestNode
    -    description: |
    -      Either party requests a specific graph node (transaction + output) from
    -      the other.  Used when walking the transaction graph to hydrate UTXOs.
    -    messages:
    -      GASPNodeRequest:
    -        $ref: "#/components/messages/GASPNodeRequest"
    -
    -  gaspNode:
    -    address: gasp/node
    -    description: |
    -      The responding party delivers the requested GASPNode (raw transaction,
    -      optional BUMP proof, optional metadata).
    -    messages:
    -      GASPNode:
    -        $ref: "#/components/messages/GASPNode"
    -
    -  gaspSubmitNode:
    -    address: gasp/submitNode
    -    description: |
    -      A party submits a node it is trying to push to the counterparty.
    -      The counterparty appends it to the temporary graph and may respond
    -      with a list of additional inputs it still needs.
    -    messages:
    -      GASPNode:
    -        $ref: "#/components/messages/GASPNode"
    -
    -  gaspNodeResponse:
    -    address: gasp/nodeResponse
    -    description: |
    -      Response to a submitted node; specifies which additional input transactions
    -      (if any) the recipient still needs to complete the graph.  An empty / null
    -      response means the graph is complete.
    -    messages:
    -      GASPNodeResponse:
    -        $ref: "#/components/messages/GASPNodeResponse"
    -
    -# ---------------------------------------------------------------------------
    -# Operations
    -# ---------------------------------------------------------------------------
    -operations:
    -  sendInitialRequest:
    -    action: send
    -    channel:
    -      $ref: "#/channels/gaspInitialRequest"
    -    summary: Initiator sends sync parameters to the responder.
    -    messages:
    -      - $ref: "#/channels/gaspInitialRequest/messages/GASPInitialRequest"
    -
    -  receiveInitialResponse:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/gaspInitialResponse"
    -    summary: Initiator receives the responder's UTXO list and since timestamp.
    -    messages:
    -      - $ref: "#/channels/gaspInitialResponse/messages/GASPInitialResponse"
    -
    -  sendInitialReply:
    -    action: send
    -    channel:
    -      $ref: "#/channels/gaspInitialReply"
    -    summary: |
    -      Initiator (bidirectional mode only) sends UTXOs the responder is missing.
    -    messages:
    -      - $ref: "#/channels/gaspInitialReply/messages/GASPInitialReply"
    -
    -  requestNode:
    -    action: send
    -    channel:
    -      $ref: "#/channels/gaspRequestNode"
    -    summary: Request a specific transaction node from the counterparty.
    -    messages:
    -      - $ref: "#/channels/gaspRequestNode/messages/GASPNodeRequest"
    -
    -  deliverNode:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/gaspNode"
    -    summary: Receive a requested graph node from the counterparty.
    -    messages:
    -      - $ref: "#/channels/gaspNode/messages/GASPNode"
    -
    -  submitNode:
    -    action: send
    -    channel:
    -      $ref: "#/channels/gaspSubmitNode"
    -    summary: Push a graph node to the counterparty for ingestion.
    -    messages:
    -      - $ref: "#/channels/gaspSubmitNode/messages/GASPNode"
    -
    -  receiveNodeResponse:
    -    action: receive
    -    channel:
    -      $ref: "#/channels/gaspNodeResponse"
    -    summary: |
    -      Receive the counterparty's response to a submitted node, listing any
    -      additional input transactions needed to complete the graph.
    -    messages:
    -      - $ref: "#/channels/gaspNodeResponse/messages/GASPNodeResponse"
    -
    -# ---------------------------------------------------------------------------
    -# Components
    -# ---------------------------------------------------------------------------
    -components:
    -  messages:
    -    GASPInitialRequest:
    -      name: GASPInitialRequest
    -      title: GASP Initial Request
    -      summary: |
    -        First message in a GASP sync session.  The initiator declares its
    -        protocol version, the timestamp of the last sync with this party, and
    -        an optional page size limit.
    -      payload:
    -        $ref: "#/components/schemas/GASPInitialRequest"
    -
    -    GASPInitialResponse:
    -      name: GASPInitialResponse
    -      title: GASP Initial Response
    -      summary: |
    -        Responder's reply to GASPInitialRequest.  Contains the list of UTXOs
    -        the responder has seen since `request.since`, plus the timestamp from
    -        which the responder wants UTXOs back from the initiator.
    -      payload:
    -        $ref: "#/components/schemas/GASPInitialResponse"
    -
    -    GASPInitialReply:
    -      name: GASPInitialReply
    -      title: GASP Initial Reply
    -      summary: |
    -        Initiator's follow-up (bidirectional mode).  UTXOs the initiator holds
    -        that were not in the Initial Response — i.e. UTXOs the responder needs.
    -      payload:
    -        $ref: "#/components/schemas/GASPInitialReply"
    -
    -    GASPNodeRequest:
    -      name: GASPNodeRequest
    -      title: GASP Node Request
    -      summary: |
    -        Request for a specific transaction node identified by graphID, txid,
    -        outputIndex, and whether transaction/output metadata should be included.
    -      payload:
    -        $ref: "#/components/schemas/GASPNodeRequest"
    -
    -    GASPNode:
    -      name: GASPNode
    -      title: GASP Node
    -      summary: |
    -        A transaction node: the raw transaction, the output index, an optional
    -        BUMP merkle proof, optional metadata strings, and a mapping of input
    -        outpoints to metadata hashes so the receiver can request ancestors.
    -      payload:
    -        $ref: "#/components/schemas/GASPNode"
    -
    -    GASPNodeResponse:
    -      name: GASPNodeResponse
    -      title: GASP Node Response
    -      summary: |
    -        Response to a submitted GASPNode.  Lists the input outpoints (in
    -        36-byte `<txid>.<vout>` format) that the recipient still needs to
    -        complete the graph.  A null / absent response means no further inputs
    -        are required and the graph is complete.
    -      payload:
    -        $ref: "#/components/schemas/GASPNodeResponse"
    -
    -  schemas:
    -    # -----------------------------------------------------------------------
    -    GASPInitialRequest:
    -      type: object
    -      description: |
    -        Parameters sent by the initiator to start a GASP sync session.
    -        Version mismatch (current version is 1) causes the responder to throw
    -        GASPVersionMismatchError and abort the session.
    -      required:
    -        - version
    -        - since
    -      properties:
    -        version:
    -          type: integer
    -          description: GASP protocol version.  Currently always 1.
    -          enum: [1]
    -          example: 1
    -        since:
    -          type: integer
    -          minimum: 0
    -          description: |
    -            UNIX timestamp (seconds since epoch) of the last successful sync
    -            with this counterparty.  Use 0 to request all UTXOs.
    -            Must be a non-negative integer.
    -          example: 1714000000
    -        limit:
    -          type: integer
    -          minimum: 1
    -          description: |
    -            Optional maximum number of UTXOs the responder should return per
    -            page.  When the response contains exactly `limit` items the
    -            initiator MUST send another GASPInitialRequest to fetch the next
    -            page.  Absent means "return all".
    -          example: 1000
    -
    -    GASPInitialResponse:
    -      type: object
    -      description: |
    -        Responder's answer to GASPInitialRequest.  `UTXOList` contains all
    -        UTXOs the responder has seen since `request.since`; unconfirmed
    -        (non-timestamped) UTXOs are always included regardless of timestamp.
    -      required:
    -        - UTXOList
    -        - since
    -      properties:
    -        UTXOList:
    -          type: array
    -          description: |
    -            UTXOs the responder knows about (after `request.since`).  The
    -            initiator will request any of these it does not already hold.
    -          items:
    -            $ref: "#/components/schemas/GASPOutput"
    -        since:
    -          type: integer
    -          minimum: 0
    -          description: |
    -            Timestamp from which the responder wants to receive UTXOs back
    -            from the initiator (used in the GASPInitialReply filter step).
    -          example: 1714001000
    -
    -    GASPInitialReply:
    -      type: object
    -      description: |
    -        Sent by the initiator in bidirectional mode.  Contains UTXOs the
    -        initiator holds that are newer than `response.since` AND were not
    -        already present in the Initial Response (so the responder can ingest
    -        them).
    -      required:
    -        - UTXOList
    -      properties:
    -        UTXOList:
    -          type: array
    -          description: UTXOs the responder needs from the initiator.
    -          items:
    -            $ref: "#/components/schemas/GASPOutput"
    -
    -    GASPOutput:
    -      type: object
    -      description: |
    -        Minimal outpoint descriptor used in the initial exchange phases.
    -        `score` is a sortable timestamp (seconds since epoch) assigned when
    -        the UTXO was first confirmed; unconfirmed UTXOs may have score 0.
    -      required:
    -        - txid
    -        - outputIndex
    -        - score
    -      properties:
    -        txid:
    -          type: string
    -          pattern: "^[0-9a-fA-F]{64}$"
    -          description: Transaction ID (hex, 64 characters).
    -          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
    -        outputIndex:
    -          type: integer
    -          minimum: 0
    -          description: Output index (vout) within the transaction.
    -          example: 0
    -        score:
    -          type: number
    -          description: |
    -            Sortable confirmation timestamp (UNIX seconds).  0 for unconfirmed
    -            outputs.  Used to filter UTXOs by the `since` parameters.
    -          example: 1714000000
    -
    -    GASPNodeRequest:
    -      type: object
    -      description: |
    -        Request for a specific graph node.  `graphID` is the 36-byte outpoint
    -        string (`<txid>.<vout>`) identifying the tip of the graph being walked.
    -      required:
    -        - graphID
    -        - txid
    -        - outputIndex
    -        - metadata
    -      properties:
    -        graphID:
    -          type: string
    -          description: |
    -            Graph identifier — the 36-byte outpoint string (`<txid>.<vout>`)
    -            of the UTXO at the tip of this sync graph.
    -          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0"
    -        txid:
    -          type: string
    -          pattern: "^[0-9a-fA-F]{64}$"
    -          description: Transaction ID of the node being requested.
    -          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
    -        outputIndex:
    -          type: integer
    -          minimum: 0
    -          description: Output index within the requested transaction.
    -          example: 0
    -        metadata:
    -          type: boolean
    -          description: |
    -            Whether the responder should include transaction and output metadata
    -            in the returned GASPNode.
    -          example: true
    -
    -    GASPNode:
    -      type: object
    -      description: |
    -        A fully-hydrated graph node.  `rawTx` is the complete serialised
    -        Bitcoin transaction in hex.  `proof` is a hex-encoded BUMP (BRC-74)
    -        merkle proof, only present for confirmed transactions.  `inputs` maps
    -        each input outpoint (`<txid>.<vout>`) to the hash of its metadata,
    -        allowing the recipient to detect when it needs updated metadata.
    -      required:
    -        - graphID
    -        - rawTx
    -        - outputIndex
    -      properties:
    -        graphID:
    -          type: string
    -          description: |
    -            Outpoint string (`<txid>.<vout>`) of the UTXO at the graph tip.
    -          example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0"
    -        rawTx:
    -          type: string
    -          description: Complete Bitcoin transaction serialised as a lowercase hex string.
    -          example: "0100000001..."
    -        outputIndex:
    -          type: integer
    -          minimum: 0
    -          description: The output index within rawTx that this node represents.
    -          example: 0
    -        proof:
    -          type: string
    -          description: |
    -            Hex-encoded BUMP merkle proof for the transaction.  Present only
    -            when the transaction is confirmed in a block.
    -        txMetadata:
    -          type: string
    -          description: |
    -            Opaque string of transaction-level metadata.  Present only when
    -            the request set `metadata: true`.
    -        outputMetadata:
    -          type: string
    -          description: |
    -            Opaque string of output-level metadata.  Present only when the
    -            request set `metadata: true`.
    -        inputs:
    -          type: object
    -          description: |
    -            Mapping of input outpoints (`<txid>.<vout>`) to an object
    -            containing the hash of their metadata.  Present only when
    -            `metadata: true` was requested.
    -          additionalProperties:
    -            type: object
    -            required:
    -              - hash
    -            properties:
    -              hash:
    -                type: string
    -                description: Hash of the input's metadata (hex or base64).
    -
    -    GASPNodeResponse:
    -      type: object
    -      description: |
    -        Response to a submitted GASPNode.  `requestedInputs` lists outpoints
    -        the recipient still needs in order to complete the graph and whether
    -        metadata is required for each.  If null or omitted, the graph is
    -        complete and will be validated and finalised.
    -      properties:
    -        requestedInputs:
    -          type: object
    -          description: |
    -            Mapping of input outpoints (`<txid>.<vout>`) to their metadata
    -            requirement.  An empty object or absent field signals completion.
    -          additionalProperties:
    -            type: object
    -            required:
    -              - metadata
    -            properties:
    -              metadata:
    -                type: boolean
    -                description: Whether the submitter should include metadata for this input.
    -
    -  # -----------------------------------------------------------------------
    -  # Error shapes
    -  # -----------------------------------------------------------------------
    -    GASPVersionMismatchError:
    -      type: object
    -      description: |
    -        Thrown (and serialised into the response) when the responder's GASP
    -        version differs from the version declared in GASPInitialRequest.
    -      required:
    -        - code
    -        - message
    -        - currentVersion
    -        - foreignVersion
    -      properties:
    -        code:
    -          type: string
    -          enum:
    -            - "ERR_GASP_VERSION_MISMATCH"
    -        message:
    -          type: string
    -          example: "GASP version mismatch. Current version: 1, foreign version: 2"
    -        currentVersion:
    -          type: integer
    -          description: The responder's supported GASP version.
    -          example: 1
    -        foreignVersion:
    -          type: integer
    -          description: The version declared by the initiator.
    -          example: 2
    -
    -
    -
    -
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    - - +GASP — Graph Aware Sync Protocol · AsyncAPI
    AsyncAPI 3.1.0 · specs/sync/gasp-asyncapi.yaml

    GASP — Graph Aware Sync Protocol

    v1.0.0
    AsyncAPI specification for GASP (Graph Aware Sync Protocol), the cross-node UTXO synchronisation protocol implemented in `gasp-core` (`@bsv/gasp-core`). GASP is a bidirectional gossip/sync protocol between overlay nodes. Two parties exchange UTXO lists (the "initial exchange") and then walk the transaction graph in a request/response pattern to transfer any UTXOs the counterparty does not yet hold. ## Protocol flow (normal, bidirectional) ``` Initiator Responder | | |-- GASPInitialRequest ---------------------->| |<- GASPInitialResponse -----------------------| |-- GASPInitialReply ------------------------->| (if not unidirectional) | | | [for each UTXO the counterparty is missing] |-- requestNode(graphID, txid, vout, meta) -->| |<- GASPNode ---------------------------------| | | | [responder may request further inputs] |<- submitNode(GASPNode) ---------------------| |-- GASPNodeResponse ------------------------>| | (repeat until graph is complete) | | ``` Source of truth: /ts/gasp-core/src/GASP.ts
    0Servers7Channels7Operations6Messages8Schemas

    Channels

    7

    gaspInitialRequest

    gasp/initialRequest

    Initiator sends its sync parameters. The responder replies on the `gasp/initialResponse` channel.
    address
    gasp/initialRequest
    description
    Initiator sends its sync parameters. The responder replies on the `gasp/initialResponse` channel.
    messages
    1 field
    GASPInitialRequest
    1 field
    $ref
    #/components/messages/GASPInitialRequest

    gaspInitialResponse

    gasp/initialResponse

    Responder sends back its list of known UTXOs and the timestamp from which it wants to receive UTXOs from the initiator.
    address
    gasp/initialResponse
    description
    Responder sends back its list of known UTXOs and the timestamp from which it wants to receive UTXOs from the initiator.
    messages
    1 field
    GASPInitialResponse
    1 field
    $ref
    #/components/messages/GASPInitialResponse

    gaspInitialReply

    gasp/initialReply

    Initiator (if operating in bidirectional mode) sends the set of UTXOs it holds that the responder does not. Absent in unidirectional mode.
    address
    gasp/initialReply
    description
    Initiator (if operating in bidirectional mode) sends the set of UTXOs it holds that the responder does not. Absent in unidirectional mode.
    messages
    1 field
    GASPInitialReply
    1 field
    $ref
    #/components/messages/GASPInitialReply

    gaspRequestNode

    gasp/requestNode

    Either party requests a specific graph node (transaction + output) from the other. Used when walking the transaction graph to hydrate UTXOs.
    address
    gasp/requestNode
    description
    Either party requests a specific graph node (transaction + output) from the other. Used when walking the transaction graph to hydrate UTXOs.
    messages
    1 field
    GASPNodeRequest
    1 field
    $ref
    #/components/messages/GASPNodeRequest

    gaspNode

    gasp/node

    The responding party delivers the requested GASPNode (raw transaction, optional BUMP proof, optional metadata).
    address
    gasp/node
    description
    The responding party delivers the requested GASPNode (raw transaction, optional BUMP proof, optional metadata).
    messages
    1 field
    GASPNode
    1 field
    $ref
    #/components/messages/GASPNode

    gaspSubmitNode

    gasp/submitNode

    A party submits a node it is trying to push to the counterparty. The counterparty appends it to the temporary graph and may respond with a list of additional inputs it still needs.
    address
    gasp/submitNode
    description
    A party submits a node it is trying to push to the counterparty. The counterparty appends it to the temporary graph and may respond with a list of additional inputs it still needs.
    messages
    1 field
    GASPNode
    1 field
    $ref
    #/components/messages/GASPNode

    gaspNodeResponse

    gasp/nodeResponse

    Response to a submitted node; specifies which additional input transactions (if any) the recipient still needs to complete the graph. An empty / null response means the graph is complete.
    address
    gasp/nodeResponse
    description
    Response to a submitted node; specifies which additional input transactions (if any) the recipient still needs to complete the graph. An empty / null response means the graph is complete.
    messages
    1 field
    GASPNodeResponse
    1 field
    $ref
    #/components/messages/GASPNodeResponse

    Operations

    7

    sendInitialRequest

    send
    Initiator sends sync parameters to the responder.
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspInitialRequest
    summary
    Initiator sends sync parameters to the responder.
    messages
    1 item
    1. $ref
      #/channels/gaspInitialRequest/messages/GASPInitialRequest

    receiveInitialResponse

    receive
    Initiator receives the responder's UTXO list and since timestamp.
    action
    receive
    channel
    1 field
    $ref
    #/channels/gaspInitialResponse
    summary
    Initiator receives the responder's UTXO list and since timestamp.
    messages
    1 item
    1. $ref
      #/channels/gaspInitialResponse/messages/GASPInitialResponse

    sendInitialReply

    send
    Initiator (bidirectional mode only) sends UTXOs the responder is missing.
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspInitialReply
    summary
    Initiator (bidirectional mode only) sends UTXOs the responder is missing.
    messages
    1 item
    1. $ref
      #/channels/gaspInitialReply/messages/GASPInitialReply

    requestNode

    send
    Request a specific transaction node from the counterparty.
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspRequestNode
    summary
    Request a specific transaction node from the counterparty.
    messages
    1 item
    1. $ref
      #/channels/gaspRequestNode/messages/GASPNodeRequest

    deliverNode

    receive
    Receive a requested graph node from the counterparty.
    action
    receive
    channel
    1 field
    $ref
    #/channels/gaspNode
    summary
    Receive a requested graph node from the counterparty.
    messages
    1 item
    1. $ref
      #/channels/gaspNode/messages/GASPNode

    submitNode

    send
    Push a graph node to the counterparty for ingestion.
    action
    send
    channel
    1 field
    $ref
    #/channels/gaspSubmitNode
    summary
    Push a graph node to the counterparty for ingestion.
    messages
    1 item
    1. $ref
      #/channels/gaspSubmitNode/messages/GASPNode

    receiveNodeResponse

    receive
    Receive the counterparty's response to a submitted node, listing any additional input transactions needed to complete the graph.
    action
    receive
    channel
    1 field
    $ref
    #/channels/gaspNodeResponse
    summary
    Receive the counterparty's response to a submitted node, listing any additional input transactions needed to complete the graph.
    messages
    1 item
    1. $ref
      #/channels/gaspNodeResponse/messages/GASPNodeResponse

    Messages

    6

    GASPInitialRequest

    First message in a GASP sync session. The initiator declares its protocol version, the timestamp of the last sync with this party, and an optional page size limit.
    name
    GASPInitialRequest
    title
    GASP Initial Request
    summary
    First message in a GASP sync session. The initiator declares its protocol version, the timestamp of the last sync with this party, and an optional page size limit.
    payload
    1 field
    $ref
    #/components/schemas/GASPInitialRequest

    GASPInitialResponse

    Responder's reply to GASPInitialRequest. Contains the list of UTXOs the responder has seen since `request.since`, plus the timestamp from which the responder wants UTXOs back from the initiator.
    name
    GASPInitialResponse
    title
    GASP Initial Response
    summary
    Responder's reply to GASPInitialRequest. Contains the list of UTXOs the responder has seen since `request.since`, plus the timestamp from which the responder wants UTXOs back from the initiator.
    payload
    1 field
    $ref
    #/components/schemas/GASPInitialResponse

    GASPInitialReply

    Initiator's follow-up (bidirectional mode). UTXOs the initiator holds that were not in the Initial Response — i.e. UTXOs the responder needs.
    name
    GASPInitialReply
    title
    GASP Initial Reply
    summary
    Initiator's follow-up (bidirectional mode). UTXOs the initiator holds that were not in the Initial Response — i.e. UTXOs the responder needs.
    payload
    1 field
    $ref
    #/components/schemas/GASPInitialReply

    GASPNodeRequest

    Request for a specific transaction node identified by graphID, txid, outputIndex, and whether transaction/output metadata should be included.
    name
    GASPNodeRequest
    title
    GASP Node Request
    summary
    Request for a specific transaction node identified by graphID, txid, outputIndex, and whether transaction/output metadata should be included.
    payload
    1 field
    $ref
    #/components/schemas/GASPNodeRequest

    GASPNode

    A transaction node: the raw transaction, the output index, an optional BUMP merkle proof, optional metadata strings, and a mapping of input outpoints to metadata hashes so the receiver can request ancestors.
    name
    GASPNode
    title
    GASP Node
    summary
    A transaction node: the raw transaction, the output index, an optional BUMP merkle proof, optional metadata strings, and a mapping of input outpoints to metadata hashes so the receiver can request ancestors.
    payload
    1 field
    $ref
    #/components/schemas/GASPNode

    GASPNodeResponse

    Response to a submitted GASPNode. Lists the input outpoints (in 36-byte `<txid>.<vout>` format) that the recipient still needs to complete the graph. A null / absent response means no further inputs are required and the graph is complete.
    name
    GASPNodeResponse
    title
    GASP Node Response
    summary
    Response to a submitted GASPNode. Lists the input outpoints (in 36-byte `<txid>.<vout>` format) that the recipient still needs to complete the graph. A null / absent response means no further inputs are required and the graph is complete.
    payload
    1 field
    $ref
    #/components/schemas/GASPNodeResponse

    Schemas

    8

    GASPInitialRequest

    Parameters sent by the initiator to start a GASP sync session. Version mismatch (current version is 1) causes the responder to throw GASPVersionMismatchError and abort the session.
    type
    object
    description
    Parameters sent by the initiator to start a GASP sync session. Version mismatch (current version is 1) causes the responder to throw GASPVersionMismatchError and abort the session.
    required
    2 items
    1. version
    2. since
    properties
    3 fields
    version
    4 fields
    type
    integer
    description
    GASP protocol version. Currently always 1.
    enum
    1 item
    1. 1
    example
    1
    since
    4 fields
    type
    integer
    minimum
    0
    description
    UNIX timestamp (seconds since epoch) of the last successful sync with this counterparty. Use 0 to request all UTXOs. Must be a non-negative integer.
    example
    1714000000
    limit
    4 fields
    type
    integer
    minimum
    1
    description
    Optional maximum number of UTXOs the responder should return per page. When the response contains exactly `limit` items the initiator MUST send another GASPInitialRequest to fetch the next page. Absent means "return all".
    example
    1000

    GASPInitialResponse

    Responder's answer to GASPInitialRequest. `UTXOList` contains all UTXOs the responder has seen since `request.since`; unconfirmed (non-timestamped) UTXOs are always included regardless of timestamp.
    type
    object
    description
    Responder's answer to GASPInitialRequest. `UTXOList` contains all UTXOs the responder has seen since `request.since`; unconfirmed (non-timestamped) UTXOs are always included regardless of timestamp.
    required
    2 items
    1. UTXOList
    2. since
    properties
    2 fields
    UTXOList
    3 fields
    type
    array
    description
    UTXOs the responder knows about (after `request.since`). The initiator will request any of these it does not already hold.
    items
    1 field
    $ref
    #/components/schemas/GASPOutput
    since
    4 fields
    type
    integer
    minimum
    0
    description
    Timestamp from which the responder wants to receive UTXOs back from the initiator (used in the GASPInitialReply filter step).
    example
    1714001000

    GASPInitialReply

    Sent by the initiator in bidirectional mode. Contains UTXOs the initiator holds that are newer than `response.since` AND were not already present in the Initial Response (so the responder can ingest them).
    type
    object
    description
    Sent by the initiator in bidirectional mode. Contains UTXOs the initiator holds that are newer than `response.since` AND were not already present in the Initial Response (so the responder can ingest them).
    required
    1 item
    1. UTXOList
    properties
    1 field
    UTXOList
    3 fields
    type
    array
    description
    UTXOs the responder needs from the initiator.
    items
    1 field
    $ref
    #/components/schemas/GASPOutput

    GASPOutput

    Minimal outpoint descriptor used in the initial exchange phases. `score` is a sortable timestamp (seconds since epoch) assigned when the UTXO was first confirmed; unconfirmed UTXOs may have score 0.
    type
    object
    description
    Minimal outpoint descriptor used in the initial exchange phases. `score` is a sortable timestamp (seconds since epoch) assigned when the UTXO was first confirmed; unconfirmed UTXOs may have score 0.
    required
    3 items
    1. txid
    2. outputIndex
    3. score
    properties
    3 fields
    txid
    4 fields
    type
    string
    pattern
    ^[0-9a-fA-F]{64}$
    description
    Transaction ID (hex, 64 characters).
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    Output index (vout) within the transaction.
    example
    0
    score
    3 fields
    type
    number
    description
    Sortable confirmation timestamp (UNIX seconds). 0 for unconfirmed outputs. Used to filter UTXOs by the `since` parameters.
    example
    1714000000

    GASPNodeRequest

    Request for a specific graph node. `graphID` is the 36-byte outpoint string (`<txid>.<vout>`) identifying the tip of the graph being walked.
    type
    object
    description
    Request for a specific graph node. `graphID` is the 36-byte outpoint string (`<txid>.<vout>`) identifying the tip of the graph being walked.
    required
    4 items
    1. graphID
    2. txid
    3. outputIndex
    4. metadata
    properties
    4 fields
    graphID
    3 fields
    type
    string
    description
    Graph identifier — the 36-byte outpoint string (`<txid>.<vout>`) of the UTXO at the tip of this sync graph.
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0
    txid
    4 fields
    type
    string
    pattern
    ^[0-9a-fA-F]{64}$
    description
    Transaction ID of the node being requested.
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    Output index within the requested transaction.
    example
    0
    metadata
    3 fields
    type
    boolean
    description
    Whether the responder should include transaction and output metadata in the returned GASPNode.
    example
    true

    GASPNode

    A fully-hydrated graph node. `rawTx` is the complete serialised Bitcoin transaction in hex. `proof` is a hex-encoded BUMP (BRC-74) merkle proof, only present for confirmed transactions. `inputs` maps each input outpoint (`<txid>.<vout>`) to the hash of its metadata, allowing the recipient to detect when it needs updated metadata.
    type
    object
    description
    A fully-hydrated graph node. `rawTx` is the complete serialised Bitcoin transaction in hex. `proof` is a hex-encoded BUMP (BRC-74) merkle proof, only present for confirmed transactions. `inputs` maps each input outpoint (`<txid>.<vout>`) to the hash of its metadata, allowing the recipient to detect when it needs updated metadata.
    required
    3 items
    1. graphID
    2. rawTx
    3. outputIndex
    properties
    7 fields
    graphID
    3 fields
    type
    string
    description
    Outpoint string (`<txid>.<vout>`) of the UTXO at the graph tip.
    example
    a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0
    rawTx
    3 fields
    type
    string
    description
    Complete Bitcoin transaction serialised as a lowercase hex string.
    example
    0100000001...
    outputIndex
    4 fields
    type
    integer
    minimum
    0
    description
    The output index within rawTx that this node represents.
    example
    0
    proof
    2 fields
    type
    string
    description
    Hex-encoded BUMP merkle proof for the transaction. Present only when the transaction is confirmed in a block.
    txMetadata
    2 fields
    type
    string
    description
    Opaque string of transaction-level metadata. Present only when the request set `metadata: true`.
    outputMetadata
    2 fields
    type
    string
    description
    Opaque string of output-level metadata. Present only when the request set `metadata: true`.
    inputs
    3 fields
    type
    object
    description
    Mapping of input outpoints (`<txid>.<vout>`) to an object containing the hash of their metadata. Present only when `metadata: true` was requested.
    additionalProperties
    3 fields
    type
    object
    required
    1 item
    1. hash
    properties
    1 field
    hash
    2 fields
    type
    string
    description
    Hash of the input's metadata (hex or base64).

    GASPNodeResponse

    Response to a submitted GASPNode. `requestedInputs` lists outpoints the recipient still needs in order to complete the graph and whether metadata is required for each. If null or omitted, the graph is complete and will be validated and finalised.
    type
    object
    description
    Response to a submitted GASPNode. `requestedInputs` lists outpoints the recipient still needs in order to complete the graph and whether metadata is required for each. If null or omitted, the graph is complete and will be validated and finalised.
    properties
    1 field
    requestedInputs
    3 fields
    type
    object
    description
    Mapping of input outpoints (`<txid>.<vout>`) to their metadata requirement. An empty object or absent field signals completion.
    additionalProperties
    3 fields
    type
    object
    required
    1 item
    1. metadata
    properties
    1 field
    metadata
    2 fields
    type
    boolean
    description
    Whether the submitter should include metadata for this input.

    GASPVersionMismatchError

    Thrown (and serialised into the response) when the responder's GASP version differs from the version declared in GASPInitialRequest.
    type
    object
    description
    Thrown (and serialised into the response) when the responder's GASP version differs from the version declared in GASPInitialRequest.
    required
    4 items
    1. code
    2. message
    3. currentVersion
    4. foreignVersion
    properties
    4 fields
    code
    2 fields
    type
    string
    enum
    1 item
    1. ERR_GASP_VERSION_MISMATCH
    message
    2 fields
    type
    string
    example
    GASP version mismatch. Current version: 1, foreign version: 2
    currentVersion
    3 fields
    type
    integer
    description
    The responder's supported GASP version.
    example
    1
    foreignVersion
    3 fields
    type
    integer
    description
    The version declared by the initiator.
    example
    2
    Raw YAML source
    asyncapi: "3.1.0"
    
    info:
      title: GASP — Graph Aware Sync Protocol
      version: "1.0.0"
      description: |
        AsyncAPI specification for GASP (Graph Aware Sync Protocol), the
        cross-node UTXO synchronisation protocol implemented in
        `gasp-core` (`@bsv/gasp-core`).
    
        GASP is a bidirectional gossip/sync protocol between overlay nodes.
        Two parties exchange UTXO lists (the "initial exchange") and then
        walk the transaction graph in a request/response pattern to transfer
        any UTXOs the counterparty does not yet hold.
    
        ## Protocol flow (normal, bidirectional)
    
        ```
        Initiator                                   Responder
           |                                             |
           |-- GASPInitialRequest ---------------------->|
           |<- GASPInitialResponse -----------------------|
           |-- GASPInitialReply ------------------------->|   (if not unidirectional)
           |                                             |
           |  [for each UTXO the counterparty is missing]
           |-- requestNode(graphID, txid, vout, meta) -->|
           |<- GASPNode ---------------------------------|
           |                                             |
           |  [responder may request further inputs]
           |<- submitNode(GASPNode) ---------------------|
           |-- GASPNodeResponse ------------------------>|
           |          (repeat until graph is complete)
           |                                             |
        ```
    
        Source of truth: /ts/gasp-core/src/GASP.ts
      license:
        name: Open BSV Licence
    
    defaultContentType: application/json
    
    # ---------------------------------------------------------------------------
    # Channels
    # ---------------------------------------------------------------------------
    channels:
      gaspInitialRequest:
        address: gasp/initialRequest
        description: |
          Initiator sends its sync parameters.  The responder replies on the
          `gasp/initialResponse` channel.
        messages:
          GASPInitialRequest:
            $ref: "#/components/messages/GASPInitialRequest"
    
      gaspInitialResponse:
        address: gasp/initialResponse
        description: |
          Responder sends back its list of known UTXOs and the timestamp from
          which it wants to receive UTXOs from the initiator.
        messages:
          GASPInitialResponse:
            $ref: "#/components/messages/GASPInitialResponse"
    
      gaspInitialReply:
        address: gasp/initialReply
        description: |
          Initiator (if operating in bidirectional mode) sends the set of UTXOs
          it holds that the responder does not.  Absent in unidirectional mode.
        messages:
          GASPInitialReply:
            $ref: "#/components/messages/GASPInitialReply"
    
      gaspRequestNode:
        address: gasp/requestNode
        description: |
          Either party requests a specific graph node (transaction + output) from
          the other.  Used when walking the transaction graph to hydrate UTXOs.
        messages:
          GASPNodeRequest:
            $ref: "#/components/messages/GASPNodeRequest"
    
      gaspNode:
        address: gasp/node
        description: |
          The responding party delivers the requested GASPNode (raw transaction,
          optional BUMP proof, optional metadata).
        messages:
          GASPNode:
            $ref: "#/components/messages/GASPNode"
    
      gaspSubmitNode:
        address: gasp/submitNode
        description: |
          A party submits a node it is trying to push to the counterparty.
          The counterparty appends it to the temporary graph and may respond
          with a list of additional inputs it still needs.
        messages:
          GASPNode:
            $ref: "#/components/messages/GASPNode"
    
      gaspNodeResponse:
        address: gasp/nodeResponse
        description: |
          Response to a submitted node; specifies which additional input transactions
          (if any) the recipient still needs to complete the graph.  An empty / null
          response means the graph is complete.
        messages:
          GASPNodeResponse:
            $ref: "#/components/messages/GASPNodeResponse"
    
    # ---------------------------------------------------------------------------
    # Operations
    # ---------------------------------------------------------------------------
    operations:
      sendInitialRequest:
        action: send
        channel:
          $ref: "#/channels/gaspInitialRequest"
        summary: Initiator sends sync parameters to the responder.
        messages:
          - $ref: "#/channels/gaspInitialRequest/messages/GASPInitialRequest"
    
      receiveInitialResponse:
        action: receive
        channel:
          $ref: "#/channels/gaspInitialResponse"
        summary: Initiator receives the responder's UTXO list and since timestamp.
        messages:
          - $ref: "#/channels/gaspInitialResponse/messages/GASPInitialResponse"
    
      sendInitialReply:
        action: send
        channel:
          $ref: "#/channels/gaspInitialReply"
        summary: |
          Initiator (bidirectional mode only) sends UTXOs the responder is missing.
        messages:
          - $ref: "#/channels/gaspInitialReply/messages/GASPInitialReply"
    
      requestNode:
        action: send
        channel:
          $ref: "#/channels/gaspRequestNode"
        summary: Request a specific transaction node from the counterparty.
        messages:
          - $ref: "#/channels/gaspRequestNode/messages/GASPNodeRequest"
    
      deliverNode:
        action: receive
        channel:
          $ref: "#/channels/gaspNode"
        summary: Receive a requested graph node from the counterparty.
        messages:
          - $ref: "#/channels/gaspNode/messages/GASPNode"
    
      submitNode:
        action: send
        channel:
          $ref: "#/channels/gaspSubmitNode"
        summary: Push a graph node to the counterparty for ingestion.
        messages:
          - $ref: "#/channels/gaspSubmitNode/messages/GASPNode"
    
      receiveNodeResponse:
        action: receive
        channel:
          $ref: "#/channels/gaspNodeResponse"
        summary: |
          Receive the counterparty's response to a submitted node, listing any
          additional input transactions needed to complete the graph.
        messages:
          - $ref: "#/channels/gaspNodeResponse/messages/GASPNodeResponse"
    
    # ---------------------------------------------------------------------------
    # Components
    # ---------------------------------------------------------------------------
    components:
      messages:
        GASPInitialRequest:
          name: GASPInitialRequest
          title: GASP Initial Request
          summary: |
            First message in a GASP sync session.  The initiator declares its
            protocol version, the timestamp of the last sync with this party, and
            an optional page size limit.
          payload:
            $ref: "#/components/schemas/GASPInitialRequest"
    
        GASPInitialResponse:
          name: GASPInitialResponse
          title: GASP Initial Response
          summary: |
            Responder's reply to GASPInitialRequest.  Contains the list of UTXOs
            the responder has seen since `request.since`, plus the timestamp from
            which the responder wants UTXOs back from the initiator.
          payload:
            $ref: "#/components/schemas/GASPInitialResponse"
    
        GASPInitialReply:
          name: GASPInitialReply
          title: GASP Initial Reply
          summary: |
            Initiator's follow-up (bidirectional mode).  UTXOs the initiator holds
            that were not in the Initial Response — i.e. UTXOs the responder needs.
          payload:
            $ref: "#/components/schemas/GASPInitialReply"
    
        GASPNodeRequest:
          name: GASPNodeRequest
          title: GASP Node Request
          summary: |
            Request for a specific transaction node identified by graphID, txid,
            outputIndex, and whether transaction/output metadata should be included.
          payload:
            $ref: "#/components/schemas/GASPNodeRequest"
    
        GASPNode:
          name: GASPNode
          title: GASP Node
          summary: |
            A transaction node: the raw transaction, the output index, an optional
            BUMP merkle proof, optional metadata strings, and a mapping of input
            outpoints to metadata hashes so the receiver can request ancestors.
          payload:
            $ref: "#/components/schemas/GASPNode"
    
        GASPNodeResponse:
          name: GASPNodeResponse
          title: GASP Node Response
          summary: |
            Response to a submitted GASPNode.  Lists the input outpoints (in
            36-byte `<txid>.<vout>` format) that the recipient still needs to
            complete the graph.  A null / absent response means no further inputs
            are required and the graph is complete.
          payload:
            $ref: "#/components/schemas/GASPNodeResponse"
    
      schemas:
        # -----------------------------------------------------------------------
        GASPInitialRequest:
          type: object
          description: |
            Parameters sent by the initiator to start a GASP sync session.
            Version mismatch (current version is 1) causes the responder to throw
            GASPVersionMismatchError and abort the session.
          required:
            - version
            - since
          properties:
            version:
              type: integer
              description: GASP protocol version.  Currently always 1.
              enum: [1]
              example: 1
            since:
              type: integer
              minimum: 0
              description: |
                UNIX timestamp (seconds since epoch) of the last successful sync
                with this counterparty.  Use 0 to request all UTXOs.
                Must be a non-negative integer.
              example: 1714000000
            limit:
              type: integer
              minimum: 1
              description: |
                Optional maximum number of UTXOs the responder should return per
                page.  When the response contains exactly `limit` items the
                initiator MUST send another GASPInitialRequest to fetch the next
                page.  Absent means "return all".
              example: 1000
    
        GASPInitialResponse:
          type: object
          description: |
            Responder's answer to GASPInitialRequest.  `UTXOList` contains all
            UTXOs the responder has seen since `request.since`; unconfirmed
            (non-timestamped) UTXOs are always included regardless of timestamp.
          required:
            - UTXOList
            - since
          properties:
            UTXOList:
              type: array
              description: |
                UTXOs the responder knows about (after `request.since`).  The
                initiator will request any of these it does not already hold.
              items:
                $ref: "#/components/schemas/GASPOutput"
            since:
              type: integer
              minimum: 0
              description: |
                Timestamp from which the responder wants to receive UTXOs back
                from the initiator (used in the GASPInitialReply filter step).
              example: 1714001000
    
        GASPInitialReply:
          type: object
          description: |
            Sent by the initiator in bidirectional mode.  Contains UTXOs the
            initiator holds that are newer than `response.since` AND were not
            already present in the Initial Response (so the responder can ingest
            them).
          required:
            - UTXOList
          properties:
            UTXOList:
              type: array
              description: UTXOs the responder needs from the initiator.
              items:
                $ref: "#/components/schemas/GASPOutput"
    
        GASPOutput:
          type: object
          description: |
            Minimal outpoint descriptor used in the initial exchange phases.
            `score` is a sortable timestamp (seconds since epoch) assigned when
            the UTXO was first confirmed; unconfirmed UTXOs may have score 0.
          required:
            - txid
            - outputIndex
            - score
          properties:
            txid:
              type: string
              pattern: "^[0-9a-fA-F]{64}$"
              description: Transaction ID (hex, 64 characters).
              example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
            outputIndex:
              type: integer
              minimum: 0
              description: Output index (vout) within the transaction.
              example: 0
            score:
              type: number
              description: |
                Sortable confirmation timestamp (UNIX seconds).  0 for unconfirmed
                outputs.  Used to filter UTXOs by the `since` parameters.
              example: 1714000000
    
        GASPNodeRequest:
          type: object
          description: |
            Request for a specific graph node.  `graphID` is the 36-byte outpoint
            string (`<txid>.<vout>`) identifying the tip of the graph being walked.
          required:
            - graphID
            - txid
            - outputIndex
            - metadata
          properties:
            graphID:
              type: string
              description: |
                Graph identifier — the 36-byte outpoint string (`<txid>.<vout>`)
                of the UTXO at the tip of this sync graph.
              example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0"
            txid:
              type: string
              pattern: "^[0-9a-fA-F]{64}$"
              description: Transaction ID of the node being requested.
              example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
            outputIndex:
              type: integer
              minimum: 0
              description: Output index within the requested transaction.
              example: 0
            metadata:
              type: boolean
              description: |
                Whether the responder should include transaction and output metadata
                in the returned GASPNode.
              example: true
    
        GASPNode:
          type: object
          description: |
            A fully-hydrated graph node.  `rawTx` is the complete serialised
            Bitcoin transaction in hex.  `proof` is a hex-encoded BUMP (BRC-74)
            merkle proof, only present for confirmed transactions.  `inputs` maps
            each input outpoint (`<txid>.<vout>`) to the hash of its metadata,
            allowing the recipient to detect when it needs updated metadata.
          required:
            - graphID
            - rawTx
            - outputIndex
          properties:
            graphID:
              type: string
              description: |
                Outpoint string (`<txid>.<vout>`) of the UTXO at the graph tip.
              example: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2.0"
            rawTx:
              type: string
              description: Complete Bitcoin transaction serialised as a lowercase hex string.
              example: "0100000001..."
            outputIndex:
              type: integer
              minimum: 0
              description: The output index within rawTx that this node represents.
              example: 0
            proof:
              type: string
              description: |
                Hex-encoded BUMP merkle proof for the transaction.  Present only
                when the transaction is confirmed in a block.
            txMetadata:
              type: string
              description: |
                Opaque string of transaction-level metadata.  Present only when
                the request set `metadata: true`.
            outputMetadata:
              type: string
              description: |
                Opaque string of output-level metadata.  Present only when the
                request set `metadata: true`.
            inputs:
              type: object
              description: |
                Mapping of input outpoints (`<txid>.<vout>`) to an object
                containing the hash of their metadata.  Present only when
                `metadata: true` was requested.
              additionalProperties:
                type: object
                required:
                  - hash
                properties:
                  hash:
                    type: string
                    description: Hash of the input's metadata (hex or base64).
    
        GASPNodeResponse:
          type: object
          description: |
            Response to a submitted GASPNode.  `requestedInputs` lists outpoints
            the recipient still needs in order to complete the graph and whether
            metadata is required for each.  If null or omitted, the graph is
            complete and will be validated and finalised.
          properties:
            requestedInputs:
              type: object
              description: |
                Mapping of input outpoints (`<txid>.<vout>`) to their metadata
                requirement.  An empty object or absent field signals completion.
              additionalProperties:
                type: object
                required:
                  - metadata
                properties:
                  metadata:
                    type: boolean
                    description: Whether the submitter should include metadata for this input.
    
      # -----------------------------------------------------------------------
      # Error shapes
      # -----------------------------------------------------------------------
        GASPVersionMismatchError:
          type: object
          description: |
            Thrown (and serialised into the response) when the responder's GASP
            version differs from the version declared in GASPInitialRequest.
          required:
            - code
            - message
            - currentVersion
            - foreignVersion
          properties:
            code:
              type: string
              enum:
                - "ERR_GASP_VERSION_MISMATCH"
            message:
              type: string
              example: "GASP version mismatch. Current version: 1, foreign version: 2"
            currentVersion:
              type: integer
              description: The responder's supported GASP version.
              example: 1
            foreignVersion:
              type: integer
              description: The version declared by the initiator.
              example: 2
    
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    \ No newline at end of file diff --git a/packages/sdk/src/primitives/utils.ts b/packages/sdk/src/primitives/utils.ts index 64f204734..c2d13e857 100644 --- a/packages/sdk/src/primitives/utils.ts +++ b/packages/sdk/src/primitives/utils.ts @@ -40,11 +40,7 @@ export const toHex = (msg: number[] | Uint8Array): string => { return BufferCtor.from(msg).toString('hex') } if (msg.length === 0) return '' - const out = new Array(msg.length) - for (let i = 0; i < msg.length; i++) { - out[i] = HEX_BYTE_STRINGS[msg[i] & 0xff] - } - return out.join('') + return Array.from(msg, byte => HEX_BYTE_STRINGS[byte & 0xff]).join('') } /** diff --git a/scripts/generate-asyncapi-html.mjs b/scripts/generate-asyncapi-html.mjs index b2b1c589b..f8e53b2ec 100644 --- a/scripts/generate-asyncapi-html.mjs +++ b/scripts/generate-asyncapi-html.mjs @@ -39,6 +39,7 @@ function escapeHtml (value) { .replaceAll('>', '>') .replaceAll('"', '"') .replaceAll("'", ''') + .replaceAll('\n', ' ') } function identifier (value) { @@ -62,12 +63,26 @@ function scalar (value) { return `${escapeHtml(JSON.stringify(value))}` } +function collectionSummary (value) { + if (Array.isArray(value)) { + const suffix = value.length === 1 ? '' : 's' + return `${value.length} item${suffix}` + } + + const count = Object.keys(value).length + const suffix = count === 1 ? '' : 's' + return `${count} field${suffix}` +} + function renderValue (value, depth = 0) { if (value == null || typeof value !== 'object') return scalar(value) if (Array.isArray(value)) { if (value.length === 0) return 'empty list' - return `
      ${value.map(item => `
    1. ${renderValue(item, depth + 1)}
    2. `).join('')}
    ` + const items = value + .map(item => '
  • ' + renderValue(item, depth + 1) + '
  • ') + .join('') + return `
      ${items}
    ` } const entries = Object.entries(value) @@ -80,7 +95,9 @@ function renderValue (value, depth = 0) { } const open = depth < 1 ? ' open' : '' - return `
    ${escapeHtml(key)}
    ${Array.isArray(child) ? `${child.length} item${child.length === 1 ? '' : 's'}` : `${Object.keys(child).length} field${Object.keys(child).length === 1 ? '' : 's'}`}${renderValue(child, depth + 1)}
    ` + const summary = collectionSummary(child) + const renderedChild = renderValue(child, depth + 1) + return `
    ${escapeHtml(key)}
    ${summary}${renderedChild}
    ` }).join('')}` } @@ -177,18 +194,18 @@ function renderSpec (document, source, specPath) {
    Generated deterministically from the repository source. No remote scripts, styles, fonts, or runtime dependencies.
    -`.replace(/[ \t]+$/gm, '') +`.split('\n').map(line => line.trim()).join('') } function validate (document, specPath) { if (document == null || typeof document !== 'object') { - throw new Error(`${specPath} must contain a YAML object`) + throw new TypeError(`${specPath} must contain a YAML object`) } if (typeof document.asyncapi !== 'string' || !document.asyncapi.startsWith('3.')) { - throw new Error(`${specPath} must declare AsyncAPI 3.x`) + throw new TypeError(`${specPath} must declare AsyncAPI 3.x`) } if (typeof document.info?.title !== 'string' || typeof document.info?.version !== 'string') { - throw new Error(`${specPath} must declare info.title and info.version`) + throw new TypeError(`${specPath} must declare info.title and info.version`) } } From f4dd5252d59d94c8ed36d97449d331f0c0249b5d Mon Sep 17 00:00:00 2001 From: Ty J Everett Date: Fri, 24 Jul 2026 19:14:08 -0700 Subject: [PATCH 3/6] fix coverage semantics for optional test suites --- packages/helpers/did-client/package.json | 2 +- packages/helpers/did/package.json | 2 +- packages/helpers/ts-templates/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/helpers/did-client/package.json b/packages/helpers/did-client/package.json index 52ad12172..af050abf5 100644 --- a/packages/helpers/did-client/package.json +++ b/packages/helpers/did-client/package.json @@ -19,7 +19,7 @@ "scripts": { "test": "npm run build && jest --passWithNoTests", "test:watch": "npm run build && jest --watch", - "test:coverage": "npm run build && jest --coverage", + "test:coverage": "npm run build && jest --coverage --passWithNoTests", "lint:ci": "oxlint src", "lint": "oxlint src", "build": "npm run build:ts && npm run build:umd", diff --git a/packages/helpers/did/package.json b/packages/helpers/did/package.json index 117e368c3..699c4a7f3 100644 --- a/packages/helpers/did/package.json +++ b/packages/helpers/did/package.json @@ -31,7 +31,7 @@ "scripts": { "test": "npm run build && jest --passWithNoTests", "test:watch": "npm run build && jest --watch", - "test:coverage": "npm run build && jest --coverage", + "test:coverage": "npm run build && jest --coverage --passWithNoTests", "lint:ci": "oxlint src tests", "lint": "oxlint src tests", "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json", diff --git a/packages/helpers/ts-templates/package.json b/packages/helpers/ts-templates/package.json index 9b98c42ca..4706b5131 100644 --- a/packages/helpers/ts-templates/package.json +++ b/packages/helpers/ts-templates/package.json @@ -27,7 +27,7 @@ "scripts": { "test": "npm run build && jest --passWithNoTests", "test:watch": "npm run build && jest --watch", - "test:coverage": "npm run build && jest --coverage", + "test:coverage": "npm run build && jest --coverage --passWithNoTests", "lint": "oxlint src", "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json", "dev": "tsc -b -w", From b4104494a5968d7d36ec30c6e6e8a711a5f37145 Mon Sep 17 00:00:00 2001 From: Ty J Everett Date: Fri, 24 Jul 2026 19:14:55 -0700 Subject: [PATCH 4/6] guard coverage script consistency --- scripts/check-versions.mjs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/check-versions.mjs b/scripts/check-versions.mjs index a7f4c8f76..5221387ed 100644 --- a/scripts/check-versions.mjs +++ b/scripts/check-versions.mjs @@ -63,6 +63,7 @@ function acceptsPeerVersion (range, wsVersion) { } let stale = 0 +let coverageMismatches = 0 for (const pkg of pkgList) { if (!pkg.path) continue @@ -74,6 +75,18 @@ for (const pkg of pkgList) { continue } const d = JSON.parse(raw) + const testCommand = d.scripts?.test + const coverageCommand = d.scripts?.['test:coverage'] + if ( + typeof testCommand === 'string' && + testCommand.includes('--passWithNoTests') && + typeof coverageCommand === 'string' && + !coverageCommand.includes('--passWithNoTests') + ) { + console.log(`COVERAGE MISMATCH ${d.name} allows an empty test suite but its test:coverage script does not`) + coverageMismatches++ + } + for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) { if (!d[field]) continue for (const [dep, range] of Object.entries(d[field])) { @@ -129,10 +142,11 @@ for (const child of located) { } } -if (stale === 0 && mismatched === 0) { +if (stale === 0 && mismatched === 0 && coverageMismatches === 0) { console.log('All cross-package version references up to date.') } else { if (stale > 0) console.error(`\n${stale} stale references. Run: node scripts/sync-versions.mjs --workspace-only`) if (mismatched > 0) console.error(`\n${mismatched} nested package(s) out of lockstep with their enclosing package. Bump them to match.`) + if (coverageMismatches > 0) console.error(`\n${coverageMismatches} coverage script(s) disagree with their package test semantics.`) process.exit(1) } From db7edd5d1a3e2350601d77161ea98745696d6831 Mon Sep 17 00:00:00 2001 From: Ty J Everett Date: Fri, 24 Jul 2026 19:17:59 -0700 Subject: [PATCH 5/6] fix ESM coverage execution and reporting --- .../messaging/message-box-client/package.json | 2 +- scripts/check-versions.mjs | 25 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/messaging/message-box-client/package.json b/packages/messaging/message-box-client/package.json index edf2a1ebf..078726990 100644 --- a/packages/messaging/message-box-client/package.json +++ b/packages/messaging/message-box-client/package.json @@ -30,7 +30,7 @@ "build:umd": "webpack --config webpack.config.js", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.ts --watchman=false", "test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.integration.ts --watchman=false", - "test:coverage": "jest --coverage --coverageReporters=text --coverageReporters=html", + "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.ts --watchman=false --coverage --coverageReporters=text --coverageReporters=html --coverageReporters=lcov", "test:watch": "jest --watch", "lint": "oxlint src", "clean": "rimraf dist node_modules && npm install" diff --git a/scripts/check-versions.mjs b/scripts/check-versions.mjs index 5221387ed..54b748176 100644 --- a/scripts/check-versions.mjs +++ b/scripts/check-versions.mjs @@ -77,14 +77,23 @@ for (const pkg of pkgList) { const d = JSON.parse(raw) const testCommand = d.scripts?.test const coverageCommand = d.scripts?.['test:coverage'] - if ( - typeof testCommand === 'string' && - testCommand.includes('--passWithNoTests') && - typeof coverageCommand === 'string' && - !coverageCommand.includes('--passWithNoTests') - ) { - console.log(`COVERAGE MISMATCH ${d.name} allows an empty test suite but its test:coverage script does not`) - coverageMismatches++ + if (typeof testCommand === 'string' && typeof coverageCommand === 'string') { + const missingCoverageBehaviors = [ + '--passWithNoTests', + '--experimental-vm-modules' + ].filter(option => testCommand.includes(option) && !coverageCommand.includes(option)) + + if ( + coverageCommand.includes('--coverageReporters') && + !coverageCommand.includes('--coverageReporters=lcov') + ) { + missingCoverageBehaviors.push('--coverageReporters=lcov') + } + + if (missingCoverageBehaviors.length > 0) { + console.log(`COVERAGE MISMATCH ${d.name} test:coverage is missing ${missingCoverageBehaviors.join(', ')}`) + coverageMismatches++ + } } for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) { From 30e273ccdf42cf8d8185dea280f7c7c316aee8d7 Mon Sep 17 00:00:00 2001 From: Ty J Everett Date: Fri, 24 Jul 2026 19:41:41 -0700 Subject: [PATCH 6/6] test: close changed-line coverage gaps --- .../src/__tests/ExpressTransport.test.ts | 16 +++++++++ .../src/__tests__/OverlayExpress.test.ts | 34 +++++++++++++++++++ .../src/__tests/OverlayGASPStorage.test.ts | 34 +++++++++++++++++++ .../sdk/src/primitives/__tests/utils.test.ts | 26 +++++++++++++- 4 files changed, 109 insertions(+), 1 deletion(-) diff --git a/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts b/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts index 9ec75b964..0bf992185 100644 --- a/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts +++ b/packages/middleware/auth-express-middleware/src/__tests/ExpressTransport.test.ts @@ -10,4 +10,20 @@ describe('ExpressTransport configuration', () => { transport.allowAuthenticated = false expect(transport.allowUnauthenticated).toBe(false) }) + + it('uses allowUnauthenticated when requests have no authentication headers', () => { + const transport = new ExpressTransport(true) + const req: any = {} + const res: any = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis() + } + const next = jest.fn() + + ;(transport as any).handleUnauthenticated(req, res, next) + + expect(req.auth).toEqual({ identityKey: 'unknown' }) + expect(next).toHaveBeenCalledTimes(1) + expect(res.status).not.toHaveBeenCalled() + }) }) diff --git a/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts b/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts index 2b26d58bb..b6e11472c 100644 --- a/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts +++ b/packages/overlays/overlay-express/src/__tests__/OverlayExpress.test.ts @@ -845,6 +845,40 @@ describe('OverlayExpress', () => { consoleError.mockRestore() }) + it.each([ + ['', 'an empty comma-separated list'], + ['tm_foo,', 'an empty comma-separated topic'], + ['["tm_foo",42]', 'a JSON array containing a non-string topic'] + ])('returns a clean 400 when X-Topics is %s (%s)', async (topicsHeader) => { + const postSpy = jest.spyOn(instance.app, 'post') + jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => { + callback() + return {} as any + }) + const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}) + await instance.start() + + const route = postSpy.mock.calls.find(call => call[0] === '/submit') + const handler: any = route === undefined ? undefined : route[route.length - 1] + const res: any = { + status: jest.fn().mockReturnThis(), + json: jest.fn().mockReturnThis() + } + handler?.({ + headers: { 'x-topics': topicsHeader }, + body: Buffer.from([1, 2, 3]) + }, res) + await new Promise(resolve => setImmediate(resolve)) + + expect(res.status).toHaveBeenCalledWith(400) + expect(res.json).toHaveBeenCalledWith({ + status: 'error', + message: 'Invalid x-topics header: expected a comma-separated list or JSON string array' + }) + expect(mockEngine.submit).not.toHaveBeenCalled() + consoleError.mockRestore() + }) + it('returns a clean 400 when /admin/health-check has no body', async () => { const postSpy = jest.spyOn(instance.app, 'post') jest.spyOn(instance.app, 'listen').mockImplementation((port: any, callback: any) => { diff --git a/packages/overlays/overlay/src/__tests/OverlayGASPStorage.test.ts b/packages/overlays/overlay/src/__tests/OverlayGASPStorage.test.ts index 00de92dc4..9db66896d 100644 --- a/packages/overlays/overlay/src/__tests/OverlayGASPStorage.test.ts +++ b/packages/overlays/overlay/src/__tests/OverlayGASPStorage.test.ts @@ -125,6 +125,40 @@ describe('OverlayGASPStorage', () => { requestedInputs: { 'neededTxid.1': { metadata: false } } }) }) + + it.each([ + [new Error('manager failed'), 'manager failed'], + ['manager failed as a string', 'manager failed as a string'] + ])('terminates the graph and logs normalized identifyNeededInputs errors', async (failure, message) => { + const mockTx: GASPNode = { + rawTx: '001122', + proof: 'someproof', + graphID: 'txid123.0', + outputIndex: 0 + } + const parsedTx = { + inputs: [], + toBEEF: jest.fn().mockReturnValue([1, 2, 3]), + id: jest.fn().mockReturnValue('txid123'), + merklePath: {} + } + Transaction.fromHex = jest.fn().mockReturnValue(parsedTx) + MerklePath.fromHex = jest.fn().mockReturnValue(parsedTx.merklePath) + mockEngine.managers['test-topic'] = { + identifyAdmissibleOutputs: jest.fn().mockResolvedValue({ + outputsToAdmit: [] + }), + identifyNeededInputs: jest.fn().mockRejectedValue(failure) + } + const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}) + + await expect(overlayStorage.findNeededInputs(mockTx)).resolves.toBeUndefined() + + expect(consoleError).toHaveBeenCalledWith( + `An error occurred when identifying needed inputs for transaction: txid123.0: ${message}` + ) + consoleError.mockRestore() + }) }) describe('discardGraph', () => { diff --git a/packages/sdk/src/primitives/__tests/utils.test.ts b/packages/sdk/src/primitives/__tests/utils.test.ts index 93df2f9ab..8df500663 100644 --- a/packages/sdk/src/primitives/__tests/utils.test.ts +++ b/packages/sdk/src/primitives/__tests/utils.test.ts @@ -33,6 +33,30 @@ describe('utils', () => { expect(toHex([0, 1, 2, 3])).toBe('00010203') }) + it('should convert to hex without a global Buffer implementation', () => { + const originalBuffer = Object.getOwnPropertyDescriptor(globalThis, 'Buffer') + Object.defineProperty(globalThis, 'Buffer', { + value: undefined, + configurable: true, + writable: true + }) + + try { + jest.isolateModules(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { toHex: fallbackToHex } = require('../../primitives/utils') + expect(fallbackToHex([])).toBe('') + expect(fallbackToHex(new Uint8Array([0, 1, 254, 255]))).toBe('0001feff') + }) + } finally { + if (originalBuffer === undefined) { + delete (globalThis as any).Buffer + } else { + Object.defineProperty(globalThis, 'Buffer', originalBuffer) + } + } + }) + it('should encode', () => { expect(encode([0, 1, 2, 3])).toEqual([0, 1, 2, 3]) expect(encode([0, 1, 2, 3], 'hex')).toBe('00010203') @@ -421,4 +445,4 @@ describe('constantTimeEquals', () => { it('works with Uint8Array', () => { expect(constantTimeEquals(new Uint8Array([5,6,7]), new Uint8Array([5,6,7]))).toBe(true) }) -}) \ No newline at end of file +})