diff --git a/rust/defi/Makefile b/rust/defi/Makefile deleted file mode 120000 index 0678e62eb..000000000 --- a/rust/defi/Makefile +++ /dev/null @@ -1 +0,0 @@ -../../motoko/defi/Makefile \ No newline at end of file diff --git a/rust/defi/Makefile b/rust/defi/Makefile new file mode 100644 index 000000000..724e6fed0 --- /dev/null +++ b/rust/defi/Makefile @@ -0,0 +1,47 @@ +SHELL = /bin/bash + +.PHONY: all +all: install + +.PHONY: node_modules +.SILENT: node_modules +node_modules: + pushd src/frontend; npm install; popd + +.PHONY: install +.SILENT: install +install: clean + ./scripts/install.sh + + +.PHONY: init-local +.SILENT: init-local +init-local: + ./scripts/initalize_local_balance.sh $(II_PRINCIPAL) + +.PHONY: build +.SILENT: build +build: + dfx canister create --all + dfx build + +.PHONY: frontend +.SILENT: frontend +frontend: node_modules + cd src/frontend && npm run dev + +.PHONY: test +.SILENT: test +test: + ./test/demo.sh + ./test/trade.sh + ./test/transfer.sh + +.PHONY: clean +.SILENT: clean +clean: + dfx stop + rm -fr .dfx + rm -fr src/frontend/node_modules/ + rm -fr src/frontend/declarations/ + rm -fr src/frontend/build/ diff --git a/rust/defi/README.md b/rust/defi/README.md deleted file mode 120000 index e1c391699..000000000 --- a/rust/defi/README.md +++ /dev/null @@ -1 +0,0 @@ -../../motoko/defi/README.md \ No newline at end of file diff --git a/rust/defi/README.md b/rust/defi/README.md new file mode 100644 index 000000000..63acc276d --- /dev/null +++ b/rust/defi/README.md @@ -0,0 +1,165 @@ +# Decentralized exchange (DEX) sample + +## Overview + +To enable DeFi applications on the IC, canisters need to interact with token canisters and the ledger canister. This sample dapp illustrates how to facilitate these interactions. You can see a quick introduction on [YouTube](https://youtu.be/fLbaOmH24Gs). + +The sample exchange is implemented in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/defi) and [Rust](https://github.com/dfinity/examples/tree/master/rust/defi) and can be seen [running on the IC](https://gzz56-daaaa-aaaal-qai2a-cai.ic0.app/). + +## Architecture + +The design of the IC allows for more complex on-chain computation. In combination with cheap storage, it is possible to have on-chain order books. This sample code takes advantage of these features and stores user balances and orders inside the exchange canister. The sample exchange functionality can be condensed into the following steps: + +- Exchange takes custody of funds (different mechanism for tokens and ICP, see below). + +- Exchange updates internal balance book. + +- Users trade on exchange causing the exchange to update its internal balance book. + +- Withdrawing funds from the exchange gives custody back to the user. + +### Interface + +Request user-specific ledger account identifier from the exchange. This unique account identifier represents a user-specific subaccount in the exchange’s ledger account, allowing it to differentiate between user deposits. + + getDepositAddress: () -> (blob); + +Initiate user deposit to exchange. If the user wants to deposit ICP, the exchange moves the funds from the user-specific deposit address to its default subaddress and adjusts the user’s ICP balance on the DEX. If the user wants to deposit a DIP token, the exchange tries to move the approved funds to its token account and adjusts the user’s balance. + + deposit: (Token) -> (DepositReceipt); + +Withdraw request to the exchange. The exchange will send funds back to the user if the user has a sufficient balance. + + withdraw: (Token, nat, principal) -> (WithdrawReceipt); + +Place new order to exchange. If the order matches an existing order, it will get executed. + + placeOrder: (Token, nat, Token, nat) -> (OrderPlacementReceipt); + +Allows the user to cancel submitted orders. + + cancelOrder: (OrderId) -> (CancelOrderReceipt); + +Request user’s balance on exchange for a specific token. + + getBalance: (Token) -> (nat) query; + +### Fee + +It is the responsibility of the exchange to subtract fees from the trades. This is important because the exchange must pay fees for withdrawals and internal transfers. + +## Token exchange walkthrough + +This section contains a detailed walkthrough of the core exchange functionalities. Most interactions require multiple steps and are simplified by using the provided frontend. Since the exchange canister functions are public, advanced users can use `dfx` to interact with the exchange. + +### Depositing ICP + +The ledger canister provides a unique interface so that interactions with ICP need to be resolved separately. + +- The user calls the `getDepositAddress` function. The response contains a unique account identifier representing a user-specific subaccount controlled by the exchange. The exchange can identify the user responsible for deposits through this address. + +- User transfers ICP to the fetched deposit address and waits for the transfer to complete. + +- To notify the exchange, the user calls `deposit` with the ICP token principal. The exchange will look into the user’s subaccount and adjust the user’s balance on the exchange. In a second step, the exchange will transfer the funds from the user subaccount to its default subaccount, where the exchange keeps all of its ICP. + +### Depositing tokens + +There are a number of token standards in development (e.g. IS20, DFT, and DRC20); This sample uses DIP20. + +- The user calls the `approve` function of the token canister. This gives the exchange the ability to transfer funds to itself on behalf of the user. + +- Similar to the ICP depositing, the user calls the `deposit` function of the exchange. The exchange then transfers the approved token funds to itself and adjusts the user’s exchange balance. + +### Placing orders + +After depositing funds to the exchange, the user can place orders. An order consists of two tuples. `from: (Token1, amount1)` and `to: (Token2, amount2)`. These orders get added to the exchange. What happens to these orders is specific to the exchange implementation. This sample provides a simple exchange that only executes exactly matching orders. Be aware this is just a toy exchange, and the exchange functionality is just for completeness. + +### Withdrawing funds + +Compared to depositing funds, withdrawing funds is simpler. Since the exchange has custody of the funds, the exchange will send funds back to the user on `withdraw` requests. The internal exchange balances are adjusted accordingly. + +## Prerequisites +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Download [cmake](https://cmake.org/). +- [x] Download [npm](https://nodejs.org/en/download/). +- [x] If you want to deploy the Rust version, make sure you add Wasm as a target: + `rustup target add wasm32-unknown-unknown` + + +## Step 1: Download the project's GitHub repo and install the dependencies: + +``` +git clone --recurse-submodules --shallow-submodules https://github.com/dfinity/examples.git +# for the rust implementation examples/rust/defi +cd examples/motoko/defi +make install +``` + +The install scripts output the URL to visit the exchange frontend: + +``` +===== VISIT DEFI FRONTEND ===== +http://127.0.0.1:4943?canisterId=by6od-j4aaa-aaaaa-qaadq-cai +===== VISIT DEFI FRONTEND ===== +``` + +or you can regenerate the URL "http://127.0.0.1:4943?canisterId=$(dfx canister id frontend)". Open this URL in a web browser. + +## Step 2: To interact with the exchange, you can create a local Internet Identity by clicking the login button. + +This sample project uses a local test version of Internet Identity. Do not use your mainnet Internet Identity, and this testnet Internet Identity will not work on the mainnet. + +![DEX II Login](../../_attachments/dex-ii.png) + +## Step 3: When prompted, select **Create Internet Identity**. + +![II Step 1](../../_attachments/II1.png) + +## Step 4: Then select **Create Passkey**. + +![II Step 2](../../_attachments/II2.png) + +## Step 5: Complete the CAPTCHA. + +![II Step 3](../../_attachments/II3.png) + +## Step 6: Save the II number and click **I saved it, continue**. + +![II Step 4](../../_attachments/II4.png) + +## Step 7: You will be redirected to the exchange's frontend webpage. + +![II Step 5](../../_attachments/II5.png) + +## Step 8: You can give yourself some tokens and ICP by running an initialization script with your II principal that you can copy from the frontend. + +![II Principal](../../_attachments/II-principal.png) + +## Step 9: Then run the following command: + +`make init-local II_PRINCIPAL=` + +## Step 10: Refresh the web browser to verify that your tokens were deposited. + +![II Deposit](../../_attachments/II-deposit.png) + +To trade tokens with yourself, you can open a second incognito browser window. + +## Common mistakes and troubleshooting + +- Concurrent execution: if canister functions have `await` statements, it is possible that execution is interleaved. To avoid bugs, it is necessary to carefully consider the placement of data structure updates to prevent double-spend attacks. + +- Floating points: more advanced exchanges should take care of floating points and make sure to limit decimals. + +- No panics after await: when a panic happens, the state gets rolled back. This can cause issues with the correctness of the exchange. + + +## Security considerations and security best practices + +If you base your application on this example, we recommend you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) for developing on the Internet Computer. This example may not implement all the best practices. + +For example, the following aspects are particularly relevant for this app: +* [Inter-canister calls and rollbacks](https://internetcomputer.org/docs/current/references/security/rust-canister-development-security-best-practices/#inter-canister-calls-and-rollbacks), since issues around inter-canister calls can e.g. lead to time-of-check time-of-use or double spending security bugs. +* [Certify query responses if they are relevant for security](https://internetcomputer.org/docs/current/references/security/general-security-best-practices#certify-query-responses-if-they-are-relevant-for-security), since this is essential when e.g. displaying important financial data in the frontend that may be used by users to decide on future transactions. +* [Use a decentralized governance system like SNS to make a canister have a decentralized controller](https://internetcomputer.org/docs/current/references/security/rust-canister-development-security-best-practices#use-a-decentralized-governance-system-like-sns-to-make-a-canister-have-a-decentralized-controller), since decentralizing control is a fundamental aspect of decentralized finance applications. + diff --git a/rust/defi/dfx.json b/rust/defi/dfx.json index e70f5b24c..b8bae4400 100644 --- a/rust/defi/dfx.json +++ b/rust/defi/dfx.json @@ -6,12 +6,18 @@ "type": "rust", "dependencies": [ "ledger" - ] + ], + "declarations": { + "output": "src/frontend/declarations/defi_dapp" + } }, "ledger": { "type": "custom", "candid": "src/ledger/ledger.did", - "wasm": "src/ledger/ledger.wasm" + "wasm": "src/ledger/ledger.wasm", + "declarations": { + "output": "src/frontend/declarations/ledger" + } }, "internet_identity": { "type": "custom", @@ -25,7 +31,9 @@ }, "frontend": { "dependencies": [ - "defi_dapp" + "defi_dapp", + "AkitaDIP20", + "GoldenDIP20" ], "source": [ "src/frontend_assets" @@ -33,10 +41,16 @@ "type": "assets" }, "AkitaDIP20": { - "main": "src/DIP20/motoko/src/token.mo" + "main": "src/DIP20/motoko/src/token.mo", + "declarations": { + "output": "src/frontend/declarations/AkitaDIP20" + } }, "GoldenDIP20": { - "main": "src/DIP20/motoko/src/token.mo" + "main": "src/DIP20/motoko/src/token.mo", + "declarations": { + "output": "src/frontend/declarations/GoldenDIP20" + } } }, "networks": { @@ -50,4 +64,4 @@ } }, "version": 1 -} \ No newline at end of file +} diff --git a/rust/defi/scripts b/rust/defi/scripts deleted file mode 120000 index 60f64de4a..000000000 --- a/rust/defi/scripts +++ /dev/null @@ -1 +0,0 @@ -../../motoko/defi/scripts \ No newline at end of file diff --git a/rust/defi/scripts/deploy_dip20.sh b/rust/defi/scripts/deploy_dip20.sh new file mode 100644 index 000000000..5159d3123 --- /dev/null +++ b/rust/defi/scripts/deploy_dip20.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Example script on how to deploy your own dip20 token + +```bash +cd src/DIP20/ +#remove old content +dfx stop +rm -rf .dfx +#create canisters +dfx canister --no-wallet create --all +# create principal idea that is inital owner of tokens +ROOT_HOME=$(mktemp -d) +ROOT_PUBLIC_KEY="principal \"$(HOME=$ROOT_HOME dfx identity get-principal)\"" +#build token canister +dfx build +# deploy token +dfx canister --no-wallet install DIP20 --argument="(\"https://dogbreedslist.com/wp-content/uploads/2019/08/Are-Golden-Retrievers-easy-to-train.png\", \"Golden Coin\", \"DOG\", 8, 10000000000000000, $ROOT_PUBLIC_KEY, 10000)" + +# set fee structure. Need Home prefix since this is location of our identity +HOME=$ROOT_HOME dfx canister call DIP20 setFeeTo "($ROOT_PUBLIC_KEY)" +#deflationary +HOME=$ROOT_HOME dfx canister call DIP20 setFee "(420)" +# get balance. Congrats you are rich +HOME=$ROOT_HOME dfx canister --no-wallet call DIP20 balanceOf "($ROOT_PUBLIC_KEY)" +``` diff --git a/rust/defi/scripts/initalize_local_balance.sh b/rust/defi/scripts/initalize_local_balance.sh new file mode 100755 index 000000000..66beab2b5 --- /dev/null +++ b/rust/defi/scripts/initalize_local_balance.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +dfx identity use default +dfx canister call AkitaDIP20 transfer '(principal '\"$1\"',10000000)' +dfx canister call GoldenDIP20 transfer '(principal '\"$1\"',10000000)' +# script to retrieve default subaccount of II in hex format +II_ACCOUNT_ID_HEX=$(python3 ./scripts/principal_to_default_account_id.py $1) +# convert hex account ID to vec format +II_ACCOUNT_ID=$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$II_ACCOUNT_ID_HEX'")]) + "}")') +dfx canister call ledger transfer "(record { amount = record { e8s = 10000000 }; to = $II_ACCOUNT_ID; fee = record { e8s = 10000}; memo = 1;})" \ No newline at end of file diff --git a/rust/defi/scripts/install.sh b/rust/defi/scripts/install.sh new file mode 100755 index 000000000..575a76d1e --- /dev/null +++ b/rust/defi/scripts/install.sh @@ -0,0 +1,72 @@ +set -e +dfx stop && dfx start --background --clean --host 127.0.0.1:8000 + + +### === DEPLOY LOCAL LEDGER ===== +dfx identity new minter --disable-encryption || true +dfx identity use minter +export MINT_ACC=$(dfx ledger account-id) + +dfx identity use default +export LEDGER_ACC=$(dfx ledger account-id) + +# Use private api for install +rm src/ledger/ledger.did || true +cp src/ledger/ledger.private.did src/ledger/ledger.did + +dfx deploy ledger --argument '(record { + minting_account = "'${MINT_ACC}'"; + initial_values = vec { record { "'${LEDGER_ACC}'"; record { e8s=100_000_000_000 } }; }; + send_whitelist = vec {} + })' +export LEDGER_ID=$(dfx canister id ledger) + +# Replace with public api +rm src/ledger/ledger.did +cp src/ledger/ledger.public.did src/ledger/ledger.did + +### === DEPLOY DIP TOKENS ===== + +dfx canister create AkitaDIP20 +dfx canister create GoldenDIP20 +dfx build AkitaDIP20 +dfx build GoldenDIP20 + +export ROOT_PRINCIPAL="principal \"$(dfx identity get-principal)\"" +dfx canister install GoldenDIP20 --argument="(\"https://dogbreedslist.com/wp-content/uploads/2019/08/Are-Golden-Retrievers-easy-to-train.png\", \"Golden Coin\", \"GLD\", 8, 10000000000000000, $ROOT_PRINCIPAL, 10000)" +dfx canister install AkitaDIP20 --argument="(\"https://akitagoose.com/wp-content/uploads/2021/12/IMG_0674.png\", \"Akita Coin\", \"AKI\", 8, 10000000000000000, $ROOT_PRINCIPAL, 10000)" + +# set fees +dfx canister call AkitaDIP20 setFeeTo "($ROOT_PRINCIPAL)" +dfx canister call AkitaDIP20 setFee "(420)" +dfx canister call GoldenDIP20 setFeeTo "($ROOT_PRINCIPAL)" +dfx canister call GoldenDIP20 setFee "(420)" + +### === DEPLOY INTERNET IDENTITY ===== + +II_FETCH_ROOT_KEY=1 dfx deploy internet_identity --no-wallet --argument '(null)' + +## === INSTALL FRONTEND / BACKEND ==== + +dfx deploy defi_dapp --argument "(opt principal \"$LEDGER_ID\")" + +dfx generate defi_dapp +dfx build defi_dapp +dfx build AkitaDIP20 +dfx build GoldenDIP20 +dfx generate defi_dapp +dfx generate AkitaDIP20 +dfx generate GoldenDIP20 +dfx generate ledger + +dfx canister create frontend +pushd src/frontend +npm install +npm run build +popd +dfx build frontend +dfx canister install frontend + +echo "===== VISIT DEFI FRONTEND =====" +echo "http://localhost:8000?canisterId=$(dfx canister id frontend)" +echo "===== VISIT DEFI FRONTEND =====" diff --git a/rust/defi/scripts/principal_to_default_account_id.py b/rust/defi/scripts/principal_to_default_account_id.py new file mode 100644 index 000000000..d62ec18bf --- /dev/null +++ b/rust/defi/scripts/principal_to_default_account_id.py @@ -0,0 +1,34 @@ +import hashlib +import base64 +import math +import binascii +import sys + +if __name__ == '__main__': + if len(sys.argv) != 2: + print("Please provide principalID") + + + principal_id_str = sys.argv[1] + subaccount = bytearray(32) + # principal_id_str = "kb4lg-bqaaa-aaaab-qabfq-cai" + # principal_id_str = "gmk2m-oiaaa-aaaab-qaaja-cai" + principal_id_str = principal_id_str.replace('-', '') + pad_length = math.ceil(len(principal_id_str) / 8) * 8 - len(principal_id_str) + principal_bytes = base64.b32decode(principal_id_str.encode('ascii') + b'=' * pad_length, True, None) + principal_bytes = principal_bytes[4:] # remove CRC32 checksum bytes + ADS = b"\x0Aaccount-id" + h = hashlib.sha224() + h.update(ADS) + h.update(principal_bytes) + h.update(subaccount) + + checksum = binascii.crc32(h.digest()) + checksum_bytes = checksum.to_bytes(4, byteorder='big') + + identifier = checksum_bytes + h.digest() + + + + + print('{}'.format(identifier.hex())) \ No newline at end of file diff --git a/rust/defi/src/frontend/README.md b/rust/defi/src/frontend/README.md deleted file mode 120000 index 2acd1d23b..000000000 --- a/rust/defi/src/frontend/README.md +++ /dev/null @@ -1 +0,0 @@ -../../../../motoko/defi/src/frontend/README.md \ No newline at end of file diff --git a/rust/defi/src/frontend/README.md b/rust/defi/src/frontend/README.md new file mode 100644 index 000000000..510777625 --- /dev/null +++ b/rust/defi/src/frontend/README.md @@ -0,0 +1,3 @@ +# Defi Frontend + +The frontend uses svelte and is based on the dfinity svelte [templates](https://github.com/dfinity/examples/tree/master/svelte-motoko-starter). \ No newline at end of file diff --git a/rust/defi/src/frontend/declarations b/rust/defi/src/frontend/declarations deleted file mode 120000 index 9a66dd68a..000000000 --- a/rust/defi/src/frontend/declarations +++ /dev/null @@ -1 +0,0 @@ -../declarations \ No newline at end of file diff --git a/rust/defi/src/frontend/package-lock.json b/rust/defi/src/frontend/package-lock.json deleted file mode 120000 index f9f072e62..000000000 --- a/rust/defi/src/frontend/package-lock.json +++ /dev/null @@ -1 +0,0 @@ -../../../../motoko/defi/src/frontend/package-lock.json \ No newline at end of file diff --git a/rust/defi/src/frontend/package-lock.json b/rust/defi/src/frontend/package-lock.json new file mode 100644 index 000000000..1a059f694 --- /dev/null +++ b/rust/defi/src/frontend/package-lock.json @@ -0,0 +1,2725 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "svelte-app", + "version": "1.0.0", + "dependencies": { + "@dfinity/agent": "^0.10.4", + "@dfinity/auth-client": "^0.10.4", + "@dfinity/authentication": "^0.10.4", + "@dfinity/candid": "^0.10.4", + "@dfinity/identity": "^0.10.4", + "@dfinity/principal": "0.10.4", + "@fortawesome/fontawesome-svg-core": "^1.2.36", + "@fortawesome/free-solid-svg-icons": "^5.15.4", + "crc": "^4.1.0", + "fontawesome-svelte": "^2.0.1", + "sirv-cli": "^1.0.0" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^3.0.0", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-inject": "^3.0.2", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-polyfill-node": "^0.7.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "svelte": "^3.49.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@dfinity/agent": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.10.4.tgz", + "integrity": "sha512-/O1443GWkQ6GngrXos/ShAbnF9IgUlWclzaQn/qEsGJIey6S7tty+iOa5yZqOS1BtOTnDe+TYh8GeERZZn7vvg==", + "dependencies": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1" + }, + "peerDependencies": { + "@dfinity/candid": "^0.10.4", + "@dfinity/principal": "^0.10.4" + } + }, + "node_modules/@dfinity/auth-client": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.10.4.tgz", + "integrity": "sha512-SHWamx9PcD3vl21rmRCnWr4wk6Iotyd9h0UZOLFdKL0AruZ9m9BD7nxRs9u7dJ+FuRwZRkWjONaDuNZemMlQ8w==", + "peerDependencies": { + "@dfinity/agent": "^0.10.4", + "@dfinity/authentication": "^0.10.4", + "@dfinity/identity": "^0.10.4", + "@dfinity/principal": "^0.10.4" + } + }, + "node_modules/@dfinity/authentication": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/authentication/-/authentication-0.10.4.tgz", + "integrity": "sha512-IP1zepm9YnXATV6lXVMqObmETKuBtkDMbWW6rgUvEekulaxITTHJppgzdMD8E7Hh5SVajVHLJm14kDa3FXwMnA==", + "peerDependencies": { + "@dfinity/agent": "^0.10.4", + "@dfinity/identity": "^0.10.4", + "@dfinity/principal": "^0.10.4" + } + }, + "node_modules/@dfinity/candid": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.10.4.tgz", + "integrity": "sha512-Rd8uoo3jd4FLmGY9aBgTRdBCYVuG/Y7QmpDJB3eQvsU3WHhVZJWLMHcodnMIoy2bzqzCKeTdLkL565K7qx5H3Q==" + }, + "node_modules/@dfinity/identity": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.10.4.tgz", + "integrity": "sha512-b4WsaD70Ts75JlJcf4+E04B140hQN5u/GnCvjhaHqN2++bwWO56Paxtv0UfAc58LMwJZj4iOyZoahnT56LhC9A==", + "dependencies": { + "borc": "^2.1.1", + "js-sha256": "^0.9.0", + "secp256k1": "^4.0.2", + "tweetnacl": "^1.0.1" + }, + "peerDependencies": { + "@dfinity/agent": "^0.10.4", + "@dfinity/principal": "^0.10.4" + } + }, + "node_modules/@dfinity/principal": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.10.4.tgz", + "integrity": "sha512-qwzpmq5wfyeKMBspRZmuYvTxu1dqN+IY0ThACHTRh6D58QjnVQNCD3Hq9d5eEDu0qyNcY22cJEWwzrzZaaoVmw==" + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "0.2.36", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", + "integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "1.2.36", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz", + "integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz", + "integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", + "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", + "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", + "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", + "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", + "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^2.30.0" + } + }, + "node_modules/@rollup/plugin-inject": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz", + "integrity": "sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "estree-walker": "^2.0.1", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.0.8" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-3.1.0.tgz", + "integrity": "sha512-pA3XRUrSKybVYqmH5TqWNZpGxF+VV+1GrYchKgCNIj2vsSOX7CVm2RCtx8p2nrC7xvkziYyK+lSi74T93MU3YA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.38", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz", + "integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "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 + }, + "node_modules/base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "dependencies": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/borc/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/console-clear": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", + "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/crc": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-4.1.1.tgz", + "integrity": "sha512-2U3ZqJ2phJl9ANuP2q5VS53LMpNmYU9vcpmh6nutJmsqUREhtWpTRh9yYxG7sDg3xkwaEEXytSeffTxw4cgwPg==", + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "buffer": ">=6.0.3" + } + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fontawesome-svelte": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fontawesome-svelte/-/fontawesome-svelte-2.0.1.tgz", + "integrity": "sha512-6OSbpfBFiQA4fcrj5CvJBx36iVYfdvQY8xEdcsQNhWk6FjdwoiWkjxOIvSsr6v1KI2fM9xr99z7uRJHLSsxreQ==", + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.26" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/iso-url": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", + "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==", + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha512-L3mEegEWHRekSHjc7+sc8eJhba9Clq1PZ8kMkzf8OxElhXc8O4TS5MwcVlj9aEbm5dr81N90WHC5nAz3UO971w==", + "dependencies": { + "delimit-stream": "0.1.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/livereload": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", + "opts": ">= 1.2.0", + "ws": "^7.4.3" + }, + "bin": { + "livereload": "bin/livereload.js" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/livereload-js": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.0.tgz", + "integrity": "sha512-F/pz9ZZP+R+arY94cECTZco7PXgBXyL+KVWUPZq8AQE9TOu14GV6fYeKOviv02JCvFa4Oi3Rs1hYEpfeajc+ow==", + "dev": true + }, + "node_modules/local-access": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/local-access/-/local-access-1.1.0.tgz", + "integrity": "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opts": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", + "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", + "dev": true + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.75.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.5.tgz", + "integrity": "sha512-JzNlJZDison3o2mOxVmb44Oz7t74EfSd1SQrplQk0wSaXV7uLQXtVdHbxlcT3w+8tZ1TL4r/eLfc7nAbz38BBA==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-css-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz", + "integrity": "sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "4" + }, + "engines": { + "node": ">=10.12.0" + }, + "peerDependencies": { + "rollup": "1 || 2" + } + }, + "node_modules/rollup-plugin-css-only/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/rollup-plugin-inject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", + "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", + "dev": true, + "dependencies": { + "estree-walker": "^0.6.1", + "magic-string": "^0.25.3", + "rollup-pluginutils": "^2.8.1" + } + }, + "node_modules/rollup-plugin-inject/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/rollup-plugin-livereload": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", + "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", + "dev": true, + "dependencies": { + "livereload": "^0.9.1" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/rollup-plugin-polyfill-node": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.7.0.tgz", + "integrity": "sha512-iJLZDfvxcQh3SpC0OiYlZG9ik26aRM29hiC2sARbAPXYunB8rzW8GtVaWuJgiCtX1hNAo/OaYvVXfPp15fMs7g==", + "dev": true, + "dependencies": { + "@rollup/plugin-inject": "^4.0.0" + } + }, + "node_modules/rollup-plugin-svelte": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", + "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", + "dev": true, + "dependencies": { + "require-relative": "^0.8.7", + "rollup-pluginutils": "^2.8.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "rollup": ">=2.0.0", + "svelte": ">=3.5.0" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/simple-cbor": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", + "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" + }, + "node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sirv-cli": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.14.tgz", + "integrity": "sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ==", + "dependencies": { + "console-clear": "^1.1.0", + "get-port": "^3.2.0", + "kleur": "^3.0.0", + "local-access": "^1.0.1", + "sade": "^1.6.0", + "semiver": "^1.0.0", + "sirv": "^1.0.13", + "tinydate": "^1.0.0" + }, + "bin": { + "sirv": "bin.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelte": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.49.0.tgz", + "integrity": "sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/terser": { + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tinydate": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", + "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ws": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", + "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@dfinity/agent": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.10.4.tgz", + "integrity": "sha512-/O1443GWkQ6GngrXos/ShAbnF9IgUlWclzaQn/qEsGJIey6S7tty+iOa5yZqOS1BtOTnDe+TYh8GeERZZn7vvg==", + "requires": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1" + } + }, + "@dfinity/auth-client": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.10.4.tgz", + "integrity": "sha512-SHWamx9PcD3vl21rmRCnWr4wk6Iotyd9h0UZOLFdKL0AruZ9m9BD7nxRs9u7dJ+FuRwZRkWjONaDuNZemMlQ8w==", + "requires": {} + }, + "@dfinity/authentication": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/authentication/-/authentication-0.10.4.tgz", + "integrity": "sha512-IP1zepm9YnXATV6lXVMqObmETKuBtkDMbWW6rgUvEekulaxITTHJppgzdMD8E7Hh5SVajVHLJm14kDa3FXwMnA==", + "requires": {} + }, + "@dfinity/candid": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.10.4.tgz", + "integrity": "sha512-Rd8uoo3jd4FLmGY9aBgTRdBCYVuG/Y7QmpDJB3eQvsU3WHhVZJWLMHcodnMIoy2bzqzCKeTdLkL565K7qx5H3Q==" + }, + "@dfinity/identity": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.10.4.tgz", + "integrity": "sha512-b4WsaD70Ts75JlJcf4+E04B140hQN5u/GnCvjhaHqN2++bwWO56Paxtv0UfAc58LMwJZj4iOyZoahnT56LhC9A==", + "requires": { + "borc": "^2.1.1", + "js-sha256": "^0.9.0", + "secp256k1": "^4.0.2", + "tweetnacl": "^1.0.1" + } + }, + "@dfinity/principal": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.10.4.tgz", + "integrity": "sha512-qwzpmq5wfyeKMBspRZmuYvTxu1dqN+IY0ThACHTRh6D58QjnVQNCD3Hq9d5eEDu0qyNcY22cJEWwzrzZaaoVmw==" + }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.36", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", + "integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.36", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz", + "integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.15.4", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz", + "integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.36" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", + "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", + "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", + "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", + "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" + }, + "@rollup/plugin-commonjs": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", + "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + } + }, + "@rollup/plugin-inject": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz", + "integrity": "sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "estree-walker": "^2.0.1", + "magic-string": "^0.25.7" + } + }, + "@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8" + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/plugin-replace": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-3.1.0.tgz", + "integrity": "sha512-pA3XRUrSKybVYqmH5TqWNZpGxF+VV+1GrYchKgCNIj2vsSOX7CVm2RCtx8p2nrC7xvkziYyK+lSi74T93MU3YA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + } + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/node": { + "version": "17.0.38", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz", + "integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==", + "dev": true + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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 + }, + "base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "requires": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "peer": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "console-clear": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", + "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==" + }, + "crc": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-4.1.1.tgz", + "integrity": "sha512-2U3ZqJ2phJl9ANuP2q5VS53LMpNmYU9vcpmh6nutJmsqUREhtWpTRh9yYxG7sDg3xkwaEEXytSeffTxw4cgwPg==", + "requires": {} + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fontawesome-svelte": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fontawesome-svelte/-/fontawesome-svelte-2.0.1.tgz", + "integrity": "sha512-6OSbpfBFiQA4fcrj5CvJBx36iVYfdvQY8xEdcsQNhWk6FjdwoiWkjxOIvSsr6v1KI2fM9xr99z7uRJHLSsxreQ==", + "requires": {} + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "iso-url": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", + "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==" + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha512-L3mEegEWHRekSHjc7+sc8eJhba9Clq1PZ8kMkzf8OxElhXc8O4TS5MwcVlj9aEbm5dr81N90WHC5nAz3UO971w==", + "requires": { + "delimit-stream": "0.1.0" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "livereload": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", + "dev": true, + "requires": { + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", + "opts": ">= 1.2.0", + "ws": "^7.4.3" + } + }, + "livereload-js": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.0.tgz", + "integrity": "sha512-F/pz9ZZP+R+arY94cECTZco7PXgBXyL+KVWUPZq8AQE9TOu14GV6fYeKOviv02JCvFa4Oi3Rs1hYEpfeajc+ow==", + "dev": true + }, + "local-access": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/local-access/-/local-access-1.1.0.tgz", + "integrity": "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==" + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" + }, + "mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opts": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", + "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.75.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.5.tgz", + "integrity": "sha512-JzNlJZDison3o2mOxVmb44Oz7t74EfSd1SQrplQk0wSaXV7uLQXtVdHbxlcT3w+8tZ1TL4r/eLfc7nAbz38BBA==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-css-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz", + "integrity": "sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "4" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + } + } + }, + "rollup-plugin-inject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", + "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1", + "magic-string": "^0.25.3", + "rollup-pluginutils": "^2.8.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } + } + }, + "rollup-plugin-livereload": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", + "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", + "dev": true, + "requires": { + "livereload": "^0.9.1" + } + }, + "rollup-plugin-polyfill-node": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.7.0.tgz", + "integrity": "sha512-iJLZDfvxcQh3SpC0OiYlZG9ik26aRM29hiC2sARbAPXYunB8rzW8GtVaWuJgiCtX1hNAo/OaYvVXfPp15fMs7g==", + "dev": true, + "requires": { + "@rollup/plugin-inject": "^4.0.0" + } + }, + "rollup-plugin-svelte": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", + "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", + "dev": true, + "requires": { + "require-relative": "^0.8.7", + "rollup-pluginutils": "^2.8.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + } + }, + "rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } + } + }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "requires": { + "mri": "^1.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==" + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "simple-cbor": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", + "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" + }, + "sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + } + }, + "sirv-cli": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-1.0.14.tgz", + "integrity": "sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ==", + "requires": { + "console-clear": "^1.1.0", + "get-port": "^3.2.0", + "kleur": "^3.0.0", + "local-access": "^1.0.1", + "sade": "^1.6.0", + "semiver": "^1.0.0", + "sirv": "^1.0.13", + "tinydate": "^1.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svelte": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.49.0.tgz", + "integrity": "sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==", + "dev": true + }, + "terser": { + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "tinydate": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", + "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==" + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz", + "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==", + "dev": true, + "requires": {} + } + } +} diff --git a/rust/defi/src/frontend/package.json b/rust/defi/src/frontend/package.json deleted file mode 120000 index 95b42d364..000000000 --- a/rust/defi/src/frontend/package.json +++ /dev/null @@ -1 +0,0 @@ -../../../../motoko/defi/src/frontend/package.json \ No newline at end of file diff --git a/rust/defi/src/frontend/package.json b/rust/defi/src/frontend/package.json new file mode 100644 index 000000000..b877b04d8 --- /dev/null +++ b/rust/defi/src/frontend/package.json @@ -0,0 +1,37 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "private": true, + "scripts": { + "build": "rollup --preserveSymlinks -c", + "dev": "rollup --preserveSymlinks -c -w", + "start": "sirv ../frontend_assets --no-clear --port 5555" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^3.0.0", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-inject": "^3.0.2", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-polyfill-node": "^0.7.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "svelte": "^3.49.0" + }, + "dependencies": { + "@dfinity/agent": "^0.10.4", + "@dfinity/auth-client": "^0.10.4", + "@dfinity/authentication": "^0.10.4", + "@dfinity/candid": "^0.10.4", + "@dfinity/identity": "^0.10.4", + "@dfinity/principal": "0.10.4", + "@fortawesome/fontawesome-svg-core": "^1.2.36", + "@fortawesome/free-solid-svg-icons": "^5.15.4", + "crc": "^4.1.0", + "fontawesome-svelte": "^2.0.1", + "sirv-cli": "^1.0.0" + } +} diff --git a/rust/defi/src/frontend/public b/rust/defi/src/frontend/public deleted file mode 120000 index 22feabc1b..000000000 --- a/rust/defi/src/frontend/public +++ /dev/null @@ -1 +0,0 @@ -../../../../motoko/defi/src/frontend/public \ No newline at end of file diff --git a/rust/defi/src/frontend/scripts b/rust/defi/src/frontend/scripts deleted file mode 120000 index fcf735a3e..000000000 --- a/rust/defi/src/frontend/scripts +++ /dev/null @@ -1 +0,0 @@ -../../../../motoko/defi/src/frontend/scripts \ No newline at end of file diff --git a/rust/defi/src/frontend/src b/rust/defi/src/frontend/src deleted file mode 120000 index eccc79112..000000000 --- a/rust/defi/src/frontend/src +++ /dev/null @@ -1 +0,0 @@ -../../../../motoko/defi/src/frontend/src \ No newline at end of file diff --git a/rust/defi/src/frontend/src/App.svelte b/rust/defi/src/frontend/src/App.svelte new file mode 100644 index 000000000..09abe20c5 --- /dev/null +++ b/rust/defi/src/frontend/src/App.svelte @@ -0,0 +1,72 @@ + + +
+
+ + diff --git a/rust/defi/src/frontend/src/components/Auth.svelte b/rust/defi/src/frontend/src/components/Auth.svelte new file mode 100644 index 000000000..11c146902 --- /dev/null +++ b/rust/defi/src/frontend/src/components/Auth.svelte @@ -0,0 +1,70 @@ + + +
+ {#if $auth.loggedIn} +
+ +
+
+ +
+ {:else} + + {/if} +
+ + diff --git a/rust/defi/src/frontend/src/components/BalanceInfo.svelte b/rust/defi/src/frontend/src/components/BalanceInfo.svelte new file mode 100755 index 000000000..4645a971a --- /dev/null +++ b/rust/defi/src/frontend/src/components/BalanceInfo.svelte @@ -0,0 +1,494 @@ + + +
+
+
+
+
+

My Balances

+
+
+ + + + + + + + + {#each $userBalances as balance} + + + + + + + {/each} + +
TokenCanister BalanceDEX Balance
+ {balance.symbol} + + {balance && balance.canisterBalance ? balance.canisterBalance.toLocaleString() : '0'} + +
+ + + + {:else} + + {/if} + {/if} +
+ + +
+ {balance && balance.dexBalance ? balance.dexBalance.toLocaleString() : '0'} +
+
+
+ Deposit Address: + + {#if fetchingAddress} +
+ {:else} + {toHexString(depositAddressBlob)} + copyDepositAddress(toHexString(depositAddressBlob))}> + + {#if didCopyDepositAddress} + Copied! + {/if} + + {/if} +
+
+ {#if iiPrincipal} +
+ II Principal: + + {iiPrincipal} + copyPrincipal(iiPrincipal)}> + + {#if didCopyPrincipal} + Copied! + {/if} + + +
+ {/if} +
+
+ + diff --git a/rust/defi/src/frontend/src/components/CanisterIds.svelte b/rust/defi/src/frontend/src/components/CanisterIds.svelte new file mode 100644 index 000000000..5a72d12b7 --- /dev/null +++ b/rust/defi/src/frontend/src/components/CanisterIds.svelte @@ -0,0 +1,18 @@ +
+

Backend canister ID: {process.env.DEFI_DAPP_CANISTER_ID}

+

Frontend canister ID: {process.env.FRONTEND_CANISTER_ID}

+

+ Internet Identity canister ID: {process.env.INTERNET_IDENTITY_CANISTER_ID} +

+
+ + diff --git a/rust/defi/src/frontend/src/components/Links.svelte b/rust/defi/src/frontend/src/components/Links.svelte new file mode 100644 index 000000000..ed282e074 --- /dev/null +++ b/rust/defi/src/frontend/src/components/Links.svelte @@ -0,0 +1,4 @@ +

+ Visit the Internet Computer SDK to learn + how to build canister smart contracts. +

diff --git a/rust/defi/src/frontend/src/components/Nav.svelte b/rust/defi/src/frontend/src/components/Nav.svelte new file mode 100644 index 000000000..382572cba --- /dev/null +++ b/rust/defi/src/frontend/src/components/Nav.svelte @@ -0,0 +1,177 @@ + + + + + diff --git a/rust/defi/src/frontend/src/components/Orders.svelte b/rust/defi/src/frontend/src/components/Orders.svelte new file mode 100644 index 000000000..a4ffa01c1 --- /dev/null +++ b/rust/defi/src/frontend/src/components/Orders.svelte @@ -0,0 +1,330 @@ + + +
+
+
+
+

Orders

+
+ {#if $auth.loggedIn || $plugWallet.isConnected} +
+ +
+ {/if} +
+
+ + {#if $orders.length || showOrderForm} + + + + + + + + {/if} + + {#if showOrderForm} + + + + + + + + {/if} + {#each $orders as order} + + + + + + + + {/each} + +
From AccountAmountTo AccountAmount
+ + + + +
+ + +
+
+ {#await getTokenSymbol(order.from)} + Loading Symbol... + {:then symbol} + {symbol} + {/await} + {order.fromAmount} + {#await getTokenSymbol(order.to)} + Loading Symbol... + {:then symbol} + {symbol} + {/await} + {order.toAmount} + {#if $auth.loggedIn} + + {#if authClient && order.owner.toText() === authClient.getIdentity().getPrincipal().toText()} + + {/if} + {/if} +
+
+
+
+ + diff --git a/rust/defi/src/frontend/src/main.js b/rust/defi/src/frontend/src/main.js new file mode 100644 index 000000000..83bc6ab06 --- /dev/null +++ b/rust/defi/src/frontend/src/main.js @@ -0,0 +1,7 @@ +import App from "./App.svelte"; + +const app = new App({ + target: document.body, +}); + +export default app; diff --git a/rust/defi/src/frontend/src/store/auth.js b/rust/defi/src/frontend/src/store/auth.js new file mode 100644 index 000000000..f02ebf5d2 --- /dev/null +++ b/rust/defi/src/frontend/src/store/auth.js @@ -0,0 +1,81 @@ +import { writable } from "svelte/store"; +import { idlFactory } from "../../declarations/defi_dapp/defi_dapp.did.js"; +import { Actor, HttpAgent } from "@dfinity/agent"; + +/** + * Creates an actor for the Backend canister + * + * @param {{agentOptions: import("@dfinity/agent").HttpAgentOptions, actorOptions: import("@dfinity/agent").ActorConfig}} options + * @returns {import("@dfinity/agent").ActorSubclass} + */ +export function createActor(options) { + const hostOptions = { + host: + process.env.DFX_NETWORK === "ic" + ? `https://${process.env.DEFI_DAPP_CANISTER_ID}.ic0.app` + : "http://localhost:8000", + }; + if (!options) { + options = { + agentOptions: hostOptions, + }; + } else if (!options.agentOptions) { + options.agentOptions = hostOptions; + } else { + options.agentOptions.host = hostOptions.host; + } + + const agent = new HttpAgent({ ...options.agentOptions }); + + // Fetch root key for certificate validation during development + if (process.env.DFX_NETWORK === "local") { + console.log('fetchRootKey') + agent.fetchRootKey().catch((err) => { + console.warn( + "Unable to fetch root key. Check to ensure that your local replica is running" + ); + console.error(err); + }); + } + + // Creates an actor with using the candid interface and the HttpAgent + return Actor.createActor(idlFactory, { + agent, + canisterId: process.env.DEFI_DAPP_CANISTER_ID, + ...options?.actorOptions, + }); +} + +export const auth = writable({ + loggedIn: false, + principal: '', + actor: createActor(), +}); + + +export const DEX_CANISTER_ID = process.env.DEFI_DAPP_CANISTER_ID; +export const AKITA_CANISTER_ID = process.env.AKITADIP20_CANISTER_ID; +export const GOLDENDIP20_CANISTER_ID = process.env.GOLDENDIP20_CANISTER_ID; +export const LEDGER_CANISTER_ID = process.env.LEDGER_CANISTER_ID; +export const whitelist = [DEX_CANISTER_ID, AKITA_CANISTER_ID, GOLDENDIP20_CANISTER_ID, LEDGER_CANISTER_ID]; + +export const host = process.env.DFX_NETWORK === "ic" +? `https://ic0.app` + : `http://localhost:8000` + +export const plugWallet = writable({ + extensionInstalled: false, + isConnected: false, + whiteList: whitelist, + host: host, + principal: '', + plugActor: null, + plugAkitaActor: null, + plugGoldenActor: null, + plugLedgerActor: null +}); + +export const anonymous = writable({ + actor: createActor() +}); + diff --git a/rust/defi/src/frontend/src/store/order.js b/rust/defi/src/frontend/src/store/order.js new file mode 100644 index 000000000..9b3f494a8 --- /dev/null +++ b/rust/defi/src/frontend/src/store/order.js @@ -0,0 +1,4 @@ +import { writable } from 'svelte/store'; + +export const orders = writable([]); +export const currentOrder = writable({}); \ No newline at end of file diff --git a/rust/defi/src/frontend/src/store/store.js b/rust/defi/src/frontend/src/store/store.js new file mode 100644 index 000000000..17e7d5102 --- /dev/null +++ b/rust/defi/src/frontend/src/store/store.js @@ -0,0 +1,21 @@ +import { Actor } from '@dfinity/agent'; +import { writable } from 'svelte/store'; + +export const canisters = writable( + [ + {symbol: 'AKI', canisterName: 'AkitaDIP20', canisterId: process.env.AKITADIP20_CANISTER_ID}, + {symbol: 'GLD', canisterName: 'GoldenDIP20', canisterId: process.env.GOLDENDIP20_CANISTER_ID}, + {symbol: 'ICP', canisterName: 'ICP', canisterId: process.env.LEDGER_CANISTER_ID} + ] +); + +export const canisterActors = writable([]); + +export const userBalances = writable([]); + +export const createCanisterActor = (agent, idl, canisterId) => { + return Actor.createActor(idl, { + agent, + canisterId + }) +} \ No newline at end of file diff --git a/rust/defi/src/frontend/src/utils/helpers.js b/rust/defi/src/frontend/src/utils/helpers.js new file mode 100644 index 000000000..968217696 --- /dev/null +++ b/rust/defi/src/frontend/src/utils/helpers.js @@ -0,0 +1,134 @@ +import { sha224 } from "js-sha256"; +import { Buffer } from "buffer"; +import crc from "crc"; + + +export const toHexString = (byteArray) => { + return Array.from(byteArray, function(byte) { + return ('0' + (byte & 0xFF).toString(16)).slice(-2); + }).join('').toUpperCase(); +}; + +export const hexToBytes = (hex) => { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; +}; + + +export const uint8ArrayToBigInt = (array) => { + const view = new DataView(array.buffer, array.byteOffset, array.byteLength); + if (typeof view.getBigUint64 === "function") { + return view.getBigUint64(0); + } else { + const high = BigInt(view.getUint32(0)); + const low = BigInt(view.getUint32(4)); + + return (high << BigInt(32)) + low; + } +}; + +const TWO_TO_THE_32 = BigInt(1) << BigInt(32); +export const bigIntToUint8Array = (value) => { + const array = new Uint8Array(8); + const view = new DataView(array.buffer, array.byteOffset, array.byteLength); + if (typeof view.setBigUint64 === "function") { + view.setBigUint64(0, value); + } else { + view.setUint32(0, Number(value >> BigInt(32))); + view.setUint32(4, Number(value % TWO_TO_THE_32)); + } + + return array; +}; + +export const arrayBufferToArrayOfNumber = ( + buffer +)=> { + const typedArray = new Uint8Array(buffer); + return Array.from(typedArray); +}; + +export const arrayOfNumberToUint8Array = ( + numbers +) => { + return new Uint8Array(numbers); +}; + +export const arrayOfNumberToArrayBuffer = ( + numbers +) => { + return arrayOfNumberToUint8Array(numbers).buffer; +}; + +export const arrayBufferToNumber = (buffer) => { + const view = new DataView(buffer); + return view.getUint32(view.byteLength - 4); +}; + +export const numberToArrayBuffer = ( + value, + byteLength +) => { + const buffer = new ArrayBuffer(byteLength); + new DataView(buffer).setUint32(byteLength - 4, value); + return buffer; +}; + +export const asciiStringToByteArray = (text)=> { + return Array.from(text).map((c) => c.charCodeAt(0)); +}; + +export const toSubAccountId = (subAccount) => { + const bytes = arrayOfNumberToArrayBuffer(subAccount); + return arrayBufferToNumber(bytes); +}; + +export const accountIdentifierToBytes = ( + accountIdentifier +) => { + return Uint8Array.from(Buffer.from(accountIdentifier, "hex")).subarray(4); +}; + +export const accountIdentifierFromBytes = ( + accountIdentifier +) => { + return Buffer.from(accountIdentifier).toString("hex"); +}; + +export const principalToAccountDefaultIdentifier = ( + principal, +) => { + // Hash (sha224) the principal, the subAccount and some padding + const padding = asciiStringToByteArray("\x0Aaccount-id"); + + const shaObj = sha224.create(); + shaObj.update([ + ...padding, + ...principal.toUint8Array(), + ...(Array(32).fill(0)), + ]); + const hash = new Uint8Array(shaObj.array()); + + // Prepend the checksum of the hash and convert to a hex string + const checksum = calculateCrc32(hash); + const bytes = new Uint8Array([...checksum, ...hash]); + return toHexString(bytes); +}; + +export const principalToSubAccount = (principal) => { + const bytes = principal.toUint8Array(); + const subAccount = new Uint8Array(32); + subAccount[0] = bytes.length; + subAccount.set(bytes, 1); + return subAccount; +}; + + +// 4 bytes +export const calculateCrc32 = (bytes) => { + const checksumArrayBuf = new ArrayBuffer(4); + const view = new DataView(checksumArrayBuf); + view.setUint32(0, crc.crc32(Buffer.from(bytes)), false); + return Buffer.from(checksumArrayBuf); +}; \ No newline at end of file diff --git a/rust/defi/src/ledger b/rust/defi/src/ledger deleted file mode 120000 index c4234e2f6..000000000 --- a/rust/defi/src/ledger +++ /dev/null @@ -1 +0,0 @@ -../../../motoko/defi/src/ledger \ No newline at end of file diff --git a/rust/defi/src/ledger/ledger.private.did b/rust/defi/src/ledger/ledger.private.did new file mode 100644 index 000000000..5d10a9a56 --- /dev/null +++ b/rust/defi/src/ledger/ledger.private.did @@ -0,0 +1,99 @@ +type ICPTs = record { + e8s : nat64; +}; + +type Duration = record { + secs: nat64; + nanos: nat32; +}; + +// Number of nanoseconds from the UNIX epoch in UTC timezone. +type TimeStamp = record { + timestamp_nanos: nat64; +}; + +type ArchiveOptions = record { + trigger_threshold : nat64; + num_blocks_to_archive : nat64; + node_max_memory_size_bytes: opt nat64; + max_message_size_bytes: opt nat64; + controller_id: principal; +}; + +// Height of a ledger block. +type BlockHeight = nat64; + +// A number associated with a transaction. +// Can be set by the caller in `send` call as a correlation identifier. +type Memo = nat64; + +// Account identifier encoded as a 64-byte ASCII hex string. +type AccountIdentifier = text; + +// Subaccount is an arbitrary 32-byte byte array. +type SubAccount = blob; + +type Transfer = variant { + Burn: record { + from: AccountIdentifier; + amount: ICPTs; + }; + Mint: record { + to: AccountIdentifier; + amount: ICPTs; + }; + Send: record { + from: AccountIdentifier; + to: AccountIdentifier; + amount: ICPTs; + }; +}; + +type Transaction = record { + transfer: Transfer; + memo: Memo; + created_at: BlockHeight; +}; + +// Arguments for the `send_dfx` call. +type SendArgs = record { + memo: Memo; + amount: ICPTs; + fee: ICPTs; + from_subaccount: opt SubAccount; + to: AccountIdentifier; + created_at_time: opt TimeStamp; +}; + +// Arguments for the `notify` call. +type NotifyCanisterArgs = record { + // The of the block to send a notification about. + block_height: BlockHeight; + // Max fee, should be 10000 e8s. + max_fee: ICPTs; + // Subaccount the payment came from. + from_subaccount: opt SubAccount; + // Canister that received the payment. + to_canister: principal; + // Subaccount that received the payment. + to_subaccount: opt SubAccount; +}; + +type AccountBalanceArgs = record { + account: AccountIdentifier; +}; + +type LedgerCanisterInitPayload = record { + minting_account: AccountIdentifier; + initial_values: vec record {AccountIdentifier; ICPTs}; + max_message_size_bytes: opt nat64; + transaction_window: opt Duration; + archive_options: opt ArchiveOptions; + send_whitelist: vec principal; +}; + +service: (LedgerCanisterInitPayload) -> { + send_dfx : (SendArgs) -> (BlockHeight); + notify_dfx: (NotifyCanisterArgs) -> (); + account_balance_dfx : (AccountBalanceArgs) -> (ICPTs) query; +} diff --git a/rust/defi/src/ledger/ledger.public.did b/rust/defi/src/ledger/ledger.public.did new file mode 100644 index 000000000..26adbe583 --- /dev/null +++ b/rust/defi/src/ledger/ledger.public.did @@ -0,0 +1,87 @@ +// This is the official Ledger interface that is guaranteed to be backward compatible. + +// Amount of tokens, measured in 10^-8 of a token. +type Tokens = record { + e8s : nat64; +}; + +// Number of nanoseconds from the UNIX epoch in UTC timezone. +type TimeStamp = record { + timestamp_nanos: nat64; +}; + +// AccountIdentifier is a 32-byte array. +// The first 4 bytes is big-endian encoding of a CRC32 checksum of the last 28 bytes. +type AccountIdentifier = blob; + +// Subaccount is an arbitrary 32-byte byte array. +// Ledger uses subaccounts to compute the source address, which enables one +// principal to control multiple ledger accounts. +type SubAccount = blob; + +// Sequence number of a block produced by the ledger. +type BlockIndex = nat64; + +// An arbitrary number associated with a transaction. +// The caller can set it in a `transfer` call as a correlation identifier. +type Memo = nat64; + +// Arguments for the `transfer` call. +type TransferArgs = record { + // Transaction memo. + // See comments for the `Memo` type. + memo: Memo; + // The amount that the caller wants to transfer to the destination address. + amount: Tokens; + // The amount that the caller pays for the transaction. + // Must be 10000 e8s. + fee: Tokens; + // The subaccount from which the caller wants to transfer funds. + // If null, the ledger uses the default (all zeros) subaccount to compute the source address. + // See comments for the `SubAccount` type. + from_subaccount: opt SubAccount; + // The destination account. + // If the transfer is successful, the balance of this address increases by `amount`. + to: AccountIdentifier; + // The point in time when the caller created this request. + // If null, the ledger uses current IC time as the timestamp. + created_at_time: opt TimeStamp; +}; + +type TransferError = variant { + // The fee that the caller specified in the transfer request was not the one that ledger expects. + // The caller can change the transfer fee to the `expected_fee` and retry the request. + BadFee : record { expected_fee : Tokens; }; + // The account specified by the caller doesn't have enough funds. + InsufficientFunds : record { balance: Tokens; }; + // The request is too old. + // The ledger only accepts requests created within 24 hours window. + // This is a non-recoverable error. + TxTooOld : record { allowed_window_nanos: nat64 }; + // The caller specified `created_at_time` that is too far in future. + // The caller can retry the request later. + TxCreatedInFuture : null; + // The ledger has already executed the request. + // `duplicate_of` field is equal to the index of the block containing the original transaction. + TxDuplicate : record { duplicate_of: BlockIndex; } +}; + +type TransferResult = variant { + Ok : BlockIndex; + Err : TransferError; +}; + +// Arguments for the `account_balance` call. +type AccountBalanceArgs = record { + account: AccountIdentifier; +}; + +service : { + // Transfers tokens from a subaccount of the caller to the destination address. + // The source address is computed from the principal of the caller and the specified subaccount. + // When successful, returns the index of the block containing the transaction. + transfer : (TransferArgs) -> (TransferResult); + + // Returns the amount of Tokens on the specified account. + account_balance : (AccountBalanceArgs) -> (Tokens) query; +} diff --git a/rust/defi/src/ledger/ledger.wasm b/rust/defi/src/ledger/ledger.wasm new file mode 100644 index 000000000..a312c5714 Binary files /dev/null and b/rust/defi/src/ledger/ledger.wasm differ diff --git a/rust/defi/src/ledger/ledger/index.d.ts b/rust/defi/src/ledger/ledger/index.d.ts new file mode 100644 index 000000000..9293a2514 --- /dev/null +++ b/rust/defi/src/ledger/ledger/index.d.ts @@ -0,0 +1,50 @@ +import type { + ActorSubclass, + HttpAgentOptions, + ActorConfig, + Agent, +} from "@dfinity/agent"; +import type { Principal } from "@dfinity/principal"; +import type { IDL } from "@dfinity/candid"; + +import { _SERVICE } from './ledger.did'; + +export declare const idlFactory: IDL.InterfaceFactory; +export declare const canisterId: string; + +export declare interface CreateActorOptions { + /** + * @see {@link Agent} + */ + agent?: Agent; + /** + * @see {@link HttpAgentOptions} + */ + agentOptions?: HttpAgentOptions; + /** + * @see {@link ActorConfig} + */ + actorOptions?: ActorConfig; +} + +/** + * Intializes an {@link ActorSubclass}, configured with the provided SERVICE interface of a canister. + * @constructs {@link ActorSubClass} + * @param {string | Principal} canisterId - ID of the canister the {@link Actor} will talk to + * @param {CreateActorOptions} options - see {@link CreateActorOptions} + * @param {CreateActorOptions["agent"]} options.agent - a pre-configured agent you'd like to use. Supercedes agentOptions + * @param {CreateActorOptions["agentOptions"]} options.agentOptions - options to set up a new agent + * @see {@link HttpAgentOptions} + * @param {CreateActorOptions["actorOptions"]} options.actorOptions - options for the Actor + * @see {@link ActorConfig} + */ +export declare const createActor: ( + canisterId: string | Principal, + options?: CreateActorOptions +) => ActorSubclass<_SERVICE>; + +/** + * Intialized Actor using default settings, ready to talk to a canister using its candid interface + * @constructs {@link ActorSubClass} + */ +export declare const ledger: ActorSubclass<_SERVICE>; diff --git a/rust/defi/src/ledger/ledger/index.js b/rust/defi/src/ledger/ledger/index.js new file mode 100644 index 000000000..82f5a60a4 --- /dev/null +++ b/rust/defi/src/ledger/ledger/index.js @@ -0,0 +1,43 @@ +import { Actor, HttpAgent } from "@dfinity/agent"; + +// Imports and re-exports candid interface +import { idlFactory } from "./ledger.did.js"; +export { idlFactory } from "./ledger.did.js"; + +/* CANISTER_ID is replaced by webpack based on node environment + * Note: canister environment variable will be standardized as + * process.env.CANISTER_ID_ + * beginning in dfx 0.15.0 + */ +export const canisterId = + process.env.CANISTER_ID_LEDGER || + process.env.LEDGER_CANISTER_ID; + +export const createActor = (canisterId, options = {}) => { + const agent = options.agent || new HttpAgent({ ...options.agentOptions }); + + if (options.agent && options.agentOptions) { + console.warn( + "Detected both agent and agentOptions passed to createActor. Ignoring agentOptions and proceeding with the provided agent." + ); + } + + // Fetch root key for certificate validation during development + if (process.env.DFX_NETWORK !== "ic") { + agent.fetchRootKey().catch((err) => { + console.warn( + "Unable to fetch root key. Check to ensure that your local replica is running" + ); + console.error(err); + }); + } + + // Creates an actor with using the candid interface and the HttpAgent + return Actor.createActor(idlFactory, { + agent, + canisterId, + ...options.actorOptions, + }); +}; + +export const ledger = createActor(canisterId); diff --git a/rust/defi/src/ledger/ledger/ledger.did.d.ts b/rust/defi/src/ledger/ledger/ledger.did.d.ts new file mode 100644 index 000000000..5613d2ec0 --- /dev/null +++ b/rust/defi/src/ledger/ledger/ledger.did.d.ts @@ -0,0 +1,31 @@ +import type { Principal } from '@dfinity/principal'; +import type { ActorMethod } from '@dfinity/agent'; + +export interface AccountBalanceArgs { 'account' : AccountIdentifier } +export type AccountIdentifier = Uint8Array | number[]; +export type BlockIndex = bigint; +export type Memo = bigint; +export type SubAccount = Uint8Array | number[]; +export interface TimeStamp { 'timestamp_nanos' : bigint } +export interface Tokens { 'e8s' : bigint } +export interface TransferArgs { + 'to' : AccountIdentifier, + 'fee' : Tokens, + 'memo' : Memo, + 'from_subaccount' : [] | [SubAccount], + 'created_at_time' : [] | [TimeStamp], + 'amount' : Tokens, +} +export type TransferError = { + 'TxTooOld' : { 'allowed_window_nanos' : bigint } + } | + { 'BadFee' : { 'expected_fee' : Tokens } } | + { 'TxDuplicate' : { 'duplicate_of' : BlockIndex } } | + { 'TxCreatedInFuture' : null } | + { 'InsufficientFunds' : { 'balance' : Tokens } }; +export type TransferResult = { 'Ok' : BlockIndex } | + { 'Err' : TransferError }; +export interface _SERVICE { + 'account_balance' : ActorMethod<[AccountBalanceArgs], Tokens>, + 'transfer' : ActorMethod<[TransferArgs], TransferResult>, +} diff --git a/rust/defi/src/ledger/ledger/ledger.did.js b/rust/defi/src/ledger/ledger/ledger.did.js new file mode 100644 index 000000000..0ce32442b --- /dev/null +++ b/rust/defi/src/ledger/ledger/ledger.did.js @@ -0,0 +1,33 @@ +export const idlFactory = ({ IDL }) => { + const AccountIdentifier = IDL.Vec(IDL.Nat8); + const AccountBalanceArgs = IDL.Record({ 'account' : AccountIdentifier }); + const Tokens = IDL.Record({ 'e8s' : IDL.Nat64 }); + const Memo = IDL.Nat64; + const SubAccount = IDL.Vec(IDL.Nat8); + const TimeStamp = IDL.Record({ 'timestamp_nanos' : IDL.Nat64 }); + const TransferArgs = IDL.Record({ + 'to' : AccountIdentifier, + 'fee' : Tokens, + 'memo' : Memo, + 'from_subaccount' : IDL.Opt(SubAccount), + 'created_at_time' : IDL.Opt(TimeStamp), + 'amount' : Tokens, + }); + const BlockIndex = IDL.Nat64; + const TransferError = IDL.Variant({ + 'TxTooOld' : IDL.Record({ 'allowed_window_nanos' : IDL.Nat64 }), + 'BadFee' : IDL.Record({ 'expected_fee' : Tokens }), + 'TxDuplicate' : IDL.Record({ 'duplicate_of' : BlockIndex }), + 'TxCreatedInFuture' : IDL.Null, + 'InsufficientFunds' : IDL.Record({ 'balance' : Tokens }), + }); + const TransferResult = IDL.Variant({ + 'Ok' : BlockIndex, + 'Err' : TransferError, + }); + return IDL.Service({ + 'account_balance' : IDL.Func([AccountBalanceArgs], [Tokens], ['query']), + 'transfer' : IDL.Func([TransferArgs], [TransferResult], []), + }); +}; +export const init = ({ IDL }) => { return []; }; diff --git a/rust/defi/test b/rust/defi/test deleted file mode 120000 index 03c855a0e..000000000 --- a/rust/defi/test +++ /dev/null @@ -1 +0,0 @@ -../../motoko/defi/test \ No newline at end of file diff --git a/rust/defi/test/demo.sh b/rust/defi/test/demo.sh new file mode 100755 index 000000000..4d8c25175 --- /dev/null +++ b/rust/defi/test/demo.sh @@ -0,0 +1,68 @@ +set -x +set -e +trap 'catch' ERR +catch() { + dfx identity use default + echo "FAIL" + exit 1 +} +# create new demo identities +dfx identity new user1 --disable-encryption || true +dfx identity use user1 +export USER1_PRINCIPAL=$(dfx identity get-principal) +export USER1_ACC=$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$(dfx ledger account-id)'")]) + "}")') +dfx identity new user2 --disable-encryption || true +dfx identity use user2 +export USER2_PRINCIPAL=$(dfx identity get-principal) +export USER2_ACC=$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$(dfx ledger account-id)'")]) + "}")') +# transfer dip tokens to user +dfx identity use default +dfx canister call defi_dapp clear +dfx canister call AkitaDIP20 transfer '(principal '\"$USER1_PRINCIPAL\"',10000000)' +dfx canister call AkitaDIP20 transfer '(principal '\"$USER2_PRINCIPAL\"',10000000)' +dfx canister call GoldenDIP20 transfer '(principal '\"$USER1_PRINCIPAL\"',10000000)' +dfx canister call GoldenDIP20 transfer '(principal '\"$USER2_PRINCIPAL\"',10000000)' +# transfer ICP tokens to users +dfx canister call ledger transfer "(record { amount = record { e8s = 100000 }; to = $USER1_ACC; fee = record { e8s = 10000}; memo = 1;})" +dfx canister call ledger transfer "(record { amount = record { e8s = 100000 }; to = $USER2_ACC; fee = record { e8s = 10000}; memo = 1;})" +# get canister IDs +export DEX_PRINCIPLE=$(dfx canister id defi_dapp) +export AKITA_ID=$(dfx canister id AkitaDIP20) +export GOLDEN_ID=$(dfx canister id GoldenDIP20) +export LEDGER_ID=$(dfx canister id ledger) +# setup DIP20 balances on DEX for user1 +dfx identity use user1 +dfx canister call AkitaDIP20 approve '(principal '\"$DEX_PRINCIPLE\"',1000000)' +dfx canister call GoldenDIP20 approve '(principal '\"$DEX_PRINCIPLE\"',1000000)' +dfx canister call defi_dapp deposit '(principal '\"$AKITA_ID\"')' +dfx canister call defi_dapp deposit '(principal '\"$GOLDEN_ID\"')' +# setup ICP balances on DEX for user1 +export ICP_DEPOSIT_ADDR_USER1=$(dfx canister call defi_dapp getDepositAddress | tr -d '\n' | sed 's/,)/)/') +dfx canister call ledger transfer "(record { amount = record { e8s = 50000 }; to = $ICP_DEPOSIT_ADDR_USER1; fee = record { e8s = 10000}; memo = 1;})" +dfx canister call defi_dapp deposit '(principal '\"$LEDGER_ID\"')' +# show balances user1 +dfx canister call defi_dapp getBalances +# setup DIP20 balances on DEX for user2 +dfx identity use user2 +dfx canister call AkitaDIP20 approve '(principal '\"$DEX_PRINCIPLE\"',1000000)' +dfx canister call GoldenDIP20 approve '(principal '\"$DEX_PRINCIPLE\"',1000000)' +dfx canister call defi_dapp deposit '(principal '\"$AKITA_ID\"')' +dfx canister call defi_dapp deposit '(principal '\"$GOLDEN_ID\"')' +# setup ICP balances on DEX for user2 +export ICP_DEPOSIT_ADDR_USER2=$(dfx canister call defi_dapp getDepositAddress | tr -d '\n' | sed 's/,)/)/') +dfx canister call ledger transfer "(record { amount = record { e8s = 50000 }; to = $ICP_DEPOSIT_ADDR_USER2; fee = record { e8s = 10000}; memo = 1;})" +dfx canister call defi_dapp deposit '(principal '\"$LEDGER_ID\"')' +# show balances user2 +dfx canister call defi_dapp getBalances +# user 1 sell 3 ICP for 200 Golden to user2 +dfx identity use user1 +dfx canister call defi_dapp placeOrder '(principal '\"$LEDGER_ID\"', 3, principal '\"$GOLDEN_ID\"', 200)' +dfx identity use user2 +dfx canister call defi_dapp placeOrder '(principal '\"$GOLDEN_ID\"', 200, principal '\"$LEDGER_ID\"', 3)' +dfx canister call defi_dapp getBalances +dfx canister call defi_dapp getBalances | grep 999_800 +dfx identity use user1 +dfx canister call defi_dapp getBalances +dfx canister call defi_dapp getBalances | grep 39_997 +dfx identity use default +echo "PASS" diff --git a/rust/defi/test/trade.sh b/rust/defi/test/trade.sh new file mode 100755 index 000000000..a0381f13f --- /dev/null +++ b/rust/defi/test/trade.sh @@ -0,0 +1,109 @@ +set -x +set -e +trap 'catch' ERR +catch() { + dfx identity use default + echo "FAIL" + exit 1 +} +dfx identity use default +export AkitaDIP20=$(dfx canister id AkitaDIP20) +echo AkitaDIP20 "${AkitaDIP20}" +export GoldenDIP20=$(dfx canister id GoldenDIP20) +echo GoldenDIP20 "${GoldenDIP20}" +dfx canister call defi_dapp clear +dfx identity new user1 --disable-encryption || true +dfx identity new user2 --disable-encryption || true +dfx identity use user1 +dfx identity get-principal +export USER1=$(dfx identity get-principal) +echo USER1 "${USER1}" +dfx canister call defi_dapp getBalance "(principal \"${AkitaDIP20}\")" +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER1}\", principal \"${AkitaDIP20}\", 1: nat)" +dfx identity use user1 +dfx canister call defi_dapp getBalance "(principal \"${AkitaDIP20}\")" +dfx identity use user2 +dfx identity get-principal +export USER2=$(dfx identity get-principal) +echo USER2 "${USER2}" +dfx canister call defi_dapp getBalance "(principal \"${GoldenDIP20}\")" +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER2}\", principal \"${GoldenDIP20}\", 100: nat)" +dfx identity use user2 +dfx canister call defi_dapp getBalance "(principal \"${GoldenDIP20}\")" +dfx identity use user1 +dfx canister call defi_dapp placeOrder "(principal \"${AkitaDIP20}\" : principal, 1: nat, principal \"${GoldenDIP20}\", 2: nat)" +dfx canister call defi_dapp getOrders +dfx identity use user2 +echo "order will partially execute" +dfx canister call defi_dapp placeOrder "(principal \"${GoldenDIP20}\" : principal, 4: nat, principal \"${AkitaDIP20}\", 2: nat)" +dfx canister call defi_dapp getOrders +echo "expect user2 98 GoldenDIP20 1 AkitaDIP20, user1 2 GoldenDIP20" +dfx canister call defi_dapp getAllBalances +dfx identity use user1 +echo "order will fail: not enough balance" +dfx canister call defi_dapp placeOrder "(principal \"${AkitaDIP20}\" : principal, 1: nat, principal \"${GoldenDIP20}\", 2: nat)" +dfx canister call defi_dapp getOrders +dfx canister call defi_dapp getAllBalances +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER1}\", principal \"${AkitaDIP20}\", 1: nat)" +dfx identity use user1 +dfx canister call defi_dapp getAllBalances +dfx canister call defi_dapp placeOrder "(principal \"${AkitaDIP20}\" : principal, 1: nat, principal \"${GoldenDIP20}\", 2: nat)" +dfx canister call defi_dapp getOrders +echo "expect empty vec" +dfx canister call defi_dapp getOrders | egrep "(vec ..)" +dfx canister call defi_dapp getAllBalances +echo "expect user1 4 GoldenDIP20" +dfx canister call defi_dapp getAllBalances | grep -B1 -A2 $GoldenDIP20 | grep -A2 $USER1 | grep "amount = 4" +echo "expect user2 96 GoldenDIP20" +dfx canister call defi_dapp getAllBalances | grep -B1 -A2 $GoldenDIP20 | grep -A2 $USER2 | grep "amount = 96" +echo "expect user2 2 AkitaDIP20" +dfx canister call defi_dapp getAllBalances | grep -B1 -A2 $AkitaDIP20 | grep -A2 $USER2 | grep "amount = 2" +echo "testing imbalanced trades" +dfx identity use default +dfx canister call defi_dapp clear +dfx identity use user1 +dfx identity get-principal +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER1}\", principal \"${AkitaDIP20}\", 9: nat)" +dfx identity use user1 +dfx identity use user2 +dfx identity get-principal +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER2}\", principal \"${GoldenDIP20}\", 2: nat)" +dfx identity use user2 +dfx canister call defi_dapp getAllBalances +dfx canister call defi_dapp placeOrder "(principal \"${GoldenDIP20}\" : principal, 2: nat, principal \"${AkitaDIP20}\", 1: nat)" +dfx canister call defi_dapp getOrders +dfx identity use user1 +dfx canister call defi_dapp placeOrder "(principal \"${AkitaDIP20}\" : principal, 9: nat, principal \"${GoldenDIP20}\", 3: nat)" +dfx canister call defi_dapp getOrders +dfx canister call defi_dapp getAllBalances +echo "Check that it partially executed" +dfx canister call defi_dapp getAllBalances | grep "amount = 5" +echo "testing imbalanced trades with non-natural number trade amounts" +dfx identity use default +dfx canister call defi_dapp clear +dfx identity use user1 +dfx identity get-principal +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER1}\", principal \"${AkitaDIP20}\", 9: nat)" +dfx identity use user1 +dfx identity use user2 +dfx identity get-principal +dfx identity use default +dfx canister call defi_dapp credit "(principal \"${USER2}\", principal \"${GoldenDIP20}\", 2: nat)" +dfx identity use user2 +dfx canister call defi_dapp getAllBalances +dfx canister call defi_dapp placeOrder "(principal \"${GoldenDIP20}\" : principal, 2: nat, principal \"${AkitaDIP20}\", 1: nat)" +dfx canister call defi_dapp getOrders +dfx identity use user1 +dfx canister call defi_dapp placeOrder "(principal \"${AkitaDIP20}\" : principal, 9: nat, principal \"${GoldenDIP20}\", 4: nat)" +dfx canister call defi_dapp getOrders +dfx canister call defi_dapp getAllBalances +echo "Check that it did not execute" +dfx canister call defi_dapp getAllBalances | grep "amount = 9" +dfx identity use default +echo "PASS" diff --git a/rust/defi/test/transfer.sh b/rust/defi/test/transfer.sh new file mode 100755 index 000000000..53b7acd0d --- /dev/null +++ b/rust/defi/test/transfer.sh @@ -0,0 +1,48 @@ +set -x +set -e +trap 'catch' ERR +catch() { + dfx identity use default + echo "FAIL" + exit 1 +} +dfx identity use default +export PRINCIPAL=$(dfx identity get-principal) +dfx canister call defi_dapp clear +# set allowance on DIP20 tokens +export DEX_ID=$(dfx canister id defi_dapp) +dfx canister call AkitaDIP20 approve '(principal '\"$DEX_ID\"',10000000)' +dfx canister call GoldenDIP20 approve '(principal '\"$DEX_ID\"',10000000)' +# get ICP deposit address (removes unnesessary comma at the end) +export ICP_DEPOSIT_ADDR=$(dfx canister call defi_dapp getDepositAddress | tr -d '\n' | sed 's/,)/)/') +# deposit some ICP in DEX +dfx canister call ledger transfer "(record { amount = record { e8s = 1000000 }; to = $ICP_DEPOSIT_ADDR; fee = record { e8s = 10000}; memo = 1;})" +# get token canister IDs +export AKITA_ID=$(dfx canister id AkitaDIP20) +export GOLDEN_ID=$(dfx canister id GoldenDIP20) +export LEDGER_ID=$(dfx canister id ledger) + +# deposit DIP. The amount that was approved + +dfx canister call defi_dapp deposit '(principal '\"$AKITA_ID\"')' +dfx canister call defi_dapp deposit '(principal '\"$GOLDEN_ID\"')' +# transfer ICP to DEX +dfx canister call defi_dapp deposit '(principal '\"$LEDGER_ID\"')' + +# withdraw ICP +dfx canister call defi_dapp withdraw '(principal '\"$LEDGER_ID\"', 100000, principal '\"$PRINCIPAL\"')' + +# withdraw DIP +# user balance +dfx canister call GoldenDIP20 balanceOf '(principal '\"$PRINCIPAL\"')' +#user balance on DEX +dfx canister call defi_dapp getBalance '(principal '\"$GOLDEN_ID\"')' +dfx canister call defi_dapp withdraw '(principal '\"$GOLDEN_ID\"', 100000, principal '\"$PRINCIPAL\"')' +# user balance +dfx canister call GoldenDIP20 balanceOf '(principal '\"$PRINCIPAL\"')' +#user balance on DEX +dfx canister call defi_dapp getBalance '(principal '\"$GOLDEN_ID\"')' +# get balances +dfx canister call defi_dapp getBalances +dfx canister call defi_dapp getBalances | grep "amount = 9_899_580" +echo "PASS"