diff --git a/package-lock.json b/package-lock.json index cdc4cc82..994cc603 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14204,8 +14204,6 @@ }, "node_modules/npm/node_modules/@isaacs/balanced-match": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -14215,8 +14213,6 @@ }, "node_modules/npm/node_modules/@isaacs/brace-expansion": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", "dev": true, "inBundle": true, "license": "MIT", @@ -14229,8 +14225,6 @@ }, "node_modules/npm/node_modules/@isaacs/fs-minipass": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, "inBundle": true, "license": "ISC", @@ -14243,16 +14237,12 @@ }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", - "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", - "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", "dev": true, "inBundle": true, "license": "ISC", @@ -14335,8 +14325,6 @@ }, "node_modules/npm/node_modules/@npmcli/fs": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", - "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", "dev": true, "inBundle": true, "license": "ISC", @@ -14349,8 +14337,6 @@ }, "node_modules/npm/node_modules/@npmcli/git": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", - "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", "dev": true, "inBundle": true, "license": "ISC", @@ -14370,8 +14356,6 @@ }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", - "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", "dev": true, "inBundle": true, "license": "ISC", @@ -14388,8 +14372,6 @@ }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-5.0.3.tgz", - "integrity": "sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw==", "dev": true, "inBundle": true, "license": "ISC", @@ -14405,8 +14387,6 @@ }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-9.0.3.tgz", - "integrity": "sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg==", "dev": true, "inBundle": true, "license": "ISC", @@ -14423,8 +14403,6 @@ }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-4.0.0.tgz", - "integrity": "sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg==", "dev": true, "inBundle": true, "license": "ISC", @@ -14434,8 +14412,6 @@ }, "node_modules/npm/node_modules/@npmcli/node-gyp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", - "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -14445,8 +14421,6 @@ }, "node_modules/npm/node_modules/@npmcli/package-json": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", - "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -14465,8 +14439,6 @@ }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", - "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", "dev": true, "inBundle": true, "license": "ISC", @@ -14479,8 +14451,6 @@ }, "node_modules/npm/node_modules/@npmcli/query": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-5.0.0.tgz", - "integrity": "sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -14493,8 +14463,6 @@ }, "node_modules/npm/node_modules/@npmcli/redact": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", - "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", "dev": true, "inBundle": true, "license": "ISC", @@ -14504,8 +14472,6 @@ }, "node_modules/npm/node_modules/@npmcli/run-script": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", - "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "dev": true, "inBundle": true, "license": "ISC", @@ -14523,8 +14489,6 @@ }, "node_modules/npm/node_modules/@sigstore/bundle": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", - "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -14537,8 +14501,6 @@ }, "node_modules/npm/node_modules/@sigstore/core": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.0.0.tgz", - "integrity": "sha512-NgbJ+aW9gQl/25+GIEGYcCyi8M+ng2/5X04BMuIgoDfgvp18vDcoNHOQjQsG9418HGNYRxG3vfEXaR1ayD37gg==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -14548,8 +14510,6 @@ }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz", - "integrity": "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -14559,8 +14519,6 @@ }, "node_modules/npm/node_modules/@sigstore/sign": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.0.1.tgz", - "integrity": "sha512-KFNGy01gx9Y3IBPG/CergxR9RZpN43N+lt3EozEfeoyqm8vEiLxwRl3ZO5sPx3Obv1ix/p7FWOlPc2Jgwfp9PA==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -14578,8 +14536,6 @@ }, "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", - "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -14589,8 +14545,6 @@ }, "node_modules/npm/node_modules/@sigstore/tuf": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.0.tgz", - "integrity": "sha512-0QFuWDHOQmz7t66gfpfNO6aEjoFrdhkJaej/AOqb4kqWZVbPWFZifXZzkxyQBB1OwTbkhdT3LNpMFxwkTvf+2w==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -14604,8 +14558,6 @@ }, "node_modules/npm/node_modules/@sigstore/verify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.0.0.tgz", - "integrity": "sha512-moXtHH33AobOhTZF8xcX1MpOFqdvfCk7v6+teJL8zymBiDXwEsQH6XG9HGx2VIxnJZNm4cNSzflTLDnQLmIdmw==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -14620,8 +14572,6 @@ }, "node_modules/npm/node_modules/@tufjs/canonical-json": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", "dev": true, "inBundle": true, "license": "MIT", @@ -14631,8 +14581,6 @@ }, "node_modules/npm/node_modules/@tufjs/models": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.0.0.tgz", - "integrity": "sha512-h5x5ga/hh82COe+GoD4+gKUeV4T3iaYOxqLt41GRKApinPI7DMidhCmNVTjKfhCWFJIGXaFJee07XczdT4jdZQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -14646,8 +14594,6 @@ }, "node_modules/npm/node_modules/@tufjs/models/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "inBundle": true, "license": "ISC", @@ -14663,8 +14609,6 @@ }, "node_modules/npm/node_modules/abbrev": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", - "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", "dev": true, "inBundle": true, "license": "ISC", @@ -14674,8 +14618,6 @@ }, "node_modules/npm/node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -14685,8 +14627,6 @@ }, "node_modules/npm/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -14696,32 +14636,24 @@ }, "node_modules/npm/node_modules/aproba": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", - "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-6.0.0.tgz", - "integrity": "sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w==", "dev": true, "inBundle": true, "license": "ISC", @@ -14738,8 +14670,6 @@ }, "node_modules/npm/node_modules/binary-extensions": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-3.1.0.tgz", - "integrity": "sha512-Jvvd9hy1w+xUad8+ckQsWA/V1AoyubOvqn0aygjMOVM4BfIaRav1NFS3LsTSDaV4n4FtcCtQXvzep1E6MboqwQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -14761,8 +14691,6 @@ }, "node_modules/npm/node_modules/cacache": { "version": "20.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", - "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", "dev": true, "inBundle": true, "license": "ISC", @@ -14785,8 +14713,6 @@ }, "node_modules/npm/node_modules/chalk": { "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "inBundle": true, "license": "MIT", @@ -14799,8 +14725,6 @@ }, "node_modules/npm/node_modules/chownr": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -14810,8 +14734,6 @@ }, "node_modules/npm/node_modules/ci-info": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", "dev": true, "funding": [ { @@ -14839,8 +14761,6 @@ }, "node_modules/npm/node_modules/cli-columns": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-columns/-/cli-columns-4.0.0.tgz", - "integrity": "sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -14854,8 +14774,6 @@ }, "node_modules/npm/node_modules/cmd-shim": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-8.0.0.tgz", - "integrity": "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==", "dev": true, "inBundle": true, "license": "ISC", @@ -14865,16 +14783,12 @@ }, "node_modules/npm/node_modules/common-ancestor-path": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, "inBundle": true, "license": "MIT", @@ -14887,8 +14801,6 @@ }, "node_modules/npm/node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "inBundle": true, "license": "MIT", @@ -14915,16 +14827,12 @@ }, "node_modules/npm/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/encoding": { "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, "inBundle": true, "license": "MIT", @@ -14935,8 +14843,6 @@ }, "node_modules/npm/node_modules/env-paths": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, "inBundle": true, "license": "MIT", @@ -14946,24 +14852,18 @@ }, "node_modules/npm/node_modules/err-code": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", - "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "dev": true, "inBundle": true, "license": "Apache-2.0" }, "node_modules/npm/node_modules/fastest-levenshtein": { "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, "inBundle": true, "license": "MIT", @@ -14973,8 +14873,6 @@ }, "node_modules/npm/node_modules/fs-minipass": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15004,16 +14902,12 @@ }, "node_modules/npm/node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "dev": true, "inBundle": true, "license": "ISC", @@ -15026,16 +14920,12 @@ }, "node_modules/npm/node_modules/http-cache-semantics": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "dev": true, "inBundle": true, "license": "BSD-2-Clause" }, "node_modules/npm/node_modules/http-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "inBundle": true, "license": "MIT", @@ -15049,8 +14939,6 @@ }, "node_modules/npm/node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "inBundle": true, "license": "MIT", @@ -15064,8 +14952,6 @@ }, "node_modules/npm/node_modules/iconv-lite": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "inBundle": true, "license": "MIT", @@ -15079,8 +14965,6 @@ }, "node_modules/npm/node_modules/ignore-walk": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", - "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", "dev": true, "inBundle": true, "license": "ISC", @@ -15093,8 +14977,6 @@ }, "node_modules/npm/node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "inBundle": true, "license": "MIT", @@ -15104,8 +14986,6 @@ }, "node_modules/npm/node_modules/ini": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", - "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15115,8 +14995,6 @@ }, "node_modules/npm/node_modules/init-package-json": { "version": "8.2.4", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-8.2.4.tgz", - "integrity": "sha512-SqX/+tPl3sZD+IY0EuMiM1kK1B45h+P6JQPo3Q9zlqNINX2XiX3x/WSbYGFqS6YCkODNbGb3L5RawMrYE/cfKw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15135,8 +15013,6 @@ }, "node_modules/npm/node_modules/ip-address": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", - "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", "dev": true, "inBundle": true, "license": "MIT", @@ -15146,8 +15022,6 @@ }, "node_modules/npm/node_modules/ip-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", - "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", "dev": true, "inBundle": true, "license": "MIT", @@ -15172,8 +15046,6 @@ }, "node_modules/npm/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "inBundle": true, "license": "MIT", @@ -15183,8 +15055,6 @@ }, "node_modules/npm/node_modules/isexe": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15194,8 +15064,6 @@ }, "node_modules/npm/node_modules/json-parse-even-better-errors": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", - "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -15205,8 +15073,6 @@ }, "node_modules/npm/node_modules/json-stringify-nice": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", - "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15216,8 +15082,6 @@ }, "node_modules/npm/node_modules/jsonparse": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, "engines": [ "node >= 0.2.0" @@ -15227,24 +15091,18 @@ }, "node_modules/npm/node_modules/just-diff": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz", - "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/just-diff-apply": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz", - "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-10.0.3.tgz", - "integrity": "sha512-JPHTfWJxIK+NVPdNMNGnkz4XGX56iijPbe0qFWbdt68HL+kIvSzh+euBL8npLZvl2fpaxo+1eZSdoG15f5YdIQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15312,8 +15170,6 @@ }, "node_modules/npm/node_modules/libnpmorg": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/libnpmorg/-/libnpmorg-8.0.1.tgz", - "integrity": "sha512-/QeyXXg4hqMw0ESM7pERjIT2wbR29qtFOWIOug/xO4fRjS3jJJhoAPQNsnHtdwnCqgBdFpGQ45aIdFFZx2YhTA==", "dev": true, "inBundle": true, "license": "ISC", @@ -15342,8 +15198,6 @@ }, "node_modules/npm/node_modules/libnpmpublish": { "version": "11.1.3", - "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-11.1.3.tgz", - "integrity": "sha512-NVPTth/71cfbdYHqypcO9Lt5WFGTzFEcx81lWd7GDJIgZ95ERdYHGUfCtFejHCyqodKsQkNEx2JCkMpreDty/A==", "dev": true, "inBundle": true, "license": "ISC", @@ -15363,8 +15217,6 @@ }, "node_modules/npm/node_modules/libnpmsearch": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/libnpmsearch/-/libnpmsearch-9.0.1.tgz", - "integrity": "sha512-oKw58X415ERY/BOGV3jQPVMcep8YeMRWMzuuqB0BAIM5VxicOU1tQt19ExCu4SV77SiTOEoziHxGEgJGw3FBYQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15377,8 +15229,6 @@ }, "node_modules/npm/node_modules/libnpmteam": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/libnpmteam/-/libnpmteam-8.0.2.tgz", - "integrity": "sha512-ypLrDUQoi8EhG+gzx5ENMcYq23YjPV17Mfvx4nOnQiHOi8vp47+4GvZBrMsEM4yeHPwxguF/HZoXH4rJfHdH/w==", "dev": true, "inBundle": true, "license": "ISC", @@ -15392,8 +15242,6 @@ }, "node_modules/npm/node_modules/libnpmversion": { "version": "8.0.3", - "resolved": "https://registry.npmjs.org/libnpmversion/-/libnpmversion-8.0.3.tgz", - "integrity": "sha512-Avj1GG3DT6MGzWOOk3yA7rORcMDUPizkIGbI8glHCO7WoYn3NYNmskLDwxg2NMY1Tyf2vrHAqTuSG58uqd1lJg==", "dev": true, "inBundle": true, "license": "ISC", @@ -15410,8 +15258,6 @@ }, "node_modules/npm/node_modules/lru-cache": { "version": "11.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", - "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", "dev": true, "inBundle": true, "license": "ISC", @@ -15421,8 +15267,6 @@ }, "node_modules/npm/node_modules/make-fetch-happen": { "version": "15.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", - "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15445,8 +15289,6 @@ }, "node_modules/npm/node_modules/minimatch": { "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -15462,8 +15304,6 @@ }, "node_modules/npm/node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15473,8 +15313,6 @@ }, "node_modules/npm/node_modules/minipass-collect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15504,8 +15342,6 @@ }, "node_modules/npm/node_modules/minipass-flush": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15518,8 +15354,6 @@ }, "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15532,8 +15366,6 @@ }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, "inBundle": true, "license": "ISC", @@ -15546,8 +15378,6 @@ }, "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15560,8 +15390,6 @@ }, "node_modules/npm/node_modules/minipass-sized": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "dev": true, "inBundle": true, "license": "ISC", @@ -15574,8 +15402,6 @@ }, "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15588,8 +15414,6 @@ }, "node_modules/npm/node_modules/minizlib": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "inBundle": true, "license": "MIT", @@ -15602,16 +15426,12 @@ }, "node_modules/npm/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", - "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15621,8 +15441,6 @@ }, "node_modules/npm/node_modules/negotiator": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, "inBundle": true, "license": "MIT", @@ -15656,8 +15474,6 @@ }, "node_modules/npm/node_modules/nopt": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", - "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15673,8 +15489,6 @@ }, "node_modules/npm/node_modules/npm-audit-report": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/npm-audit-report/-/npm-audit-report-7.0.0.tgz", - "integrity": "sha512-bluLL4xwGr/3PERYz50h2Upco0TJMDcLcymuFnfDWeGO99NqH724MNzhWi5sXXuXf2jbytFF0LyR8W+w1jTI6A==", "dev": true, "inBundle": true, "license": "ISC", @@ -15684,8 +15498,6 @@ }, "node_modules/npm/node_modules/npm-bundled": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", - "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15698,8 +15510,6 @@ }, "node_modules/npm/node_modules/npm-install-checks": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", - "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -15712,8 +15522,6 @@ }, "node_modules/npm/node_modules/npm-normalize-package-bin": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", - "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", "dev": true, "inBundle": true, "license": "ISC", @@ -15723,8 +15531,6 @@ }, "node_modules/npm/node_modules/npm-package-arg": { "version": "13.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", - "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", "dev": true, "inBundle": true, "license": "ISC", @@ -15753,8 +15559,6 @@ }, "node_modules/npm/node_modules/npm-pick-manifest": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", - "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15770,8 +15574,6 @@ }, "node_modules/npm/node_modules/npm-profile": { "version": "12.0.1", - "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-12.0.1.tgz", - "integrity": "sha512-Xs1mejJ1/9IKucCxdFMkiBJUre0xaxfCpbsO7DB7CadITuT4k68eI05HBlw4kj+Em1rsFMgeFNljFPYvPETbVQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15785,8 +15587,6 @@ }, "node_modules/npm/node_modules/npm-registry-fetch": { "version": "19.1.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", - "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15806,8 +15606,6 @@ }, "node_modules/npm/node_modules/npm-user-validate": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-4.0.0.tgz", - "integrity": "sha512-TP+Ziq/qPi/JRdhaEhnaiMkqfMGjhDLoh/oRfW+t5aCuIfJxIUxvwk6Sg/6ZJ069N/Be6gs00r+aZeJTfS9uHQ==", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -15817,8 +15615,6 @@ }, "node_modules/npm/node_modules/p-map": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -15862,8 +15658,6 @@ }, "node_modules/npm/node_modules/parse-conflict-json": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-5.0.1.tgz", - "integrity": "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15878,8 +15672,6 @@ }, "node_modules/npm/node_modules/path-scurry": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -15896,8 +15688,6 @@ }, "node_modules/npm/node_modules/postcss-selector-parser": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "inBundle": true, "license": "MIT", @@ -15911,8 +15701,6 @@ }, "node_modules/npm/node_modules/proc-log": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15922,8 +15710,6 @@ }, "node_modules/npm/node_modules/proggy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/proggy/-/proggy-4.0.0.tgz", - "integrity": "sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -15933,8 +15719,6 @@ }, "node_modules/npm/node_modules/promise-all-reject-late": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15944,8 +15728,6 @@ }, "node_modules/npm/node_modules/promise-call-limit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz", - "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==", "dev": true, "inBundle": true, "license": "ISC", @@ -15955,8 +15737,6 @@ }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, "inBundle": true, "license": "MIT", @@ -15970,8 +15750,6 @@ }, "node_modules/npm/node_modules/promzard": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/promzard/-/promzard-3.0.1.tgz", - "integrity": "sha512-M5mHhWh+Adz0BIxgSrqcc6GTCSconR7zWQV9vnOSptNtr6cSFlApLc28GbQhuN6oOWBQeV2C0bNE47JCY/zu3Q==", "dev": true, "inBundle": true, "license": "ISC", @@ -15984,8 +15762,6 @@ }, "node_modules/npm/node_modules/qrcode-terminal": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", - "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", "dev": true, "inBundle": true, "bin": { @@ -15994,8 +15770,6 @@ }, "node_modules/npm/node_modules/read": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/read/-/read-5.0.1.tgz", - "integrity": "sha512-+nsqpqYkkpet2UVPG8ZiuE8d113DK4vHYEoEhcrXBAlPiq6di7QRTuNiKQAbaRYegobuX2BpZ6QjanKOXnJdTA==", "dev": true, "inBundle": true, "license": "ISC", @@ -16008,8 +15782,6 @@ }, "node_modules/npm/node_modules/read-cmd-shim": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-6.0.0.tgz", - "integrity": "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==", "dev": true, "inBundle": true, "license": "ISC", @@ -16019,8 +15791,6 @@ }, "node_modules/npm/node_modules/retry": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, "inBundle": true, "license": "MIT", @@ -16030,8 +15800,6 @@ }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "inBundle": true, "license": "MIT", @@ -16051,8 +15819,6 @@ }, "node_modules/npm/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "inBundle": true, "license": "ISC", @@ -16065,8 +15831,6 @@ }, "node_modules/npm/node_modules/sigstore": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.0.0.tgz", - "integrity": "sha512-Gw/FgHtrLM9WP8P5lLcSGh9OQcrTruWCELAiS48ik1QbL0cH+dfjomiRTUE9zzz+D1N6rOLkwXUvVmXZAsNE0Q==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -16084,8 +15848,6 @@ }, "node_modules/npm/node_modules/smart-buffer": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, "inBundle": true, "license": "MIT", @@ -16096,8 +15858,6 @@ }, "node_modules/npm/node_modules/socks": { "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "dev": true, "inBundle": true, "license": "MIT", @@ -16112,8 +15872,6 @@ }, "node_modules/npm/node_modules/socks-proxy-agent": { "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, "inBundle": true, "license": "MIT", @@ -16128,8 +15886,6 @@ }, "node_modules/npm/node_modules/spdx-correct": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -16140,8 +15896,6 @@ }, "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "inBundle": true, "license": "MIT", @@ -16152,16 +15906,12 @@ }, "node_modules/npm/node_modules/spdx-exceptions": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, "inBundle": true, "license": "CC-BY-3.0" }, "node_modules/npm/node_modules/spdx-expression-parse": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "inBundle": true, "license": "MIT", @@ -16172,16 +15922,12 @@ }, "node_modules/npm/node_modules/spdx-license-ids": { "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", "dev": true, "inBundle": true, "license": "CC0-1.0" }, "node_modules/npm/node_modules/ssri": { "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", "dev": true, "inBundle": true, "license": "ISC", @@ -16194,8 +15940,6 @@ }, "node_modules/npm/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "inBundle": true, "license": "MIT", @@ -16210,8 +15954,6 @@ }, "node_modules/npm/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "inBundle": true, "license": "MIT", @@ -16224,8 +15966,6 @@ }, "node_modules/npm/node_modules/supports-color": { "version": "10.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", - "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "dev": true, "inBundle": true, "license": "MIT", @@ -16238,8 +15978,6 @@ }, "node_modules/npm/node_modules/tar": { "version": "7.5.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", - "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -16256,8 +15994,6 @@ }, "node_modules/npm/node_modules/tar/node_modules/yallist": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -16267,16 +16003,12 @@ }, "node_modules/npm/node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/tiny-relative-date": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tiny-relative-date/-/tiny-relative-date-2.0.2.tgz", - "integrity": "sha512-rGxAbeL9z3J4pI2GtBEoFaavHdO4RKAU54hEuOef5kfx5aPqiQtbhYktMOTL5OA33db8BjsDcLXuNp+/v19PHw==", "dev": true, "inBundle": true, "license": "MIT" @@ -16299,8 +16031,6 @@ }, "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "inBundle": true, "license": "MIT", @@ -16318,8 +16048,6 @@ }, "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "inBundle": true, "license": "MIT", @@ -16333,8 +16061,6 @@ }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz", - "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==", "dev": true, "inBundle": true, "license": "ISC", @@ -16344,8 +16070,6 @@ }, "node_modules/npm/node_modules/tuf-js": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.0.0.tgz", - "integrity": "sha512-Lq7ieeGvXDXwpoSmOSgLWVdsGGV9J4a77oDTAPe/Ltrqnnm/ETaRlBAQTH5JatEh8KXuE6sddf9qAv1Q2282Hg==", "dev": true, "inBundle": true, "license": "MIT", @@ -16360,8 +16084,6 @@ }, "node_modules/npm/node_modules/unique-filename": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", - "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", "dev": true, "inBundle": true, "license": "ISC", @@ -16374,8 +16096,6 @@ }, "node_modules/npm/node_modules/unique-slug": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", - "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", "dev": true, "inBundle": true, "license": "ISC", @@ -16388,16 +16108,12 @@ }, "node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -16408,8 +16124,6 @@ }, "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "inBundle": true, "license": "MIT", @@ -16429,8 +16143,6 @@ }, "node_modules/npm/node_modules/walk-up-path": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", - "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", "dev": true, "inBundle": true, "license": "ISC", @@ -16440,8 +16152,6 @@ }, "node_modules/npm/node_modules/which": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", "dev": true, "inBundle": true, "license": "ISC", @@ -16457,8 +16167,6 @@ }, "node_modules/npm/node_modules/write-file-atomic": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.0.tgz", - "integrity": "sha512-YnlPC6JqnZl6aO4uRc+dx5PHguiR9S6WeoLtpxNT9wIG+BDya7ZNE1q7KOjVgaA73hKhKLpVPgJ5QA9THQ5BRg==", "dev": true, "inBundle": true, "license": "ISC", @@ -16472,8 +16180,6 @@ }, "node_modules/npm/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, "inBundle": true, "license": "ISC" diff --git a/packages/wasm-solana/js/explain.ts b/packages/wasm-solana/js/explain.ts deleted file mode 100644 index 06acfae3..00000000 --- a/packages/wasm-solana/js/explain.ts +++ /dev/null @@ -1,435 +0,0 @@ -/** - * High-level transaction explanation. - * - * Builds on top of `parseTransaction` (WASM) to provide a structured - * "explain" view of a Solana transaction: type, outputs, inputs, fee, etc. - * - * The WASM parser returns raw individual instructions. This module combines - * related instruction sequences into higher-level operations and derives the - * overall transaction type. - */ - -import { parseTransaction } from "./parser.js"; -import type { InstructionParams, ParsedTransaction } from "./parser.js"; - -// ============================================================================= -// Public types -// ============================================================================= - -export enum TransactionType { - Send = "Send", - StakingActivate = "StakingActivate", - StakingDeactivate = "StakingDeactivate", - StakingWithdraw = "StakingWithdraw", - StakingAuthorize = "StakingAuthorize", - StakingDelegate = "StakingDelegate", - WalletInitialization = "WalletInitialization", - AssociatedTokenAccountInitialization = "AssociatedTokenAccountInitialization", -} - -/** Solana base fee per signature (protocol constant). */ -const DEFAULT_LAMPORTS_PER_SIGNATURE = 5000n; - -export interface ExplainOptions { - /** Defaults to 5000 (Solana protocol constant). */ - lamportsPerSignature?: bigint | number | string; - tokenAccountRentExemptAmount?: bigint | number | string; -} - -export interface ExplainedOutput { - address: string; - amount: bigint; - tokenName?: string; -} - -export interface ExplainedInput { - address: string; - value: bigint; -} - -export interface TokenEnablement { - /** The ATA address being created */ - address: string; - /** The SPL token mint address */ - mintAddress: string; -} - -export interface StakingAuthorizeInfo { - stakingAddress: string; - oldAuthorizeAddress: string; - newAuthorizeAddress: string; - authorizeType: "Staker" | "Withdrawer"; - custodianAddress?: string; -} - -export interface ExplainedTransaction { - /** Transaction ID (base58 signature). Undefined if the transaction is unsigned. */ - id: string | undefined; - type: TransactionType; - feePayer: string; - fee: bigint; - blockhash: string; - durableNonce?: { walletNonceAddress: string; authWalletAddress: string }; - outputs: ExplainedOutput[]; - inputs: ExplainedInput[]; - outputAmount: bigint; - memo?: string; - /** - * Maps ATA address → owner address for CreateAssociatedTokenAccount instructions. - * Allows resolving newly-created token account ownership without an external lookup. - */ - ataOwnerMap: Record; - /** - * Token enablements from CreateAssociatedTokenAccount instructions. - * Contains the ATA address and mint address (consumer resolves token names). - */ - tokenEnablements: TokenEnablement[]; - /** Staking authorize details, present when the transaction changes stake authority. */ - stakingAuthorize?: StakingAuthorizeInfo; - numSignatures: number; -} - -// ============================================================================= -// Instruction combining -// ============================================================================= - -// Solana native staking requires 3 separate instructions: -// CreateAccount (fund the stake account) + StakeInitialize (set authorities) + DelegateStake (pick validator) -// Semantically this is a single "activate stake" operation. -// Marinade staking uses only CreateAccount + StakeInitialize (no Delegate) because -// Marinade's staker authority is the Marinade program, not a validator. - -interface CombinedStakeActivate { - kind: "StakingActivate"; - fromAddress: string; - stakingAddress: string; - amount: bigint; -} - -interface CombinedWalletInit { - kind: "WalletInitialization"; - fromAddress: string; - nonceAddress: string; - amount: bigint; -} - -type CombinedPattern = CombinedStakeActivate | CombinedWalletInit; - -/** - * Scan for multi-instruction patterns that should be combined: - * - * 1. CreateAccount + StakeInitialize [+ StakingDelegate] → StakingActivate - * - With Delegate following = NATIVE staking - * - Without Delegate = MARINADE staking (Marinade's program handles delegation) - * 2. CreateAccount + NonceInitialize → WalletInitialization - * - BitGo creates a nonce account during wallet initialization - */ -function detectCombinedPattern(instructions: InstructionParams[]): CombinedPattern | null { - for (let i = 0; i < instructions.length - 1; i++) { - const curr = instructions[i]; - const next = instructions[i + 1]; - - if (curr.type === "CreateAccount" && next.type === "StakeInitialize") { - return { - kind: "StakingActivate", - fromAddress: curr.fromAddress, - stakingAddress: curr.newAddress, - amount: curr.amount, - }; - } - - if (curr.type === "CreateAccount" && next.type === "NonceInitialize") { - return { - kind: "WalletInitialization", - fromAddress: curr.fromAddress, - nonceAddress: curr.newAddress, - amount: curr.amount, - }; - } - } - - return null; -} - -// ============================================================================= -// Transaction type derivation -// ============================================================================= - -const BOILERPLATE_TYPES = new Set([ - "NonceAdvance", - "Memo", - "SetComputeUnitLimit", - "SetPriorityFee", -]); - -function deriveTransactionType( - instructions: InstructionParams[], - combined: CombinedPattern | null, - memo: string | undefined, -): TransactionType { - if (combined) return TransactionType[combined.kind]; - - // Marinade deactivate: Transfer + memo containing "PrepareForRevoke" - if (memo?.includes("PrepareForRevoke")) return TransactionType.StakingDeactivate; - - // Jito pool operations map to staking types - if (instructions.some((i) => i.type === "StakePoolDepositSol")) - return TransactionType.StakingActivate; - if (instructions.some((i) => i.type === "StakePoolWithdrawStake")) - return TransactionType.StakingDeactivate; - - // ATA-only transactions (ignoring boilerplate like nonce/memo/compute budget) - const meaningful = instructions.filter((i) => !BOILERPLATE_TYPES.has(i.type)); - if (meaningful.length > 0 && meaningful.every((i) => i.type === "CreateAssociatedTokenAccount")) { - return TransactionType.AssociatedTokenAccountInitialization; - } - - // For staking instructions, the instruction type IS the transaction type - const staking = instructions.find((i) => i.type in TransactionType); - if (staking) return TransactionType[staking.type as keyof typeof TransactionType]; - - return TransactionType.Send; -} - -// ============================================================================= -// Transaction ID extraction -// ============================================================================= - -// Base58 encoding of 64 zero bytes. Unsigned transactions have all-zero -// signatures which encode to this constant. -const ALL_ZEROS_BASE58 = "1111111111111111111111111111111111111111111111111111111111111111"; - -function extractTransactionId(signatures: string[]): string | undefined { - const sig = signatures[0]; - if (!sig || sig === ALL_ZEROS_BASE58) return undefined; - return sig; -} - -// ============================================================================= -// Main export -// ============================================================================= - -/** - * Explain a Solana transaction. - * - * Takes raw transaction bytes and fee parameters, then returns a structured - * explanation including transaction type, outputs, inputs, fee, memo, and - * associated-token-account owner mappings. - * - * @param input - Raw transaction bytes (caller is responsible for decoding base64/hex) - * @param options - Fee parameters for calculating the total fee - * @returns An ExplainedTransaction with all fields populated - * - * @example - * ```typescript - * import { explainTransaction } from '@bitgo/wasm-solana'; - * - * const txBytes = Buffer.from(txBase64, 'base64'); - * const explained = explainTransaction(txBytes, { - * lamportsPerSignature: 5000n, - * tokenAccountRentExemptAmount: 2039280n, - * }); - * console.log(explained.type); // "Send", "StakingActivate", etc. - * ``` - */ -export function explainTransaction( - input: Uint8Array, - options: ExplainOptions, -): ExplainedTransaction { - const { lamportsPerSignature, tokenAccountRentExemptAmount } = options; - - const parsed: ParsedTransaction = parseTransaction(input); - - // --- Transaction ID --- - const id = extractTransactionId(parsed.signatures); - - // --- Fee calculation --- - // Base fee = numSignatures × lamportsPerSignature - let fee = - BigInt(parsed.numSignatures) * - (lamportsPerSignature !== undefined - ? BigInt(lamportsPerSignature) - : DEFAULT_LAMPORTS_PER_SIGNATURE); - - // Each CreateAssociatedTokenAccount instruction creates a new token account, - // which requires a rent-exempt deposit. Add that to the fee. - const ataCount = parsed.instructionsData.filter( - (i) => i.type === "CreateAssociatedTokenAccount", - ).length; - if (ataCount > 0 && tokenAccountRentExemptAmount !== undefined) { - fee += BigInt(ataCount) * BigInt(tokenAccountRentExemptAmount); - } - - // --- Extract memo (needed before type derivation) --- - let memo: string | undefined; - for (const instr of parsed.instructionsData) { - if (instr.type === "Memo") { - memo = instr.memo; - } - } - - // --- Detect combined instruction patterns --- - const combined = detectCombinedPattern(parsed.instructionsData); - const txType = deriveTransactionType(parsed.instructionsData, combined, memo); - - // Marinade deactivate: Transfer + PrepareForRevoke memo. - // The Transfer is a contract interaction (not a real value transfer), - // so we skip it from outputs. - const isMarinadeDeactivate = - txType === TransactionType.StakingDeactivate && - memo !== undefined && - memo.includes("PrepareForRevoke"); - - // --- Extract outputs and inputs --- - const outputs: ExplainedOutput[] = []; - const inputs: ExplainedInput[] = []; - - if (combined?.kind === "StakingActivate") { - // Combined native/Marinade staking activate — the staking address receives - // the full amount from the funding account. - outputs.push({ - address: combined.stakingAddress, - amount: combined.amount, - }); - inputs.push({ - address: combined.fromAddress, - value: combined.amount, - }); - } else if (combined?.kind === "WalletInitialization") { - // Wallet initialization — funds the new nonce account. - outputs.push({ - address: combined.nonceAddress, - amount: combined.amount, - }); - inputs.push({ - address: combined.fromAddress, - value: combined.amount, - }); - } else { - // Process individual instructions for outputs/inputs - for (const instr of parsed.instructionsData) { - switch (instr.type) { - case "Transfer": - // Skip Transfer for Marinade deactivate — it's a program interaction, - // not a real value transfer to an external address. - if (isMarinadeDeactivate) break; - outputs.push({ - address: instr.toAddress, - amount: instr.amount, - }); - inputs.push({ - address: instr.fromAddress, - value: instr.amount, - }); - break; - - case "TokenTransfer": - outputs.push({ - address: instr.toAddress, - amount: instr.amount, - tokenName: instr.tokenAddress, - }); - inputs.push({ - address: instr.fromAddress, - value: instr.amount, - }); - break; - - case "StakingActivate": - outputs.push({ - address: instr.stakingAddress, - amount: instr.amount, - }); - inputs.push({ - address: instr.fromAddress, - value: instr.amount, - }); - break; - - case "StakingWithdraw": - // Withdraw: SOL flows FROM the staking address TO the recipient. - // `fromAddress` is the recipient (where funds go), - // `stakingAddress` is the source. - outputs.push({ - address: instr.fromAddress, - amount: instr.amount, - }); - inputs.push({ - address: instr.stakingAddress, - value: instr.amount, - }); - break; - - case "StakePoolDepositSol": - // Jito liquid staking: SOL is deposited into the stake pool. - // The funding account is debited; output goes to the pool address. - outputs.push({ - address: instr.stakePool, - amount: instr.lamports, - }); - inputs.push({ - address: instr.fundingAccount, - value: instr.lamports, - }); - break; - - // StakingDeactivate, StakingAuthorize, StakingDelegate, - // StakePoolWithdrawStake, NonceAdvance, CreateAccount, - // StakeInitialize, NonceInitialize, SetComputeUnitLimit, - // SetPriorityFee, CreateAssociatedTokenAccount, - // CloseAssociatedTokenAccount, Memo, Unknown - // — no value inputs/outputs. - } - } - } - - // --- Output amount --- - // Only count native SOL outputs (no tokenName). Token amounts are in different - // denominations and shouldn't be mixed with SOL lamports. - const outputAmount = outputs.filter((o) => !o.tokenName).reduce((sum, o) => sum + o.amount, 0n); - - // --- ATA owner mapping and token enablements --- - const ataOwnerMap: Record = {}; - const tokenEnablements: TokenEnablement[] = []; - for (const instr of parsed.instructionsData) { - if (instr.type === "CreateAssociatedTokenAccount") { - ataOwnerMap[instr.ataAddress] = instr.ownerAddress; - tokenEnablements.push({ - address: instr.ataAddress, - mintAddress: instr.mintAddress, - }); - } - } - - // --- Staking authorize --- - let stakingAuthorize: StakingAuthorizeInfo | undefined; - for (const instr of parsed.instructionsData) { - if (instr.type === "StakingAuthorize") { - stakingAuthorize = { - stakingAddress: instr.stakingAddress, - oldAuthorizeAddress: instr.oldAuthorizeAddress, - newAuthorizeAddress: instr.newAuthorizeAddress, - authorizeType: instr.authorizeType, - custodianAddress: instr.custodianAddress, - }; - break; - } - } - - return { - id, - type: txType, - feePayer: parsed.feePayer, - fee, - blockhash: parsed.nonce, - durableNonce: parsed.durableNonce, - outputs, - inputs, - outputAmount, - memo, - ataOwnerMap, - tokenEnablements, - stakingAuthorize, - numSignatures: parsed.numSignatures, - }; -} diff --git a/packages/wasm-solana/js/index.ts b/packages/wasm-solana/js/index.ts index d362ea07..38cb1d8a 100644 --- a/packages/wasm-solana/js/index.ts +++ b/packages/wasm-solana/js/index.ts @@ -9,7 +9,6 @@ export * as pubkey from "./pubkey.js"; export * as transaction from "./transaction.js"; export * as parser from "./parser.js"; export * as builder from "./builder.js"; -export * as explain from "./explain.js"; // Top-level class exports for convenience export { Keypair } from "./keypair.js"; @@ -24,8 +23,6 @@ export type { AddressLookupTableData } from "./versioned.js"; export { parseTransaction } from "./parser.js"; export { buildFromVersionedData } from "./builder.js"; export { buildFromIntent, buildFromIntent as buildTransactionFromIntent } from "./intentBuilder.js"; -export { explainTransaction, TransactionType } from "./explain.js"; - // Intent builder type exports export type { BaseIntent, @@ -99,16 +96,6 @@ export type { UnknownInstructionParams, } from "./parser.js"; -// Explain types -export type { - ExplainedTransaction, - ExplainedOutput, - ExplainedInput, - ExplainOptions, - TokenEnablement, - StakingAuthorizeInfo, -} from "./explain.js"; - // Versioned transaction builder type exports export type { AddressLookupTable as BuilderAddressLookupTable, diff --git a/packages/wasm-solana/js/parser.ts b/packages/wasm-solana/js/parser.ts index b55148c3..538582d2 100644 --- a/packages/wasm-solana/js/parser.ts +++ b/packages/wasm-solana/js/parser.ts @@ -1,13 +1,14 @@ /** * High-level transaction parsing. * - * Provides types and functions for parsing Solana transactions into semantic data - * matching BitGoJS's TxData format. + * Provides types and functions for parsing Solana transactions into + * semantic data matching BitGoJS's TxData format. * * All monetary amounts (amount, fee, lamports, poolTokens) are returned as bigint. */ import { ParserNamespace } from "./wasm/wasm_solana.js"; +import type { Transaction } from "./transaction.js"; // ============================================================================= // Instruction Types - matching BitGoJS InstructionParams. @@ -273,17 +274,24 @@ export interface ParsedTransaction { // ============================================================================= /** - * Parse raw transaction bytes into a plain data object with decoded instructions. + * Parse a Transaction into a plain data object with decoded instructions. * * This is the main parsing function that returns structured data with all * instructions decoded into semantic types (Transfer, StakingActivate, etc.) * with amounts as bigint. * - * For signing/serialization, use `Transaction.fromBytes()` instead. + * Accepts a `Transaction` object (from `Transaction.fromBytes()`), avoiding + * double deserialization. * - * @param bytes - Raw transaction bytes + * @param tx - A Transaction instance (from Transaction.fromBytes()) * @returns A ParsedTransaction with all instructions decoded + * + * @example + * ```typescript + * const tx = Transaction.fromBytes(txBytes); + * const parsed = parseTransaction(tx); + * ``` */ -export function parseTransaction(bytes: Uint8Array): ParsedTransaction { - return ParserNamespace.parse_transaction(bytes) as ParsedTransaction; +export function parseTransaction(tx: Transaction): ParsedTransaction { + return ParserNamespace.parse_from_transaction(tx.wasm) as ParsedTransaction; } diff --git a/packages/wasm-solana/js/transaction.ts b/packages/wasm-solana/js/transaction.ts index 17928390..ef2fa6e3 100644 --- a/packages/wasm-solana/js/transaction.ts +++ b/packages/wasm-solana/js/transaction.ts @@ -30,22 +30,23 @@ export interface Instruction { * Solana Transaction — deserialization wrapper for signing and serialization. * * Use `Transaction.fromBytes(bytes)` to create an instance for signing. - * Use `parseTransaction(bytes)` from parser.ts to get decoded instruction data. + * Use `parseTransaction(tx)` from parser.ts to get decoded instruction data. * * @example * ```typescript * import { Transaction, parseTransaction } from '@bitgo/wasm-solana'; * + * const tx = Transaction.fromBytes(txBytes); + * * // Parse for decoded instructions - * const parsed = parseTransaction(txBytes); + * const parsed = parseTransaction(tx); * for (const instr of parsed.instructionsData) { * if (instr.type === 'Transfer') { * console.log(`${instr.amount} lamports to ${instr.toAddress}`); * } * } * - * // Deserialize for signing - * const tx = Transaction.fromBytes(txBytes); + * // Sign and serialize * tx.addSignature(pubkey, signature); * const signedBytes = tx.toBytes(); * ``` diff --git a/packages/wasm-solana/src/intent/build.rs b/packages/wasm-solana/src/intent/build.rs index 18b8ddea..07541a13 100644 --- a/packages/wasm-solana/src/intent/build.rs +++ b/packages/wasm-solana/src/intent/build.rs @@ -313,8 +313,7 @@ fn build_jito_stake( // For Jito, validatorAddress is the stake pool address let stake_pool: Pubkey = config .stake_pool_address - .as_ref() - .map(|s| s.as_str()) + .as_deref() .unwrap_or(validator_address) .parse() .map_err(|_| WasmSolanaError::new("Invalid stakePoolAddress"))?; @@ -1156,7 +1155,7 @@ mod tests { .transaction .signatures .iter() - .filter(|s| s.as_ref() != &zero_sig) + .filter(|s| s.as_ref() != zero_sig) .count(); assert_eq!( non_zero_count, 1, diff --git a/packages/wasm-solana/src/parser.rs b/packages/wasm-solana/src/parser.rs index b0e2f265..6882f78c 100644 --- a/packages/wasm-solana/src/parser.rs +++ b/packages/wasm-solana/src/parser.rs @@ -9,6 +9,7 @@ use crate::instructions::{decode_instruction, InstructionContext, ParsedInstruction}; use crate::js_obj; +use crate::transaction::Transaction; use crate::versioned::VersionedTransactionExt; use crate::wasm::try_into_js_value::{JsConversionError, TryIntoJsValue}; use solana_message::VersionedMessage; @@ -91,20 +92,52 @@ pub fn parse_transaction(bytes: &[u8]) -> Result { { VersionedMessage::Legacy(msg) => ( msg.account_keys.iter().map(|k| k.to_string()).collect(), - &msg.instructions, + &msg.instructions[..], msg.recent_blockhash.to_string(), msg.header.num_required_signatures, ), VersionedMessage::V0(msg) => ( msg.account_keys.iter().map(|k| k.to_string()).collect(), - &msg.instructions, + &msg.instructions[..], msg.recent_blockhash.to_string(), msg.header.num_required_signatures, ), }; - let account_keys: Vec = account_keys; + parse_transaction_inner( + account_keys, + instructions, + recent_blockhash, + num_required_signatures, + &tx.signatures, + ) +} + +/// Parse a pre-deserialized legacy Transaction into structured data. +/// +/// Same logic as `parse_transaction(bytes)` but skips deserialization. +/// Used when the caller already has a `Transaction` from `fromBytes()`. +pub fn parse_from_transaction(tx: &Transaction) -> Result { + let msg = &tx.message; + let account_keys: Vec = msg.account_keys.iter().map(|k| k.to_string()).collect(); + + parse_transaction_inner( + account_keys, + &msg.instructions, + msg.recent_blockhash.to_string(), + msg.header.num_required_signatures, + &tx.signatures, + ) +} +/// Shared parsing logic for both bytes-based and Transaction-based entry points. +fn parse_transaction_inner( + account_keys: Vec, + instructions: &[solana_message::compiled_instruction::CompiledInstruction], + recent_blockhash: String, + num_required_signatures: u8, + signatures: &[solana_signature::Signature], +) -> Result { // Extract fee payer (first account key) let fee_payer = account_keys .first() @@ -156,8 +189,7 @@ pub fn parse_transaction(bytes: &[u8]) -> Result { // Extract signatures as base58 strings. // All-zeros signatures (unsigned placeholder slots) are returned as empty strings // so the JS side can simply use `signatures[0] || 'UNAVAILABLE'`. - let signatures: Vec = tx - .signatures + let signatures: Vec = signatures .iter() .map(|s| { let bytes: &[u8] = s.as_ref(); diff --git a/packages/wasm-solana/src/wasm/parser.rs b/packages/wasm-solana/src/wasm/parser.rs index 96bf3ca9..ae1b34f4 100644 --- a/packages/wasm-solana/src/wasm/parser.rs +++ b/packages/wasm-solana/src/wasm/parser.rs @@ -1,9 +1,10 @@ //! WASM binding for high-level transaction parsing. //! -//! Exposes a single `parseTransaction` function that returns fully decoded +//! Exposes transaction parsing functions that return fully decoded //! transaction data matching BitGoJS's TxData format. use crate::parser; +use crate::wasm::transaction::WasmTransaction; use crate::wasm::try_into_js_value::TryIntoJsValue; use wasm_bindgen::prelude::*; @@ -38,4 +39,22 @@ impl ParserNamespace { .try_to_js_value() .map_err(|e| JsValue::from_str(&format!("Conversion error: {}", e))) } + + /// Parse a pre-deserialized Transaction into structured data. + /// + /// Same as `parse_transaction(bytes)` but accepts an already-deserialized + /// WasmTransaction, avoiding double deserialization when the caller already + /// has a Transaction from `fromBytes()`. + /// + /// @param tx - A WasmTransaction instance + /// @returns A ParsedTransaction object + #[wasm_bindgen] + pub fn parse_from_transaction(tx: &WasmTransaction) -> Result { + let parsed = + parser::parse_from_transaction(tx.inner()).map_err(|e| JsValue::from_str(&e))?; + + parsed + .try_to_js_value() + .map_err(|e| JsValue::from_str(&format!("Conversion error: {}", e))) + } } diff --git a/packages/wasm-solana/test/bitgojs-compat.ts b/packages/wasm-solana/test/bitgojs-compat.ts index a1c2f25d..e6b4b1c0 100644 --- a/packages/wasm-solana/test/bitgojs-compat.ts +++ b/packages/wasm-solana/test/bitgojs-compat.ts @@ -6,6 +6,7 @@ */ import * as assert from "assert"; import { parseTransaction } from "../js/parser.js"; +import { Transaction } from "../js/transaction.js"; // Helper to decode base64 in tests function base64ToBytes(base64: string): Uint8Array { @@ -51,25 +52,25 @@ describe("BitGoJS Compatibility", () => { it("should parse feePayer correctly", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); assert.strictEqual(parsed.feePayer, EXPECTED.feePayer); }); it("should parse nonce correctly", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); assert.strictEqual(parsed.nonce, EXPECTED.nonce); }); it("should parse numSignatures correctly", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); assert.strictEqual(parsed.numSignatures, EXPECTED.numSignatures); }); it("should detect durable nonce transaction", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); assert.ok(parsed.durableNonce, "Should detect durable nonce"); assert.strictEqual( parsed.durableNonce.walletNonceAddress, @@ -83,7 +84,7 @@ describe("BitGoJS Compatibility", () => { it("should have NonceAdvance in both instructionsData and durableNonce", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // WASM returns all instructions including NonceAdvance const nonceAdvance = parsed.instructionsData.find((i) => i.type === "NonceAdvance"); assert.ok(nonceAdvance, "NonceAdvance should be in instructionsData"); @@ -97,7 +98,7 @@ describe("BitGoJS Compatibility", () => { it("should parse Transfer instruction correctly", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Transfer is at index 1 (after NonceAdvance) const instr = parsed.instructionsData[1]; @@ -114,7 +115,7 @@ describe("BitGoJS Compatibility", () => { it("should parse Memo instruction correctly", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Memo is at index 2 (after NonceAdvance and Transfer) const instr = parsed.instructionsData[2]; @@ -129,7 +130,7 @@ describe("BitGoJS Compatibility", () => { it("should have correct number of instructions", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // 3 instructions: NonceAdvance + Transfer + Memo assert.strictEqual(parsed.instructionsData.length, 3); }); @@ -154,7 +155,7 @@ describe("BitGoJS Compatibility", () => { it("should parse multi-transfer with correct structure", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); assert.strictEqual(parsed.feePayer, EXPECTED_FEE_PAYER); assert.strictEqual(parsed.nonce, EXPECTED_NONCE); @@ -166,7 +167,7 @@ describe("BitGoJS Compatibility", () => { it("should parse all transfer recipients correctly", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Transfers are at indices 1-6 (index 0 is NonceAdvance) const transfers = parsed.instructionsData.slice(1, 7); @@ -185,7 +186,7 @@ describe("BitGoJS Compatibility", () => { it("should have memo as last instruction", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); const lastInstr = parsed.instructionsData[parsed.instructionsData.length - 1]; assert.strictEqual(lastInstr.type, "Memo"); @@ -202,7 +203,7 @@ describe("BitGoJS Compatibility", () => { it("should parse staking transaction structure", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); assert.strictEqual(parsed.feePayer, "5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe"); assert.ok(parsed.instructionsData.length >= 1, "Should have instructions"); @@ -225,7 +226,7 @@ describe("BitGoJS Compatibility", () => { it("should parse token transfer transaction", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Should have 4 instructions: NonceAdvance, SetPriorityFee, TokenTransfer, Memo assert.strictEqual(parsed.instructionsData.length, 4); @@ -252,7 +253,7 @@ describe("BitGoJS Compatibility", () => { it("should parse basic unsigned transfer", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // This is a durable nonce transaction: NonceAdvance + Transfer assert.strictEqual(parsed.instructionsData.length, 2); @@ -275,7 +276,7 @@ describe("BitGoJS Compatibility", () => { it("should parse Jito DepositSol instruction", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Find the StakePoolDepositSol instruction const depositSolInstr = parsed.instructionsData.find((i) => i.type === "StakePoolDepositSol"); @@ -294,7 +295,7 @@ describe("BitGoJS Compatibility", () => { it("should have correct fee payer for Jito transaction", () => { const bytes = base64ToBytes(TX_BASE64); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Fee payer from BitGoJS tests assert.strictEqual(parsed.feePayer, "5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe"); diff --git a/packages/wasm-solana/test/intentBuilder.ts b/packages/wasm-solana/test/intentBuilder.ts index 519e3a68..b0fd9967 100644 --- a/packages/wasm-solana/test/intentBuilder.ts +++ b/packages/wasm-solana/test/intentBuilder.ts @@ -58,7 +58,7 @@ describe("buildFromIntent", function () { }); // Parse to verify - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); // Should have 2 Transfer instructions const transfers = parsed.instructionsData.filter((i: any) => i.type === "Transfer"); @@ -83,7 +83,7 @@ describe("buildFromIntent", function () { }); // Parse to verify - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); // Should have Memo instruction const memos = parsed.instructionsData.filter((i: any) => i.type === "Memo"); @@ -125,7 +125,7 @@ describe("buildFromIntent", function () { }); // Parse to verify - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); // Native staking should have 3 instructions: CreateAccount, StakeInitialize, StakeDelegate assert(parsed.instructionsData.length >= 3, "Should have at least 3 instructions"); @@ -157,7 +157,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instruction - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const deactivate = parsed.instructionsData.find((i: any) => i.type === "StakingDeactivate"); assert(deactivate, "Should have StakingDeactivate instruction"); @@ -178,7 +178,7 @@ describe("buildFromIntent", function () { }); // Verify instructions - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const deactivates = parsed.instructionsData.filter( (i: any) => i.type === "StakingDeactivate", @@ -204,7 +204,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instruction - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const withdraw = parsed.instructionsData.find((i: any) => i.type === "StakingWithdraw"); assert(withdraw, "Should have StakingWithdraw instruction"); @@ -228,7 +228,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instruction - delegate is a StakingDelegate instruction - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const delegate = parsed.instructionsData.find((i: any) => i.type === "StakingDelegate"); assert(delegate, "Should have StakingDelegate instruction"); @@ -252,7 +252,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instruction - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const createAta = parsed.instructionsData.find( (i: any) => i.type === "CreateAssociatedTokenAccount", @@ -285,7 +285,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instructions - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const createAtaInstructions = parsed.instructionsData.filter( (i: any) => i.type === "CreateAssociatedTokenAccount", @@ -314,7 +314,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instruction - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); const closeAta = parsed.instructionsData.find( (i: any) => i.type === "CloseAssociatedTokenAccount", @@ -347,7 +347,7 @@ describe("buildFromIntent", function () { assert.equal(result.generatedKeypairs.length, 0, "Should not generate keypairs"); // Verify instruction - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); // Should have a Transfer instruction where the sender is the child address const transfer = parsed.instructionsData.find((i: any) => i.type === "Transfer"); @@ -379,7 +379,7 @@ describe("buildFromIntent", function () { nonce: { type: "blockhash", value: blockhash }, }); - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); // Should have 2 Transfer instructions const transfers = parsed.instructionsData.filter((i: any) => i.type === "Transfer"); @@ -413,7 +413,7 @@ describe("buildFromIntent", function () { }); // Verify instructions - const parsed = parseTransaction(result.transaction.toBytes()); + const parsed = parseTransaction(result.transaction); // First instruction should be NonceAdvance assert.equal( diff --git a/packages/wasm-solana/test/parser.ts b/packages/wasm-solana/test/parser.ts index 9f7d41c5..1f58cae3 100644 --- a/packages/wasm-solana/test/parser.ts +++ b/packages/wasm-solana/test/parser.ts @@ -1,5 +1,6 @@ import * as assert from "assert"; import { parseTransaction } from "../js/parser.js"; +import { Transaction } from "../js/transaction.js"; // Helper to decode base64 in tests function base64ToBytes(base64: string): Uint8Array { @@ -15,7 +16,7 @@ describe("parseTransaction", () => { const TEST_TX_BYTES = base64ToBytes(TEST_TX_BASE64); it("should parse a SOL transfer transaction", () => { - const parsed = parseTransaction(TEST_TX_BYTES); + const parsed = parseTransaction(Transaction.fromBytes(TEST_TX_BYTES)); // Check basic structure assert.ok(parsed.feePayer); @@ -26,7 +27,7 @@ describe("parseTransaction", () => { }); it("should decode SOL transfer instruction correctly", () => { - const parsed = parseTransaction(TEST_TX_BYTES); + const parsed = parseTransaction(Transaction.fromBytes(TEST_TX_BYTES)); assert.strictEqual(parsed.instructionsData.length, 1); const instr = parsed.instructionsData[0]; @@ -44,25 +45,25 @@ describe("parseTransaction", () => { }); it("should include fee payer as first account key", () => { - const parsed = parseTransaction(TEST_TX_BYTES); + const parsed = parseTransaction(Transaction.fromBytes(TEST_TX_BYTES)); assert.strictEqual(parsed.feePayer, parsed.accountKeys[0]); }); it("should reject invalid bytes", () => { const invalidBytes = new Uint8Array([0, 1, 2, 3]); - assert.throws(() => parseTransaction(invalidBytes)); + assert.throws(() => Transaction.fromBytes(invalidBytes)); }); it("should set durableNonce for nonce transactions", () => { // This is a regular (non-nonce) transaction, so durableNonce should be undefined - const parsed = parseTransaction(TEST_TX_BYTES); + const parsed = parseTransaction(Transaction.fromBytes(TEST_TX_BYTES)); assert.strictEqual(parsed.durableNonce, undefined); }); describe("instruction type discrimination", () => { it("should have type field on all instructions", () => { - const parsed = parseTransaction(TEST_TX_BYTES); + const parsed = parseTransaction(Transaction.fromBytes(TEST_TX_BYTES)); for (const instr of parsed.instructionsData) { assert.ok("type" in instr, "Instruction should have type field"); @@ -71,7 +72,7 @@ describe("parseTransaction", () => { }); it("Transfer instruction should have correct fields", () => { - const parsed = parseTransaction(TEST_TX_BYTES); + const parsed = parseTransaction(Transaction.fromBytes(TEST_TX_BYTES)); const transfer = parsed.instructionsData[0]; if (transfer.type === "Transfer") { @@ -91,7 +92,7 @@ describe("StakingAuthorize parsing", () => { "BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAwQJSN/yAiroYbrh33Xw+MKSGtu8m4Hx4sqwncAXz/he+b84neq4+YPEcZolDyLtQRwrgvHDZaDkTO1AFV+8JECpZViONvuJhgX6ijN1ogXXktMlrW9LsGh17WRMFiwbX9DjtnKIrK5VJ/5vhQidfy2H5id17M7MCqU8z9fuL/G26kb+iZNTXfchXIJtP9yKrACRJunT7w9bkgs7KLnfQO4e/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqHYF5E3VCqYNDe9/ip6slV/U1yKeHIraKSdwAAAAAAGp9UXGMd0yShWY5hpHV62i164o5tLbVxzVVshAAAAAAan1RcZLFaO4IqEX3PSl4jPA1wxRbIas0TYBi6pQAAAHv54hjZyXUu92IV/PX26I8zpgfXc5S/zZXMURlOUSjQCBQMECAAEBAAAAAYFBAcCAQMICgAAAAEAAAA="; const bytes = Buffer.from(STAKING_AUTHORIZE_RAW_MSG_TXN, "base64"); - const parsed = parseTransaction(bytes); + const parsed = parseTransaction(Transaction.fromBytes(bytes)); // Should have NonceAdvance + StakingAuthorize assert.strictEqual(parsed.instructionsData.length, 2); diff --git a/packages/webui/src/wasm-solana/transaction/index.ts b/packages/webui/src/wasm-solana/transaction/index.ts index f8b4cfe5..f7fdd070 100644 --- a/packages/webui/src/wasm-solana/transaction/index.ts +++ b/packages/webui/src/wasm-solana/transaction/index.ts @@ -9,6 +9,7 @@ import { BaseComponent, defineComponent, h, css, fragment, type Child } from ".. import { setParams } from "../../lib/router"; import { commonStyles } from "../../index"; import { + Transaction, parseTransaction, type ParsedTransaction, type InstructionParams, @@ -516,7 +517,8 @@ class SolanaTransactionParser extends BaseComponent { try { // Parse the transaction const bytes = base64ToBytes(txData); - const parsed = parseTransaction(bytes); + const tx = Transaction.fromBytes(bytes); + const parsed = parseTransaction(tx); // Render transaction info txInfoEl.replaceChildren(this.renderTxInfo(parsed));