diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..7b3216310 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + ignorePatterns: ["**/*"] +}; diff --git a/.gitattributes b/.gitattributes index 762fea469..27a039ad1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,10 @@ bin/* filter=lfs diff=lfs merge=lfs -text bin/*/* filter=lfs diff=lfs merge=lfs -text pkg/arvo/**/*.css binary pkg/arvo/app/naive/logs.eth-logs filter=lfs diff=lfs merge=lfs -text +**/package-lock.json binary merge=theirs +pkg/arvo/tmp/garden.jam filter=lfs diff=lfs merge=lfs -text +pkg/arvo/tmp/landscape.jam filter=lfs diff=lfs merge=lfs -text +pkg/arvo/tmp/base.jam filter=lfs diff=lfs merge=lfs -text +pkg/arvo/tmp/bitcoin.jam filter=lfs diff=lfs merge=lfs -text +pkg/arvo/tmp/webterm.jam filter=lfs diff=lfs merge=lfs -text + diff --git a/.github/actions/glob/Dockerfile b/.github/actions/glob/Dockerfile index 28fc45710..e372532ac 100644 --- a/.github/actions/glob/Dockerfile +++ b/.github/actions/glob/Dockerfile @@ -1,4 +1,4 @@ -FROM jaredtobin/janeway:v0.15.2 +FROM tloncorp/janeway:v0.15.4 COPY entrypoint.sh /entrypoint.sh EXPOSE 22/tcp ENTRYPOINT ["/entrypoint.sh"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 166bc72af..afdc9188e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,15 +74,15 @@ jobs: # for the docker build. We don't want in on Mac, where it isn't but # it breaks the nix install. The two `if` clauses should be mutually # exclusive - - uses: cachix/install-nix-action@v12 + - uses: cachix/install-nix-action@v13 with: extra_nix_config: | system-features = nixos-test benchmark big-parallel kvm if: ${{ matrix.os == 'ubuntu-latest' }} - - uses: cachix/install-nix-action@v12 + - uses: cachix/install-nix-action@v13 if: ${{ matrix.os != 'ubuntu-latest' }} - - uses: cachix/cachix-action@v8 + - uses: cachix/cachix-action@v10 with: name: ares authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} @@ -107,8 +107,8 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v12 - - uses: cachix/cachix-action@v8 + - uses: cachix/install-nix-action@v13 + - uses: cachix/cachix-action@v10 with: name: ares authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} @@ -116,3 +116,24 @@ jobs: - run: nix-build -A hs.urbit-king.components.exes.urbit-king --arg enableStatic true - run: nix-build -A hs-checks - run: nix-build shell.nix + + mingw: + runs-on: windows-latest + defaults: + run: + shell: C:\msys64\msys2_shell.cmd -mingw64 -defterm -no-start -here -c ". <(cygpath '{0}')" + working-directory: ./pkg/urbit + + steps: + - uses: actions/checkout@v2 + with: + lfs: true + + # echo suppresses pacman prompt + - run: echo|./configure + env: + CACHIX_CACHE: ares + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - run: make build/urbit build/urbit-worker + - run: build/urbit -l -d -B ../../bin/solid.pill -F bus && curl -f --data '{"source":{"dojo":"+hood/exit"},"sink":{"app":"hood"}}' http://localhost:12321 diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 92a8774e0..1d8711f7f 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - - run: cd 'pkg/interface' && npm i + - run: npm i && npm run bootstrap - name: Publish to Chromatic uses: chromaui/action@v1 with: diff --git a/.github/workflows/frontend-test.yml b/.github/workflows/frontend-test.yml new file mode 100644 index 000000000..89e68662a --- /dev/null +++ b/.github/workflows/frontend-test.yml @@ -0,0 +1,24 @@ +name: frontend-test + +on: + pull_request: + paths: + - 'pkg/interface/**' + - 'pkg/btc-wallet/**' + - 'pkg/npm/**' + +jobs: + frontend-test: + runs-on: ubuntu-latest + name: "Test changed frontend packages" + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - run: git fetch --prune + - name: 'Setup root deps' + run: npm ci + - name: 'Setup dependencies' + run: npm run bootstrap + - name: 'Run tests' + run: npm run test -- --since origin/$GITHUB_BASE_REF --include-dependents diff --git a/.github/workflows/glob.yml b/.github/workflows/glob.yml index ba67d98cb..be5d77115 100644 --- a/.github/workflows/glob.yml +++ b/.github/workflows/glob.yml @@ -6,14 +6,14 @@ on: jobs: glob: runs-on: ubuntu-latest - name: "Create and deploy a glob to ~lomlyx-lopsem-nidsut-tomdun" + name: "Create and deploy a glob to ~hanruc-nalfus-nidsut-tomdun" steps: - uses: actions/checkout@v2 with: lfs: true - uses: ./.github/actions/glob with: - ship: 'lomlyx-lopsem-nidsut-tomdun' + ship: 'hanruc-nalfus-nidsut-tomdun' credentials: ${{ secrets.JANEWAY_SERVICE_KEY }} ssh-sec-key: ${{ secrets.JANEWAY_SSH_SEC_KEY }} ssh-pub-key: ${{ secrets.JANEWAY_SSH_PUB_KEY }} diff --git a/.github/workflows/ops-group-timer.yml b/.github/workflows/ops-group-timer.yml deleted file mode 100644 index f28a615ab..000000000 --- a/.github/workflows/ops-group-timer.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: group-timer -on: - push: - branches: - - 'ops/group-timer' -jobs: - glob: - runs-on: ubuntu-latest - name: "Create and deploy a glob to ~difmex-passed" - steps: - - uses: actions/checkout@v2 - with: - lfs: true - - uses: ./.github/actions/glob - with: - ship: 'difmex-passed' - credentials: ${{ secrets.JANEWAY_SERVICE_KEY }} - ssh-sec-key: ${{ secrets.JANEWAY_SSH_SEC_KEY }} - ssh-pub-key: ${{ secrets.JANEWAY_SSH_PUB_KEY }} - diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index bae515601..8f49b6d03 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -16,11 +16,11 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v12 + - uses: cachix/install-nix-action@v13 with: extra_nix_config: | system-features = nixos-test benchmark big-parallel kvm - - uses: cachix/cachix-action@v8 + - uses: cachix/cachix-action@v10 with: name: ares authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index db22e4b8d..e42e79dc4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,8 +17,8 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: cachix/install-nix-action@v12 - - uses: cachix/cachix-action@v8 + - uses: cachix/install-nix-action@v13 + - uses: cachix/cachix-action@v10 with: name: ${{ secrets.CACHIX_NAME }} authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} @@ -35,7 +35,8 @@ jobs: - name: Run upload to bootstrap.urbit.org run: | version="$(cat ./pkg/urbit/version)" - system="$(nix eval --raw '(builtins.currentSystem)')" + system="$(nix-instantiate --eval --expr 'builtins.currentSystem')" + system=${system:1:${#system}-2} target="gs://bootstrap.urbit.org/ci/urbit-v${version}-${system}-${GITHUB_SHA:0:9}.tgz" gsutil cp -n ./result "$target" diff --git a/.github/workflows/typescript-check.yml b/.github/workflows/typescript-check.yml deleted file mode 100644 index 6ad913bba..000000000 --- a/.github/workflows/typescript-check.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: typescript-check - -on: - pull_request: - paths: - - 'pkg/interface/**' - -jobs: - typescript-check: - runs-on: ubuntu-latest - name: "Check pkg/interface types" - steps: - - uses: actions/checkout@v2 - - run: cd 'pkg/interface' && npm i && npm run tsc diff --git a/.gitignore b/.gitignore index 14e61e6a8..2bfb2cd26 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ result-* # NodeJS node_modules +.eslintcache # Haskell .stack-work @@ -54,7 +55,11 @@ release/ dist/ out/ work/ +pkg/*/*.a *.o +*.so +*.dll +*.dylib # Landscape Dev urbitrc @@ -77,3 +82,5 @@ pkg/interface/link-webext/web-ext-artifacts # Logs *.log + +.vercel diff --git a/.vercelignore b/.vercelignore new file mode 100644 index 000000000..6203dc090 --- /dev/null +++ b/.vercelignore @@ -0,0 +1,16 @@ +bin +doc +extras +nix +pkg/arvo +pkg/base-dev +pkg/docker-image +pkg/ent +pkg/garden +pkg/garden-dev +pkg/ge-additions +pkg/herb +pkg/hs +pkg/libaes_siv +pkg/urbit +sh \ No newline at end of file diff --git a/bin/brass.pill b/bin/brass.pill index f549dac58..799a4e8de 100644 --- a/bin/brass.pill +++ b/bin/brass.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61e583dd7db795dac4a7c31bfd3ee8b240e679bb882e35d4e7d1acb5f9f2f3d6 -size 8270131 +oid sha256:9a56f675d2a6c5dafa92a9e2d55040d994f3d3d27a1ed827bd87d1158b1e69d0 +size 3749183 diff --git a/bin/ivory.pill b/bin/ivory.pill index 9f9071cf9..9d89aa606 100644 --- a/bin/ivory.pill +++ b/bin/ivory.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:063cb7928607fd3e3882e46a369047e3304e1635ee7761e2daa1fe611eb74ca7 -size 7130416 +oid sha256:e6e3c7c0274352d2cfba2a9f2b3382cdeab0e0fb97455b42293a214561d177ee +size 1101949 diff --git a/bin/multi-brass.pill b/bin/multi-brass.pill new file mode 100644 index 000000000..05a99aec6 --- /dev/null +++ b/bin/multi-brass.pill @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:049801d388b4cb7203854b4668826688c21089f90430bd547d276e7b59386e8d +size 5588170 diff --git a/bin/multi.pill b/bin/multi.pill new file mode 100644 index 000000000..9e95dfefb --- /dev/null +++ b/bin/multi.pill @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c27cdb47bccda98ba68556181cae6cd845c6daf8d7426d82adf67c1e8f532be9 +size 7454265 diff --git a/bin/solid.pill b/bin/solid.pill index afdacd3ef..1eeb48d53 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d654c8c49f9836102b1db7dec7e625d5e8100ab7db4baa31b4184751c73c009 -size 15337032 +oid sha256:1f75add9e2b4522ee18a3ef64beb52a3f3b49345e8ac31e4954449c4f4d3b2ef +size 21338783 diff --git a/default.nix b/default.nix index ac85d95ee..2f8dfb52a 100644 --- a/default.nix +++ b/default.nix @@ -1,3 +1,4 @@ + /* Examples Shared urbit and urbit-worker binaries: @@ -85,19 +86,11 @@ let # Local vendored packages defined in ./pkg. # For non-vendored nixpkgs specific package overrides, see ./nix/overlays. pkgsLocal = { - argon2u = callPackage ./nix/pkgs/argon2u { }; - ca-bundle = callPackage ./nix/pkgs/ca-bundle { }; - ed25519 = callPackage ./nix/pkgs/ed25519 { }; - ent = callPackage ./nix/pkgs/ent { }; - ge-additions = callPackage ./nix/pkgs/ge-additions { }; - - libaes_siv = callPackage ./nix/pkgs/libaes_siv { }; - - libscrypt = callPackage ./nix/pkgs/libscrypt { }; + libaes_siv = callPackage ./nix/pkgs/libaes_siv { inherit (pkgsNative) cmake; }; murmur3 = callPackage ./nix/pkgs/murmur3 { }; @@ -113,8 +106,12 @@ let solid = callPackage ./nix/pkgs/pill/solid.nix { }; + marsSources = callPackage ./nix/pkgs/marsSources { }; + urbit = callPackage ./nix/pkgs/urbit { inherit enableStatic; }; + urcrypt = callPackage ./nix/pkgs/urcrypt { inherit enableStatic; }; + docker-image = callPackage ./nix/pkgs/docker-image { }; hs = callPackage ./nix/pkgs/hs { diff --git a/lerna.json b/lerna.json new file mode 100644 index 000000000..abd412c3f --- /dev/null +++ b/lerna.json @@ -0,0 +1,9 @@ +{ + "packages": [ + "pkg/npm/*", + "pkg/btc-wallet", + "pkg/interface", + "pkg/grid" + ], + "version": "independent" +} diff --git a/nix/overlays/native.nix b/nix/overlays/native.nix index f7f60e041..748ee9f55 100644 --- a/nix/overlays/native.nix +++ b/nix/overlays/native.nix @@ -11,6 +11,11 @@ in { outputs = [ "out" "dev" "lib" ]; }); + secp256k1 = prev.secp256k1.overrideAttrs (_attrs: { + version = final.sources.secp256k1.rev; + src = final.sources.secp256k1; + }); + libsigsegv = prev.libsigsegv.overrideAttrs (attrs: { patches = optionalList attrs.patches ++ [ ../pkgs/libsigsegv/disable-stackvma_fault-linux-arm.patch diff --git a/nix/pkgs/argon2u/default.nix b/nix/pkgs/argon2u/default.nix deleted file mode 100644 index 60c7a1089..000000000 --- a/nix/pkgs/argon2u/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ stdenv, sources, enableParallelBuilding ? true }: - -stdenv.mkDerivation { - pname = "argon2u"; - version = sources.argon2u.rev; - src = sources.argon2u; - - postPatch = '' - substituteInPlace Makefile --replace 'ar rcs' '$(AR) rcs' - ''; - - buildPhase = '' - make libargon2.a - ''; - - installPhase = '' - mkdir -p $out/{lib,include} - cp libargon2.a $out/lib/ - cp include/argon2.h $out/include/ - cp ./src/blake2/*.h $out/include/ - ''; - - makeFlags = [ - "AR=${stdenv.cc.targetPrefix}ar" # Fix cross-compilation - ]; - - NO_THREADS = true; - - inherit enableParallelBuilding; -} diff --git a/nix/pkgs/arvo/default.nix b/nix/pkgs/arvo/default.nix index c9204a01f..9d9d10806 100644 --- a/nix/pkgs/arvo/default.nix +++ b/nix/pkgs/arvo/default.nix @@ -1,46 +1,21 @@ -{ lib, stdenvNoCC, bc }: +{ lib, stdenvNoCC, marsSources }: stdenvNoCC.mkDerivation { name = "arvo"; - src = lib.cleanSource ../../../pkg/arvo; - buildInputs = [ bc ]; + src = marsSources; outputs = [ "out" "ropsten" ]; phases = [ "mainnetPhase" "ropstenPhase" ]; mainnetPhase = '' - cp -r $src/ $out - chmod -R u+w $out - ''; + ln -s ${marsSources.out}/arvo $out + ''; ropstenPhase = '' - cp -r $src tmp - chmod -R u+w tmp - - ZUSE=tmp/sys/zuse.hoon - AMES=tmp/sys/vane/ames.hoon - ACME=tmp/app/acme.hoon - - # Replace the mainnet azimuth contract with the ropsten contract - sed --in-place \ - 's/\(\+\+ contracts \)mainnet\-contracts/\1ropsten-contracts/' \ - $ZUSE - - # Increment the %ames protocol version - sed -r --in-place \ - 's_^(=/ protocol\-version=\?\(.*\) %)([0-7])_echo "\1$(echo "(\2+1) % 8" | bc)"_e' \ - $AMES - - # Use the staging API in :acme - sed --in-place \ - 's_https://acme-v02.api.letsencrypt.org/directory_https://acme-staging-v02.api.letsencrypt.org/directory_' \ - $ACME - - cp -r tmp $ropsten - chmod -R u+w $ropsten - ''; + ln -s ${marsSources.ropsten}/arvo $ropsten + ''; preferLocalBuild = true; } diff --git a/nix/pkgs/ed25519/default.nix b/nix/pkgs/ed25519/default.nix deleted file mode 100644 index 7edd85223..000000000 --- a/nix/pkgs/ed25519/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ stdenv, sources }: - -stdenv.mkDerivation { - pname = "ed25519"; - version = sources.ed25519.rev; - src = sources.ed25519; - - buildPhase = '' - CFLAGS="-O3 -Wall -I$src/src" - - for f in $(find src -type f -name '*.c'); do - $CC $CFLAGS -c $f -o "''${f//\//_}.o" - done - ''; - - installPhase = '' - mkdir -p $out/{lib,include} - $AR rcs $out/lib/libed25519.a *.o - cp $src/src/*.h $out/include/ - ''; -} diff --git a/nix/pkgs/ge-additions/default.nix b/nix/pkgs/ge-additions/default.nix deleted file mode 100644 index e317972d6..000000000 --- a/nix/pkgs/ge-additions/default.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ lib, stdenv, ed25519, enableParallelBuilding ? true }: - -stdenv.mkDerivation { - name = "ge-additions"; - src = lib.cleanSource ../../../pkg/ge-additions; - - buildInputs = [ ed25519 ]; - - installFlags = [ "PREFIX=$(out)" ]; - - inherit enableParallelBuilding; -} - diff --git a/nix/pkgs/libaes_siv/cmakefiles_static.patch b/nix/pkgs/libaes_siv/cmakefiles_static.patch new file mode 100644 index 000000000..7b7c71b25 --- /dev/null +++ b/nix/pkgs/libaes_siv/cmakefiles_static.patch @@ -0,0 +1,34 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -5,6 +5,8 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "") + set(CMAKE_BUILD_TYPE Release) + endif("${CMAKE_BUILD_TYPE}" STREQUAL "") + ++option(BUILD_SHARED_LIBS "Build shared libraries" ON) ++ + include(GNUInstallDirs) + + # Warning: don't use the UB sanitizer in production builds. It can introduce timing side-channels +@@ -31,10 +33,12 @@ endif(NOT DISABLE_DOCS) + configure_file(config.h.in config.h) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + ++if(BUILD_SHARED_LIBS) + add_library(aes_siv SHARED aes_siv.c) + target_include_directories(aes_siv PUBLIC ${OPENSSL_INCLUDE_DIR}) + target_link_libraries(aes_siv ${OPENSSL_CRYPTO_LIBRARY}) + set_target_properties(aes_siv PROPERTIES VERSION "1.0.1" SOVERSION 1) ++endif() + + add_library(aes_siv_static STATIC aes_siv.c) + target_include_directories(aes_siv_static PUBLIC ${OPENSSL_INCLUDE_DIR}) +@@ -63,7 +67,9 @@ endif(ENABLE_SANITIZER) + add_executable(bench EXCLUDE_FROM_ALL bench.c) + target_link_libraries(bench aes_siv_static) + ++if(BUILD_SHARED_LIBS) + install(TARGETS aes_siv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++endif() + install(TARGETS aes_siv_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES aes_siv.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + diff --git a/nix/pkgs/libaes_siv/default.nix b/nix/pkgs/libaes_siv/default.nix index 8b298f72f..287083351 100644 --- a/nix/pkgs/libaes_siv/default.nix +++ b/nix/pkgs/libaes_siv/default.nix @@ -1,12 +1,17 @@ -{ lib, stdenv, openssl, enableParallelBuilding ? true }: +{ stdenv, sources, cmake, openssl, enableParallelBuilding ? true }: stdenv.mkDerivation { name = "libaes_siv"; - src = lib.cleanSource ../../../pkg/libaes_siv; + version = sources.libaes_siv.rev; + src = sources.libaes_siv; + patches = [ ./cmakefiles_static.patch ]; + nativeBuildInputs = [ cmake ]; buildInputs = [ openssl ]; - installFlags = [ "PREFIX=$(out)" ]; + cmakeFlags = [ + "-DBUILD_SHARED_LIBS=OFF" + ]; inherit enableParallelBuilding; } diff --git a/nix/pkgs/libscrypt/default.nix b/nix/pkgs/libscrypt/default.nix deleted file mode 100644 index 55ed88f2c..000000000 --- a/nix/pkgs/libscrypt/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ stdenv, sources }: - -stdenv.mkDerivation { - pname = "libscrypt"; - version = sources.libscrypt.rev; - src = sources.libscrypt; - - buildPhase = '' - sources=" \ - crypto_scrypt-check \ - crypto_scrypt-hash \ - crypto_scrypt-hexconvert \ - crypto_scrypt-nosse \ - crypto-mcf \ - crypto-scrypt-saltgen \ - slowequals \ - sha256 \ - b64 \ - " - - CFLAGS="-I$src -Wall -ffast-math -O3 -D_FORTIFY_SOURCE=2 -fstack-protector" - - for s in $sources; do - $CC $CFLAGS -c $src/$s.c -o $s.o - done - - $AR rcs libscrypt.a *.o - ''; - - installPhase = '' - mkdir -p $out/{lib,include} - cp libscrypt.a $out/lib - cp $src/*.h $out/include/ - ''; -} diff --git a/nix/pkgs/marsSources/default.nix b/nix/pkgs/marsSources/default.nix new file mode 100644 index 000000000..80bbf303b --- /dev/null +++ b/nix/pkgs/marsSources/default.nix @@ -0,0 +1,46 @@ +{ lib, stdenvNoCC, bc }: + +stdenvNoCC.mkDerivation { + name = "sources"; + src = lib.cleanSource ../../../pkg; + + buildInputs = [ bc ]; + + outputs = [ "out" "ropsten" ]; + + phases = [ "mainnetPhase" "ropstenPhase" ]; + + mainnetPhase = '' + cp -r $src $out + chmod -R u+w $out + ''; + + ropstenPhase = '' + cp -r $src tmp + chmod -R u+w tmp + + ZUSE=tmp/arvo/sys/zuse.hoon + AMES=tmp/arvo/sys/vane/ames.hoon + ACME=tmp/arvo/app/acme.hoon + + # Replace the mainnet azimuth contract with the ropsten contract + sed --in-place \ + 's/\(\+\+ contracts \)mainnet\-contracts/\1ropsten-contracts/' \ + $ZUSE + + # Increment the %ames protocol version + sed -r --in-place \ + 's_^(=/ protocol\-version=\?\(.*\) %)([0-7])_echo "\1$(echo "(\2+1) % 8" | bc)"_e' \ + $AMES + + # Use the staging API in :acme + sed --in-place \ + 's_https://acme-v02.api.letsencrypt.org/directory_https://acme-staging-v02.api.letsencrypt.org/directory_' \ + $ACME + + cp -r tmp $ropsten + chmod -R u+w $ropsten + ''; + + preferLocalBuild = true; +} diff --git a/nix/pkgs/urbit/default.nix b/nix/pkgs/urbit/default.nix index c92543964..112956438 100644 --- a/nix/pkgs/urbit/default.nix +++ b/nix/pkgs/urbit/default.nix @@ -1,8 +1,12 @@ -{ lib, stdenv, coreutils, pkgconfig, argon2u, cacert, ca-bundle, curlMinimal -, ed25519, ent, ge-additions, gmp, h2o, herb, ivory, libaes_siv, libscrypt -, libsigsegv, libuv, lmdb, murmur3, openssl, secp256k1, softfloat3, zlib -, enableStatic ? stdenv.hostPlatform.isStatic, enableDebug ? false -, doCheck ? true, enableParallelBuilding ? true, dontStrip ? true }: +{ lib, stdenv, coreutils, pkgconfig # build/env +, cacert, ca-bundle, ivory # codegen +, curlMinimal, ent, gmp, h2o, libsigsegv, libuv, lmdb # libs +, murmur3, openssl, softfloat3, urcrypt, zlib # +, enableStatic ? stdenv.hostPlatform.isStatic # opts +, enableDebug ? false +, doCheck ? true +, enableParallelBuilding ? true +, dontStrip ? true }: let @@ -19,30 +23,23 @@ in stdenv.mkDerivation { nativeBuildInputs = [ pkgconfig ]; buildInputs = [ - argon2u cacert ca-bundle curlMinimal - ed25519 ent - ge-additions gmp h2o ivory.header - libaes_siv - libscrypt libsigsegv libuv lmdb murmur3 openssl - secp256k1 softfloat3 + urcrypt zlib ]; - checkInputs = [ herb ]; - # Ensure any `/usr/bin/env bash` shebang is patched. postPatch = '' patchShebangs ./configure @@ -56,9 +53,14 @@ in stdenv.mkDerivation { cp ./build/urbit-worker $out/bin/urbit-worker ''; + dontDisableStatic = enableStatic; + + configureFlags = if enableStatic + then [ "--disable-shared" "--enable-static" ] + else []; + CFLAGS = [ (if enableDebug then "-O0" else "-O3") "-g" ] - ++ lib.optionals (!enableDebug) [ "-Werror" ] - ++ lib.optionals enableStatic [ "-static" ]; + ++ lib.optionals (!enableDebug) [ "-Werror" ]; MEMORY_DEBUG = enableDebug; CPU_DEBUG = enableDebug; diff --git a/nix/pkgs/urcrypt/default.nix b/nix/pkgs/urcrypt/default.nix new file mode 100644 index 000000000..1726447c9 --- /dev/null +++ b/nix/pkgs/urcrypt/default.nix @@ -0,0 +1,21 @@ +{ stdenv, autoreconfHook, pkgconfig +, libaes_siv, openssl, secp256k1 +, enableStatic ? stdenv.hostPlatform.isStatic }: + +stdenv.mkDerivation rec { + name = "urcrypt"; + src = ../../../pkg/urcrypt; + + # XX why are these required for darwin? + dontDisableStatic = enableStatic; + + configureFlags = if enableStatic + then [ "--disable-shared" "--enable-static" ] + else []; + + nativeBuildInputs = + [ autoreconfHook pkgconfig ]; + + propagatedBuildInputs = + [ openssl secp256k1 libaes_siv ]; +} diff --git a/nix/sources-pmnsh.json b/nix/sources-pmnsh.json new file mode 100644 index 000000000..9d6c2a1b1 --- /dev/null +++ b/nix/sources-pmnsh.json @@ -0,0 +1,65 @@ +{ + "curl": { + "branch": "master", + "description": "A command line tool and library for transferring data with URL syntax", + "homepage": "http://curl.se/", + "pmnsh": { + "include": "include", + "lib": "lib/.libs", + "prepare": "autoreconf -vfi && ./configure --disable-shared --disable-ldap --disable-rtsp --without-brotli --without-libidn2 --without-libpsl --without-nghttp2 --with-openssl", + "make": "-C lib libcurl.la" + }, + "owner": "curl", + "repo": "curl", + "rev": "curl-7_77_0", + "type": "tarball", + "url": "https://github.com/curl/curl/archive/curl-7_77_0.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "lmdb": { + "branch": "mdb.master", + "description": "LMDB library", + "homepage": "http://www.lmdb.tech/", + "pmnsh": { + "strip": 2, + "make": "liblmdb.a" + }, + "owner": "LMDB", + "repo": "lmdb", + "rev": "48a7fed59a8aae623deff415dda27097198ca0c1", + "type": "tarball", + "url": "https://github.com/LMDB/lmdb/archive/48a7fed59a8aae623deff415dda27097198ca0c1.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "uv": { + "branch": "v1.x", + "description": "Cross-platform asynchronous I/O", + "homepage": "http://libuv.org/", + "pmnsh": { + "include": "include", + "lib": ".libs", + "prepare": "./autogen.sh && ./configure --disable-shared", + "make": "libuv.la", + "compat": { + "m1brew": false + } + }, + "owner": "libuv", + "repo": "libuv", + "rev": "v1.40.0", + "type": "tarball", + "url": "https://github.com/libuv/libuv/archive/v1.40.0.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "ent": { + "pmnsh": { + "prepare": "./configure" + } + }, + "urcrypt": { + "pmnsh": { + "prepare": "./autogen.sh && ./configure --disable-shared PKG_CONFIG_PATH=../secp256k1 CFLAGS=\"-I../secp256k1/include -I../libaes_siv\" LDFLAGS=-L../libaes_siv", + "make": "install" + } + } +} diff --git a/nix/sources.json b/nix/sources.json index abe295cd0..eb4c88331 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -1,38 +1,24 @@ { - "argon2u": { - "branch": "master", - "description": "With argon2u. Based off https://github.com/P-H-C/phc-winner-argon2", - "homepage": "", - "owner": "urbit", - "repo": "argon2", - "rev": "4da94a611ee62bad87ab2b131ffda3bcc0723d9c", - "sha256": "0bqq1hg367l4jkb6cqhxlblpvdbwz3l586qsfakwzfd9wdvnm3yc", - "type": "tarball", - "url": "https://github.com/urbit/argon2/archive/4da94a611ee62bad87ab2b131ffda3bcc0723d9c.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - }, - "ed25519": { - "branch": "master", - "description": "Submodule included by Urbit", - "homepage": null, - "owner": "urbit", - "repo": "ed25519", - "rev": "76385f2ebbbc9580a9c236952d68d11d73a6135c", - "sha256": "0s1spif4s9lgcwcny3fl2fvpbw6acqn3s8r6qxnrmkd9icgyw4cp", - "type": "tarball", - "url": "https://github.com/urbit/ed25519/archive/76385f2ebbbc9580a9c236952d68d11d73a6135c.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - }, "h2o": { "branch": "master", "description": "H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server", "homepage": "https://h2o.examp1e.net", + "pmnsh": { + "include": "include", + "prepare": "cmake .", + "make": "libh2o", + "compat": { + "mingw": { + "prepare": "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=. ." + } + } + }, "owner": "h2o", "repo": "h2o", - "rev": "v2.2.4", - "sha256": "0176x0bzjry19zs074a9i5vhncc842xikmx43wj61jky318nq4w4", + "rev": "v2.2.6", + "sha256": "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7", "type": "tarball", - "url": "https://github.com/h2o/h2o/archive/v2.2.4.tar.gz", + "url": "https://github.com/h2o/h2o/archive/v2.2.6.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "hackage.nix": { @@ -59,22 +45,37 @@ "url": "https://github.com/input-output-hk/haskell.nix/archive/bbb34dcdf7b90d478002f91713531f418ddf1b53.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, - "libscrypt": { + "libaes_siv": { "branch": "master", "description": null, "homepage": null, - "owner": "urbit", - "repo": "libscrypt", - "rev": "029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2", - "sha256": "17pcxypzjmmrvacw45cacvibm6mlr9ip30hy30l1appsnywx679n", + "pmnsh": { + "compat": { + "m1brew": { + "prepare": "cmake .", + "make": "install CFLAGS=$(pkg-config --cflags openssl)" + }, + "mingw": { + "prepare": "cmake -G\"MSYS Makefiles\" -DDISABLE_DOCS:BOOL=ON .", + "make": "aes_siv_static" + } + } + }, + "owner":"dfoxfranke", + "repo": "libaes_siv", + "rev": "9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b", + "sha256": "1g4wy0m5wpqx7z6nillppkh5zki9fkx9rdw149qcxh7mc5vlszzi", "type": "tarball", - "url": "https://github.com/urbit/libscrypt/archive/029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2.tar.gz", + "url": "https://github.com/dfoxfranke/libaes_siv/archive/9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "murmur3": { "branch": "master", "description": null, "homepage": null, + "pmnsh": { + "make": "static" + }, "owner": "urbit", "repo": "murmur3", "rev": "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca", @@ -111,6 +112,19 @@ "branch": "master", "description": null, "homepage": null, + "pmnsh": { + "include": "source/include", + "compat": { + "m1brew": { + "lib": "build/template-FAST_INT64", + "make": "-C build/template-FAST_INT64 libsoftfloat3.a" + }, + "mingw": { + "lib": "build/Win64-MinGW-w64", + "make": "-C build/Win64-MinGW-w64 libsoftfloat3.a" + } + } + }, "owner": "urbit", "repo": "berkeley-softfloat-3", "rev": "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986", @@ -119,6 +133,24 @@ "url": "https://github.com/urbit/berkeley-softfloat-3/archive/ec4c7e31b32e07aad80e52f65ff46ac6d6aad986.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, + "secp256k1": { + "branch": "master", + "description": "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1.", + "homepage": null, + "pmnsh": { + "include": "include", + "lib": ".libs", + "prepare": "./autogen.sh && ./configure --disable-shared --enable-module-recovery CFLAGS=-DSECP256K1_API=", + "make": "libsecp256k1.la" + }, + "owner": "bitcoin-core", + "repo": "secp256k1", + "rev": "26de4dfeb1f1436dae1fcf17f57bdaa43540f940", + "sha256": "03i3nv8d3ci7q9y98q11rrp3rvwdqc0hc0ss0pr6xckybvizsmbb", + "type": "tarball", + "url": "https://github.com/bitcoin-core/secp256k1/archive/26de4dfeb1f1436dae1fcf17f57bdaa43540f940.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, "stackage.nix": { "branch": "master", "description": "Automatically generated Nix expressions of Stackage snapshots", diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..c092b5c7e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,15713 @@ +{ + "name": "root", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "root", + "devDependencies": { + "eslint": "^7.29.0", + "husky": "^6.0.0", + "lerna": "^4.0.0", + "lint-staged": "^11.1.2", + "prettier": "^2.3.2" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@lerna/add": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-4.0.0.tgz", + "integrity": "sha512-cpmAH1iS3k8JBxNvnMqrGTTjbY/ZAiKa1ChJzFevMYY3eeqbvhsBKnBcxjRXtdrJ6bd3dCQM+ZtK+0i682Fhng==", + "dev": true, + "dependencies": { + "@lerna/bootstrap": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/npm-conf": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "npm-package-arg": "^8.1.0", + "p-map": "^4.0.0", + "pacote": "^11.2.6", + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/bootstrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-4.0.0.tgz", + "integrity": "sha512-RkS7UbeM2vu+kJnHzxNRCLvoOP9yGNgkzRdy4UV2hNalD7EP41bLvRVOwRYQ7fhc2QcbhnKNdOBihYRL0LcKtw==", + "dev": true, + "dependencies": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/has-npm-version": "4.0.0", + "@lerna/npm-install": "4.0.0", + "@lerna/package-graph": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/rimraf-dir": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/symlink-binary": "4.0.0", + "@lerna/symlink-dependencies": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "get-port": "^5.1.1", + "multimatch": "^5.0.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "p-map-series": "^2.1.0", + "p-waterfall": "^2.1.1", + "read-package-tree": "^5.3.1", + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/changed": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-4.0.0.tgz", + "integrity": "sha512-cD+KuPRp6qiPOD+BO6S6SN5cARspIaWSOqGBpGnYzLb4uWT8Vk4JzKyYtc8ym1DIwyoFXHosXt8+GDAgR8QrgQ==", + "dev": true, + "dependencies": { + "@lerna/collect-updates": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/listable": "4.0.0", + "@lerna/output": "4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/check-working-tree": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-4.0.0.tgz", + "integrity": "sha512-/++bxM43jYJCshBiKP5cRlCTwSJdRSxVmcDAXM+1oUewlZJVSVlnks5eO0uLxokVFvLhHlC5kHMc7gbVFPHv6Q==", + "dev": true, + "dependencies": { + "@lerna/collect-uncommitted": "4.0.0", + "@lerna/describe-ref": "4.0.0", + "@lerna/validation-error": "4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/child-process": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-4.0.0.tgz", + "integrity": "sha512-XtCnmCT9eyVsUUHx6y/CTBYdV9g2Cr/VxyseTWBgfIur92/YKClfEtJTbOh94jRT62hlKLqSvux/UhxXVh613Q==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "execa": "^5.0.0", + "strong-log-transformer": "^2.1.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/clean": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-4.0.0.tgz", + "integrity": "sha512-uugG2iN9k45ITx2jtd8nEOoAtca8hNlDCUM0N3lFgU/b1mEQYAPRkqr1qs4FLRl/Y50ZJ41wUz1eazS+d/0osA==", + "dev": true, + "dependencies": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/rimraf-dir": "4.0.0", + "p-map": "^4.0.0", + "p-map-series": "^2.1.0", + "p-waterfall": "^2.1.1" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/cli": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-4.0.0.tgz", + "integrity": "sha512-Neaw3GzFrwZiRZv2g7g6NwFjs3er1vhraIniEs0jjVLPMNC4eata0na3GfE5yibkM/9d3gZdmihhZdZ3EBdvYA==", + "dev": true, + "dependencies": { + "@lerna/global-options": "4.0.0", + "dedent": "^0.7.0", + "npmlog": "^4.1.2", + "yargs": "^16.2.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/collect-uncommitted": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-4.0.0.tgz", + "integrity": "sha512-ufSTfHZzbx69YNj7KXQ3o66V4RC76ffOjwLX0q/ab//61bObJ41n03SiQEhSlmpP+gmFbTJ3/7pTe04AHX9m/g==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "chalk": "^4.1.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/collect-updates": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-4.0.0.tgz", + "integrity": "sha512-bnNGpaj4zuxsEkyaCZLka9s7nMs58uZoxrRIPJ+nrmrZYp1V5rrd+7/NYTuunOhY2ug1sTBvTAxj3NZQ+JKnOw==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/describe-ref": "4.0.0", + "minimatch": "^3.0.4", + "npmlog": "^4.1.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/command": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-4.0.0.tgz", + "integrity": "sha512-LM9g3rt5FsPNFqIHUeRwWXLNHJ5NKzOwmVKZ8anSp4e1SPrv2HNc1V02/9QyDDZK/w+5POXH5lxZUI1CHaOK/A==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/package-graph": "4.0.0", + "@lerna/project": "4.0.0", + "@lerna/validation-error": "4.0.0", + "@lerna/write-log-file": "4.0.0", + "clone-deep": "^4.0.1", + "dedent": "^0.7.0", + "execa": "^5.0.0", + "is-ci": "^2.0.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/conventional-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-4.0.0.tgz", + "integrity": "sha512-CSUQRjJHFrH8eBn7+wegZLV3OrNc0Y1FehYfYGhjLE2SIfpCL4bmfu/ViYuHh9YjwHaA+4SX6d3hR+xkeseKmw==", + "dev": true, + "dependencies": { + "@lerna/validation-error": "4.0.0", + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-core": "^4.2.2", + "conventional-recommended-bump": "^6.1.0", + "fs-extra": "^9.1.0", + "get-stream": "^6.0.0", + "lodash.template": "^4.5.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "pify": "^5.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/conventional-commits/node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-4.0.0.tgz", + "integrity": "sha512-mVOB1niKByEUfxlbKTM1UNECWAjwUdiioIbRQZEeEabtjCL69r9rscIsjlGyhGWCfsdAG5wfq4t47nlDXdLLag==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/npm-conf": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "fs-extra": "^9.1.0", + "globby": "^11.0.2", + "init-package-json": "^2.0.2", + "npm-package-arg": "^8.1.0", + "p-reduce": "^2.1.0", + "pacote": "^11.2.6", + "pify": "^5.0.0", + "semver": "^7.3.4", + "slash": "^3.0.0", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^3.0.0", + "whatwg-url": "^8.4.0", + "yargs-parser": "20.2.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/create-symlink": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-4.0.0.tgz", + "integrity": "sha512-I0phtKJJdafUiDwm7BBlEUOtogmu8+taxq6PtIrxZbllV9hWg59qkpuIsiFp+no7nfRVuaasNYHwNUhDAVQBig==", + "dev": true, + "dependencies": { + "cmd-shim": "^4.1.0", + "fs-extra": "^9.1.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/create/node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/describe-ref": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-4.0.0.tgz", + "integrity": "sha512-eTU5+xC4C5Gcgz+Ey4Qiw9nV2B4JJbMulsYJMW8QjGcGh8zudib7Sduj6urgZXUYNyhYpRs+teci9M2J8u+UvQ==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-4.0.0.tgz", + "integrity": "sha512-jYPKprQVg41+MUMxx6cwtqsNm0Yxx9GDEwdiPLwcUTFx+/qKCEwifKNJ1oGIPBxyEHX2PFCOjkK39lHoj2qiag==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/validation-error": "4.0.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/exec": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-4.0.0.tgz", + "integrity": "sha512-VGXtL/b/JfY84NB98VWZpIExfhLOzy0ozm/0XaS4a2SmkAJc5CeUfrhvHxxkxiTBLkU+iVQUyYEoAT0ulQ8PCw==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/profiler": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/validation-error": "4.0.0", + "p-map": "^4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/filter-options": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-4.0.0.tgz", + "integrity": "sha512-vV2ANOeZhOqM0rzXnYcFFCJ/kBWy/3OA58irXih9AMTAlQLymWAK0akWybl++sUJ4HB9Hx12TOqaXbYS2NM5uw==", + "dev": true, + "dependencies": { + "@lerna/collect-updates": "4.0.0", + "@lerna/filter-packages": "4.0.0", + "dedent": "^0.7.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/filter-packages": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-4.0.0.tgz", + "integrity": "sha512-+4AJIkK7iIiOaqCiVTYJxh/I9qikk4XjNQLhE3kixaqgMuHl1NQ99qXRR0OZqAWB9mh8Z1HA9bM5K1HZLBTOqA==", + "dev": true, + "dependencies": { + "@lerna/validation-error": "4.0.0", + "multimatch": "^5.0.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/get-npm-exec-opts": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-4.0.0.tgz", + "integrity": "sha512-yvmkerU31CTWS2c7DvmAWmZVeclPBqI7gPVr5VATUKNWJ/zmVcU4PqbYoLu92I9Qc4gY1TuUplMNdNuZTSL7IQ==", + "dev": true, + "dependencies": { + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/get-packed": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-4.0.0.tgz", + "integrity": "sha512-rfWONRsEIGyPJTxFzC8ECb3ZbsDXJbfqWYyeeQQDrJRPnEJErlltRLPLgC2QWbxFgFPsoDLeQmFHJnf0iDfd8w==", + "dev": true, + "dependencies": { + "fs-extra": "^9.1.0", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/get-packed/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/get-packed/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@lerna/get-packed/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/get-packed/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@lerna/get-packed/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/get-packed/node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/github-client": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-4.0.0.tgz", + "integrity": "sha512-2jhsldZtTKXYUBnOm23Lb0Fx8G4qfSXF9y7UpyUgWUj+YZYd+cFxSuorwQIgk5P4XXrtVhsUesIsli+BYSThiw==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@octokit/plugin-enterprise-rest": "^6.0.1", + "@octokit/rest": "^18.1.0", + "git-url-parse": "^11.4.4", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/gitlab-client": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-4.0.0.tgz", + "integrity": "sha512-OMUpGSkeDWFf7BxGHlkbb35T7YHqVFCwBPSIR6wRsszY8PAzCYahtH3IaJzEJyUg6vmZsNl0FSr3pdA2skhxqA==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1", + "npmlog": "^4.1.2", + "whatwg-url": "^8.4.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/global-options": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-4.0.0.tgz", + "integrity": "sha512-TRMR8afAHxuYBHK7F++Ogop2a82xQjoGna1dvPOY6ltj/pEx59pdgcJfYcynYqMkFIk8bhLJJN9/ndIfX29FTQ==", + "dev": true, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/has-npm-version": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-4.0.0.tgz", + "integrity": "sha512-LQ3U6XFH8ZmLCsvsgq1zNDqka0Xzjq5ibVN+igAI5ccRWNaUsE/OcmsyMr50xAtNQMYMzmpw5GVLAivT2/YzCg==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-4.0.0.tgz", + "integrity": "sha512-FaIhd+4aiBousKNqC7TX1Uhe97eNKf5/SC7c5WZANVWtC7aBWdmswwDt3usrzCNpj6/Wwr9EtEbYROzxKH8ffg==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "fs-extra": "^9.1.0", + "p-map-series": "^2.1.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/info/-/info-4.0.0.tgz", + "integrity": "sha512-8Uboa12kaCSZEn4XRfPz5KU9XXoexSPS4oeYGj76s2UQb1O1GdnEyfjyNWoUl1KlJ2i/8nxUskpXIftoFYH0/Q==", + "dev": true, + "dependencies": { + "@lerna/command": "4.0.0", + "@lerna/output": "4.0.0", + "envinfo": "^7.7.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/init": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-4.0.0.tgz", + "integrity": "sha512-wY6kygop0BCXupzWj5eLvTUqdR7vIAm0OgyV9WHpMYQGfs1V22jhztt8mtjCloD/O0nEe4tJhdG62XU5aYmPNQ==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "fs-extra": "^9.1.0", + "p-map": "^4.0.0", + "write-json-file": "^4.3.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-4.0.0.tgz", + "integrity": "sha512-KlvPi7XTAcVOByfaLlOeYOfkkDcd+bejpHMCd1KcArcFTwijOwXOVi24DYomIeHvy6HsX/IUquJ4PPUJIeB4+w==", + "dev": true, + "dependencies": { + "@lerna/command": "4.0.0", + "@lerna/package-graph": "4.0.0", + "@lerna/symlink-dependencies": "4.0.0", + "p-map": "^4.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/list": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-4.0.0.tgz", + "integrity": "sha512-L2B5m3P+U4Bif5PultR4TI+KtW+SArwq1i75QZ78mRYxPc0U/piau1DbLOmwrdqr99wzM49t0Dlvl6twd7GHFg==", + "dev": true, + "dependencies": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/listable": "4.0.0", + "@lerna/output": "4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/listable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-4.0.0.tgz", + "integrity": "sha512-/rPOSDKsOHs5/PBLINZOkRIX1joOXUXEtyUs5DHLM8q6/RP668x/1lFhw6Dx7/U+L0+tbkpGtZ1Yt0LewCLgeQ==", + "dev": true, + "dependencies": { + "@lerna/query-graph": "4.0.0", + "chalk": "^4.1.0", + "columnify": "^1.5.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/log-packed": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-4.0.0.tgz", + "integrity": "sha512-+dpCiWbdzgMAtpajLToy9PO713IHoE6GV/aizXycAyA07QlqnkpaBNZ8DW84gHdM1j79TWockGJo9PybVhrrZQ==", + "dev": true, + "dependencies": { + "byte-size": "^7.0.0", + "columnify": "^1.5.4", + "has-unicode": "^2.0.1", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/npm-conf": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-4.0.0.tgz", + "integrity": "sha512-uS7H02yQNq3oejgjxAxqq/jhwGEE0W0ntr8vM3EfpCW1F/wZruwQw+7bleJQ9vUBjmdXST//tk8mXzr5+JXCfw==", + "dev": true, + "dependencies": { + "config-chain": "^1.1.12", + "pify": "^5.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/npm-conf/node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/npm-dist-tag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-4.0.0.tgz", + "integrity": "sha512-F20sg28FMYTgXqEQihgoqSfwmq+Id3zT23CnOwD+XQMPSy9IzyLf1fFVH319vXIw6NF6Pgs4JZN2Qty6/CQXGw==", + "dev": true, + "dependencies": { + "@lerna/otplease": "4.0.0", + "npm-package-arg": "^8.1.0", + "npm-registry-fetch": "^9.0.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/npm-dist-tag/node_modules/make-fetch-happen": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/npm-dist-tag/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/npm-dist-tag/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@lerna/npm-dist-tag/node_modules/npm-registry-fetch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz", + "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==", + "dev": true, + "dependencies": { + "@npmcli/ci-detect": "^1.0.0", + "lru-cache": "^6.0.0", + "make-fetch-happen": "^8.0.9", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/npm-install": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-4.0.0.tgz", + "integrity": "sha512-aKNxq2j3bCH3eXl3Fmu4D54s/YLL9WSwV8W7X2O25r98wzrO38AUN6AB9EtmAx+LV/SP15et7Yueg9vSaanRWg==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/get-npm-exec-opts": "4.0.0", + "fs-extra": "^9.1.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "signal-exit": "^3.0.3", + "write-pkg": "^4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/npm-publish": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-4.0.0.tgz", + "integrity": "sha512-vQb7yAPRo5G5r77DRjHITc9piR9gvEKWrmfCH7wkfBnGWEqu7n8/4bFQ7lhnkujvc8RXOsYpvbMQkNfkYibD/w==", + "dev": true, + "dependencies": { + "@lerna/otplease": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "fs-extra": "^9.1.0", + "libnpmpublish": "^4.0.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "pify": "^5.0.0", + "read-package-json": "^3.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/npm-publish/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/npm-publish/node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/npm-publish/node_modules/read-package-json": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-3.0.1.tgz", + "integrity": "sha512-aLcPqxovhJTVJcsnROuuzQvv6oziQx4zd3JvG0vGCL5MjTONUc4uJ90zCBC6R7W7oUKBNoR/F8pkyfVwlbxqng==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^3.0.0", + "npm-normalize-package-bin": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/npm-run-script": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-4.0.0.tgz", + "integrity": "sha512-Jmyh9/IwXJjOXqKfIgtxi0bxi1pUeKe5bD3S81tkcy+kyng/GNj9WSqD5ZggoNP2NP//s4CLDAtUYLdP7CU9rA==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "@lerna/get-npm-exec-opts": "4.0.0", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/otplease": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/otplease/-/otplease-4.0.0.tgz", + "integrity": "sha512-Sgzbqdk1GH4psNiT6hk+BhjOfIr/5KhGBk86CEfHNJTk9BK4aZYyJD4lpDbDdMjIV4g03G7pYoqHzH765T4fxw==", + "dev": true, + "dependencies": { + "@lerna/prompt": "4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/output": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/output/-/output-4.0.0.tgz", + "integrity": "sha512-Un1sHtO1AD7buDQrpnaYTi2EG6sLF+KOPEAMxeUYG5qG3khTs2Zgzq5WE3dt2N/bKh7naESt20JjIW6tBELP0w==", + "dev": true, + "dependencies": { + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/pack-directory": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-4.0.0.tgz", + "integrity": "sha512-NJrmZNmBHS+5aM+T8N6FVbaKFScVqKlQFJNY2k7nsJ/uklNKsLLl6VhTQBPwMTbf6Tf7l6bcKzpy7aePuq9UiQ==", + "dev": true, + "dependencies": { + "@lerna/get-packed": "4.0.0", + "@lerna/package": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "npm-packlist": "^2.1.4", + "npmlog": "^4.1.2", + "tar": "^6.1.0", + "temp-write": "^4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/pack-directory/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/pack-directory/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@lerna/pack-directory/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/pack-directory/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@lerna/pack-directory/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/pack-directory/node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/package": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/package/-/package-4.0.0.tgz", + "integrity": "sha512-l0M/izok6FlyyitxiQKr+gZLVFnvxRQdNhzmQ6nRnN9dvBJWn+IxxpM+cLqGACatTnyo9LDzNTOj2Db3+s0s8Q==", + "dev": true, + "dependencies": { + "load-json-file": "^6.2.0", + "npm-package-arg": "^8.1.0", + "write-pkg": "^4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/package-graph": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-4.0.0.tgz", + "integrity": "sha512-QED2ZCTkfXMKFoTGoccwUzjHtZMSf3UKX14A4/kYyBms9xfFsesCZ6SLI5YeySEgcul8iuIWfQFZqRw+Qrjraw==", + "dev": true, + "dependencies": { + "@lerna/prerelease-id-from-version": "4.0.0", + "@lerna/validation-error": "4.0.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/prerelease-id-from-version": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-4.0.0.tgz", + "integrity": "sha512-GQqguzETdsYRxOSmdFZ6zDBXDErIETWOqomLERRY54f4p+tk4aJjoVdd9xKwehC9TBfIFvlRbL1V9uQGHh1opg==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/profiler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/profiler/-/profiler-4.0.0.tgz", + "integrity": "sha512-/BaEbqnVh1LgW/+qz8wCuI+obzi5/vRE8nlhjPzdEzdmWmZXuCKyWSEzAyHOJWw1ntwMiww5dZHhFQABuoFz9Q==", + "dev": true, + "dependencies": { + "fs-extra": "^9.1.0", + "npmlog": "^4.1.2", + "upath": "^2.0.1" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/project": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-4.0.0.tgz", + "integrity": "sha512-o0MlVbDkD5qRPkFKlBZsXZjoNTWPyuL58564nSfZJ6JYNmgAptnWPB2dQlAc7HWRZkmnC2fCkEdoU+jioPavbg==", + "dev": true, + "dependencies": { + "@lerna/package": "4.0.0", + "@lerna/validation-error": "4.0.0", + "cosmiconfig": "^7.0.0", + "dedent": "^0.7.0", + "dot-prop": "^6.0.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.2", + "load-json-file": "^6.2.0", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "resolve-from": "^5.0.0", + "write-json-file": "^4.3.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/project/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/prompt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-4.0.0.tgz", + "integrity": "sha512-4Ig46oCH1TH5M7YyTt53fT6TuaKMgqUUaqdgxvp6HP6jtdak6+amcsqB8YGz2eQnw/sdxunx84DfI9XpoLj4bQ==", + "dev": true, + "dependencies": { + "inquirer": "^7.3.3", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/publish": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-4.0.0.tgz", + "integrity": "sha512-K8jpqjHrChH22qtkytA5GRKIVFEtqBF6JWj1I8dWZtHs4Jywn8yB1jQ3BAMLhqmDJjWJtRck0KXhQQKzDK2UPg==", + "dev": true, + "dependencies": { + "@lerna/check-working-tree": "4.0.0", + "@lerna/child-process": "4.0.0", + "@lerna/collect-updates": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/describe-ref": "4.0.0", + "@lerna/log-packed": "4.0.0", + "@lerna/npm-conf": "4.0.0", + "@lerna/npm-dist-tag": "4.0.0", + "@lerna/npm-publish": "4.0.0", + "@lerna/otplease": "4.0.0", + "@lerna/output": "4.0.0", + "@lerna/pack-directory": "4.0.0", + "@lerna/prerelease-id-from-version": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/validation-error": "4.0.0", + "@lerna/version": "4.0.0", + "fs-extra": "^9.1.0", + "libnpmaccess": "^4.0.1", + "npm-package-arg": "^8.1.0", + "npm-registry-fetch": "^9.0.0", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "p-pipe": "^3.1.0", + "pacote": "^11.2.6", + "semver": "^7.3.4" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/publish/node_modules/make-fetch-happen": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@lerna/publish/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/publish/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@lerna/publish/node_modules/npm-registry-fetch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz", + "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==", + "dev": true, + "dependencies": { + "@npmcli/ci-detect": "^1.0.0", + "lru-cache": "^6.0.0", + "make-fetch-happen": "^8.0.9", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@lerna/pulse-till-done": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-4.0.0.tgz", + "integrity": "sha512-Frb4F7QGckaybRhbF7aosLsJ5e9WuH7h0KUkjlzSByVycxY91UZgaEIVjS2oN9wQLrheLMHl6SiFY0/Pvo0Cxg==", + "dev": true, + "dependencies": { + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/query-graph": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-4.0.0.tgz", + "integrity": "sha512-YlP6yI3tM4WbBmL9GCmNDoeQyzcyg1e4W96y/PKMZa5GbyUvkS2+Jc2kwPD+5KcXou3wQZxSPzR3Te5OenaDdg==", + "dev": true, + "dependencies": { + "@lerna/package-graph": "4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/resolve-symlink": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-4.0.0.tgz", + "integrity": "sha512-RtX8VEUzqT+uLSCohx8zgmjc6zjyRlh6i/helxtZTMmc4+6O4FS9q5LJas2uGO2wKvBlhcD6siibGt7dIC3xZA==", + "dev": true, + "dependencies": { + "fs-extra": "^9.1.0", + "npmlog": "^4.1.2", + "read-cmd-shim": "^2.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/rimraf-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-4.0.0.tgz", + "integrity": "sha512-QNH9ABWk9mcMJh2/muD9iYWBk1oQd40y6oH+f3wwmVGKYU5YJD//+zMiBI13jxZRtwBx0vmBZzkBkK1dR11cBg==", + "dev": true, + "dependencies": { + "@lerna/child-process": "4.0.0", + "npmlog": "^4.1.2", + "path-exists": "^4.0.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/run": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-4.0.0.tgz", + "integrity": "sha512-9giulCOzlMPzcZS/6Eov6pxE9gNTyaXk0Man+iCIdGJNMrCnW7Dme0Z229WWP/UoxDKg71F2tMsVVGDiRd8fFQ==", + "dev": true, + "dependencies": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/npm-run-script": "4.0.0", + "@lerna/output": "4.0.0", + "@lerna/profiler": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/timer": "4.0.0", + "@lerna/validation-error": "4.0.0", + "p-map": "^4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/run-lifecycle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-4.0.0.tgz", + "integrity": "sha512-IwxxsajjCQQEJAeAaxF8QdEixfI7eLKNm4GHhXHrgBu185JcwScFZrj9Bs+PFKxwb+gNLR4iI5rpUdY8Y0UdGQ==", + "dev": true, + "dependencies": { + "@lerna/npm-conf": "4.0.0", + "npm-lifecycle": "^3.1.5", + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/run-topologically": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-4.0.0.tgz", + "integrity": "sha512-EVZw9hGwo+5yp+VL94+NXRYisqgAlj0jWKWtAIynDCpghRxCE5GMO3xrQLmQgqkpUl9ZxQFpICgYv5DW4DksQA==", + "dev": true, + "dependencies": { + "@lerna/query-graph": "4.0.0", + "p-queue": "^6.6.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/symlink-binary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-4.0.0.tgz", + "integrity": "sha512-zualodWC4q1QQc1pkz969hcFeWXOsVYZC5AWVtAPTDfLl+TwM7eG/O6oP+Rr3fFowspxo6b1TQ6sYfDV6HXNWA==", + "dev": true, + "dependencies": { + "@lerna/create-symlink": "4.0.0", + "@lerna/package": "4.0.0", + "fs-extra": "^9.1.0", + "p-map": "^4.0.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/symlink-dependencies": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-4.0.0.tgz", + "integrity": "sha512-BABo0MjeUHNAe2FNGty1eantWp8u83BHSeIMPDxNq0MuW2K3CiQRaeWT3EGPAzXpGt0+hVzBrA6+OT0GPn7Yuw==", + "dev": true, + "dependencies": { + "@lerna/create-symlink": "4.0.0", + "@lerna/resolve-symlink": "4.0.0", + "@lerna/symlink-binary": "4.0.0", + "fs-extra": "^9.1.0", + "p-map": "^4.0.0", + "p-map-series": "^2.1.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/timer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-4.0.0.tgz", + "integrity": "sha512-WFsnlaE7SdOvjuyd05oKt8Leg3ENHICnvX3uYKKdByA+S3g+TCz38JsNs7OUZVt+ba63nC2nbXDlUnuT2Xbsfg==", + "dev": true, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/validation-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-4.0.0.tgz", + "integrity": "sha512-1rBOM5/koiVWlRi3V6dB863E1YzJS8v41UtsHgMr6gB2ncJ2LsQtMKlJpi3voqcgh41H8UsPXR58RrrpPpufyw==", + "dev": true, + "dependencies": { + "npmlog": "^4.1.2" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/version": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-4.0.0.tgz", + "integrity": "sha512-otUgiqs5W9zGWJZSCCMRV/2Zm2A9q9JwSDS7s/tlKq4mWCYriWo7+wsHEA/nPTMDyYyBO5oyZDj+3X50KDUzeA==", + "dev": true, + "dependencies": { + "@lerna/check-working-tree": "4.0.0", + "@lerna/child-process": "4.0.0", + "@lerna/collect-updates": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/conventional-commits": "4.0.0", + "@lerna/github-client": "4.0.0", + "@lerna/gitlab-client": "4.0.0", + "@lerna/output": "4.0.0", + "@lerna/prerelease-id-from-version": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/validation-error": "4.0.0", + "chalk": "^4.1.0", + "dedent": "^0.7.0", + "load-json-file": "^6.2.0", + "minimatch": "^3.0.4", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "p-pipe": "^3.1.0", + "p-reduce": "^2.1.0", + "p-waterfall": "^2.1.1", + "semver": "^7.3.4", + "slash": "^3.0.0", + "temp-write": "^4.0.0", + "write-json-file": "^4.3.0" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/write-log-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-4.0.0.tgz", + "integrity": "sha512-XRG5BloiArpXRakcnPHmEHJp+4AtnhRtpDIHSghmXD5EichI1uD73J7FgPp30mm2pDRq3FdqB0NbwSEsJ9xFQg==", + "dev": true, + "dependencies": { + "npmlog": "^4.1.2", + "write-file-atomic": "^3.0.3" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/@lerna/write-log-file/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/ci-detect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz", + "integrity": "sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==", + "dev": true + }, + "node_modules/@npmcli/git": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz", + "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^1.3.2", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + } + }, + "node_modules/@npmcli/git/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", + "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", + "dev": true, + "dependencies": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "installed-package-contents": "index.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/move-file/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz", + "integrity": "sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==", + "dev": true + }, + "node_modules/@npmcli/promise-spawn": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz", + "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==", + "dev": true, + "dependencies": { + "infer-owner": "^1.0.4" + } + }, + "node_modules/@npmcli/run-script": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.5.tgz", + "integrity": "sha512-NQspusBCpTjNwNRFMtz2C5MxoxyzlbuJ4YEhxAKrIonTiirKDtatsZictx9RgamQIx6+QuHMNmPl0wQdoESs9A==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", + "infer-owner": "^1.0.4", + "node-gyp": "^7.1.0", + "read-package-json-fast": "^2.0.1" + } + }, + "node_modules/@npmcli/run-script/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/run-script/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/run-script/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@npmcli/run-script/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/run-script/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/run-script/node_modules/node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@npmcli/run-script/node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz", + "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", + "dev": true, + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", + "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==", + "dev": true + }, + "node_modules/@octokit/plugin-enterprise-rest": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", + "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", + "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.18.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.4.1.tgz", + "integrity": "sha512-Nx0g7I5ayAYghsLJP4Q1Ch2W9jYYM0FlWWWZocUro8rNxVwuZXGfFd7Rcqi9XDWepSXjg1WByiNJnZza2hIOvQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.18.1", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/request/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.6.7", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.6.7.tgz", + "integrity": "sha512-Kn6WrI2ZvmAztdx+HEaf88RuJn+LK72S8g6OpciE4kbZddAN84fu4fiPGxcEu052WmqKVnA/cnQsbNlrYC6rqQ==", + "dev": true, + "dependencies": { + "@octokit/core": "^3.5.0", + "@octokit/plugin-paginate-rest": "^2.6.2", + "@octokit/plugin-request-log": "^1.0.2", + "@octokit/plugin-rest-endpoint-methods": "5.4.1" + } + }, + "node_modules/@octokit/types": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", + "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^8.2.1" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", + "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "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/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", + "dev": true + }, + "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/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/byte-size": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz", + "integrity": "sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacache": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "dev": true, + "dependencies": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacache/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/chalk/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/chalk/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/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cli-truncate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cmd-shim": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-4.1.0.tgz", + "integrity": "sha512-lb9L7EM4I/ZRVuljLPEtUJOP+xiQVknZ4ZMpMgEp4JzNldPb27HU03hi6K1/6CoIuit/Zm/LQXySErFeXxDprw==", + "dev": true, + "dependencies": { + "mkdirp-infer-owner": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "node_modules/columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "dev": true, + "dependencies": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "node_modules/columnify/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/columnify/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/compare-func/node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/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==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/conventional-changelog-angular": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", + "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.3.tgz", + "integrity": "sha512-MwnZjIoMRL3jtPH5GywVNqetGILC7g6RQFvdb8LRU/fA/338JbeWAku3PZ8yQ+mtVRViiISqJlb0sOz0htBZig==", + "dev": true, + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", + "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==", + "dev": true, + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", + "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0", + "trim-off-newlines": "^1.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "node_modules/detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "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/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", + "dev": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "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/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "node_modules/get-pkg-repo": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.1.2.tgz", + "integrity": "sha512-/FjamZL9cBYllEbReZkxF2IMh80d8TJoC4e3bmLNif8ibHw95aj0N/tzqK0kZz9eU/3w3dL6lF4fnnX/sDdW3A==", + "dev": true, + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "meow": "^7.0.0", + "through2": "^2.0.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/meow": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-pkg-repo/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-pkg-repo/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-pkg-repo/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-pkg-repo/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-pkg-repo/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", + "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-remote-origin-url/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "dependencies": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-semver-tags/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/git-up": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.2.tgz", + "integrity": "sha512-kbuvus1dWQB2sSW4cbfTeGpCMd8ge9jx9RKnhXhuJ7tnvT+NIrTVfYZxjtflZddQYcmdOTlkAcjmx7bor+15AQ==", + "dev": true, + "dependencies": { + "is-ssh": "^1.3.0", + "parse-url": "^5.0.0" + } + }, + "node_modules/git-url-parse": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.5.0.tgz", + "integrity": "sha512-TZYSMDeM37r71Lqg1mbnMlOqlHd7BSij9qN7XwTkRqSAYFMihGLGhfHwgqQob3GUhEneKnV4nskN9rbQw2KGxA==", + "dev": true, + "dependencies": { + "git-up": "^4.0.0" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "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/globals": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "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-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/husky": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", + "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/init-package-json": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.3.tgz", + "integrity": "sha512-tk/gAgbMMxR6fn1MgMaM1HpU1ryAmBWWitnxG5OhuNXeX0cbpbgV5jA4AIpQJVNoyOfOevTtO6WX+rPs+EFqaQ==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "npm-package-arg": "^8.1.2", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "^3.0.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/init-package-json/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/init-package-json/node_modules/read-package-json": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-3.0.1.tgz", + "integrity": "sha512-aLcPqxovhJTVJcsnROuuzQvv6oziQx4zd3JvG0vGCL5MjTONUc4uJ90zCBC6R7W7oUKBNoR/F8pkyfVwlbxqng==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^3.0.0", + "npm-normalize-package-bin": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-ssh": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz", + "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==", + "dev": true, + "dependencies": { + "protocols": "^1.1.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "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/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lerna": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-4.0.0.tgz", + "integrity": "sha512-DD/i1znurfOmNJb0OBw66NmNqiM8kF6uIrzrJ0wGE3VNdzeOhz9ziWLYiRaZDGGwgbcjOo6eIfcx9O5Qynz+kg==", + "dev": true, + "dependencies": { + "@lerna/add": "4.0.0", + "@lerna/bootstrap": "4.0.0", + "@lerna/changed": "4.0.0", + "@lerna/clean": "4.0.0", + "@lerna/cli": "4.0.0", + "@lerna/create": "4.0.0", + "@lerna/diff": "4.0.0", + "@lerna/exec": "4.0.0", + "@lerna/import": "4.0.0", + "@lerna/info": "4.0.0", + "@lerna/init": "4.0.0", + "@lerna/link": "4.0.0", + "@lerna/list": "4.0.0", + "@lerna/publish": "4.0.0", + "@lerna/run": "4.0.0", + "@lerna/version": "4.0.0", + "import-local": "^3.0.2", + "npmlog": "^4.1.2" + }, + "bin": { + "lerna": "cli.js" + }, + "engines": { + "node": ">= 10.18.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libnpmaccess": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-4.0.3.tgz", + "integrity": "sha512-sPeTSNImksm8O2b6/pf3ikv4N567ERYEpeKRPSmqlNt1dTZbvgpJIzg5vAhXHpw2ISBsELFRelk0jEahj1c6nQ==", + "dev": true, + "dependencies": { + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/libnpmaccess/node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/libnpmaccess/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/libnpmpublish": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-4.0.2.tgz", + "integrity": "sha512-+AD7A2zbVeGRCFI2aO//oUmapCwy7GHqPXFJh3qpToSRNU+tXKJ2YFUgjt04LPPAf2dlEH95s6EhIHM1J7bmOw==", + "dev": true, + "dependencies": { + "normalize-package-data": "^3.0.2", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0", + "semver": "^7.1.3", + "ssri": "^8.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/libnpmpublish/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/lint-staged": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.1.2.tgz", + "integrity": "sha512-6lYpNoA9wGqkL6Hew/4n1H6lRqF3qCsujVT0Oq5Z4hiSAM7S6NksPJ3gnr7A7R52xCtiZMcEUNNQ6d6X5Bvh9w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.1", + "cli-truncate": "^2.1.0", + "commander": "^7.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "listr2": "^3.8.2", + "log-symbols": "^4.1.0", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/listr2": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.10.0.tgz", + "integrity": "sha512-eP40ZHihu70sSmqFNbNy2NL1YwImmlMmPh9WO5sLmPDleurMHt3n+SwEWNu2kzKScexZnkyFtc1VI0z/TGlmpw==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^1.2.2", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + } + }, + "node_modules/load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/load-json-file/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-update/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/make-fetch-happen": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.0.3.tgz", + "integrity": "sha512-uZ/9Cf2vKqsSWZyXhZ9wHHyckBrkntgbnqV68Bfe8zZenlf7D6yuGMXvHZQ+jSnzPkjosuNP1HGasj1J4h8OlQ==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/make-fetch-happen/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dev": true, + "dependencies": { + "mime-db": "1.48.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", + "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-infer-owner": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz", + "integrity": "sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-infer-owner/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-infer-owner/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", + "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.1.2", + "request": "^2.88.0", + "rimraf": "^2.6.3", + "semver": "^5.7.1", + "tar": "^4.4.12", + "which": "^1.3.1" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-gyp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "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/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-install-checks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz", + "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-lifecycle": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz", + "integrity": "sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==", + "dev": true, + "dependencies": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.15", + "node-gyp": "^5.0.2", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + } + }, + "node_modules/npm-lifecycle/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/npm-package-arg": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz", + "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "semver": "^7.3.4", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-packlist": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz", + "integrity": "sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + }, + "bin": { + "npm-packlist": "bin/index.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-pick-manifest": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz", + "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==", + "dev": true, + "dependencies": { + "npm-install-checks": "^4.0.0", + "npm-normalize-package-bin": "^1.0.1", + "npm-package-arg": "^8.1.2", + "semver": "^7.3.4" + } + }, + "node_modules/npm-registry-fetch": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz", + "integrity": "sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==", + "dev": true, + "dependencies": { + "make-fetch-happen": "^9.0.1", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-registry-fetch/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-registry-fetch/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", + "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-pipe": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", + "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-waterfall": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", + "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", + "dev": true, + "dependencies": { + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pacote": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz", + "integrity": "sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg==", + "dev": true, + "dependencies": { + "@npmcli/git": "^2.1.0", + "@npmcli/installed-package-contents": "^1.0.6", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^1.8.2", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^2.1.4", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^11.0.0", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^2.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pacote/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/pacote/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/pacote/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pacote/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/pacote/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pacote/node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-path": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", + "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", + "dev": true, + "dependencies": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0", + "qs": "^6.9.4", + "query-string": "^6.13.8" + } + }, + "node_modules/parse-path/node_modules/qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/parse-url": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.7.tgz", + "integrity": "sha512-CgbjyWT6aOh2oNSUS0cioYQsGysj9hQ2IdbOfeNwq5KOaKM7dOw/yTupiI0cnJhaDHJEIGybPkQz7LF9WNIhyw==", + "dev": true, + "dependencies": { + "is-ssh": "^1.3.0", + "normalize-url": "4.5.1", + "parse-path": "^4.0.0", + "protocols": "^1.4.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promzard": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", + "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", + "dev": true, + "dependencies": { + "read": "1" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "node_modules/protocols": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", + "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", + "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/read-cmd-shim": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz", + "integrity": "sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw==", + "dev": true + }, + "node_modules/read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz", + "integrity": "sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/read-package-tree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "dev": true, + "dependencies": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "dev": true, + "dependencies": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/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==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringify-object/node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, + "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/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/temp-write": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/temp-write/-/temp-write-4.0.0.tgz", + "integrity": "sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "is-stream": "^2.0.0", + "make-dir": "^3.0.0", + "temp-dir": "^1.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-write/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/temp-write/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2/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==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "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/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/uglify-js": { + "version": "3.13.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", + "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/umask": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz", + "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=", + "dev": true + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/util-promisify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", + "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/write-json-file": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", + "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", + "dev": true, + "dependencies": { + "detect-indent": "^6.0.0", + "graceful-fs": "^4.1.15", + "is-plain-obj": "^2.0.0", + "make-dir": "^3.0.0", + "sort-keys": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8.3" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/write-json-file/node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/write-json-file/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/write-json-file/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/write-json-file/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/write-json-file/node_modules/sort-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", + "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/write-json-file/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/write-pkg": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz", + "integrity": "sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==", + "dev": true, + "dependencies": { + "sort-keys": "^2.0.0", + "type-fest": "^0.4.1", + "write-json-file": "^3.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/write-pkg/node_modules/type-fest": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", + "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/write-pkg/node_modules/write-json-file": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", + "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", + "dev": true, + "dependencies": { + "detect-indent": "^5.0.0", + "graceful-fs": "^4.1.15", + "make-dir": "^2.1.0", + "pify": "^4.0.1", + "sort-keys": "^2.0.0", + "write-file-atomic": "^2.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true + }, + "@lerna/add": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-4.0.0.tgz", + "integrity": "sha512-cpmAH1iS3k8JBxNvnMqrGTTjbY/ZAiKa1ChJzFevMYY3eeqbvhsBKnBcxjRXtdrJ6bd3dCQM+ZtK+0i682Fhng==", + "dev": true, + "requires": { + "@lerna/bootstrap": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/npm-conf": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "npm-package-arg": "^8.1.0", + "p-map": "^4.0.0", + "pacote": "^11.2.6", + "semver": "^7.3.4" + } + }, + "@lerna/bootstrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-4.0.0.tgz", + "integrity": "sha512-RkS7UbeM2vu+kJnHzxNRCLvoOP9yGNgkzRdy4UV2hNalD7EP41bLvRVOwRYQ7fhc2QcbhnKNdOBihYRL0LcKtw==", + "dev": true, + "requires": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/has-npm-version": "4.0.0", + "@lerna/npm-install": "4.0.0", + "@lerna/package-graph": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/rimraf-dir": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/symlink-binary": "4.0.0", + "@lerna/symlink-dependencies": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "get-port": "^5.1.1", + "multimatch": "^5.0.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "p-map-series": "^2.1.0", + "p-waterfall": "^2.1.1", + "read-package-tree": "^5.3.1", + "semver": "^7.3.4" + } + }, + "@lerna/changed": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-4.0.0.tgz", + "integrity": "sha512-cD+KuPRp6qiPOD+BO6S6SN5cARspIaWSOqGBpGnYzLb4uWT8Vk4JzKyYtc8ym1DIwyoFXHosXt8+GDAgR8QrgQ==", + "dev": true, + "requires": { + "@lerna/collect-updates": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/listable": "4.0.0", + "@lerna/output": "4.0.0" + } + }, + "@lerna/check-working-tree": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-4.0.0.tgz", + "integrity": "sha512-/++bxM43jYJCshBiKP5cRlCTwSJdRSxVmcDAXM+1oUewlZJVSVlnks5eO0uLxokVFvLhHlC5kHMc7gbVFPHv6Q==", + "dev": true, + "requires": { + "@lerna/collect-uncommitted": "4.0.0", + "@lerna/describe-ref": "4.0.0", + "@lerna/validation-error": "4.0.0" + } + }, + "@lerna/child-process": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-4.0.0.tgz", + "integrity": "sha512-XtCnmCT9eyVsUUHx6y/CTBYdV9g2Cr/VxyseTWBgfIur92/YKClfEtJTbOh94jRT62hlKLqSvux/UhxXVh613Q==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "execa": "^5.0.0", + "strong-log-transformer": "^2.1.0" + } + }, + "@lerna/clean": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-4.0.0.tgz", + "integrity": "sha512-uugG2iN9k45ITx2jtd8nEOoAtca8hNlDCUM0N3lFgU/b1mEQYAPRkqr1qs4FLRl/Y50ZJ41wUz1eazS+d/0osA==", + "dev": true, + "requires": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/rimraf-dir": "4.0.0", + "p-map": "^4.0.0", + "p-map-series": "^2.1.0", + "p-waterfall": "^2.1.1" + } + }, + "@lerna/cli": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-4.0.0.tgz", + "integrity": "sha512-Neaw3GzFrwZiRZv2g7g6NwFjs3er1vhraIniEs0jjVLPMNC4eata0na3GfE5yibkM/9d3gZdmihhZdZ3EBdvYA==", + "dev": true, + "requires": { + "@lerna/global-options": "4.0.0", + "dedent": "^0.7.0", + "npmlog": "^4.1.2", + "yargs": "^16.2.0" + } + }, + "@lerna/collect-uncommitted": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-4.0.0.tgz", + "integrity": "sha512-ufSTfHZzbx69YNj7KXQ3o66V4RC76ffOjwLX0q/ab//61bObJ41n03SiQEhSlmpP+gmFbTJ3/7pTe04AHX9m/g==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "chalk": "^4.1.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/collect-updates": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-4.0.0.tgz", + "integrity": "sha512-bnNGpaj4zuxsEkyaCZLka9s7nMs58uZoxrRIPJ+nrmrZYp1V5rrd+7/NYTuunOhY2ug1sTBvTAxj3NZQ+JKnOw==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/describe-ref": "4.0.0", + "minimatch": "^3.0.4", + "npmlog": "^4.1.2", + "slash": "^3.0.0" + } + }, + "@lerna/command": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-4.0.0.tgz", + "integrity": "sha512-LM9g3rt5FsPNFqIHUeRwWXLNHJ5NKzOwmVKZ8anSp4e1SPrv2HNc1V02/9QyDDZK/w+5POXH5lxZUI1CHaOK/A==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/package-graph": "4.0.0", + "@lerna/project": "4.0.0", + "@lerna/validation-error": "4.0.0", + "@lerna/write-log-file": "4.0.0", + "clone-deep": "^4.0.1", + "dedent": "^0.7.0", + "execa": "^5.0.0", + "is-ci": "^2.0.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/conventional-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-4.0.0.tgz", + "integrity": "sha512-CSUQRjJHFrH8eBn7+wegZLV3OrNc0Y1FehYfYGhjLE2SIfpCL4bmfu/ViYuHh9YjwHaA+4SX6d3hR+xkeseKmw==", + "dev": true, + "requires": { + "@lerna/validation-error": "4.0.0", + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-core": "^4.2.2", + "conventional-recommended-bump": "^6.1.0", + "fs-extra": "^9.1.0", + "get-stream": "^6.0.0", + "lodash.template": "^4.5.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "pify": "^5.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true + } + } + }, + "@lerna/create": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-4.0.0.tgz", + "integrity": "sha512-mVOB1niKByEUfxlbKTM1UNECWAjwUdiioIbRQZEeEabtjCL69r9rscIsjlGyhGWCfsdAG5wfq4t47nlDXdLLag==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/npm-conf": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "fs-extra": "^9.1.0", + "globby": "^11.0.2", + "init-package-json": "^2.0.2", + "npm-package-arg": "^8.1.0", + "p-reduce": "^2.1.0", + "pacote": "^11.2.6", + "pify": "^5.0.0", + "semver": "^7.3.4", + "slash": "^3.0.0", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^3.0.0", + "whatwg-url": "^8.4.0", + "yargs-parser": "20.2.4" + }, + "dependencies": { + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + } + } + }, + "@lerna/create-symlink": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-4.0.0.tgz", + "integrity": "sha512-I0phtKJJdafUiDwm7BBlEUOtogmu8+taxq6PtIrxZbllV9hWg59qkpuIsiFp+no7nfRVuaasNYHwNUhDAVQBig==", + "dev": true, + "requires": { + "cmd-shim": "^4.1.0", + "fs-extra": "^9.1.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/describe-ref": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-4.0.0.tgz", + "integrity": "sha512-eTU5+xC4C5Gcgz+Ey4Qiw9nV2B4JJbMulsYJMW8QjGcGh8zudib7Sduj6urgZXUYNyhYpRs+teci9M2J8u+UvQ==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-4.0.0.tgz", + "integrity": "sha512-jYPKprQVg41+MUMxx6cwtqsNm0Yxx9GDEwdiPLwcUTFx+/qKCEwifKNJ1oGIPBxyEHX2PFCOjkK39lHoj2qiag==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/validation-error": "4.0.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/exec": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-4.0.0.tgz", + "integrity": "sha512-VGXtL/b/JfY84NB98VWZpIExfhLOzy0ozm/0XaS4a2SmkAJc5CeUfrhvHxxkxiTBLkU+iVQUyYEoAT0ulQ8PCw==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/profiler": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/validation-error": "4.0.0", + "p-map": "^4.0.0" + } + }, + "@lerna/filter-options": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-4.0.0.tgz", + "integrity": "sha512-vV2ANOeZhOqM0rzXnYcFFCJ/kBWy/3OA58irXih9AMTAlQLymWAK0akWybl++sUJ4HB9Hx12TOqaXbYS2NM5uw==", + "dev": true, + "requires": { + "@lerna/collect-updates": "4.0.0", + "@lerna/filter-packages": "4.0.0", + "dedent": "^0.7.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/filter-packages": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-4.0.0.tgz", + "integrity": "sha512-+4AJIkK7iIiOaqCiVTYJxh/I9qikk4XjNQLhE3kixaqgMuHl1NQ99qXRR0OZqAWB9mh8Z1HA9bM5K1HZLBTOqA==", + "dev": true, + "requires": { + "@lerna/validation-error": "4.0.0", + "multimatch": "^5.0.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/get-npm-exec-opts": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-4.0.0.tgz", + "integrity": "sha512-yvmkerU31CTWS2c7DvmAWmZVeclPBqI7gPVr5VATUKNWJ/zmVcU4PqbYoLu92I9Qc4gY1TuUplMNdNuZTSL7IQ==", + "dev": true, + "requires": { + "npmlog": "^4.1.2" + } + }, + "@lerna/get-packed": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-4.0.0.tgz", + "integrity": "sha512-rfWONRsEIGyPJTxFzC8ECb3ZbsDXJbfqWYyeeQQDrJRPnEJErlltRLPLgC2QWbxFgFPsoDLeQmFHJnf0iDfd8w==", + "dev": true, + "requires": { + "fs-extra": "^9.1.0", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + } + } + }, + "@lerna/github-client": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-4.0.0.tgz", + "integrity": "sha512-2jhsldZtTKXYUBnOm23Lb0Fx8G4qfSXF9y7UpyUgWUj+YZYd+cFxSuorwQIgk5P4XXrtVhsUesIsli+BYSThiw==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@octokit/plugin-enterprise-rest": "^6.0.1", + "@octokit/rest": "^18.1.0", + "git-url-parse": "^11.4.4", + "npmlog": "^4.1.2" + } + }, + "@lerna/gitlab-client": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-4.0.0.tgz", + "integrity": "sha512-OMUpGSkeDWFf7BxGHlkbb35T7YHqVFCwBPSIR6wRsszY8PAzCYahtH3IaJzEJyUg6vmZsNl0FSr3pdA2skhxqA==", + "dev": true, + "requires": { + "node-fetch": "^2.6.1", + "npmlog": "^4.1.2", + "whatwg-url": "^8.4.0" + } + }, + "@lerna/global-options": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-4.0.0.tgz", + "integrity": "sha512-TRMR8afAHxuYBHK7F++Ogop2a82xQjoGna1dvPOY6ltj/pEx59pdgcJfYcynYqMkFIk8bhLJJN9/ndIfX29FTQ==", + "dev": true + }, + "@lerna/has-npm-version": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-4.0.0.tgz", + "integrity": "sha512-LQ3U6XFH8ZmLCsvsgq1zNDqka0Xzjq5ibVN+igAI5ccRWNaUsE/OcmsyMr50xAtNQMYMzmpw5GVLAivT2/YzCg==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "semver": "^7.3.4" + } + }, + "@lerna/import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-4.0.0.tgz", + "integrity": "sha512-FaIhd+4aiBousKNqC7TX1Uhe97eNKf5/SC7c5WZANVWtC7aBWdmswwDt3usrzCNpj6/Wwr9EtEbYROzxKH8ffg==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/validation-error": "4.0.0", + "dedent": "^0.7.0", + "fs-extra": "^9.1.0", + "p-map-series": "^2.1.0" + } + }, + "@lerna/info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/info/-/info-4.0.0.tgz", + "integrity": "sha512-8Uboa12kaCSZEn4XRfPz5KU9XXoexSPS4oeYGj76s2UQb1O1GdnEyfjyNWoUl1KlJ2i/8nxUskpXIftoFYH0/Q==", + "dev": true, + "requires": { + "@lerna/command": "4.0.0", + "@lerna/output": "4.0.0", + "envinfo": "^7.7.4" + } + }, + "@lerna/init": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-4.0.0.tgz", + "integrity": "sha512-wY6kygop0BCXupzWj5eLvTUqdR7vIAm0OgyV9WHpMYQGfs1V22jhztt8mtjCloD/O0nEe4tJhdG62XU5aYmPNQ==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/command": "4.0.0", + "fs-extra": "^9.1.0", + "p-map": "^4.0.0", + "write-json-file": "^4.3.0" + } + }, + "@lerna/link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-4.0.0.tgz", + "integrity": "sha512-KlvPi7XTAcVOByfaLlOeYOfkkDcd+bejpHMCd1KcArcFTwijOwXOVi24DYomIeHvy6HsX/IUquJ4PPUJIeB4+w==", + "dev": true, + "requires": { + "@lerna/command": "4.0.0", + "@lerna/package-graph": "4.0.0", + "@lerna/symlink-dependencies": "4.0.0", + "p-map": "^4.0.0", + "slash": "^3.0.0" + } + }, + "@lerna/list": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-4.0.0.tgz", + "integrity": "sha512-L2B5m3P+U4Bif5PultR4TI+KtW+SArwq1i75QZ78mRYxPc0U/piau1DbLOmwrdqr99wzM49t0Dlvl6twd7GHFg==", + "dev": true, + "requires": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/listable": "4.0.0", + "@lerna/output": "4.0.0" + } + }, + "@lerna/listable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-4.0.0.tgz", + "integrity": "sha512-/rPOSDKsOHs5/PBLINZOkRIX1joOXUXEtyUs5DHLM8q6/RP668x/1lFhw6Dx7/U+L0+tbkpGtZ1Yt0LewCLgeQ==", + "dev": true, + "requires": { + "@lerna/query-graph": "4.0.0", + "chalk": "^4.1.0", + "columnify": "^1.5.4" + } + }, + "@lerna/log-packed": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-4.0.0.tgz", + "integrity": "sha512-+dpCiWbdzgMAtpajLToy9PO713IHoE6GV/aizXycAyA07QlqnkpaBNZ8DW84gHdM1j79TWockGJo9PybVhrrZQ==", + "dev": true, + "requires": { + "byte-size": "^7.0.0", + "columnify": "^1.5.4", + "has-unicode": "^2.0.1", + "npmlog": "^4.1.2" + } + }, + "@lerna/npm-conf": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-4.0.0.tgz", + "integrity": "sha512-uS7H02yQNq3oejgjxAxqq/jhwGEE0W0ntr8vM3EfpCW1F/wZruwQw+7bleJQ9vUBjmdXST//tk8mXzr5+JXCfw==", + "dev": true, + "requires": { + "config-chain": "^1.1.12", + "pify": "^5.0.0" + }, + "dependencies": { + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true + } + } + }, + "@lerna/npm-dist-tag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-4.0.0.tgz", + "integrity": "sha512-F20sg28FMYTgXqEQihgoqSfwmq+Id3zT23CnOwD+XQMPSy9IzyLf1fFVH319vXIw6NF6Pgs4JZN2Qty6/CQXGw==", + "dev": true, + "requires": { + "@lerna/otplease": "4.0.0", + "npm-package-arg": "^8.1.0", + "npm-registry-fetch": "^9.0.0", + "npmlog": "^4.1.2" + }, + "dependencies": { + "make-fetch-happen": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", + "dev": true, + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "npm-registry-fetch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz", + "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==", + "dev": true, + "requires": { + "@npmcli/ci-detect": "^1.0.0", + "lru-cache": "^6.0.0", + "make-fetch-happen": "^8.0.9", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + } + } + } + }, + "@lerna/npm-install": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-4.0.0.tgz", + "integrity": "sha512-aKNxq2j3bCH3eXl3Fmu4D54s/YLL9WSwV8W7X2O25r98wzrO38AUN6AB9EtmAx+LV/SP15et7Yueg9vSaanRWg==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/get-npm-exec-opts": "4.0.0", + "fs-extra": "^9.1.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "signal-exit": "^3.0.3", + "write-pkg": "^4.0.0" + } + }, + "@lerna/npm-publish": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-4.0.0.tgz", + "integrity": "sha512-vQb7yAPRo5G5r77DRjHITc9piR9gvEKWrmfCH7wkfBnGWEqu7n8/4bFQ7lhnkujvc8RXOsYpvbMQkNfkYibD/w==", + "dev": true, + "requires": { + "@lerna/otplease": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "fs-extra": "^9.1.0", + "libnpmpublish": "^4.0.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "pify": "^5.0.0", + "read-package-json": "^3.0.0" + }, + "dependencies": { + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true + }, + "read-package-json": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-3.0.1.tgz", + "integrity": "sha512-aLcPqxovhJTVJcsnROuuzQvv6oziQx4zd3JvG0vGCL5MjTONUc4uJ90zCBC6R7W7oUKBNoR/F8pkyfVwlbxqng==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^3.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + } + } + }, + "@lerna/npm-run-script": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-4.0.0.tgz", + "integrity": "sha512-Jmyh9/IwXJjOXqKfIgtxi0bxi1pUeKe5bD3S81tkcy+kyng/GNj9WSqD5ZggoNP2NP//s4CLDAtUYLdP7CU9rA==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "@lerna/get-npm-exec-opts": "4.0.0", + "npmlog": "^4.1.2" + } + }, + "@lerna/otplease": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/otplease/-/otplease-4.0.0.tgz", + "integrity": "sha512-Sgzbqdk1GH4psNiT6hk+BhjOfIr/5KhGBk86CEfHNJTk9BK4aZYyJD4lpDbDdMjIV4g03G7pYoqHzH765T4fxw==", + "dev": true, + "requires": { + "@lerna/prompt": "4.0.0" + } + }, + "@lerna/output": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/output/-/output-4.0.0.tgz", + "integrity": "sha512-Un1sHtO1AD7buDQrpnaYTi2EG6sLF+KOPEAMxeUYG5qG3khTs2Zgzq5WE3dt2N/bKh7naESt20JjIW6tBELP0w==", + "dev": true, + "requires": { + "npmlog": "^4.1.2" + } + }, + "@lerna/pack-directory": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-4.0.0.tgz", + "integrity": "sha512-NJrmZNmBHS+5aM+T8N6FVbaKFScVqKlQFJNY2k7nsJ/uklNKsLLl6VhTQBPwMTbf6Tf7l6bcKzpy7aePuq9UiQ==", + "dev": true, + "requires": { + "@lerna/get-packed": "4.0.0", + "@lerna/package": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "npm-packlist": "^2.1.4", + "npmlog": "^4.1.2", + "tar": "^6.1.0", + "temp-write": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + } + } + }, + "@lerna/package": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/package/-/package-4.0.0.tgz", + "integrity": "sha512-l0M/izok6FlyyitxiQKr+gZLVFnvxRQdNhzmQ6nRnN9dvBJWn+IxxpM+cLqGACatTnyo9LDzNTOj2Db3+s0s8Q==", + "dev": true, + "requires": { + "load-json-file": "^6.2.0", + "npm-package-arg": "^8.1.0", + "write-pkg": "^4.0.0" + } + }, + "@lerna/package-graph": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-4.0.0.tgz", + "integrity": "sha512-QED2ZCTkfXMKFoTGoccwUzjHtZMSf3UKX14A4/kYyBms9xfFsesCZ6SLI5YeySEgcul8iuIWfQFZqRw+Qrjraw==", + "dev": true, + "requires": { + "@lerna/prerelease-id-from-version": "4.0.0", + "@lerna/validation-error": "4.0.0", + "npm-package-arg": "^8.1.0", + "npmlog": "^4.1.2", + "semver": "^7.3.4" + } + }, + "@lerna/prerelease-id-from-version": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-4.0.0.tgz", + "integrity": "sha512-GQqguzETdsYRxOSmdFZ6zDBXDErIETWOqomLERRY54f4p+tk4aJjoVdd9xKwehC9TBfIFvlRbL1V9uQGHh1opg==", + "dev": true, + "requires": { + "semver": "^7.3.4" + } + }, + "@lerna/profiler": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/profiler/-/profiler-4.0.0.tgz", + "integrity": "sha512-/BaEbqnVh1LgW/+qz8wCuI+obzi5/vRE8nlhjPzdEzdmWmZXuCKyWSEzAyHOJWw1ntwMiww5dZHhFQABuoFz9Q==", + "dev": true, + "requires": { + "fs-extra": "^9.1.0", + "npmlog": "^4.1.2", + "upath": "^2.0.1" + } + }, + "@lerna/project": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-4.0.0.tgz", + "integrity": "sha512-o0MlVbDkD5qRPkFKlBZsXZjoNTWPyuL58564nSfZJ6JYNmgAptnWPB2dQlAc7HWRZkmnC2fCkEdoU+jioPavbg==", + "dev": true, + "requires": { + "@lerna/package": "4.0.0", + "@lerna/validation-error": "4.0.0", + "cosmiconfig": "^7.0.0", + "dedent": "^0.7.0", + "dot-prop": "^6.0.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.2", + "load-json-file": "^6.2.0", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "resolve-from": "^5.0.0", + "write-json-file": "^4.3.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@lerna/prompt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-4.0.0.tgz", + "integrity": "sha512-4Ig46oCH1TH5M7YyTt53fT6TuaKMgqUUaqdgxvp6HP6jtdak6+amcsqB8YGz2eQnw/sdxunx84DfI9XpoLj4bQ==", + "dev": true, + "requires": { + "inquirer": "^7.3.3", + "npmlog": "^4.1.2" + } + }, + "@lerna/publish": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-4.0.0.tgz", + "integrity": "sha512-K8jpqjHrChH22qtkytA5GRKIVFEtqBF6JWj1I8dWZtHs4Jywn8yB1jQ3BAMLhqmDJjWJtRck0KXhQQKzDK2UPg==", + "dev": true, + "requires": { + "@lerna/check-working-tree": "4.0.0", + "@lerna/child-process": "4.0.0", + "@lerna/collect-updates": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/describe-ref": "4.0.0", + "@lerna/log-packed": "4.0.0", + "@lerna/npm-conf": "4.0.0", + "@lerna/npm-dist-tag": "4.0.0", + "@lerna/npm-publish": "4.0.0", + "@lerna/otplease": "4.0.0", + "@lerna/output": "4.0.0", + "@lerna/pack-directory": "4.0.0", + "@lerna/prerelease-id-from-version": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/pulse-till-done": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/validation-error": "4.0.0", + "@lerna/version": "4.0.0", + "fs-extra": "^9.1.0", + "libnpmaccess": "^4.0.1", + "npm-package-arg": "^8.1.0", + "npm-registry-fetch": "^9.0.0", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "p-pipe": "^3.1.0", + "pacote": "^11.2.6", + "semver": "^7.3.4" + }, + "dependencies": { + "make-fetch-happen": { + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", + "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", + "dev": true, + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "npm-registry-fetch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz", + "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==", + "dev": true, + "requires": { + "@npmcli/ci-detect": "^1.0.0", + "lru-cache": "^6.0.0", + "make-fetch-happen": "^8.0.9", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + } + } + } + }, + "@lerna/pulse-till-done": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-4.0.0.tgz", + "integrity": "sha512-Frb4F7QGckaybRhbF7aosLsJ5e9WuH7h0KUkjlzSByVycxY91UZgaEIVjS2oN9wQLrheLMHl6SiFY0/Pvo0Cxg==", + "dev": true, + "requires": { + "npmlog": "^4.1.2" + } + }, + "@lerna/query-graph": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-4.0.0.tgz", + "integrity": "sha512-YlP6yI3tM4WbBmL9GCmNDoeQyzcyg1e4W96y/PKMZa5GbyUvkS2+Jc2kwPD+5KcXou3wQZxSPzR3Te5OenaDdg==", + "dev": true, + "requires": { + "@lerna/package-graph": "4.0.0" + } + }, + "@lerna/resolve-symlink": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-4.0.0.tgz", + "integrity": "sha512-RtX8VEUzqT+uLSCohx8zgmjc6zjyRlh6i/helxtZTMmc4+6O4FS9q5LJas2uGO2wKvBlhcD6siibGt7dIC3xZA==", + "dev": true, + "requires": { + "fs-extra": "^9.1.0", + "npmlog": "^4.1.2", + "read-cmd-shim": "^2.0.0" + } + }, + "@lerna/rimraf-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-4.0.0.tgz", + "integrity": "sha512-QNH9ABWk9mcMJh2/muD9iYWBk1oQd40y6oH+f3wwmVGKYU5YJD//+zMiBI13jxZRtwBx0vmBZzkBkK1dR11cBg==", + "dev": true, + "requires": { + "@lerna/child-process": "4.0.0", + "npmlog": "^4.1.2", + "path-exists": "^4.0.0", + "rimraf": "^3.0.2" + } + }, + "@lerna/run": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-4.0.0.tgz", + "integrity": "sha512-9giulCOzlMPzcZS/6Eov6pxE9gNTyaXk0Man+iCIdGJNMrCnW7Dme0Z229WWP/UoxDKg71F2tMsVVGDiRd8fFQ==", + "dev": true, + "requires": { + "@lerna/command": "4.0.0", + "@lerna/filter-options": "4.0.0", + "@lerna/npm-run-script": "4.0.0", + "@lerna/output": "4.0.0", + "@lerna/profiler": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/timer": "4.0.0", + "@lerna/validation-error": "4.0.0", + "p-map": "^4.0.0" + } + }, + "@lerna/run-lifecycle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-4.0.0.tgz", + "integrity": "sha512-IwxxsajjCQQEJAeAaxF8QdEixfI7eLKNm4GHhXHrgBu185JcwScFZrj9Bs+PFKxwb+gNLR4iI5rpUdY8Y0UdGQ==", + "dev": true, + "requires": { + "@lerna/npm-conf": "4.0.0", + "npm-lifecycle": "^3.1.5", + "npmlog": "^4.1.2" + } + }, + "@lerna/run-topologically": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-4.0.0.tgz", + "integrity": "sha512-EVZw9hGwo+5yp+VL94+NXRYisqgAlj0jWKWtAIynDCpghRxCE5GMO3xrQLmQgqkpUl9ZxQFpICgYv5DW4DksQA==", + "dev": true, + "requires": { + "@lerna/query-graph": "4.0.0", + "p-queue": "^6.6.2" + } + }, + "@lerna/symlink-binary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-4.0.0.tgz", + "integrity": "sha512-zualodWC4q1QQc1pkz969hcFeWXOsVYZC5AWVtAPTDfLl+TwM7eG/O6oP+Rr3fFowspxo6b1TQ6sYfDV6HXNWA==", + "dev": true, + "requires": { + "@lerna/create-symlink": "4.0.0", + "@lerna/package": "4.0.0", + "fs-extra": "^9.1.0", + "p-map": "^4.0.0" + } + }, + "@lerna/symlink-dependencies": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-4.0.0.tgz", + "integrity": "sha512-BABo0MjeUHNAe2FNGty1eantWp8u83BHSeIMPDxNq0MuW2K3CiQRaeWT3EGPAzXpGt0+hVzBrA6+OT0GPn7Yuw==", + "dev": true, + "requires": { + "@lerna/create-symlink": "4.0.0", + "@lerna/resolve-symlink": "4.0.0", + "@lerna/symlink-binary": "4.0.0", + "fs-extra": "^9.1.0", + "p-map": "^4.0.0", + "p-map-series": "^2.1.0" + } + }, + "@lerna/timer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-4.0.0.tgz", + "integrity": "sha512-WFsnlaE7SdOvjuyd05oKt8Leg3ENHICnvX3uYKKdByA+S3g+TCz38JsNs7OUZVt+ba63nC2nbXDlUnuT2Xbsfg==", + "dev": true + }, + "@lerna/validation-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-4.0.0.tgz", + "integrity": "sha512-1rBOM5/koiVWlRi3V6dB863E1YzJS8v41UtsHgMr6gB2ncJ2LsQtMKlJpi3voqcgh41H8UsPXR58RrrpPpufyw==", + "dev": true, + "requires": { + "npmlog": "^4.1.2" + } + }, + "@lerna/version": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-4.0.0.tgz", + "integrity": "sha512-otUgiqs5W9zGWJZSCCMRV/2Zm2A9q9JwSDS7s/tlKq4mWCYriWo7+wsHEA/nPTMDyYyBO5oyZDj+3X50KDUzeA==", + "dev": true, + "requires": { + "@lerna/check-working-tree": "4.0.0", + "@lerna/child-process": "4.0.0", + "@lerna/collect-updates": "4.0.0", + "@lerna/command": "4.0.0", + "@lerna/conventional-commits": "4.0.0", + "@lerna/github-client": "4.0.0", + "@lerna/gitlab-client": "4.0.0", + "@lerna/output": "4.0.0", + "@lerna/prerelease-id-from-version": "4.0.0", + "@lerna/prompt": "4.0.0", + "@lerna/run-lifecycle": "4.0.0", + "@lerna/run-topologically": "4.0.0", + "@lerna/validation-error": "4.0.0", + "chalk": "^4.1.0", + "dedent": "^0.7.0", + "load-json-file": "^6.2.0", + "minimatch": "^3.0.4", + "npmlog": "^4.1.2", + "p-map": "^4.0.0", + "p-pipe": "^3.1.0", + "p-reduce": "^2.1.0", + "p-waterfall": "^2.1.1", + "semver": "^7.3.4", + "slash": "^3.0.0", + "temp-write": "^4.0.0", + "write-json-file": "^4.3.0" + } + }, + "@lerna/write-log-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-4.0.0.tgz", + "integrity": "sha512-XRG5BloiArpXRakcnPHmEHJp+4AtnhRtpDIHSghmXD5EichI1uD73J7FgPp30mm2pDRq3FdqB0NbwSEsJ9xFQg==", + "dev": true, + "requires": { + "npmlog": "^4.1.2", + "write-file-atomic": "^3.0.3" + }, + "dependencies": { + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@npmcli/ci-detect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz", + "integrity": "sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==", + "dev": true + }, + "@npmcli/git": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz", + "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==", + "dev": true, + "requires": { + "@npmcli/promise-spawn": "^1.3.2", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@npmcli/installed-package-contents": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", + "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", + "dev": true, + "requires": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@npmcli/node-gyp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz", + "integrity": "sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==", + "dev": true + }, + "@npmcli/promise-spawn": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz", + "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==", + "dev": true, + "requires": { + "infer-owner": "^1.0.4" + } + }, + "@npmcli/run-script": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.5.tgz", + "integrity": "sha512-NQspusBCpTjNwNRFMtz2C5MxoxyzlbuJ4YEhxAKrIonTiirKDtatsZictx9RgamQIx6+QuHMNmPl0wQdoESs9A==", + "dev": true, + "requires": { + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", + "infer-owner": "^1.0.4", + "node-gyp": "^7.1.0", + "read-package-json-fast": "^2.0.1" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + } + } + }, + "@octokit/auth-token": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz", + "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "dev": true, + "requires": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + } + } + }, + "@octokit/graphql": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", + "dev": true, + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", + "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==", + "dev": true + }, + "@octokit/plugin-enterprise-rest": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", + "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", + "dev": true + }, + "@octokit/plugin-paginate-rest": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", + "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", + "dev": true, + "requires": { + "@octokit/types": "^6.18.0" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.4.1.tgz", + "integrity": "sha512-Nx0g7I5ayAYghsLJP4Q1Ch2W9jYYM0FlWWWZocUro8rNxVwuZXGfFd7Rcqi9XDWepSXjg1WByiNJnZza2hIOvQ==", + "dev": true, + "requires": { + "@octokit/types": "^6.18.1", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", + "dev": true, + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + } + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "18.6.7", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.6.7.tgz", + "integrity": "sha512-Kn6WrI2ZvmAztdx+HEaf88RuJn+LK72S8g6OpciE4kbZddAN84fu4fiPGxcEu052WmqKVnA/cnQsbNlrYC6rqQ==", + "dev": true, + "requires": { + "@octokit/core": "^3.5.0", + "@octokit/plugin-paginate-rest": "^2.6.2", + "@octokit/plugin-request-log": "^1.0.2", + "@octokit/plugin-rest-endpoint-methods": "5.4.1" + } + }, + "@octokit/types": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", + "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^8.2.1" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "requires": {} + }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "agentkeepalive": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", + "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "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" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "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 + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", + "dev": true + }, + "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" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", + "dev": true + }, + "byte-size": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz", + "integrity": "sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A==", + "dev": true + }, + "cacache": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "cmd-shim": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-4.1.0.tgz", + "integrity": "sha512-lb9L7EM4I/ZRVuljLPEtUJOP+xiQVknZ4ZMpMgEp4JzNldPb27HU03hi6K1/6CoIuit/Zm/LQXySErFeXxDprw==", + "dev": true, + "requires": { + "mkdirp-infer-owner": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + }, + "dependencies": { + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "conventional-changelog-angular": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", + "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-core": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.3.tgz", + "integrity": "sha512-MwnZjIoMRL3jtPH5GywVNqetGILC7g6RQFvdb8LRU/fA/338JbeWAku3PZ8yQ+mtVRViiISqJlb0sOz0htBZig==", + "dev": true, + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + } + } + }, + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", + "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==", + "dev": true, + "requires": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", + "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0", + "trim-off-newlines": "^1.0.0" + } + }, + "conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "requires": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true + }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + } + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "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" + } + }, + "filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": 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 + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "get-pkg-repo": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.1.2.tgz", + "integrity": "sha512-/FjamZL9cBYllEbReZkxF2IMh80d8TJoC4e3bmLNif8ibHw95aj0N/tzqK0kZz9eU/3w3dL6lF4fnnX/sDdW3A==", + "dev": true, + "requires": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "meow": "^7.0.0", + "through2": "^2.0.0" + }, + "dependencies": { + "meow": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-raw-commits": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", + "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "requires": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "git-up": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.2.tgz", + "integrity": "sha512-kbuvus1dWQB2sSW4cbfTeGpCMd8ge9jx9RKnhXhuJ7tnvT+NIrTVfYZxjtflZddQYcmdOTlkAcjmx7bor+15AQ==", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "parse-url": "^5.0.0" + } + }, + "git-url-parse": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.5.0.tgz", + "integrity": "sha512-TZYSMDeM37r71Lqg1mbnMlOqlHd7BSij9qN7XwTkRqSAYFMihGLGhfHwgqQob3GUhEneKnV4nskN9rbQw2KGxA==", + "dev": true, + "requires": { + "git-up": "^4.0.0" + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "requires": { + "ini": "^1.3.2" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "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" + } + }, + "globals": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "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-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "husky": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", + "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "init-package-json": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-2.0.3.tgz", + "integrity": "sha512-tk/gAgbMMxR6fn1MgMaM1HpU1ryAmBWWitnxG5OhuNXeX0cbpbgV5jA4AIpQJVNoyOfOevTtO6WX+rPs+EFqaQ==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^8.1.2", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "^3.0.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "read-package-json": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-3.0.1.tgz", + "integrity": "sha512-aLcPqxovhJTVJcsnROuuzQvv6oziQx4zd3JvG0vGCL5MjTONUc4uJ90zCBC6R7W7oUKBNoR/F8pkyfVwlbxqng==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^3.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + } + } + }, + "inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "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-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-ssh": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz", + "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==", + "dev": true, + "requires": { + "protocols": "^1.1.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "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 + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "lerna": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-4.0.0.tgz", + "integrity": "sha512-DD/i1znurfOmNJb0OBw66NmNqiM8kF6uIrzrJ0wGE3VNdzeOhz9ziWLYiRaZDGGwgbcjOo6eIfcx9O5Qynz+kg==", + "dev": true, + "requires": { + "@lerna/add": "4.0.0", + "@lerna/bootstrap": "4.0.0", + "@lerna/changed": "4.0.0", + "@lerna/clean": "4.0.0", + "@lerna/cli": "4.0.0", + "@lerna/create": "4.0.0", + "@lerna/diff": "4.0.0", + "@lerna/exec": "4.0.0", + "@lerna/import": "4.0.0", + "@lerna/info": "4.0.0", + "@lerna/init": "4.0.0", + "@lerna/link": "4.0.0", + "@lerna/list": "4.0.0", + "@lerna/publish": "4.0.0", + "@lerna/run": "4.0.0", + "@lerna/version": "4.0.0", + "import-local": "^3.0.2", + "npmlog": "^4.1.2" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "libnpmaccess": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-4.0.3.tgz", + "integrity": "sha512-sPeTSNImksm8O2b6/pf3ikv4N567ERYEpeKRPSmqlNt1dTZbvgpJIzg5vAhXHpw2ISBsELFRelk0jEahj1c6nQ==", + "dev": true, + "requires": { + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0" + }, + "dependencies": { + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "libnpmpublish": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-4.0.2.tgz", + "integrity": "sha512-+AD7A2zbVeGRCFI2aO//oUmapCwy7GHqPXFJh3qpToSRNU+tXKJ2YFUgjt04LPPAf2dlEH95s6EhIHM1J7bmOw==", + "dev": true, + "requires": { + "normalize-package-data": "^3.0.2", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0", + "semver": "^7.1.3", + "ssri": "^8.0.1" + }, + "dependencies": { + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + } + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.1.2.tgz", + "integrity": "sha512-6lYpNoA9wGqkL6Hew/4n1H6lRqF3qCsujVT0Oq5Z4hiSAM7S6NksPJ3gnr7A7R52xCtiZMcEUNNQ6d6X5Bvh9w==", + "dev": true, + "requires": { + "chalk": "^4.1.1", + "cli-truncate": "^2.1.0", + "commander": "^7.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "listr2": "^3.8.2", + "log-symbols": "^4.1.0", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + } + }, + "listr2": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.10.0.tgz", + "integrity": "sha512-eP40ZHihu70sSmqFNbNy2NL1YwImmlMmPh9WO5sLmPDleurMHt3n+SwEWNu2kzKScexZnkyFtc1VI0z/TGlmpw==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^1.2.2", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "make-fetch-happen": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.0.3.tgz", + "integrity": "sha512-uZ/9Cf2vKqsSWZyXhZ9wHHyckBrkntgbnqV68Bfe8zZenlf7D6yuGMXvHZQ+jSnzPkjosuNP1HGasj1J4h8OlQ==", + "dev": true, + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + } + } + }, + "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 + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dev": true, + "requires": { + "mime-db": "1.48.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-fetch": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", + "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", + "dev": true, + "requires": { + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + } + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mkdirp-infer-owner": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz", + "integrity": "sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + } + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true + }, + "node-gyp": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", + "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.1.2", + "request": "^2.88.0", + "rimraf": "^2.6.3", + "semver": "^5.7.1", + "tar": "^4.4.12", + "which": "^1.3.1" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "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 + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-install-checks": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz", + "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==", + "dev": true, + "requires": { + "semver": "^7.1.1" + } + }, + "npm-lifecycle": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz", + "integrity": "sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==", + "dev": true, + "requires": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.15", + "node-gyp": "^5.0.2", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-package-arg": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz", + "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "semver": "^7.3.4", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-packlist": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz", + "integrity": "sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz", + "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==", + "dev": true, + "requires": { + "npm-install-checks": "^4.0.0", + "npm-normalize-package-bin": "^1.0.1", + "npm-package-arg": "^8.1.2", + "semver": "^7.3.4" + } + }, + "npm-registry-fetch": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz", + "integrity": "sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==", + "dev": true, + "requires": { + "make-fetch-happen": "^9.0.1", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + } + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-map-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", + "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", + "dev": true + }, + "p-pipe": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", + "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", + "dev": true + }, + "p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + } + }, + "p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true + }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "p-waterfall": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", + "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", + "dev": true, + "requires": { + "p-reduce": "^2.0.0" + } + }, + "pacote": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.5.tgz", + "integrity": "sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg==", + "dev": true, + "requires": { + "@npmcli/git": "^2.1.0", + "@npmcli/installed-package-contents": "^1.0.6", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^1.8.2", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "infer-owner": "^1.0.4", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^2.1.4", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^11.0.0", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^2.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.1.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse-path": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", + "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0", + "qs": "^6.9.4", + "query-string": "^6.13.8" + }, + "dependencies": { + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "parse-url": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.7.tgz", + "integrity": "sha512-CgbjyWT6aOh2oNSUS0cioYQsGysj9hQ2IdbOfeNwq5KOaKM7dOw/yTupiI0cnJhaDHJEIGybPkQz7LF9WNIhyw==", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "normalize-url": "4.5.1", + "parse-path": "^4.0.0", + "protocols": "^1.4.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "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 + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "promzard": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", + "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", + "dev": true, + "requires": { + "read": "1" + } + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "protocols": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", + "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "query-string": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", + "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz", + "integrity": "sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw==", + "dev": true + }, + "read-package-json": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz", + "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "read-package-json-fast": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz", + "integrity": "sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ==", + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "read-package-tree": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "dev": true, + "requires": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "dev": true + }, + "socks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", + "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^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 + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "dev": true + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } + }, + "strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + } + }, + "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" + } + }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true + }, + "temp-write": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/temp-write/-/temp-write-4.0.0.tgz", + "integrity": "sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "is-stream": "^2.0.0", + "make-dir": "^3.0.0", + "temp-dir": "^1.0.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "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" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "uglify-js": { + "version": "3.13.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", + "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", + "dev": true + }, + "umask": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz", + "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util-promisify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz", + "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "write-json-file": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", + "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", + "dev": true, + "requires": { + "detect-indent": "^6.0.0", + "graceful-fs": "^4.1.15", + "is-plain-obj": "^2.0.0", + "make-dir": "^3.0.0", + "sort-keys": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "sort-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", + "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", + "dev": true, + "requires": { + "is-plain-obj": "^2.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } + } + }, + "write-pkg": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz", + "integrity": "sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==", + "dev": true, + "requires": { + "sort-keys": "^2.0.0", + "type-fest": "^0.4.1", + "write-json-file": "^3.2.0" + }, + "dependencies": { + "type-fest": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", + "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", + "dev": true + }, + "write-json-file": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", + "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", + "dev": true, + "requires": { + "detect-indent": "^5.0.0", + "graceful-fs": "^4.1.15", + "make-dir": "^2.1.0", + "pify": "^4.0.1", + "sort-keys": "^2.0.0", + "write-file-atomic": "^2.4.2" + } + } + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..2644942f0 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "root", + "private": true, + "devDependencies": { + "eslint": "^7.29.0", + "husky": "^6.0.0", + "lerna": "^4.0.0", + "lint-staged": "^11.1.2", + "prettier": "^2.3.2" + }, + "scripts": { + "watch-libs": "lerna run watch --no-private --parallel", + "build-libs": "lerna run build --no-private", + "test": "lerna run test", + "bootstrap": "lerna bootstrap", + "build:prod": "lerna run build:prod" + } +} diff --git a/pkg/arvo/app/aggregator.hoon b/pkg/arvo/app/aggregator.hoon deleted file mode 100644 index 760a9f16f..000000000 --- a/pkg/arvo/app/aggregator.hoon +++ /dev/null @@ -1,838 +0,0 @@ -:: aggregator: Azimuth L2 roll aggregator -:: -:: general flow is as described below, to ensure transactions actually go -:: through once we start sending it out, in the dumbest reasonable way. -:: -:: periodic timer fires: -:: if there are no pending l2 txs, do nothing. -:: else kick off tx submission flow: -:: "freeze" pending txs, store alongside nonce, then increment nonce, -:: kick off thread for sending the corresponding l1 tx: -:: if nonce doesn't match on-chain expected nonce, bail. -:: if we can't afford the tx fee, bail. -:: construct, sign, submit the l1 tx. -:: if thread bailed, retry in five minutes. -:: if thread succeeded, retry in five minutes with higher gas price. -:: when retrying, only do so if l2 txs remain in the "frozen" txs group. -:: on %tx diff from naive, remove the matching tx from the frozen group. -:: -::TODO questions: -:: - it's a bit weird how we just assume the raw and tx in raw-tx to match... -:: -/- *aggregator -/+ azimuth, - naive, - lib=naive-transactions, - default-agent, - ethereum, - dbug, - verb -:: -|% -+$ state-0 - $: %0 - :: pending: the next l2 txs to be sent - :: sending: the l2 txs currently sending/awaiting l2 confirmation - :: finding: raw-tx-hash reverse lookup for sending map - :: history: status of l2 txs by ethereum address - :: next-nonce: next l1 nonce to use - :: next-batch: when then next l2 batch will be sent - :: pre: predicted l2 state - :: flush: flag for deriving predicted state - :: - pending=(list pend-tx) - :: - $= sending - %+ map l1-tx-pointer - [next-gas-price=@ud txs=(list raw-tx:naive)] - :: - finding=(map keccak ?(%confirmed %failed l1-tx-pointer)) - history=(jug address:ethereum roller-tx) - next-nonce=(unit @ud) - next-batch=time - pre=^state:naive - flush=? - :: - :: pk: private key to send the roll - :: frequency: time to wait between sending batches (TODO fancier) - :: endpoint: ethereum rpc endpoint to use - :: contract: ethereum contract address - :: chain-id: mainnet, ropsten, local (https://chainid.network/) - :: - pk=@ - frequency=@dr - endpoint=(unit @t) - contract=@ux - chain-id=@ - == -:: -+$ config - $% [%frequency frequency=@dr] - [%setkey pk=@] - [%endpoint endpoint=@t] - [%network net=?(%mainnet %ropsten %local)] - == -:: -+$ action - $% [%submit force=? sig=@ tx=part-tx] - [%cancel sig=@ keccak=@ =l2-tx] - [%commit ~] ::TODO maybe pk=(unit @) later - [%config config] - == -:: -+$ card card:agent:gall -:: -:: TODO: add to config -:: -++ resend-time ~m5 -:: -++ lverb & --- -:: -=| state-0 -=* state - -:: -%- agent:dbug -%+ verb | -^- agent:gall -:: -=< - |_ =bowl:gall - +* this . - do ~(. +> bowl) - def ~(. (default-agent this %|) bowl) - :: - ++ on-init - ^- (quip card _this) - =. frequency ~h1 - =. contract naive:local-contracts:azimuth - =. chain-id chain-id:local-contracts:azimuth - =^ card next-batch set-timer - :_ this - :~ card - [%pass /azimuth-txs %agent [our.bowl %azimuth] %watch /txs] - == - :: - ++ on-save !>(state) - ++ on-load - |= old=vase - ^- (quip card _this) - [~ this(state !<(state-0 old))] - :: - ++ on-poke - |= [=mark =vase] - ^- (quip card _this) - =^ cards state - ?+ mark (on-poke:def mark vase) - %aggregator-action - =+ !<(poke=action vase) - (on-action:do poke) - == - [cards this] - :: +on-peek: scry paths - :: - :: /x/pending -> %noun (list pend-tx) - :: /x/pending/[~ship] -> %noun (list pend-tx) - :: /x/pending/[0xadd.ress] -> %noun (list pend-tx) - :: /x/tx/[0xke.ccak]/status -> %noun tx-status - :: /x/nonce/[~ship]/[proxy] -> %noun (unit @) - :: /x/spawned/[~ship] -> %noun (list [ship address]) - :: /x/next-batch -> %atom time - :: /x/point/[~ship] -> %noun point:naive - :: /x/points/[0xadd.ress] -> %noun (list [ship point:naive]) - :: /x/config -> %noun config - :: - ++ on-peek - |= =path - ^- (unit (unit cage)) - |^ - ?+ path ~ - [%x %pending ~] ``noun+!>(pending) - [%x %pending @ ~] (pending-by i.t.t.path) - [%x %tx @ %status ~] (status i.t.t.path) - [%x %history @ ~] (history i.t.t.path) - [%x %nonce @ @ ~] (nonce i.t.t.path i.t.t.t.path) - [%x %spawned @ ~] (spawned i.t.t.path) - [%x %next-batch ~] ``noun+!>(next-batch) - [%x %point @ ~] (point i.t.t.path) - [%x %points @ ~] (points i.t.t.path) - [%x %config ~] config - == - :: - ++ pending-by - |= wat=@t - ?~ who=(slaw %p wat) - :: by-address - :: - ?~ wer=(slaw %ux wat) - [~ ~] - =; pending=(list pend-tx) - ``noun+!>(pending) - %+ skim pending - |= pend-tx - =(u.wer (get-l1-address tx.raw-tx pre)) - :: by-ship - :: - =; pending=(list pend-tx) - ``noun+!>(pending) - %+ skim pending - |= pend-tx - =(u.who ship.from.tx.raw-tx) - :: - ++ status - |= wat=@t - ?~ keccak=(slaw %ux wat) - [~ ~] - :+ ~ ~ - :- %noun - !> ^- tx-status - ?^ status=(~(get by finding) u.keccak) - ?@ u.status [u.status ~] - [%sending status] - ::TODO potentially slow! - =; known=? - [?:(known %pending %unknown) ~] - %+ lien pending - |= pend-tx - =(u.keccak (hash-tx raw.raw-tx)) - :: - ++ history - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list roller-tx) - ?~ addr=(slaw %ux wat) ~ - %~ tap in - (~(get ju ^history) u.addr) - :: - ++ nonce - |= [who=@t proxy=@t] - ?~ who=(slaw %p who) - [~ ~] - ?. ?=(proxy:naive proxy) - [~ ~] - :+ ~ ~ - :- %noun - !> ^- (unit @) - ?~ point=(get:orm:naive points.pre u.who) - ~ - =< `nonce - (proxy-from-point:naive proxy u.point) - :: - ++ spawned - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list [=^ship =address:ethereum]) - ?~ star=(slaw %p wat) ~ - =/ range - %+ lot:orm:naive points.pre - :: range exclusive [star next-star-first-planet-] - :: TODO: make range inclusive ([first-planet last-planet])? - :: - [`u.star `(cat 3 +(u.star) 0x1)] - %+ turn (tap:orm:naive range) - |= [=ship =point:naive] - ^- [=^ship =address:ethereum] - :- ship - address:(proxy-from-point:naive %own point) - :: - ++ point - |= wat=@t - ?~ ship=(rush wat ;~(pfix sig fed:ag)) - ``noun+!>(*(unit point:naive)) - ``noun+!>((get:orm:naive points.pre u.ship)) - :: - ++ points - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list [ship point:naive]) - ?~ addr=(slaw %ux wat) - ~ - %~ tap in - (~(get ju owners.pre) u.addr) - :: - ++ config - :+ ~ ~ - :- %noun - !> ^- roller-config - :* next-batch - frequency - resend-time - contract - chain-id - == - -- - :: - ++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card _this) - ?+ wire (on-arvo:def wire sign-arvo) - [%timer ~] - ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) - %wake =^(cards state on-timer:do [cards this]) - == - :: - [%predict ~] - ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) - %wake - =. state (predicted-state canonical-state):do - `this(flush &) - == - :: - [%resend @ @ ~] - =/ [address=@ux nonce=@ud] - [(slav %ux i.t.wire) (rash i.t.t.wire dem)] - ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) - %wake [(send-roll:do address nonce) this] - == - == - :: - ++ on-fail - |= [=term =tang] - ::TODO if crashed during timer, set new timer? how to detect? - (on-fail:def term tang) - :: - ++ on-watch on-watch:def - ++ on-leave on-leave:def - ++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card _this) - |^ - ?+ wire (on-agent:def wire sign) - [%send @ @ *] (send-batch i.t.wire i.t.t.wire sign) - [%azimuth-txs ~] (azimuth-update sign) - [%nonce ~] (nonce sign) - == - :: - ++ send-batch - |= [address=@t nonce=@t =sign:agent:gall] - ^- (quip card _this) - =/ [address=@ux nonce=@ud] - [(slav %ux address) (rash nonce dem)] - ?- -.sign - %poke-ack - ?~ p.sign - %- (slog leaf+"Send batch thread started successfully" ~) - [~ this] - %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) - :_ this - [(leave:spider:do wire)]~ - :: - %watch-ack - ?~ p.sign - [~ this] - =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to thread" - %- (slog tank u.p.sign) - [~ this] - :: - %kick - [~ this] - :: - %fact - ?+ p.cage.sign (on-agent:def wire sign) - %thread-fail - =+ !<([=term =tang] q.cage.sign) - %- (slog leaf+"{(trip dap.bowl)} failed" leaf+ tang) - =^ cards state - (on-batch-result:do address nonce %.n^'thread failed') - [cards this] - :: - %thread-done - =+ !<(result=(each @ud @t) q.cage.sign) - =^ cards state - (on-batch-result:do address nonce result) - [cards this] - == - == - :: - ++ azimuth-update - |= =sign:agent:gall - ^- (quip card _this) - ?+ -.sign [~ this] - %watch-ack - ?~ p.sign [~ this] - =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to %azimuth" - %- (slog tank u.p.sign) - [~ this] - :: - %fact - ?+ p.cage.sign (on-agent:def wire sign) - %naive-diffs - =+ !<(=diff:naive q.cage.sign) - =^ cards state - (on-naive-diff:do diff) - [cards this] - :: - %naive-state - ~& > %received-naive-state - :- ~ - :: cache naive state, received upon innitializing subscription - :: this assumes that /app/azimuth has already processed eth data - :: - =. state (predicted-state:do !<(^state:naive q.cage.sign)) - this - == - == - :: - ++ nonce - |= =sign:agent:gall - ^- (quip card _this) - ?- -.sign - %poke-ack - ?~ p.sign - %- (slog leaf+"Nonce thread started successfully" ~) - [~ this] - %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) - :_ this - [(leave:spider:do wire)]~ - :: - %watch-ack - ?~ p.sign - [~ this] - =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to thread" - %- (slog tank u.p.sign) - [~ this] - :: - %kick - [~ this] - :: - %fact - ?+ p.cage.sign (on-agent:def wire sign) - %thread-fail - =+ !<([=term =tang] q.cage.sign) - %- (slog leaf+"{(trip dap.bowl)} failed" leaf+ tang) - [~ this] - :: - %thread-done - =+ !<(nonce=@ud q.cage.sign) - [~ this(next-nonce `nonce)] - == - == - -- - -- -:: -|_ =bowl:gall -::TODO /lib/sys.hoon? -++ sys - |% - ++ b - |% - ++ wait - |= [=wire =time] - ^- card - [%pass wire %arvo %b %wait time] - -- - -- -::TODO /lib/spider.hoon? -++ spider - |% - ++ start-thread - |= [=wire thread=term arg=vase] - ^- (list card) - =/ tid=@ta (rap 3 thread '--' (scot %uv eny.bowl) ~) - =/ args [~ `tid thread arg] - :~ [%pass wire %agent [our.bowl %spider] %watch /thread-result/[tid]] - [%pass wire %agent [our.bowl %spider] %poke %spider-start !>(args)] - == - :: - ++ leave - |= =path - ^- card - [%pass path %agent [our.bowl %spider] %leave ~] - -- -:: -++ hash-tx keccak-256:keccak:crypto -:: -++ hash-raw-tx - |= =raw-tx:naive - ^- @ux - (hash-tx raw.raw-tx) -:: -++ part-tx-to-full - |= =part-tx - ^- [octs tx:naive] - ?- -.part-tx - %raw - ?~ batch=(parse-raw-tx:naive q.raw.part-tx) - ~& %parse-failed - :: TODO: maybe return a unit if parsing fails? - :: - !! - [raw tx]:-.u.batch - :: - %don [(gen-tx-octs:lib +.part-tx) +.part-tx] - %ful +.part-tx - == -:: +canonical-state: load current l2 state from /app/azimuth -:: -++ canonical-state - .^ ^state:naive - %gx - (scot %p our.bowl) - %azimuth - (scot %da now.bowl) - /nas/noun - == -:: +predicted-state -:: -:: derives predicted state from pending/sending txs and -:: canonical state, discarding invalid txs in the process. -:: -++ predicted-state - |= nas=^state:naive - ^+ state - =. pre.state nas - |^ - =^ nes state apply-sending - =^ nep state (update-txs pending %pending) - %_ state - sending nes - pending nep - == - :: - ++ apply-sending - =| valid=_sending - =+ sending=~(tap by sending) - |- ^+ [valid state] - ?~ sending [valid state] - :: - =* key p.i.sending - =* val q.i.sending - =^ new-valid state - %+ update-txs - (turn txs.val |=(=raw-tx:naive [| 0x0 raw-tx])) - %sending - =. valid - %+ ~(put by valid) key - val(txs (turn new-valid (cork tail tail))) - $(sending t.sending) - :: - ++ update-txs - |= [txs=(list pend-tx) type=?(%pending %sending)] - =/ valid=_txs ~ - =| local=(set keccak) - |- ^+ [valid state] - ?~ txs [valid state] - :: - =* tx i.txs - =/ hash=@ux (hash-raw-tx raw-tx.tx) - ?: (~(has in local) hash) - :: if tx was already seen here, skip - :: - $(txs t.txs) - =^ gud=? pre.state - (try-apply pre.state [force raw-tx]:tx) - =? valid gud (snoc valid tx) - =? finding.state !gud - (~(put by finding.state) [hash %failed]) - =? history.state !gud - =/ =roller-tx - [[type ~] hash (l2-tx +<.tx.raw-tx.tx)] - %. [address.tx roller-tx(status [%failed ~])] - ~(put ju (~(del ju history.state) address.tx roller-tx)) - $(txs t.txs, local (~(put in local) hash)) - :: - ++ try-apply - |= [nas=^state:naive force=? =raw-tx:naive] - ^- [success=? _nas] - =/ chain-t=@t (ud-to-ascii:naive chain-id) - ?. (verify-sig-and-nonce:naive verifier:lib chain-t nas raw-tx) - ~& [%verify-sig-and-nonce %failed] - [force nas] - =^ * points.nas - (increment-nonce:naive nas from.tx.raw-tx) - ?~ nex=(receive-tx:naive nas tx.raw-tx) - [force nas] - [& +.u.nex] - -- -:: -++ get-l1-address - |= [=tx:naive nas=^state:naive] - ^- address:ethereum - ?~ point=(get:orm:naive points.nas ship.from.tx) - !! - =< address - (proxy-from-point:naive proxy.from.tx u.point) -:: -++ on-action - |= =action - ^- (quip card _state) - ?- -.action - %commit on-timer - %config (on-config +.action) - %cancel (cancel-tx +.action) - %submit (take-tx force.action sig.action (part-tx-to-full tx.action)) - == -:: -++ on-config - |= =config - ^- (quip card _state) - ?- -.config - %frequency [~ state(frequency frequency.config)] - %endpoint [~ state(endpoint `endpoint.config)] - :: - %network - :- ~ - =/ [contract=@ux chain-id=@] - =< [naive chain-id] - =, azimuth - ?- net.config - %mainnet mainnet-contracts - %ropsten ropsten-contracts - %local local-contracts - == - state(contract contract, chain-id chain-id) - :: - %setkey - ?~ pk=(de:base16:mimes:html pk.config) - `state - [(get-nonce q.u.pk) state(pk q.u.pk)] - == -:: TODO: move address to state? -:: -++ get-address - ^- address:ethereum - (address-from-prv:key:ethereum pk) -:: +cancel-tx: cancel a pending transaction -:: -++ cancel-tx - |= [sig=@ =keccak =l2-tx] - ^- (quip card _state) - ?^ status=(~(get by finding) keccak) - ~? lverb [dap.bowl %tx-not-pending status+u.status] - [~ state] - :: "cancel: 0x1234abcd" - :: - =/ message=octs - %: cad:naive 3 - 8^'cancel: ' - :: - =; hash=@t - (met 3 hash)^hash - (crip "0x{((x-co:co 20) keccak)}") - :: - ~ - == - ?~ addr=(verify-sig sig message) - ~? lverb [dap.bowl %cancel-sig-fail] - [~ state] - =. history - %+ ~(del ju history) u.addr - [[%pending ~] keccak l2-tx] - =. pending - %+ skip pending - |= pend-tx - =(keccak (hash-raw-tx raw-tx)) - [~ state] -:: TODO: move to /lib/naive-transactions -:: -++ verify-sig - |= [sig=@ txdata=octs] - ^- (unit address:naive) - |^ - :: Reversed of the usual r-s-v order because Ethereum integers are - :: big-endian - :: - =^ v sig (take 3) - =^ s sig (take 3 32) - =^ r sig (take 3 32) - :: In Ethereum, v is generally 27 + recid, and verifier expects a - :: recid. Old versions of geth used 0 + recid, so most software - :: now supports either format. See: - :: - :: https://github.com/ethereum/go-ethereum/issues/2053 - :: - =? v (gte v 27) (sub v 27) - (verifier:lib txdata v r s) - :: - ++ take - |= =bite - [(end bite sig) (rsh bite sig)] - -- -:: +take-tx: accept submitted l2 tx into the :pending list -:: -++ take-tx - |= [force=? =raw-tx:naive] - ^- (quip card _state) - =/ =address:ethereum - (get-l1-address tx.raw-tx pre) - =/ hash=@ux (hash-raw-tx raw-tx) - :: TODO: what if this hash/tx is already in the history? - :: check in finding that hash doesn't exist ? - :: - :: =/ not-sent=? !(~(has by finding) hash) - :: =? pending not-sent - =. pending - (snoc pending [force address raw-tx]) - :: =? history not-sent - =. history - %+ ~(put ju history) address - [[%pending ~] hash (l2-tx +<.tx.raw-tx)] - :: ?. not-sent ~& "skip" [~ state] - :: toggle flush flag - :: - :_ state(flush ?:(flush | &)) - ?. flush ~ - :: derive predicted state in 5m. - :: - [(wait:b:sys /predict (add ~m5 now.bowl))]~ -:: +set-timer: %wait until next whole :frequency -:: -++ set-timer - ^- [=card =time] - =+ time=(mul +((div now.bowl frequency)) frequency) - [(wait:b:sys /timer time) time] -:: +on-timer: every :frequency, freeze :pending txs roll and start sending it -:: -++ on-timer - ^- (quip card _state) - =. state (predicted-state canonical-state) - =^ cards state - ?: =(~ pending) [~ state] - ?~ next-nonce - ~&([dap.bowl %no-nonce] [~ state]) - =/ nonce=@ud u.next-nonce - =: pending ~ - flush & - next-nonce `+(u.next-nonce) - :: - sending - %+ ~(put by sending) - [get-address nonce] - [0 (turn pending (cork tail tail))] - :: - finding - %- ~(gas by finding) - %+ turn pending - |= pend-tx - (hash-raw-tx raw-tx)^[address nonce] - :: - history - %+ roll pending - |= [pend-tx hist=_history] - =/ tx=roller-tx - :+ [%pending ~] - (hash-raw-tx raw-tx) - (l2-tx +<.tx.raw-tx) - %+ ~(put ju (~(del ju hist) address tx)) - address - tx(status [%sending ~]) - == - [(send-roll get-address nonce) state] - =^ card next-batch set-timer - [[card cards] state] -:: +get-nonce: retrieves the latest nonce -:: -++ get-nonce - |= pk=@ - ^- (list card) - ?~ endpoint ~&([dap.bowl %no-endpoint] ~) - (start-thread:spider /nonce [%aggregator-nonce !>([u.endpoint pk])]) -:: -:: +send-roll: start thread to submit roll from :sending to l1 -:: -++ send-roll - |= [=address:ethereum nonce=@ud] - ^- (list card) - :: if this nonce isn't in the sending queue anymore, it's done - :: - ?. (~(has by sending) [address nonce]) - ~? lverb [dap.bowl %done-sending [address nonce]] - ~ - :: start the thread, passing in the l2 txs to use - :: - ?~ endpoint ~&([dap.bowl %no-endpoint] ~) - ::TODO should go ahead and set resend timer in case thread hangs, or nah? - %+ start-thread:spider - /send/(scot %ux address)/(scot %ud nonce) - :- %aggregator-send - !> ^- rpc-send-roll - :* u.endpoint - contract - chain-id - pk - nonce - (~(got by sending) [address nonce]) - == -:: +on-batch-result: await resend after thread success or failure -:: -++ on-batch-result - |= [=address:ethereum nonce=@ud result=(each @ud @t)] - ^- (quip card _state) - :: update gas price for this tx in state - :: - =? sending ?=(%& -.result) - %+ ~(jab by sending) [address nonce] - (cork tail (lead p.result)) - :: print error if there was one - :: - ~? ?=(%| -.result) [dap.bowl %send-error p.result] - :: resend the l1 tx in five minutes - :: - :_ state - :_ ~ - %+ wait:b:sys - /resend/(scot %ux address)/(scot %ud nonce) - (add resend-time now.bowl) -:: +on-naive-diff: process l2 tx confirmations -:: -++ on-naive-diff - |= =diff:naive - ^- (quip card _state) - ?. ?=(%tx -.diff) - [~ state] - =/ =keccak (hash-raw-tx raw-tx.diff) - ?~ wer=(~(get by finding) keccak) - [~ state] - :: if we had already seen the tx, no-op - :: - ?@ u.wer - ~? &(?=(%confirmed u.wer) ?=(~ err.diff)) - [dap.bowl %weird-double-confirm from.tx.raw-tx.diff] - [~ state] - =* nonce nonce.u.wer - :: remove the tx from the sending map - :: - =. sending - ?~ sen=(~(get by sending) [get-address nonce]) - ~& [dap.bowl %weird-double-remove] - sending - ?~ nin=(find [raw-tx.diff]~ txs.u.sen) - ~& [dap.bowl %weird-unknown] - sending - =. txs.u.sen (oust [u.nin 1] txs.u.sen) - ?~ txs.u.sen - ~? lverb [dap.bowl %done-with-nonce [get-address nonce]] - (~(del by sending) [get-address nonce]) - (~(put by sending) [get-address nonce] u.sen) - :: update the finding map with the new status - :: - =. finding - %+ ~(put by finding) keccak - ?~ err.diff %confirmed - :: if we kept the forced flag around for longer, we could notify of - :: unexpected tx failures here. would that be useful? probably not? - :: ~? !forced [dap.bowl %aggregated-tx-failed-anyway err.diff] - %failed - :: - =. history - =/ tx=roller-tx - :+ [%sending ~] - keccak - (l2-tx +<.tx.raw-tx.diff) - =/ =address:ethereum - (get-l1-address tx.raw-tx.diff pre) - %+ ~(put ju (~(del ju history) address tx)) - address - %_ tx - status ?~(err.diff [%confirmed ~] [%failed ~]) - == - :_ state(flush ?:(flush | &)) - ?. flush ~ - :: derive predicted state in 5m. - :: - [(wait:b:sys /predict (add ~m5 now.bowl))]~ -:: --- diff --git a/pkg/arvo/app/aqua.hoon b/pkg/arvo/app/aqua.hoon index b530003ae..ac4cdb1a6 100644 --- a/pkg/arvo/app/aqua.hoon +++ b/pkg/arvo/app/aqua.hoon @@ -30,7 +30,7 @@ == +$ state-0 $: %0 - pil=pill + pil=$>(%pill pill) assembled=* tym=@da fleet-snaps=(map term fleet) @@ -38,11 +38,7 @@ == :: XX temporarily shadowed, fix and remove :: - +$ pill - $: boot-ova=* - kernel-ova=(list unix-event) - userspace-ova=(list unix-event) - == + +$ pill pill:pill-lib :: +$ fleet [ships=(map ship pier) azi=az-state] +$ pier @@ -86,7 +82,7 @@ =^ cards state ?+ mark ~|([%aqua-bad-mark mark] !!) %aqua-events (poke-aqua-events:ac !<((list aqua-event) vase)) - %pill (poke-pill:ac !<(pill vase)) + %pill (poke-pill:ac !<(pill vase)) %noun (poke-noun:ac !<(* vase)) %azimuth-action (poke-azimuth-action:ac !<(azimuth-action vase)) == @@ -183,7 +179,7 @@ ?. processing-events ..abet-pe =^ ue next-events ~(get to next-events) - =/ poke-arm (mox +47.snap) + =/ poke-arm (mox +23.snap) ?> ?=(%0 -.poke-arm) =/ poke p.poke-arm =. tym (max +(tym) now.hid) @@ -202,20 +198,21 @@ :: ++ peek |= p=* - =/ res (mox +46.snap) + =/ res (mox +22.snap) ?> ?=(%0 -.res) =/ peek p.res =/ pax (path p) ?> ?=([@ @ @ @ *] pax) =. i.t.t.t.pax (scot %da tym) - =/ pek (slum peek [tym pax]) - pek - :: + =/ pek (slum peek [[~ ~] & pax]) + =+ ;;(res=(unit (cask)) pek) + (bind res tail) + :: :: Wish :: ++ wish |= txt=@t - =/ res (mox +22.snap) + =/ res (mox +10.snap) ?> ?=(%0 -.res) =/ wish p.res ~& [who=who %wished (slum wish txt)] @@ -373,6 +370,7 @@ ++ poke-pill |= p=pill ^- (quip card:agent:gall _state) + ?< ?=(%ivory -.p) =. this apex-aqua =< abet-aqua =. pil p ~& lent=(met 3 (jam boot-ova.pil)) @@ -411,10 +409,11 @@ :: ?+ val ~|(%bad-noun-arg !!) [%swap-vanes vs=*] - ?> ?=([[%7 * %1 installed=*] ~] boot-ova.pil) - =. installed.boot-ova.pil + ?> ?=(^ boot-ova.pil) + ?> ?=([%7 * %1 installed=*] i.boot-ova.pil) + =. installed.i.boot-ova.pil %+ roll (,(list term) vs.val) - |= [v=term =_installed.boot-ova.pil] + |= [v=term =_installed.i.boot-ova.pil] %^ slum installed now.hid =/ vane ?+ v ~|([%unknown-vane v] !!) @@ -507,28 +506,42 @@ ?- -.ae :: %init-ship - :: XX Note that the keys that get passed in are unused. The keys field - :: should be deleted now that aqua is capable of managing azimuth state - :: internally. Its been left this way for now until all the ph tests - :: can be rewritten - =/ keys=dawn-event:jael (dawn who.ae) =. this abet-pe:(publish-effect:(pe who.ae) [/ %sleep ~]) =/ initted =< plow %- push-events:apex:(pe who.ae) ^- (list unix-event) - :~ [/ %wack 0] :: eny - [/ %whom who.ae] :: eny - [//newt/0v1n.2m9vh %born ~] - [//behn/0v1n.2m9vh %born ~] - :^ //term/1 %boot & - ?~ keys.ae - [%fake who.ae] - [%dawn keys] - -.userspace-ova.pil - [//http-client/0v1n.2m9vh %born ~] - [//http-server/0v1n.2m9vh %born ~] - [//http-server/0v1n.2m9vh %live 8.080 `8.445] + %- zing + :~ + :~ [/ %wack 0] :: eny + :: [/ %verb `|] :: possible verb + :^ / %wyrd [~.nonce /aqua] :: dummy runtime version + nonce + ^- (list (pair term @)) + :~ zuse+zuse + lull+lull + arvo+arvo + hoon+hoon-version + nock+4 + == + [/ %whom who.ae] :: who + == + :: + kernel-ova.pil :: load compiler + :: + :_ ~ + :^ /d/term/1 %boot & + ?: fake.ae + [%fake who.ae] + [%dawn (dawn who.ae)] + :: + userspace-ova.pil :: load os + :: + :~ [/b/behn/0v1n.2m9vh %born ~] + [/i/http-client/0v1n.2m9vh %born ~] + [/e/http-server/0v1n.2m9vh %born ~] + [/e/http-server/0v1n.2m9vh %live 8.080 `8.445] + [/a/newt/0v1n.2m9vh %born ~] + == == =. this abet-pe:initted (pe who.ae) diff --git a/pkg/arvo/app/azimuth-rpc.hoon b/pkg/arvo/app/azimuth-rpc.hoon index eacb57d74..832971233 100644 --- a/pkg/arvo/app/azimuth-rpc.hoon +++ b/pkg/arvo/app/azimuth-rpc.hoon @@ -1,14 +1,13 @@ :: Azimuth JSON-RPC API :: -/- rpc=json-rpc, *aggregator +/- rpc=json-rpc /+ naive, - azimuth-rpc, + azimuth-roll-rpc, json-rpc, *server, default-agent, verb, dbug, - version, agentio |% :: @@ -71,7 +70,7 @@ :: TODO: method not supported :: (give-simple-payload:app id not-found:gen) - ?~ rpc-request=(validate-request:json-rpc body.req parse-method) + ?~ rpc-request=(validate-request:json-rpc body.req) :: TODO: malformed request :: (give-simple-payload:app id not-found:gen) @@ -83,11 +82,7 @@ ?~ data ~ :_ $(data t.data) ^- card - [%pass / %agent [our.bowl %aggregator] %poke i.data] - :: TODO: validate that format is e.g. 'getPoint' - :: TODO: maybe use getPoint and translate to %get-point - :: - ++ parse-method |=(t=@t `term`t) + [%pass / %agent [our.bowl %azimuth] %poke i.data] -- -- :: @@ -145,35 +140,15 @@ :: ++ process |= request:rpc - =, azimuth-rpc + =, azimuth-roll-rpc ?. ?=([%map *] params) [~ ~(parse error:json-rpc id)] =/ method=@tas (enkebab method) ?+ method [~ ~(method error:json-rpc id)] - %get-point `(get-point id +.params point:scry) - %get-points `(get-points id +.params points:scry) - %get-dns `(get-dns id +.params dns:scry) - %transfer-point (transfer-point id +.params) - %cancel-transaction (cancel-tx id +.params) - %get-spawned `(get-spawned id +.params spawned:scry) - %configure-keys (configure-keys id +.params) - %spawn (spawn id +.params) - %escape (escape id +.params method) - %cancel-escape (cancel-escape id +.params method) - %adopt (adopt id +.params method) - %detach (detach id +.params method) - %reject (reject id +.params method) - %set-management-proxy (management-proxy id +.params method) - %set-spawn-proxy (spawn-proxy id +.params method) - %set-transfer-proxy (transfer-proxy id +.params method) - %get-all-pending `(all:pending id +.params all:pending:scry) - %get-pending-by-ship `(ship:pending id +.params ship:pending:scry) - %get-pending-by-address `(addr:pending id +.params addr:pending:scry) - %get-transaction-status `(status id +.params tx-status:scry) - %when-next-batch `(next-batch id +.params next-batch:scry) - %get-nonce `(nonce id +.params nonce:scry) - %get-history `(history id +.params addr:history:scry) - %get-roller-config `(get-config id +.params config:scry) + %get-point `(get-point id +.params point:scry) + %get-dns `(get-dns id +.params dns:scry) + %get-naive-state `(get-naive id +.params naive-state:scry) + %get-refresh `(get-refresh id +.params refresh:scry) == -- :: @@ -183,93 +158,25 @@ |= =ship .^ (unit point:naive) %gx - (~(scry agentio bowl) %aggregator /point/(scot %p ship)/noun) - == - :: - ++ points - |= =address:naive - .^ (list [ship point:naive]) - %gx - (~(scry agentio bowl) %azimuth /points/(scot %ux address)/noun) - == - :: - ++ spawned - |= =ship - .^ (list [@p @ux]) - %gx - (~(scry agentio bowl) %aggregator /spawned/(scot %p ship)/noun) - == - :: - ++ pending - |% - ++ all - .^ (list pend-tx) - %gx - (~(scry agentio bowl) %aggregator /pending/noun) - == - :: - ++ ship - |= =^ship - .^ (list pend-tx) - %gx - (~(scry agentio bowl) %aggregator /pending/(scot %p ship)/noun) - == - :: - ++ addr - |= =address:naive - .^ (list pend-tx) - %gx - %+ ~(scry agentio bowl) %aggregator - /pending/[(scot %ux address)]/noun - == - -- - :: - ++ history - |% - ++ addr - |= =address:naive - .^ (list roller-tx) - %gx - (~(scry agentio bowl) %aggregator /history/(scot %ux address)/noun) - == - -- - :: - ++ tx-status - |= keccak=@ux - .^ ^tx-status - %gx - (~(scry agentio bowl) %aggregator /tx/(scot %ux keccak)/status/noun) - == - :: - ++ next-batch - .^ time - %gx - (~(scry agentio bowl) %aggregator /next-batch/noun) - == - :: - ++ nonce - |= [=ship =proxy:naive] - .^ (unit @) - %gx - %+ ~(scry agentio bowl) - %aggregator - /nonce/(scot %p ship)/[proxy]/noun + (~(scry agentio bowl) %azimuth /point/(scot %p ship)/noun) == :: ++ dns .^ (list @t) %gx - %+ ~(scry agentio bowl) - %azimuth - /dns/noun + (~(scry agentio bowl) %azimuth /dns/noun) == :: - ++ config - .^ roller-config + ++ naive-state + .^ ^state:naive %gx - %+ ~(scry agentio bowl) - %aggregator - /config/noun + (~(scry agentio bowl) %azimuth /nas/noun) + == + :: + ++ refresh + .^ @dr + %gx + (~(scry agentio bowl) %azimuth /refresh/noun) == -- -- diff --git a/pkg/arvo/app/azimuth.hoon b/pkg/arvo/app/azimuth.hoon index 90d7e6e1c..4e47d5ed9 100644 --- a/pkg/arvo/app/azimuth.hoon +++ b/pkg/arvo/app/azimuth.hoon @@ -1,5 +1,11 @@ -/- eth-watcher -/+ ethereum, azimuth, naive, default-agent, verb, dbug +/- eth-watcher, *dice +/+ ethereum, + azimuth, + naive, + dice, + default-agent, + verb, + dbug /* snap %eth-logs /app/azimuth/logs/eth-logs :: =/ last-snap :: maybe just use the last one? @@ -11,35 +17,183 @@ :: =, jael |% -++ app-state - $: %3 ++$ versioned-state + $% app-state + == +:::: ++$ app-state + $: %0 url=@ta + net=network whos=(set ship) nas=^state:naive own=owners logs=(list =event-log:rpc:ethereum) == +:: +$ poke-data $% :: %listen :: [%listen whos=(list ship) =source:jael] - :: %watch: configure node url + :: %watch: configure node url and network :: - [%watch url=@ta] + [%watch url=@ta net=network] == -+$ tagged-diff [=id:block diff:naive] :: -+$ network ?(%mainnet %ropsten %local) -+$ owners (jug address:naive [ship point:naive]) ++$ tagged-diff [=id:block diff:naive] ++$ network ?(%mainnet %ropsten %local) ++$ card card:agent:gall +:: TODO: add to state? +:: +++ refresh ~m5 -- :: -|% -++ net - ^- network - :: TODO: add poke action to allow switching? - :: eth snapshot could also be considered +=| state=app-state +%- agent:dbug +%+ verb | +^- agent:gall +=< + |_ =bowl:gall + +* this . + do ~(. +> bowl) + def ~(. (default-agent this %|) bowl) :: - %local + ++ on-init + ^- (quip card _this) + =. net.state %local + :_ this + :_ ~ + :* %pass + /eth-watcher + %agent + [our.bowl %eth-watcher] + %watch + /logs/[dap.bowl] + == + :: + ++ on-save !>(state) + ++ on-load + |= old=vase + ^- (quip card _this) + `this(state !<(versioned-state old)) + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + ?: =(%noun mark) + ?+ q.vase !! + %rerun + ~& [%rerunning (lent logs.state)] + =. points.nas.state ~ + =. own.state ~ + =^ * state (run-logs:do logs.state) + `this + :: + %resub + :_ this :_ ~ + [%pass /eth-watcher %agent [our.bowl %eth-watcher] %watch /logs/[dap.bowl]] + :: + %resnap + =. logs.state snap + $(mark %noun, vase !>(%rerun)) + == + ?: =(%eth-logs mark) + =+ !<(logs=(list event-log:rpc:ethereum) vase) + =. logs.state logs + $(mark %noun, vase !>(%rerun)) + :: + ?. ?=(%azimuth-poke mark) + (on-poke:def mark vase) + =+ !<(poke=poke-data vase) + ?- -.poke + %listen + [[%pass /lo %arvo %j %listen (silt whos.poke) source.poke]~ this] + :: + %watch + :: TODO: only wipe out state when switching networks? + :: ?: =(net.state net.poke) + :: [~ this] + =: nas.state *^state:naive + net.state net.poke + url.state url.poke + own.state ~ + logs.state ~ + == + [start:do this] + == + :: + ++ on-watch + |= =path + ^- (quip card _this) + ?< =(/sole/drum path) + ?: =(/event path) + :_ this + [%give %fact ~ %naive-state !>([nas.state own.state])]~ + =/ who=(unit ship) + ?~ path ~ + ?: ?=([@ ~] path) ~ + `(slav %p i.path) + =. whos.state + ?~ who + ~ + (~(put in whos.state) u.who) + ^- (quip card _this) + [start:do this] + :: + ++ on-leave on-leave:def + ++ on-peek + |= =path + ^- (unit (unit cage)) + |^ + ?+ path (on-peek:def path) + [%x %logs ~] ``noun+!>(logs.state) + [%x %nas ~] ``noun+!>(nas.state) + [%x %dns ~] ``noun+!>(dns.nas.state) + [%x %own ~] ``noun+!>(own.state) + [%x %refresh ~] ``atom+!>(refresh) + [%x %point @ ~] ``noun+(point i.t.t.path) + == + :: + ++ point + |= wat=@t + ^- vase + !> ^- (unit point:naive) + ?~ ship=(rush wat ;~(pfix sig fed:ag)) + ~ + (get:orm:naive points.nas.state u.ship) + -- + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card _this) + ?. ?=([%eth-watcher ~] wire) + (on-agent:def wire sign) + ?. ?=(%fact -.sign) + (on-agent:def wire sign) + ?. ?=(%eth-watcher-diff p.cage.sign) + (on-agent:def wire sign) + =+ !<(diff=diff:eth-watcher q.cage.sign) + ?: ?=(%disavow -.diff) + [(jael-update:do [*ship id.diff %disavow ~]~) this] + :: + =. logs.state + ?- -.diff + :: %history loglist.diff + %history (welp logs.state loglist.diff) + %logs (welp logs.state loglist.diff) + == + =? nas.state ?=(%history -.diff) *^state:naive + =^ effects state (run-logs:do loglist.diff) + :: + :_ this + %+ weld + (event-update:do effects) + (jael-update:do (to-udiffs:do effects)) + :: + ++ on-arvo on-arvo:def + ++ on-fail on-fail:def + -- +|_ =bowl:gall :: TODO: maybe flop the endianness here so metamask signs it in normal :: order? :: @@ -70,45 +224,18 @@ ?: =(data '0x') *@ux (hex-to-num:ethereum data) :: -++ update-ownership - |= [=diff:naive own=owners old=(unit point:naive) new=point:naive] - ^+ own - ?. ?=([%point *] diff) own - =* event +>.diff - =; [to=@ux from=@ux] - =? own !=(from 0x0) - ?> ?=(^ old) - (~(del ju own) from [ship.diff u.old]) - ?: =(to 0x0) own - (~(put ju own) to [ship.diff new]) - ?+ -.event [0x0 0x0] - %owner - [+.event ?~(old 0x0 address.owner.own.u.old)] - :: - %spawn-proxy - [+.event ?~(old 0x0 address.transfer-proxy.own.u.old)] - :: - %management-proxy - [+.event ?~(old 0x0 address.management-proxy.own.u.old)] - :: - %voting-proxy - [+.event ?~(old 0x0 address.voting-proxy.own.u.old)] - :: - %transfer-proxy - [+.event ?~(old 0x0 address.spawn-proxy.own.u.old)] - == -:: ++ run-logs - |= [state=app-state logs=(list event-log:rpc:ethereum)] - ^- [(list tagged-diff) _state] - =/ [contract=@ux * chain-id=@ *] (get-network net) + |= [logs=(list event-log:rpc:ethereum)] + ^- (quip tagged-diff _state) + =+ net=(get-network net.state) ?~ logs `state ?~ mined.i.logs $(logs t.logs) =/ [raw-effects=effects:naive new-nas=_nas.state] =/ =^input:naive - ?: =(contract address.i.logs) + :- block-number.u.mined.i.logs + ?: =(azimuth.net address.i.logs) =/ data (data-to-hex data.i.logs) =/ =event-log:naive [address.i.logs data topics.i.logs] @@ -118,20 +245,26 @@ [%bat u.input.u.mined.i.logs] =/ res %- mule - |.((%*(. naive lac |) verifier chain-id nas.state input)) + |.((%*(. naive lac |) verifier chain-id.net nas.state input)) ?- -.res %& p.res %| ((slog 'naive-fail' p.res) `nas.state) == =. own.state - %+ roll raw-effects - |= [=diff:naive own=_own.state] - ^+ own - =, orm:naive - ?. ?=([%point *] diff) own - =/ old=(unit point:naive) (get points.nas.state ship.diff) - =/ new=point:naive (need (get points.new-nas ship.diff)) - (update-ownership diff own old new) + =< own + ?. =(azimuth.net address.i.logs) + %: apply-effects:dice + raw-effects + nas.state + own.state + chain-id.net + == + %: update-ownership:dice + raw-effects + nas.state + new-nas + own.state + == =. nas.state new-nas =/ effects-1 =/ =id:block [block-hash block-number]:u.mined.i.logs @@ -157,10 +290,10 @@ :: ++ jael-update |= =udiffs:point - ^- (list card:agent:gall) + ^- (list card) ?: & ~ :: XX :- [%give %fact ~[/] %azimuth-udiffs !>(udiffs)] - |- ^- (list card:agent:gall) + |- ^- (list card) ?~ udiffs ~ =/ =path /(scot %p ship.i.udiffs) @@ -169,20 +302,20 @@ :- [%give %fact ~[path] %azimuth-udiffs !>(~[i.udiffs])] $(udiffs t.udiffs) :: -++ tx-update +++ event-update |= effects=(list tagged-diff) - ^- (list card:agent:gall) + ^- (list card) %+ murn effects |= tag=tagged-diff - ^- (unit card:agent:gall) - ?. ?=(%tx +<.tag) ~ + ^- (unit card) + ?. |(?=(%tx +<.tag) ?=(%point +<.tag)) ~ %- some - ^- card:agent:gall - [%give %fact ~[/txs] %naive-diffs !>(+.tag)] + ^- card + [%give %fact ~[/event] %naive-diffs !>(+.tag)] :: ++ get-network |= =network - ^- [@ux @ux @ @] + ^- [azimuth=@ux naive=@ux chain-id=@ launch=@] =< [azimuth naive chain-id launch] =, azimuth ?- network @@ -192,204 +325,16 @@ == :: ++ start - |= [state=app-state =network our=ship dap=term] - ^- card:agent:gall - =/ [azimuth=@ux naive=@ux * launch=@ud] (get-network network) + ^- (list card) + =+ net=(get-network net.state) =/ args=vase !> - :+ %watch /[dap] + :+ %watch /[dap.bowl] ^- config:eth-watcher - :* url.state =(%czar (clan:title our)) ~m5 ~h30 - (max launch last-snap) - ~[azimuth] - ~[naive] + :* url.state =(%czar (clan:title our.bowl)) refresh ~h30 + (max launch.net last-snap) + ~[azimuth.net] + ~[naive.net] (topics whos.state) == - [%pass /wa %agent [our %eth-watcher] %poke %eth-watcher-poke args] --- -:: -=| state=app-state -%- agent:dbug -%+ verb | -^- agent:gall -|_ =bowl:gall -+* this . - def ~(. (default-agent this %|) bowl) -:: -++ on-init - ^- (quip card:agent:gall agent:gall) - :_ this :_ ~ - ^- card:agent:gall - [%pass /eth-watcher %agent [our.bowl %eth-watcher] %watch /logs/[dap.bowl]] -:: -++ on-save !>(state) -++ on-load - |= old=vase - |^ - =+ !<(old-state=app-states old) - =? old-state ?=(%0 -.old-state) - %= old-state - - %1 - logs - %+ turn logs.old-state - |= =event-log-0 - event-log-0(mined ?~(mined.event-log-0 ~ `mined.event-log-0)) - == - =? old-state ?=(%1 -.old-state) - %= old-state - - %2 - nas *^state:naive - == - =? old-state ?=(%2 -.old-state) - %= old-state - - %3 - own *owners - == - `this(state ?>(?=(%3 -.old-state) old-state)) - :: - ++ app-states $%(app-state-0 app-state-1 app-state-2 app-state) - ++ app-state-2 - $: %2 - url=@ta - whos=(set ship) - nas=^state:naive - own=* - logs=(list =event-log:rpc:ethereum) - == - ++ app-state-1 - $: %1 - url=@ta - whos=(set ship) - nas=* - own=* - logs=(list =event-log:rpc:ethereum) - == - ++ app-state-0 - $: %0 - url=@ta - whos=(set ship) - nas=* - own=* - logs=(list =event-log-0) - == - :: - +$ event-log-0 - $: $= mined %- unit - $: log-index=@ud - transaction-index=@ud - transaction-hash=@ux - block-number=@ud - block-hash=@ux - removed=? - == - :: - address=@ux - data=@t - topics=(lest @ux) - == - -- -:: -++ on-poke - |= [=mark =vase] - ?: =(%noun mark) - ?+ q.vase !! - %rerun - ~& [%rerunning (lent logs.state)] - =^ effects state (run-logs state logs.state) - `this - :: - %resub - :_ this :_ ~ - [%pass /eth-watcher %agent [our.bowl %eth-watcher] %watch /logs/[dap.bowl]] - :: - %resnap - =. logs.state snap - $(mark %noun, vase !>(%rerun)) - == - ?: =(%eth-logs mark) - =+ !<(logs=(list event-log:rpc:ethereum) vase) - =. logs.state logs - $(mark %noun, vase !>(%rerun)) - :: - ?. ?=(%azimuth-poke mark) - (on-poke:def mark vase) - =+ !<(poke=poke-data vase) - ?- -.poke - %listen [[%pass /lo %arvo %j %listen (silt whos.poke) source.poke]~ this] - %watch - =. url.state url.poke - [[(start state net [our dap]:bowl) ~] this] - == -:: -++ on-watch - |= =path - ^- (quip card:agent:gall _this) - ?< =(/sole/drum path) - ?: =(/txs path) - :_ this - [%give %fact ~ %naive-state !>(nas.state)]~ - =/ who=(unit ship) - ?~ path ~ - ?: ?=([@ ~] path) ~ - `(slav %p i.path) - =. whos.state - ?~ who - ~ - (~(put in whos.state) u.who) - :_ this :_ ~ - (start state net [our dap]:bowl) -:: -++ on-leave on-leave:def -++ on-peek - |= =path - ^- (unit (unit cage)) - ?+ path (on-peek:def path) - [%x %logs ~] ``noun+!>(logs.state) - [%x %nas ~] ``noun+!>(nas.state) - [%x %dns ~] ``noun+!>(dns.nas.state) - [%x %points @ ~] - =* wat i.t.t.path - :+ ~ ~ - :- %noun - !> ^- (list [ship point:naive]) - ?~ addr=(slaw %ux wat) - ~ - %~ tap in - (~(get ju own.state) u.addr) - == -:: -++ on-agent - |= [=wire =sign:agent:gall] - ?. ?=([%eth-watcher ~] wire) - (on-agent:def wire sign) - ?. ?=(%fact -.sign) - (on-agent:def wire sign) - ?. ?=(%eth-watcher-diff p.cage.sign) - (on-agent:def wire sign) - =+ !<(diff=diff:eth-watcher q.cage.sign) - ?: ?=(%disavow -.diff) - [(jael-update [*ship id.diff %disavow ~]~) this] - :: - =. logs.state - ?- -.diff - :: %history loglist.diff - %history (welp logs.state loglist.diff) - %logs (welp logs.state loglist.diff) - == - =? nas.state ?=(%history -.diff) *^state:naive - =^ effects state - =; nas=^state:naive - (run-logs state(nas nas) loglist.diff) - ?- -.diff - :: %history *^state:naive - %history nas.state - %logs nas.state - == - :: - :_ this - %+ weld - (tx-update effects) - (jael-update (to-udiffs effects)) -:: -++ on-arvo on-arvo:def -++ on-fail on-fail:def + [%pass /wa %agent [our.bowl %eth-watcher] %poke %eth-watcher-poke args]~ -- diff --git a/pkg/arvo/app/btc-provider.hoon b/pkg/arvo/app/btc-provider.hoon deleted file mode 100644 index e88fe55a4..000000000 --- a/pkg/arvo/app/btc-provider.hoon +++ /dev/null @@ -1,355 +0,0 @@ -:: btc-provider.hoon -:: Proxy that serves a BTC full node and ElectRS address indexer -:: -:: Subscriptions: none -:: To Subscribers: /clients -:: current connection state -:: results/errors of RPC calls -:: -:: Scrys -:: x/is-whitelisted/SHIP: bool, whether ship is whitelisted -:: -/- *bitcoin, json-rpc, *btc-provider -/+ dbug, default-agent, bl=btc, groupl=group, resource -|% -+$ versioned-state - $% state-0 - == -:: -+$ state-0 [%0 =host-info =whitelist] -:: -+$ card card:agent:gall -:: --- -%- agent:dbug -=| state-0 -=* state - -^- agent:gall -=< -|_ =bowl:gall -+* this . - def ~(. (default-agent this %|) bowl) - hc ~(. +> bowl) -:: -++ on-init - ^- (quip card _this) - ~& > '%btc-provider initialized successfully' - =| wl=^whitelist - :- ~ - %_ this - host-info - ['' connected=%.n %main block=0 clients=*(set ship)] - whitelist wl(public %.n, kids %.n) - == -:: -++ on-save - ^- vase - !>(state) -:: -++ on-load - |= old-state=vase - ^- (quip card _this) - ~& > '%btc-provider recompiled successfully ' - `this(state !<(versioned-state old-state)) -:: -++ on-poke - |= [=mark =vase] - ^- (quip card _this) - ?> ?|((team:title our.bowl src.bowl) (is-client:hc src.bowl)) - =^ cards state - ?+ mark (on-poke:def mark vase) - %btc-provider-command - ?> (team:title our.bowl src.bowl) - (handle-command:hc !<(command vase)) - %btc-provider-action - (handle-action:hc !<(action vase)) - == - [cards this] -:: -++ on-watch - |= pax=path - ^- (quip card _this) - :: checking provider permissions before trying to subscribe - :: terrible hack until we have cross-ship scries - :: - ?: ?=([%permitted @ ~] pax) - :_ this - =/ jon=json - %+ frond:enjs:format - %'providerStatus' - %- pairs:enjs:format - :~ provider+s+(scot %p our.bowl) - permitted+b+(is-whitelisted:hc src.bowl) - == - [%give %fact ~ %json !>(jon)]~ - :: - ?> ?=([%clients *] pax) - ?. (is-whitelisted:hc src.bowl) - ~& >>> "btc-provider: blocked client {}" - [~[[%give %kick ~ ~]] this] - ~& > "btc-provider: accepted client {}" - :- [do-ping:hc]~ - this(clients.host-info (~(put in clients.host-info) src.bowl)) -:: -++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card _this) - :: check for connectivity every 30 seconds - :: - ?: ?=([%ping-timer *] wire) - :_ this - :~ do-ping:hc - (start-ping-timer:hc ~s30) - == - =^ cards state - ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) - %http-response - (handle-rpc-response:hc wire client-response.sign-arvo) - == - [cards this] -:: -++ on-peek - |= pax=path - ^- (unit (unit cage)) - ?+ pax (on-peek:def pax) - [%x %is-whitelisted @t ~] - ``noun+!>((is-whitelisted:hc (ship (slav %p +>-.pax)))) - :: - [%x %is-client @t ~] - ``noun+!>((is-client (ship (slav %p +>-.pax)))) -== -:: -++ on-leave on-leave:def -++ on-agent on-agent:def -++ on-fail on-fail:def --- -:: helper core -|_ =bowl:gall -++ handle-command - |= comm=command - ^- (quip card _state) - ?- -.comm - %set-credentials - :- :~ do-ping - (start-ping-timer ~s30) - == - %= state - host-info - [api-url.comm connected=%.n network.comm block=0 clients=*(set ship)] - == - :: - %add-whitelist - ?- -.wt.comm - %public - `state(public.whitelist %.y) - :: - %kids - `state(kids.whitelist %.y) - :: - %users - `state(users.whitelist (~(uni in users.whitelist) users.wt.comm)) - :: - %groups - `state(groups.whitelist (~(uni in groups.whitelist) groups.wt.comm)) - == - :: - %remove-whitelist - =. state - ?- -.wt.comm - %public - state(public.whitelist %.n) - :: - %kids - state(kids.whitelist %.n) - :: - %users - state(users.whitelist (~(dif in users.whitelist) users.wt.comm)) - :: - %groups - state(groups.whitelist (~(dif in groups.whitelist) groups.wt.comm)) - == - clean-client-list - == -:: if not connected, only %ping action is allowed -:: -++ handle-action - |= act=action - ^- (quip card _state) - ?. ?|(connected.host-info ?=(%ping -.act)) - ~& >>> "Not connected to RPC" - [~[(send-update [%| %not-connected 500])] state] - :: - =/ ract=action:rpc-types - ?- -.act :: ~|("Invalid action" !!) - %address-info - [%get-address-info address.act] - :: - %tx-info - [%get-tx-vals txid.act] - :: - %raw-tx - [%get-raw-tx txid.act] - :: - %broadcast-tx - [%broadcast-tx rawtx.act] - :: - %ping - [%get-block-info ~] - == - [~[(req-card act ract)] state] -:: -++ req-card - |= [act=action ract=action:rpc-types] - =| out=outbound-config:iris - =/ req=request:http - (gen-request:bl host-info ract) - [%pass (rpc-wire act) %arvo %i %request req out] -:: wire structure: /action-tas/now -:: -++ rpc-wire - |= act=action ^- wire - /[-.act]/[(scot %ux (cut 3 [0 20] eny.bowl))] -:: -++ kick-client - |= client=ship - ^- (quip card _state) - ~& >>> "dropping client {}" - :- ~[[%give %kick ~[/clients] `client]] - state(clients.host-info (~(dif in clients.host-info) (silt ~[client]))) -:: -:: Handles HTTP responses from RPC servers. Parses for errors, then handles response. -:: For actions that require collating multiple RPC calls, uses req-card to call out -:: to RPC again if more information is required. -:: -++ handle-rpc-response - |= [=wire response=client-response:iris] - ^- (quip card _state) - ?. ?=(%finished -.response) `state - =* status status-code.response-header.response - :: handle error types: connection errors, RPC errors (in order) - :: - =^ conn-err state - (connection-error status) - ?^ conn-err - :_ state(connected.host-info %.n) - ~[(send-status [%disconnected ~]) (send-update [%| u.conn-err])] - :: - %+ handle-rpc-result wire - %- parse-result:rpc:bl - (get-rpc-response:bl response) -:: -++ connection-error - |= status=@ud - ^- [(unit error) _state] - ?+ status [`[%rpc-error ~] state] - %200 - [~ state] - %400 - [`[%bad-request status] state] - %401 - [`[%no-auth status] state(connected.host-info %.n)] - %502 - [`[%not-connected status] state(connected.host-info %.n)] - %504 - [`[%not-connected status] state(connected.host-info %.n)] - == -:: -++ handle-rpc-result - |= [=wire r=result:rpc-types] - ^- (quip card _state) - ?+ -.wire ~|("Unexpected HTTP response" !!) - %address-info - ?> ?=([%get-address-info *] r) - :_ state - ~[(send-update [%.y %address-info +.r])] - :: - %tx-info - ?> ?=([%get-tx-vals *] r) - :_ state - ~[(send-update [%.y %tx-info +.r])] - :: - %raw-tx - ?> ?=([%get-raw-tx *] r) - :_ state - ~[(send-update [%.y %raw-tx +.r])] - :: - %broadcast-tx - ?> ?=([%broadcast-tx *] r) - :_ state - ~[(send-update [%.y %broadcast-tx +.r])] - :: - %ping - ?> ?=([%get-block-info *] r) - :_ state(connected.host-info %.y, block.host-info block.r) - ?: =(block.host-info block.r) - ~[(send-status [%connected network.host-info block.r fee.r])] - ~[(send-status [%new-block network.host-info block.r fee.r blockhash.r blockfilter.r])] - == -:: -++ send-status - |= =status ^- card - %- ?: ?=(%new-block -.status) - ~&(>> "%new-block: {}" same) - same - [%give %fact ~[/clients] %btc-provider-status !>(status)] -:: -++ send-update - |= =update - ^- card - =+ c=[%give %fact ~[/clients] %btc-provider-update !>(update)] - ?: ?=(%.y -.update) -:: ~& >> "prov. update: {}" - c - ~& >> "prov. err: {}" - c -:: -++ is-whitelisted - |= user=ship ^- ? - |^ - ?| public.whitelist - =(our.bowl user) - ?&(kids.whitelist is-kid) - (~(has in users.whitelist) user) - in-group - == - ++ is-kid - =(our.bowl (sein:title our.bowl now.bowl user)) - ++ in-group - =/ gs ~(tap in groups.whitelist) - |- - ?~ gs %.n - ?: (~(is-member groupl bowl) user i.gs) - %.y - $(gs t.gs) - :: .^((unit group:g) %gx ;:(weld /=group-store=/groups p /noun)) - -- -:: +clean-client-list: remove clients who are no longer whitelisted -:: called after a whitelist change -:: -++ clean-client-list - ^- (quip card _state) - =/ to-kick=(set ship) - %- silt - %+ murn ~(tap in clients.host-info) - |= c=ship ^- (unit ship) - ?:((is-whitelisted c) ~ `c) - :_ state(clients.host-info (~(dif in clients.host-info) to-kick)) - %+ turn ~(tap in to-kick) - |=(c=ship [%give %kick ~[/clients] `c]) -:: -++ is-client - |= user=ship ^- ? - (~(has in clients.host-info) user) -:: -++ start-ping-timer - |= interval=@dr ^- card - [%pass /ping-timer %arvo %b %wait (add now.bowl interval)] -:: -++ do-ping - ^- card - =/ act=action [%ping ~] - :* %pass /ping/[(scot %da now.bowl)] %agent - [our.bowl %btc-provider] %poke - %btc-provider-action !>(act) - == --- diff --git a/pkg/arvo/app/btc-wallet.hoon b/pkg/arvo/app/btc-wallet.hoon deleted file mode 100644 index bd46aad8d..000000000 --- a/pkg/arvo/app/btc-wallet.hoon +++ /dev/null @@ -1,1161 +0,0 @@ -:: btc-wallet -:: -:: Scrys -:: x/scanned: (list xpub) of all scanned wallets -:: x/balance/xpub: balance (in sats) of wallet -/- *btc-wallet, bp=btc-provider, file-server, launch-store -/+ dbug, default-agent, bl=btc, bc=bitcoin, bip32 -|% -++ defaults - |% - ++ params - :* batch-size=20 - fam-limit=10 - piym-limit=3 - == - ++ confs 6 - ++ fee 100 - -- -:: -+$ versioned-state - $% state-0 - state-1 - == -:: -+$ state-0 - $: %0 - prov=(unit provider) - walts=(map xpub:bc walt-0) - =btc-state - =history - curr-xpub=(unit xpub:bc) - =scans - =params - feybs=(map ship sats) - =piym - =poym - ahistorical-txs=(set txid) - == -:: -+$ state-1 - $: %1 - prov=(unit provider) - walts=(map xpub:bc walt) - =btc-state - =history - curr-xpub=(unit xpub:bc) - =scans - =params - feybs=(map ship sats) - =piym - =poym - ahistorical-txs=(set txid) - == -:: -+$ card card:agent:gall -:: --- -=| state-1 -=* state - -%- agent:dbug -^- agent:gall -=< -|_ =bowl:gall -+* this . - def ~(. (default-agent this %|) bowl) - hc ~(. +> bowl) -:: -++ on-init -^- (quip card _this) - ~& > '%btc-wallet initialized' - =/ file - [%file-server-action !>([%serve-dir /'~btc' /app/btc-wallet %.n %.y])] - =/ tile - :- %launch-action - !> :+ %add - %btc-wallet - [[%custom `'/~btc' `'/~btc/img/tile.svg'] %.y] - =/ warning [%settings-event !>([%put-entry %btc-wallet %warning %b %.y])] - =/ currency - [%settings-event !>([%put-entry %btc-wallet %currency %s 'USD'])] - :- :~ [%pass /btc-wallet-server %agent [our.bowl %file-server] %poke file] - [%pass /btc-wallet-tile %agent [our.bowl %launch] %poke tile] - [%pass /warn %agent [our.bowl %settings-store] %poke warning] - [%pass /warn %agent [our.bowl %settings-store] %poke currency] - == - %_ this - state - :* %1 - ~ - *(map xpub:bc walt) - *^btc-state - *^history - ~ - *^scans - params:defaults - *(map ship sats) - *^piym - *^poym - ~ - == - == -:: -++ on-save - ^- vase - !>(state) -:: -++ on-load - |= old-state=vase - ^- (quip card _this) - ~& > '%btc-wallet recompiled' - =/ ver !<(versioned-state old-state) - =| cards=(list card) - |- - ?- -.ver - %1 - [cards this(state ver)] - :: - %0 - =/ new-walts=(map xpub:bc walt) - %- ~(run by walts.ver) - |= old-walt=walt-0 - ^- walt - old-walt(wilt +6:wilt.old-walt) - $(ver [%1 +.ver(walts new-walts)]) - == -:: -++ on-poke - |= [=mark =vase] - ^- (quip card _this) - =^ cards state - ?+ mark (on-poke:def mark vase) - %btc-wallet-command - ?> =(our.bowl src.bowl) - (handle-command:hc !<(command vase)) - :: - %btc-wallet-action - ?< =(our.bowl src.bowl) - (handle-action:hc !<(action vase)) - :: - %btc-wallet-internal - ?> =(our.bowl src.bowl) - (handle-internal:hc !<(internal vase)) - == - [cards this] -++ on-peek - |= pax=path - ^- (unit (unit cage)) - ?+ pax (on-peek:def pax) - [%x %configured ~] - =/ provider=json - ?~ prov ~ - [%s (scot %p host.u.prov)] - =/ result=json - %- pairs:enjs:format - :~ [%'provider' provider] - [%'hasWallet' b+?=(^ walts)] - == - ``json+!>(result) - :: - [%x %scanned ~] - ``noun+!>(scanned-wallets) - :: - [%x %balance @ ~] - ``noun+!>((balance:hc (xpub:bc +>-.pax))) - == -++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card _this) - ?+ -.sign (on-agent:def wire sign) - %kick - ~& >>> "kicked from prov {}" - ?~ prov `this - ?: ?& ?=(%set-provider -.wire) - =(host.u.prov src.bowl) - == - `this(prov ~) - `this - :: - %fact - =^ cards state - ?+ p.cage.sign `state - %btc-provider-status - (handle-provider-status:hc !<(status:bp q.cage.sign)) - :: - %btc-provider-update - (handle-provider-update:hc !<(update:bp q.cage.sign)) - :: - %json - ?+ wire `state - [%check-payee @ ~] - =/ who (slav %p i.t.wire) - :_ state - :~ [%give %fact ~[/all] cage.sign] - [%pass wire %agent [who %btc-wallet] %leave ~] - == - :: - [%permitted @ ~] - =/ who (slav %p i.t.wire) - :_ state - :~ [%give %fact ~[/all] cage.sign] - [%pass wire %agent [who %btc-provider] %leave ~] - == - == - == - [cards this] - == -:: -++ on-watch - |= =path - ^- (quip card _this) - ?+ path (on-watch:def path) - [%check-payee @ ~] - =/ who (slav %p i.t.path) - ?> =(who our.bowl) - =/ response=json - %+ frond:enjs:format 'checkPayee' - %- pairs:enjs:format - :~ ['hasWallet' b+?=(^ curr-xpub)] - ['payee' (ship:enjs:format our.bowl)] - == - :_ this - [%give %fact ~ %json !>(response)]~ - :: - [%all ~] - ?> (team:title our.bowl src.bowl) - :_ this - [give-initial:hc]~ - == -:: -++ on-leave on-leave:def -++ on-arvo on-arvo:def -++ on-fail on-fail:def --- -|_ =bowl:gall -++ handle-command - |= comm=command - ^- (quip card _state) - ?> (team:title our.bowl src.bowl) - ?- -.comm - %set-provider - |^ - ?~ provider.comm - ?~ prov `state - :_ state(prov ~) - :~ (leave-provider host.u.prov) - (give-update %change-provider ~) - == - :_ state(prov [~ u.provider.comm %.n]) - ?~ prov - [(watch-provider u.provider.comm)]~ - :~ (leave-provider host.u.prov) - (watch-provider u.provider.comm) - (give-update %change-provider `[u.provider.comm %.n]) - == - :: - ++ watch-provider - |= who=@p - ^- card - :* %pass /set-provider/[(scot %p who)] %agent [who %btc-provider] - %watch /clients - == - ++ leave-provider - |= who=@p - ^- card - :* %pass /set-provider/[(scot %p who)] %agent [who %btc-provider] - %leave ~ - == - -- - :: - %check-provider - =/ pax /permitted/(scot %p provider.comm) - :_ state - [%pass pax %agent [provider.comm %btc-provider] %watch pax]~ - :: - %check-payee - =/ pax /check-payee/(scot %p payee.comm) - :_ state - [%pass pax %agent [payee.comm %btc-wallet] %watch pax]~ - :: - %set-current-wallet - (set-curr-xpub xpub.comm) - :: - %add-wallet - ?~ (~(has by walts) xpub.comm) - ((slog ~[leaf+"xpub already in wallet"]) `state) - =/ w=walt (from-xpub:bl +.comm) - =. walts (~(put by walts) xpub.comm w) - =^ c1 state (init-batches xpub.comm (dec max-gap.w)) - =^ c2 state (set-curr-xpub xpub.comm) - [(weld c1 c2) state] - :: - %delete-wallet - =* cw curr-xpub.state - =? cw ?&(?=(^ cw) =(u.cw xpub.comm)) - ~ - =. scans (~(del by scans) [xpub.comm %0]) - =. scans (~(del by scans) [xpub.comm %1]) - =. walts (~(del by walts) xpub.comm) - =. history - %- ~(rep by history) - |= [[=txid =hest] out=_history] - ?: =(xpub.hest xpub.comm) - (~(del by out) txid) - out - :_ state - [give-initial]~ - :: - %init-payment-external - ?: is-broadcasting - %- (slog ~[leaf+"broadcasting a transaction"]) - [[(give-update %error %tx-being-signed)]~ state] - ?~ curr-xpub ~|("btc-wallet: no curr-xpub set" !!) - ?: (is-dust value.comm address.comm) - %- (slog ~[leaf+"sending dust"]) - [[(give-update %error %no-dust)]~ state] - :: - =/ uw (~(get by walts) u.curr-xpub) - ?: ?|(?=(~ uw) ?!(scanned.u.uw)) - ~|("no wallet with xpub or wallet not scanned yet" !!) - =/ [tb=(unit txbu) chng=(unit sats)] - %~ with-change sut:bl - [u.uw eny.bowl block.btc-state ~ feyb.comm ~[[address.comm value.comm ~]]] - ?~ tb - %- (slog ~[leaf+"insufficient balance or not enough confirmed balance"]) - [[(give-update %error %insufficient-balance)]~ state] - =^ tb=(unit txbu) state - ?~ chng `state - =/ [addr=address =idx w=walt] - ~(nixt-address wad:bl u.uw %1) - :- `(~(add-output txb:bl u.tb) addr u.chng `(~(hdkey wad:bl w %1) idx)) - state(walts (~(put by walts) u.curr-xpub w)) - =/ po=^poym ?~(tb [~ ~] [tb note.comm]) - :_ state(poym po) - ?~ tb ~ - %+ turn txis.u.tb - |= =txi - (poke-provider %raw-tx txid.utxo.txi) - :: - :: overwrites any payment being built in poym - :: - %init-payment - ?: =(src.bowl payee.comm) - %- (slog ~[leaf+"can't pay ourselves"]) - [[(give-update %error %cant-pay-ourselves)]~ state] - ?: ?=(%pawn (clan:title payee.comm)) - %- (slog ~[leaf+"no comets"]) - [[(give-update %error %no-comets)]~ state] - ?: is-broadcasting - %- (slog ~[leaf+"broadcasting a transaction"]) - [[(give-update %error %tx-being-signed)]~ state] - :_ state(poym [~ note.comm], feybs (~(put by feybs) payee.comm feyb.comm)) - ~[(poke-peer payee.comm [%gen-pay-address value.comm note.comm])] - :: - %broadcast-tx - ?~ prov ~|("Provider not connected" !!) - =+ signed=(from-cord:hxb:bc txhex.comm) - =/ tx-match=? - ?~ txbu.poym %.n - =((get-id:txu:bc (decode:txu:bc signed)) ~(get-txid txb:bl u.txbu.poym)) - :- ?. tx-match - %- (slog leaf+"txid didn't match txid in wallet") - [(give-update %error %broadcast-fail)]~ - ~[(poke-provider [%broadcast-tx signed])] - ?. tx-match state - ?~ txbu.poym state - state(signed-tx.u.txbu.poym `signed) - :: - %gen-new-address - ?~ curr-xpub ~|("btc-wallet: no curr-xpub set" !!) - =/ uw=(unit walt) (~(get by walts) u.curr-xpub) - ?: ?|(?=(~ uw) ?!(scanned.u.uw)) - ~|("no wallet with xpub or wallet not scanned yet" !!) - =/ [addr=address =idx w=walt] - ~(gen-address wad:bl u.uw %0) - :_ state(walts (~(put by walts) u.curr-xpub w)) - [(give-update %new-address addr)]~ - == -:: -++ handle-action - |= act=action - ^- (quip card _state) - ?- -.act - :: comets can't pay (could spam address requests) - :: reuses payment address for ship if ship in piym already - :: - %gen-pay-address - ~| "no comets" - ?< ?=(%pawn (clan:title src.bowl)) - ?~ curr-xpub ~|("btc-wallet: no curr-xpub set" !!) - |^ - =^ cards state reuse-address - ?^ cards [cards state] :: if cards returned, means we already have an address - =+ f=(fam:bl our.bowl now.bowl src.bowl) - =+ n=(~(gut by num-fam.piym) f 0) - ?: (gte n fam-limit.params) - ~|("More than {} addresses for moons + planet" !!) - =. state state(num-fam.piym (~(put by num-fam.piym) f +(n))) - =^ a=address state - (generate-address u.curr-xpub %0) - :- ~[(poke-peer src.bowl [%give-pay-address a value.act])] - %= state - ps.piym - %+ ~(put by ps.piym) src.bowl - [~ u.curr-xpub a src.bowl value.act note.act] - == - :: - ++ generate-address - |= [=xpub:bc =chyg] - =/ uw=(unit walt) (~(get by walts) xpub) - ?: ?|(?=(~ uw) ?!(scanned.u.uw)) - ~|("no wallet with xpub or wallet not scanned yet" !!) - =/ [addr=address =idx w=walt] - ~(gen-address wad:bl u.uw chyg) - [addr state(walts (~(put by walts) xpub w))] - :: - ++ reuse-address - ^- (quip card _state) - =* payer src.bowl - =+ p=(~(get by ps.piym) payer) - ?~ p `state - ?^ pend.u.p ~|("%gen-address: {} already has pending payment to us" !!) - =+ newp=u.p(value value.act) - :_ state(ps.piym (~(put by ps.piym) payer newp)) - ~[(poke-peer payer [%give-pay-address address.newp value.act])] - -- - :: - %give-pay-address - ?: =(src.bowl our.bowl) ~|("Can't pay ourselves" !!) - ?: is-broadcasting ~|("Broadcasting a transaction" !!) - ?~ curr-xpub ~|("btc-wallet-hook: no curr-xpub set" !!) - ?: (is-dust value.act address.act) - %- (slog ~[leaf+"sending dust"]) - [[(give-update %error %no-dust)]~ state] - :: - =+ feyb=(~(gut by feybs) src.bowl ?~(fee.btc-state fee:defaults u.fee.btc-state)) - |^ - =^ tb=(unit txbu) state - (generate-txbu u.curr-xpub `src.bowl feyb ~[[address.act value.act ~]]) - =/ po=^poym ?~(tb [~ ~] [tb note.poym]) - :_ state(poym po) - ?~ tb [(give-update %error %insufficient-balance)]~ - %+ turn txis.u.tb - |=(=txi (poke-provider [%raw-tx txid.utxo.txi])) - :: - ++ generate-txbu - |= [=xpub:bc payee=(unit ship) feyb=sats txos=(list txo)] - ^- [(unit txbu) _state] - =/ uw (~(get by walts) xpub) - ?: ?|(?=(~ uw) ?!(scanned.u.uw)) - ~|("no wallet with xpub or wallet not scanned yet" !!) - =/ [tb=(unit txbu) chng=(unit sats)] - %~ with-change sut:bl - [u.uw eny.bowl block.btc-state payee feyb txos] - ?~ tb ((slog ~[leaf+"insufficient balance or not enough confirmed balance"]) [tb state]) - :: if no change, return txbu; else add change output to txbu - :: - ?~ chng [tb state] - =/ [addr=address =idx w=walt] - ~(nixt-address wad:bl u.uw %1) - :- `(~(add-output txb:bl u.tb) addr u.chng `(~(hdkey wad:bl w %1) idx)) - state(walts (~(put by walts) xpub w)) - -- - :: - :: %expect-payment - :: - check that payment is in piym - :: - replace pend.payment with incoming txid (lock) - :: - add txid to pend.piym - :: - request tx-info from provider - :: - %expect-payment - |^ - =+ pay=(~(get by ps.piym) src.bowl) - ~| "%expect-payment: matching payment not in piym" - ?~ pay !! - ?> (piym-matches u.pay) - :_ (update-pend-piym txid.act u.pay(pend `txid.act)) - ?~ prov ~ - ~[(poke-provider [%tx-info txid.act])] - :: - ++ piym-matches - |= p=payment - ?& =(payer.p src.bowl) - =(value.p value.act) - == - :: - ++ update-pend-piym - |= [txid=hexb p=payment] - ^- _state - ?~ pend.p ~|("update-pend-piym: no pending payment" !!) - %= state - ps.piym (~(put by ps.piym) payer.p p) - pend.piym (~(put by pend.piym) txid p) - == - -- - == -:: -++ handle-internal - |= intr=internal - ^- (quip card _state) - ?- -.intr - %add-poym-raw-txi - |^ - ?> =(src.bowl our.bowl) - ?~ txbu.poym `state - =. txis.u.txbu.poym - (update-poym-txis txis.u.txbu.poym +.intr) - :_ state - =+ pb=~(to-psbt txb:bl u.txbu.poym) - ?~ pb ~ - =+ vb=~(vbytes txb:bl u.txbu.poym) - =+ fee=~(fee txb:bl u.txbu.poym) - ~& >> "{} vbytes, {<(div fee vb)>} sats/byte, {} sats fee" - %- (slog [%leaf "PSBT: {}"]~) - [(give-update [%psbt u.pb fee])]~ - :: update outgoing payment with a rawtx, if the txid is in poym's txis - :: - ++ update-poym-txis - |= [txis=(list txi) txid=hexb rawtx=hexb] - ^- (list txi) - =| i=@ - |- ?: (gte i (lent txis)) txis - =/ ith=txi (snag i txis) - =? txis =(txid txid.utxo.ith) - (snap txis i `txi`ith(rawtx `rawtx)) - $(i +(i)) - -- - :: delete an incoming/outgoing payment when we see it included in a tx - :: - %close-pym - ?> =(src.bowl our.bowl) - |^ - =^ cards state - ?. included.ti.intr - `state - ?: (~(has by pend.piym) txid.ti.intr) - (piym-to-history ti.intr) - ?: (poym-has-txid txid.ti.intr) - (poym-to-history ti.intr) - `state - =^ cards2 state - (handle-tx-info ti.intr) - :_ state - (weld cards cards2) - :: - ++ poym-has-txid - |= txid=hexb - ^- ? - ?~ txbu.poym %.n - ?~ signed-tx.u.txbu.poym %.n - =(txid (get-id:txu:bc (decode:txu:bc u.signed-tx.u.txbu.poym))) - :: - checks whether poym has a signed tx - :: - checks whether the txid matches that signed tx, if not, skip - :: - clears poym - :: - returns card that adds hest to history - :: - ++ poym-to-history - |= ti=info:tx - ^- (quip card _state) - |^ - ?~ txbu.poym `state - ?~ signed-tx.u.txbu.poym `state - ?. (poym-has-txid txid.ti) - `state - =+ vout=(get-vout txos.u.txbu.poym) - ?~ vout ~|("poym-to-history: poym should always have an output" !!) - =/ new-hest=hest - (mk-hest ti xpub.u.txbu.poym our.bowl payee.u.txbu.poym u.vout note.poym) - :- [(give-update %new-tx new-hest)]~ - %= state - poym [~ ~] - history (~(put by history) txid.ti new-hest) - == - :: - ++ get-vout - |= txos=(list txo) - ^- (unit @ud) - =| idx=@ud - |- ?~ txos ~ - ?~ hk.i.txos `idx - $(idx +(idx), txos t.txos) - -- - :: - checks whether txid in pend.piym - :: - checks whether ti has a matching value output to piym - :: - if no match found, just deletes pend.piym with this tx - :: stops peer from spamming txids - :: - returns card that adds hest to history - :: - ++ piym-to-history - |= ti=info:tx - |^ ^- (quip card _state) - =+ pay=(~(get by pend.piym) txid.ti) - ?~ pay `state - :: if no matching output in piym, delete from pend.piym to stop DDOS of txids - :: - =+ vout=(get-vout value.u.pay) - ?~ vout - `(del-pend-piym txid.ti) - =/ new-hest (mk-hest ti xpub.u.pay payer.u.pay `our.bowl u.vout note.u.pay) - =. state (del-all-piym txid.ti payer.u.pay) - :- [(give-update %new-tx new-hest)]~ - %= state - history (~(put by history) txid.ti new-hest) - == - :: - ++ get-vout - |= value=sats - ^- (unit @ud) - =| idx=@ud - =+ os=outputs.ti - |- ?~ os ~ - ?: =(value.i.os value) - `idx - $(os t.os, idx +(idx)) - :: - ++ del-pend-piym - |= txid=hexb - ^- _state - state(pend.piym (~(del by pend.piym) txid.ti)) - :: - ++ del-all-piym - |= [txid=hexb payer=ship] - ^- _state - =+ nf=(~(gut by num-fam.piym) payer 1) - %= state - pend.piym (~(del by pend.piym) txid) - ps.piym (~(del by ps.piym) payer) - num-fam.piym (~(put by num-fam.piym) payer (dec nf)) - == - -- - :: - ++ mk-hest - |= $: ti=info:tx - =xpub:bc - payer=ship - payee=(unit ship) - vout=@ud - note=(unit @t) - == - ^- hest - :* xpub - txid.ti - confs.ti - recvd.ti - (turn inputs.ti |=(i=val:tx [i `payer])) - %+ turn outputs.ti - |= o=val:tx - ?: =(pos.o vout) :: check whether this is the output that went to payee - [o payee] - [o `payer] - note - == - -- - :: - %fail-broadcast-tx - ?> =(src.bowl our.bowl) - ~& >>> "%fail-broadcast-tx" - :_ state(poym [~ ~]) - [(give-update %error %broadcast-fail)]~ - :: - %succeed-broadcast-tx - ?> =(src.bowl our.bowl) - ~& > "%succeed-broadcast-tx" - :_ state - :- (give-update %broadcast-success ~) - ?~ prov ~ - :- (poke-provider [%tx-info txid.intr]) - ?~ txbu.poym ~ - ?~ payee.u.txbu.poym ~ - :_ ~ - %- poke-peer - :* u.payee.u.txbu.poym - %expect-payment - txid.intr - value:(snag 0 txos.u.txbu.poym) - == - == -:: -:: +handle-provider-status: handle connectivity updates from provider -:: - retry pend.piym on any %connected event, since we're checking mempool -:: - if status is %connected, retry all pending address lookups -:: - only retry all if previously disconnected -:: - if block is updated, retry all address reqs -:: - if provider's network doesn't match network in our state, leave -:: -++ handle-provider-status - |= s=status:bp - ^- (quip card _state) - |^ - =^ cards state - ?~ prov `state - ?. =(host.u.prov src.bowl) `state - ?- -.s - %new-block - (on-connected u.prov network.s block.s fee.s `blockhash.s `blockfilter.s) - :: - %connected - (on-connected u.prov network.s block.s fee.s ~ ~) - :: - %disconnected - `state(prov `u.prov(connected %.n)) - == - :_ state - :* (give-update %btc-state btc-state) - (give-update %change-provider prov) - cards - == - :: - ++ on-connected - |= $: p=provider - =network - block=@ud - fee=(unit sats) - blockhash=(unit hexb) - blockfilter=(unit hexb) - == - ^- (quip card _state) - :_ %_ state - prov `p(connected %.y) - btc-state [block fee now.bowl] - == - ?: ?|(?!(connected.p) (lth block.btc-state block)) - ;: weld - (retry-pend-piym network) - (retry-poym network) - (retry-addrs network) - (retry-txs network) - (retry-scans network) - retry-ahistorical-txs - == - ;: weld -:: (retry-addrs network) - retry-ahistorical-txs - (retry-pend-piym network) - == - :: - ++ retry-ahistorical-txs - ^- (list card) - %+ turn ~(tap in ahistorical-txs) - |= =txid - (poke-provider [%tx-info txid]) - - :: - ++ retry-scans - |= =network - ^- (list card) - %- zing - %+ murn ~(tap by scans) - |= [[=xpub:bc =chyg] =batch] - ?. =(network network:(~(got by walts) xpub)) ~ - `-:(req-scan batch xpub chyg) - :: +retry-addrs: get info on addresses with unconfirmed UTXOs - :: - ++ retry-addrs - |= =network - ^- (list card) - %- zing - %+ murn ~(val by walts) - |= w=walt - ?. =(network network.w) ~ - ^- (unit (list card)) - :- ~ - %+ turn ~(tap by wach.w) - |= [a=address *] - (poke-provider [%address-info a]) - :: +retry-txs: get info on txs without enough confirmations - :: - ++ retry-txs - |= =network - ^- (list card) - %+ murn ~(tap by history) - |= [=txid =hest] - =/ w (~(get by walts) xpub.hest) - ?~ w ~ - ?. =(network network.u.w) ~ - ?: (gte confs.hest confs.u.w) ~ - `(poke-provider [%tx-info txid]) - :: - ++ retry-poym - |= =network - ^- (list card) - ?~ txbu.poym ~ - =/ w (~(get by walts) xpub.u.txbu.poym) - ?~ w ~ - ?. =(network network.u.w) ~ - %+ weld - ?~ signed-tx.u.txbu.poym ~ - ~[(poke-provider [%broadcast-tx u.signed-tx.u.txbu.poym])] - %+ turn txis.u.txbu.poym - |= =txi - (poke-provider [%raw-tx ~(get-txid txb:bl u.txbu.poym)]) - :: +retry-pend-piym: check whether txids in pend-piym are in mempool - :: - ++ retry-pend-piym - |= =network - ^- (list card) - %+ murn ~(tap by pend.piym) - |= [=txid p=payment] - =/ w (~(get by walts) xpub.p) - ?~ w ~ - ?. =(network network.u.w) ~ - `(poke-provider [%tx-info txid]) - -- -:: -++ handle-provider-update - |= upd=update:bp - ^- (quip card _state) - ?~ prov `state - ?. =(host.u.prov src.bowl) `state - ?. ?=(%.y -.upd) `state - ?- -.p.upd - %address-info - :: located in the helper in Scan Logic to keep all of that unified - :: - (handle-address-info address.p.upd utxos.p.upd used.p.upd) - :: - %tx-info - =/ [cards=(list card) sty=state-1] - (handle-tx-info info.p.upd) - :_ sty - [(poke-internal [%close-pym info.p.upd]) cards] - :: - %raw-tx - :_ state - ~[(poke-internal [%add-poym-raw-txi +.p.upd])] - :: - %broadcast-tx - ?~ txbu.poym `state - ?. =(~(get-txid txb:bl u.txbu.poym) txid.p.upd) - `state - :_ state - ?: ?|(broadcast.p.upd included.p.upd) - ~[(poke-internal [%succeed-broadcast-tx txid.p.upd])] - :~ (poke-internal [%fail-broadcast-tx txid.p.upd]) - (give-update %cancel-tx txid.p.upd) - == - == -:: -++ handle-tx-info - |= ti=info:tx - ^- (quip card _state) - |^ - =/ h (~(get by history) txid.ti) - =. ahistorical-txs (~(del in ahistorical-txs) txid.ti) - =/ our-inputs=(set address) - %- silt - %+ skim - %+ turn inputs.ti - |=(=val:tx address.val) - is-our-address - =/ our-outputs=(set address) - %- silt - %+ skim - %+ turn outputs.ti - |=(=val:tx address.val) - is-our-address - =/ our-addrs=(set address) :: all our addresses in inputs/outputs of tx - (~(uni in our-inputs) our-outputs) - :: - =/ addr-info-cards=(list card) - %+ turn ~(tap in our-addrs) - |= a=address - ^- card - (poke-provider [%address-info a]) - ?: =(0 ~(wyt in our-addrs)) `state - =/ =xpub - xpub.w:(need (address-coords:bl (snag 0 ~(tap in our-addrs)) ~(val by walts))) - ?~ h :: addresses in wallets, but tx not in history - =/ new-hest=hest (mk-hest xpub our-inputs our-outputs) - =. history (~(put by history) txid.ti new-hest) - :_ state - :_ :_ addr-info-cards - (give-update %new-tx new-hest) - (give-update %balance current-balance) - ?. included.ti :: tx in history, but not in mempool/blocks - :_ state(history (~(del by history) txid.ti)) - :_ :_ addr-info-cards - (give-update %cancel-tx txid.ti) - (give-update %balance current-balance) - =/ new-hest u.h(confs confs.ti, recvd recvd.ti) - =. history (~(put by history) txid.ti new-hest) - :_ state - :_ :_ addr-info-cards - (give-update %new-tx new-hest) - (give-update %balance current-balance) - :: - ++ mk-hest - :: has tx-info - |= [=xpub:bc our-inputs=(set address) our-outputs=(set address)] - ^- hest - :* xpub - txid.ti - confs.ti - recvd.ti - (turn inputs.ti |=(v=val:tx (is-our-ship our-inputs v))) - (turn outputs.ti |=(v=val:tx (is-our-ship our-outputs v))) - ~ - == - :: - ++ is-our-ship - |= [as=(set address) v=val:tx] - ^- [=val:tx s=(unit ship)] - [v ?:((~(has in as) address.v) `our.bowl ~)] - :: - ++ is-our-address - |=(a=address ?=(^ (address-coords:bl a ~(val by walts)))) - -- -++ set-curr-xpub - |= =xpub - ^- (quip card _state) - ?~ (find ~[xpub] scanned-wallets) `state - =. curr-xpub `xpub - :_ state - [give-initial]~ -:: -:: -:: Scan Logic -:: -:: Algorithm -:: Initiate a batch for each chyg, with max-gap idxs in it -:: Watch all of the addresses made from idxs -:: Request info on all addresses from provider -:: When an %address-info comes back: -:: - remove that idx from todo.batch -:: - run check-scan to check whether that chyg is done -:: - if it isn't, refill it with max-gap idxs to scan -:: -:: +handle-address-info: updates scans and wallet with address info -:: -++ handle-address-info - |= [=address utxos=(set utxo) used=?] - ^- (quip card _state) - =/ ac (address-coords:bl address ~(val by walts)) - ?~ ac - `state - =/ [w=walt =chyg =idx] u.ac - =. walts - %+ ~(put by walts) xpub.w - %+ ~(update-address wad:bl w chyg) - address - [used chyg idx utxos] - :: if transactions haven't made it into history, request transaction info - :: - =^ cards=(list card) ahistorical-txs - %+ roll ~(tap in utxos) - |= [u=utxo cad=(list card) ah=(set txid)] - ^- [(list card) (set txid)] - ?: (~(has by history) txid.u) - [cad ah] - :- [(poke-provider [%tx-info txid.u]) cad] - (~(put by ah) txid.u) - :: if the wallet+chyg is being scanned, update the scan batch - :: - =/ b (~(get by scans) [xpub.w chyg]) - ?~ b - [cards state] - =. scans - (del-scanned u.b(has-used ?|(used has-used.u.b)) xpub.w chyg idx) - ?: empty:(scan-status xpub.w chyg) - =^ scan-cards=(list card) state - (check-scan xpub.w) - [(weld scan-cards cards) state] - :: - [cards state] -:: +req-scan -:: - adds addresses in batch to wallet's watch map as un-used addresses -:: - returns provider %address-info request cards -:: -++ req-scan - |= [b=batch =xpub:bc =chyg] - ^- (quip card _state) - =/ w=walt (~(got by walts) xpub) - =/ as=(list [address [? ^chyg idx (set utxo)]]) - %+ turn ~(tap in todo.b) - |=(=idx [(~(mk-address wad:bl w chyg) idx) [%.n chyg idx *(set utxo)]]) - =. w - |- ?~ as w - $(as t.as, w (~(update-address wad:bl w chyg) -.i.as +.i.as)) - :- (turn as |=([a=address *] (poke-provider [%address-info a]))) - %= state - scans - (~(put by scans) [xpub chyg] b) - walts - (~(put by walts) xpub w) - == -:: -++ scan-status - |= [=xpub:bc =chyg] - ^- [empty=? done=?] - =/ b=batch (~(got by scans) [xpub chyg]) - =/ empty=? =(0 ~(wyt in todo.b)) - :- empty - ?&(empty ?!(has-used.b)) -:: -++ init-batches - |= [=xpub:bc endpoint=idx] - ^- (quip card _state) - =/ b=batch - [(silt (gulf 0 endpoint)) endpoint %.n] - =^ cards0 state (req-scan b xpub %0) - =^ cards1 state (req-scan b xpub %1) - [(weld cards0 cards1) state] -:: +bump-batch -:: if the batch is done but the wallet isn't done scanning, -:: returns new address requests and updated batch -:: -++ bump-batch - |= [=xpub:bc =chyg] - ^- (quip card _state) - =/ b=batch (~(got by scans) xpub chyg) - =/ s (scan-status xpub chyg) - ?. ?&(empty.s ?!(done.s)) - `state - =/ w=walt (~(got by walts) xpub) - =/ newb=batch - :* (silt (gulf +(endpoint.b) (add endpoint.b max-gap.w))) - (add endpoint.b max-gap.w) - %.n - == - (req-scan newb xpub chyg) -:: +del-scanned: delete scanned idxs -:: -++ del-scanned - |= [b=batch =xpub:bc =chyg to-delete=idx] - ^- ^scans - %+ ~(put by scans) [xpub chyg] - b(todo (~(del in todo.b) to-delete)) -:: delete the xpub from scans and set wallet to scanned -:: -++ end-scan - |= [=xpub:bc] - ^- (quip card _state) - =/ w=walt (~(got by walts) xpub) - =. scans (~(del by scans) [xpub %0]) - =. scans (~(del by scans) [xpub %1]) - %- (slog ~[leaf+"Scanned xpub {}"]) - =. state state(walts (~(put by walts) xpub w(scanned %.y))) - (set-curr-xpub xpub) -:: +check-scan: initiate a scan if one hasn't started -:: check status of scan if one is running -:: -++ check-scan - |= =xpub:bc - ^- (quip card _state) - =/ s0 (scan-status xpub %0) - =/ s1 (scan-status xpub %1) - ?: ?&(empty.s0 done.s0 empty.s1 done.s1) - (end-scan xpub) - =^ cards0=(list card) state - (bump-batch xpub %0) - =^ cards1=(list card) state - (bump-batch xpub %1) - [(weld cards0 cards1) state] -:: -:: -:: -++ poke-provider - |= [act=action:bp] - ^- card - ?~ prov ~|("provider not set" !!) - :* %pass /[(scot %da now.bowl)] - %agent [host.u.prov %btc-provider] - %poke %btc-provider-action !>([act]) - == -:: -++ poke-peer - |= [target=ship act=action] - ^- card - :* %pass /[(scot %da now.bowl)] %agent - [target %btc-wallet] %poke - %btc-wallet-action !>(act) - == -++ poke-internal - |= [intr=internal] - ^- card - :* %pass /[(scot %da now.bowl)] %agent - [our.bowl %btc-wallet] %poke - %btc-wallet-internal !>(intr) - == -:: -++ give-update - |= upd=update - ^- card - [%give %fact ~[/all] %btc-wallet-update !>(upd)] -:: -++ give-initial - ^- card - =^ a=(unit address) state - ?~ curr-xpub `state - =/ uw=(unit walt) (~(get by walts) u.curr-xpub) - ?: ?|(?=(~ uw) ?!(scanned.u.uw)) - ~|("no wallet with xpub or wallet not scanned yet" !!) - =/ [addr=address =idx w=walt] - ~(gen-address wad:bl u.uw %0) - [`addr state(walts (~(put by walts) u.curr-xpub w))] - =/ initial=update - :* %initial - prov - curr-xpub - current-balance - current-history - btc-state - a - == - (give-update initial) -:: -++ is-dust - |= [=sats =address] - ^- ? - %+ lth sats - (mul 3 (input-weight:bc (get-bipt:adr:bc address))) -:: -++ is-broadcasting - ^- ? - ?~ txbu.poym %.n - ?=(^ signed-tx.u.txbu.poym) -:: -:: Scry Helpers -:: -++ scanned-wallets - ^- (list xpub:bc) - %+ murn ~(tap by walts) - |= [=xpub:bc w=walt] - ^- (unit xpub:bc) - ?:(scanned.w `xpub ~) -:: -++ balance - |= =xpub:bc - ^- (unit [sats sats]) - =/ w (~(get by walts) xpub) - ?~ w ~ - =/ values=(list [confirmed=sats unconfirmed=sats]) - %+ turn ~(val by wach.u.w) - |= =addi ^- [sats sats] - %+ roll - %+ turn ~(tap by utxos.addi) - |= =utxo - ^- [sats sats] - ?: (~(spendable sut:bl [u.w eny.bowl block.btc-state ~ 0 ~]) utxo) - [value.utxo 0] - [0 value.utxo] - |= [[a=sats b=sats] out=[p=sats q=sats]] - [(add a p.out) (add b q.out)] - :- ~ - %+ roll values - |= [[a=sats b=sats] out=[p=sats q=sats]] - [(add a p.out) (add b q.out)] - :: -:: -++ current-balance - ^- (unit [sats sats]) - ?~ curr-xpub ~ - (balance u.curr-xpub) -:: -++ current-history - ^- ^history - ?~ curr-xpub ~ - %- ~(gas by *^history) - %+ skim ~(tap by history) - |= [txid =hest] - =(u.curr-xpub xpub.hest) --- diff --git a/pkg/arvo/app/claz.hoon b/pkg/arvo/app/claz.hoon index 005b7f85a..5beb81c37 100644 --- a/pkg/arvo/app/claz.hoon +++ b/pkg/arvo/app/claz.hoon @@ -22,6 +22,7 @@ +* this . do ~(. +> bowl) def ~(. (default-agent this %|) bowl) + bec byk.bowl(r da+now.bowl) :: ++ on-init on-init:def ++ on-save !>(state) @@ -86,6 +87,7 @@ -- :: |_ =bowl:gall +++ bec byk.bowl(r da+now.bowl) :: ++ poke-spider |= [=path our=@p =cage] @@ -108,7 +110,7 @@ =/ new-tid=@ta :((cury cat 3) dap.bowl '--' (scot %uv eny.bowl)) =/ args - [~ `new-tid %claz-prep-command !>([node-url command])] + [~ `new-tid bec %claz-prep-command !>([node-url command])] :~ (watch-spider /prepare our.bowl /thread-result/[new-tid]) (poke-spider /prepare our.bowl %spider-start !>(args)) == diff --git a/pkg/arvo/app/dbug.hoon b/pkg/arvo/app/dbug.hoon index e2c340ce2..b5c4da98c 100644 --- a/pkg/arvo/app/dbug.hoon +++ b/pkg/arvo/app/dbug.hoon @@ -132,6 +132,12 @@ =? site ?=([%'~debug' *] site) t.site ?~ ext $(ext `%html, site [%index ~]) ::NOTE hack + :: serve dynamic session.js + :: + ?: =([/js/session `%js] [site ext]) + %- js-response:gen + %- as-octt:mimes:html + "window.ship = '{(slag 1 (scow %p our.bowl))}';" :: if not json, serve static file :: ?. ?=([~ %json] ext) @@ -418,13 +424,16 @@ ++ apps |% ++ all - ^- (list term) - %+ murn - (scry (list path) %ct %home /app) - |= =path - ^- (unit term) - ?. ?=([%app @ %hoon ~] path) ~ - `i.t.path + ^- (list dude:gall) + %- zing + ^- (list (list dude:gall)) + %+ turn + ~(tap in (scry (set desk) %cd %$ /)) + |= =desk + ^- (list dude:gall) + =- (turn ~(tap in -) head) + ;; (set [dude:gall ?]) ::TODO for some reason we need this? + (scry (set [dude:gall ?]) %ge desk /) :: ++ running |= app=term diff --git a/pkg/arvo/app/debug/index.html b/pkg/arvo/app/debug/index.html index eb37ada11..cc97475f1 100644 --- a/pkg/arvo/app/debug/index.html +++ b/pkg/arvo/app/debug/index.html @@ -12,8 +12,8 @@
- - + + diff --git a/pkg/arvo/app/landscape/js/channel.js b/pkg/arvo/app/debug/js/channel.js similarity index 100% rename from pkg/arvo/app/landscape/js/channel.js rename to pkg/arvo/app/debug/js/channel.js diff --git a/pkg/arvo/app/dojo.hoon b/pkg/arvo/app/dojo.hoon index a8a9b5dd1..affd134c7 100644 --- a/pkg/arvo/app/dojo.hoon +++ b/pkg/arvo/app/dojo.hoon @@ -12,7 +12,7 @@ => |% :: external structures +$ id @tasession :: session id +$ house :: all state - $: %6 + $: %8 egg=@u :: command count hoc=(map id session) :: conversations acl=(set ship) :: remote access whitelist @@ -65,8 +65,8 @@ $~ [%ex *hoon] $% [%ur p=@t] :: http GET request [%ge p=dojo-model] :: generator - [%te p=term q=(list dojo-source)] :: thread - [%dv p=path] :: core from source + [%te p=[=desk =term] q=(list dojo-source)] :: thread + [%dv p=beak q=path] :: core from source [%ex p=hoon] :: hoon expression [%sa p=mark] :: example mark value [%as p=mark q=dojo-source] :: simple transmute @@ -79,7 +79,7 @@ == :: +$ dojo-server :: numbered device $: p=@ud :: assembly index - q=path :: gate path + q=[=desk =path] :: gate location == :: +$ dojo-config :: configuration $: p=(list dojo-source) :: by order @@ -125,7 +125,14 @@ ++ to-command |= [gol=goal mod=dojo-model] ^- dojo-command - [[%poke gol] [0 [%ge mod(q.p [q.gol q.p.mod])]]] + =/ =desk + ::TODO maybe should recognize if the user specified a desk explicitly. + :: currently eats the :app|desk#gen case. + =+ gop=(en-beam dir(q q.gol, s /)) + ?. .^(? %gu gop) + q.dir + .^(desk %gd gop) + [[%poke gol] [0 [%ge mod(q.p [desk q.gol path.q.p.mod])]]] :: ++ parse-variable |* [sym=rule src=rule] @@ -217,7 +224,7 @@ ;~ pose ;~(plug (cold %ur lus) parse-url) ;~(plug (cold %ge lus) parse-model) - ;~(plug (cold %te hep) sym (star ;~(pfix ace parse-source))) + ;~(plug (cold %te hep) parse-thread (star ;~(pfix ace parse-source))) ;~(plug (cold %as pam) sym ;~(pfix ace parse-source)) ;~(plug (cold %do cab) parse-hoon ;~(pfix ace parse-source)) parse-value @@ -263,7 +270,20 @@ auri:de-purl:html :: ++ parse-model ;~(plug parse-server parse-config) - ++ parse-server (stag 0 (most fas sym)) + :: + ++ parse-server + %+ stag 0 + ;~ plug + ;~(pose ;~(sfix sym zap) (easy q.dir)) + (most fas sym) + == + :: + ++ parse-thread + ;~ plug + ;~(pose ;~(sfix sym zap) (easy q.dir)) + sym + == + :: ++ parse-hoon tall:hoon-parser :: ++ parse-rood @@ -334,11 +354,11 @@ :: +dy-sing: make a clay read request :: ++ dy-sing - |= [way=wire =care:clay =path] + |= [way=wire =care:clay =beak =path] ^+ +>+> ?> ?=(~ pux) %- he-card(poy `+>+<(pux `way)) - =/ [=ship =desk =case:clay] he-beak + =/ [=ship =desk =case:clay] beak [%pass way %arvo %c %warp ship desk ~ %sing care case path] :: ++ dy-request @@ -427,7 +447,13 @@ ++ dy-init-server :: ++dojo-server |= srv=dojo-server =. p.srv num - [srv +>.$(num +(num), job (~(put by job) num [%dv [%gen q.srv]]))] + =/ bek=beak he-beak + :- srv + %_ +>.$ + num +(num) + job %+ ~(put by job) num + [%dv bek(q desk.q.srv) [%gen path.q.srv]] + == :: ++ dy-init-config :: prepare config |= cig=dojo-config @@ -512,7 +538,7 @@ $?(%eny %now %our) !! %lib .(lib ~) %sur .(sur ~) - %dir .(dir [[our.hid %home ud+0] /]) + %dir .(dir [[our.hid %base ud+0] /]) == =+ cay=(~(got by rez) p.q.mad) ?- -.p.mad @@ -538,8 +564,8 @@ :: %dir =+ ^= pax ^- path =+ pax=((dy-cast path !>(*path)) q.cay) - ?: ?=(~ pax) ~[(scot %p our.hid) %home '0'] - ?: ?=([@ ~] pax) ~[i.pax %home '0'] + ?: ?=(~ pax) ~[(scot %p our.hid) %base '0'] + ?: ?=([@ ~] pax) ~[i.pax %base '0'] ?: ?=([@ @ ~] pax) ~[i.pax i.t.pax '0'] pax =. dir (need (de-beam pax)) @@ -673,9 +699,9 @@ [%sa mark] [%as mark dy-shown] [%do hoon dy-shown] - [%te term (list dy-shown)] - [%ge path (list dy-shown) (map term (unit dy-shown))] - [%dv path] + [%te [desk term] (list dy-shown)] + [%ge [desk path] (list dy-shown) (map term (unit dy-shown))] + [%dv beak path] == == :: @@ -850,7 +876,7 @@ (dy-hand %noun q.cag) :: ++ dy-wool-poke - |= [fil=term src=(list dojo-source)] + |= [[=desk =term] src=(list dojo-source)] ^+ +>+> ?> ?=(~ pux) =/ tid (scot %ta (cat 3 'dojo_' (scot %uv (sham eny.hid)))) @@ -860,7 +886,9 @@ [%pass /wool %agent [our.hid %spider] %watch /thread-result/[tid]] %- he-card =/ =cage :: also sub - [%spider-start !>([~ `tid fil (dy-some src)])] + ::TODO would be nice if spider supported starting from paths, + :: for semantics/abilities/code closer to generators. + [%spider-start !>([~ `tid he-beak(q.dir desk) term (dy-some src)])] [%pass /wool %agent [our.hid %spider] %poke cage] :: ++ dy-make :: build step @@ -871,7 +899,7 @@ %ur (dy-request /hand `request:http`[%'GET' p.bil ~ ~]) %te (dy-wool-poke p.bil q.bil) %ex (dy-mere p.bil) - %dv (dy-sing hand+p.bil %a (snoc p.bil %hoon)) + %dv (dy-sing hand+q.bil %a p.bil (snoc q.bil %hoon)) %ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil) %sa =+ .^(=dais:clay cb+(en-beam he-beak /[p.bil])) @@ -879,6 +907,9 @@ :: %as =/ cag=cage (dy-cage p.q.bil) + =/ has-mark .?((get-fit:clay he-beak %mar p.bil)) + ?. has-mark :: yolo + (dy-hand p.bil q.cag) =+ .^(=tube:clay cc+(en-beam he-beak /[p.cag]/[p.bil])) (dy-hand p.bil (tube q.cag)) :: @@ -1015,13 +1046,13 @@ :: ++ he-prow :: where we are ^- tape - ?: &(=(our.hid p.dir) =(%home q.dir) =([%ud 0] r.dir) =(~ s.dir)) ~ + ?: &(=(our.hid p.dir) =(%base q.dir) =([%ud 0] r.dir) =(~ s.dir)) ~ %+ weld ?: &(=(our.hid p.dir) =([%ud 0] r.dir)) (weld "/" (trip q.dir)) ;: weld "/" ?:(=(our.hid p.dir) "=" (scow %p p.dir)) - "/" ?:(=(%home q.dir) "=" (trip q.dir)) + "/" ?:(=(%base q.dir) "=" (trip q.dir)) "/" ?:(=([%ud 0] r.dir) "=" (scow r.dir)) == ?:(=(~ s.dir) "" (spud s.dir)) @@ -1039,6 +1070,7 @@ ?+ way !! [%hand *] ?~ riot + ~> %slog.0^leaf/"dojo: %writ fail {}" (he-diff(poy ~) %tan >%generator-build-fail< >(snoc t.way %hoon)< ~) (~(dy-hand dy u.poy(pux ~)) noun+!<(vase q.r.u.riot)) == @@ -1140,7 +1172,7 @@ :+ %clhp [%rock %tas %cx] %+ rash pax.source.com - rood:(vang | /(scot %p our.hid)/home/(scot %da now.hid)) + rood:(vang | /(scot %p our.hid)/base/(scot %da now.hid)) :: %url [%ur (crip (en-purl:html url.source.com))] %api !! @@ -1171,7 +1203,7 @@ %hoon :* %do %+ rash code.source.com - tall:(vang | /(scot %p our.hid)/home/(scot %da now.hid)) + tall:(vang | /(scot %p our.hid)/base/(scot %da now.hid)) $(num +(num), source.com next.source.com) == :: @@ -1351,7 +1383,7 @@ ++ complete-naked-poke |= app=term =/ pax=path - /(scot %p our.hid)/[q.byk.hid]/(scot %da now.hid)/app + /(scot %p our.hid)/[q:he-beam]/(scot %da now.hid)/app %+ complete (cat 3 ':' app) %+ murn ~(tap by dir:.^(arch %cy pax)) |= [=term ~] @@ -1381,7 +1413,7 @@ (cat 3 '|' gen) :((cury cat 3) ':' app '|' gen) =/ pfix=path - /(scot %p our.hid)/[q.byk.hid]/(scot %da now.hid)/gen/[app] + /(scot %p our.hid)/[q:he-beam]/(scot %da now.hid)/gen/[app] :: %^ tab-generators:auto pfix `app %+ murn @@ -1397,7 +1429,7 @@ |= gen=term %+ complete (cat 3 '+' gen) =/ pax=path - /(scot %p our.hid)/[q.byk.hid]/(scot %da now.hid)/gen + /(scot %p our.hid)/[q:he-beam]/(scot %da now.hid)/gen %^ tab-generators:auto pax ~ %+ murn ~(tap by dir:.^(arch %cy pax)) @@ -1493,12 +1525,53 @@ !>(state) :: ++ on-load - |= old=vase - ?: ?=(%6 +<.old) - `..on-init(state !<(house old)) - =/ old-5 !<([%5 egg=@u hoc=(map id session)] old) - =/ =house [%6 egg.old-5 hoc.old-5 *(set ship)] - `..on-init(state house) + |= ole=vase + |^ =+ old=!<(house-any ole) + =? old ?=(%5 -.old) + (house-5-to-6 old) + =? old ?=(?(%6 %7) -.old) + (house-6-7-to-8 +.old) + ?> ?=(%8 -.old) + `..on-init(state old) + :: + +$ house-any $%(house house-7 house-6 house-5) + :: + +$ house-7 [%7 house-6-7] + +$ house-6 [%6 house-6-7] + +$ house-6-7 + $: egg=@u :: command count + hoc=(map id session-6) :: conversations + acl=(set ship) :: remote access whitelist + == :: + +$ session-6 :: per conversation + $: say=sole-share :: command-line state + dir=beam :: active path + poy=(unit *) :: working + $: :: sur: structure imports + :: + sur=(list cable:clay) + :: lib: library imports + :: + lib=(list cable:clay) + == + var=(map term cage) :: variable state + old=(set term) :: used TLVs + buf=tape :: multiline buffer + == :: + ++ house-6-7-to-8 + |= old=house-6-7 + [%8 egg.old (~(run by hoc.old) session-6-to-8) acl.old] + ++ session-6-to-8 + |= old=session-6 + ~? ?=(^ poy.old) [dap.hid %cancelling-for-load] + old(poy ~, -.dir [our.hid %base ud+0]) + :: + +$ house-5 + [%5 egg=@u hoc=(map id session)] + ++ house-5-to-6 + |= old=house-5 + [%6 egg.old hoc.old *(set ship)] + -- :: ++ on-poke |= [=mark =vase] @@ -1555,7 +1628,7 @@ =? hoc (~(has by hoc) id) ~& [%dojo-peer-replaced id] (~(del by hoc) id) - =/ =session %*(. *session -.dir [our.hid %home ud+0]) + =/ =session %*(. *session -.dir [our.hid %base ud+0]) =^ moves state he-abet:~(he-prom he hid id ~ session) [moves ..on-init] diff --git a/pkg/arvo/app/eth-sender.hoon b/pkg/arvo/app/eth-sender.hoon index 78eebbb16..5c4a5d34a 100644 --- a/pkg/arvo/app/eth-sender.hoon +++ b/pkg/arvo/app/eth-sender.hoon @@ -49,6 +49,7 @@ +* this . do ~(. +> bowl) def ~(. (default-agent this %|) bowl) + bec byk.bowl(r da+now.bowl) :: ++ on-init on-init:def ++ on-save !>(state) @@ -117,6 +118,7 @@ -- :: |_ =bowl:gall +++ bec byk.bowl(r da+now.bowl) ++ poke-spider |= [=path our=@p =cage] ^- card @@ -137,9 +139,7 @@ ^- (list card) =/ tid=@ta :((cury cat 3) dap.bowl '--' node-id '--' (scot %uv eny.bowl)) - =/ args - :^ ~ `tid %eth-send-txs - !>([node step txs]) + =/ args [~ `tid bec %eth-send-txs !>([node step txs])] :~ (watch-spider /send/[tid] our.bowl /thread-result/[tid]) (poke-spider /send/[tid] our.bowl %spider-start !>(args)) == @@ -151,7 +151,7 @@ .^ (list cord) %cx (scot %p our.bowl) - %home + %base (scot %da now.bowl) path == diff --git a/pkg/arvo/app/eth-watcher.hoon b/pkg/arvo/app/eth-watcher.hoon index a599d7539..59761bb0e 100644 --- a/pkg/arvo/app/eth-watcher.hoon +++ b/pkg/arvo/app/eth-watcher.hoon @@ -64,6 +64,7 @@ |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) + bec byk.bowl(r da+now.bowl) :: ++ on-init ^- (quip card _this) @@ -535,8 +536,9 @@ (cat 3 'eth-watcher--' (scot %uv eny.bowl)) :_ dog(running `[now.bowl new-tid]) =/ args - :^ ~ `new-tid %eth-watcher - !>([~ `watchpup`[- number pending-logs blocks]:dog]) + :* ~ `new-tid bec %eth-watcher + !>([~ `watchpup`[- number pending-logs blocks]:dog]) + == :~ (watch-spider path our.bowl /thread-result/[new-tid]) (poke-spider path our.bowl %spider-start !>(args)) == diff --git a/pkg/arvo/app/gaze.hoon b/pkg/arvo/app/gaze.hoon index 8b7cef5b4..18f154e47 100644 --- a/pkg/arvo/app/gaze.hoon +++ b/pkg/arvo/app/gaze.hoon @@ -62,6 +62,7 @@ +* this . do ~(. +> bowl) def ~(. (default-agent this %|) bowl) + bec byk.bowl(r da+now.bowl) :: ++ on-init ^- (quip card _this) @@ -174,6 +175,7 @@ -- :: |_ =bowl:gall +++ bec byk.bowl(r da+now.bowl) ++ setup-cards ^- (list card) :~ wait-export @@ -297,7 +299,7 @@ :: %+ poke-spider /timestamps/[tid] :- %spider-start - =- !>([~ `tid %eth-get-timestamps -]) + =- !>([~ `tid bec %eth-get-timestamps -]) !> ^- [@t (list @ud)] :- node-url =- ~(tap in -) diff --git a/pkg/arvo/app/goad.hoon b/pkg/arvo/app/goad.hoon deleted file mode 100644 index 5b043309b..000000000 --- a/pkg/arvo/app/goad.hoon +++ /dev/null @@ -1,46 +0,0 @@ -/+ default-agent, verb -%+ verb | -^- agent:gall -=> - |% - ++ goad - |= force=? - :~ [%pass /gall %arvo %g %goad force ~] - == - +$ state - $@ ~ - [%0 ~] - -- -|_ =bowl:gall -+* this . - def ~(. (default-agent this %|) bowl) -:: -++ on-poke - |= [=mark =vase] - ?: ?=([%noun * %go] +<) - [(goad |) this] - ?: ?=([%noun * %force] +<) - [(goad &) this] - (on-poke:def mark vase) -:: -++ on-arvo - |= [wir=wire sin=sign-arvo] - ?+ wir (on-arvo:def wir sin) - [%clay ~] `this - [%behn ~] `this :: backcompat - == -:: -++ on-agent on-agent:def -++ on-fail on-fail:def -++ on-init on-init:def -++ on-leave on-leave:def -++ on-load - |= =vase - =+ !<(old=state vase) - ?^ old `this - [(goad &) this] -:: -++ on-peek on-peek:def -++ on-save !>([%0 ~]) -++ on-watch on-watch:def --- diff --git a/pkg/arvo/app/hark-graph-hook.hoon b/pkg/arvo/app/hark-graph-hook.hoon deleted file mode 100644 index 6cc767efc..000000000 --- a/pkg/arvo/app/hark-graph-hook.hoon +++ /dev/null @@ -1,472 +0,0 @@ -:: hark-graph-hook: notifications for graph-store [landscape] -:: -/- post, group-store, metadata=metadata-store, hook=hark-graph-hook, store=hark-store -/+ resource, mdl=metadata, default-agent, dbug, graph-store, graph, grouplib=group, store=hark-store -:: -:: -~% %hark-graph-hook-top ..part ~ -|% -+$ card card:agent:gall -+$ versioned-state - $% state-0 - state-1 - == -:: -+$ state-0 - [%0 base-state-0] -:: -+$ state-1 - [%1 base-state-0] -:: -+$ base-state-0 - $: watching=(set [resource index:post]) - mentions=_& - watch-on-self=_& - == -:: -++ scry - |* [[our=@p now=@da] =mold p=path] - ?> ?=(^ p) - ?> ?=(^ t.p) - .^(mold i.p (scot %p our) i.t.p (scot %da now) t.t.p) -:: -++ scry-conversion - |= [[our=@p now=@da] desk=term =mark] - ~+ - %^ scry [our now] - tube:clay - /cc/[desk]/[mark]/notification-kind --- -:: -=| state-1 -=* state - -:: -=< -%- agent:dbug -^- agent:gall -~% %hark-graph-hook-agent ..card ~ -|_ =bowl:gall -+* this . - ha ~(. +> bowl) - def ~(. (default-agent this %|) bowl) - met ~(. mdl bowl) - grp ~(. grouplib bowl) - gra ~(. graph bowl) -:: -++ on-init - :_ this - ~[watch-graph:ha] -:: -++ on-save !>(state) -++ on-load - |= =vase - ^- (quip card _this) - =+ !<(old=versioned-state vase) - =| cards=(list card) - |- - ?: ?=(%0 -.old) - %_ $ - -.old %1 - :: - cards - :_ cards - [%pass / %agent [our dap]:bowl %poke noun+!>(%rewatch-dms)] - == - :_ this(state old) - =. cards (flop cards) - %+ welp - ?: (~(has by wex.bowl) [/graph our.bowl %graph-store]) - cards - [watch-graph:ha cards] - %+ turn - ^- (list mark) - :~ %graph-validator-chat - %graph-validator-link - %graph-validator-publish - == - |= =mark - ^- card - =/ =wire /validator/[mark] - =/ =rave:clay [%sing %c [%da now.bowl] /[mark]/notification-kind] - [%pass wire %arvo %c %warp our.bowl [%home `rave]] -:: -++ on-watch - |= =path - ^- (quip card _this) - =^ cards state - ?+ path (on-watch:def path) - :: - [%updates ~] - :_ state - %+ give:ha ~ - :* %initial - watching - mentions - watch-on-self - == - == - [cards this] -:: -++ on-poke - ~/ %hark-graph-hook-poke - |= [=mark =vase] - ^- (quip card _this) - |^ - ?> (team:title our.bowl src.bowl) - =^ cards state - ?+ mark (on-poke:def mark vase) - %hark-graph-hook-action - (hark-graph-hook-action !<(action:hook vase)) - %noun - (poke-noun !<(* vase)) - == - [cards this] - :: - ++ poke-noun - |= non=* - [~ state] -:: ?> ?=(%rewatch-dms non) -:: =/ graphs=(list resource) -:: ~(tap in get-keys:gra) -:: %_ state -:: watching -:: %- ~(gas in watching) -:: (murn graphs |=(rid=resource ?:((should-watch:ha rid) `[rid ~] ~))) -:: == - :: - ++ hark-graph-hook-action - |= =action:hook - ^- (quip card _state) - |^ - :- (give:ha ~[/updates] action) - ?- -.action - %listen (listen +.action) - %ignore (ignore +.action) - %set-mentions (set-mentions +.action) - %set-watch-on-self (set-watch-on-self +.action) - == - ++ listen - |= [graph=resource =index:post] - ^+ state - state(watching (~(put in watching) [graph index])) - :: - ++ ignore - |= [graph=resource =index:post] - ^+ state - state(watching (~(del in watching) [graph index])) - :: - ++ set-mentions - |= ment=? - ^+ state - state(mentions ment) - :: - ++ set-watch-on-self - |= self=? - ^+ state - state(watch-on-self self) - -- - -- -:: -++ on-agent - ~/ %hark-graph-hook-agent - |= [=wire =sign:agent:gall] - ^- (quip card _this) - |^ - ?+ -.sign (on-agent:def wire sign) - %kick - :_ this - ?. ?=([%graph ~] wire) - ~ - ~[watch-graph:ha] - :: - %fact - ?. ?=(%graph-update-2 p.cage.sign) - (on-agent:def wire sign) - =^ cards state - (graph-update !<(update:graph-store q.cage.sign)) - [cards this] - == - :: - ++ graph-update - |= =update:graph-store - ^- (quip card _state) - ?+ -.q.update `state - %add-graph (add-graph resource.q.update) - :: - ?(%remove-graph %archive-graph) - (remove-graph resource.q.update) - :: - %remove-posts - (remove-posts resource.q.update indices.q.update) - :: - %add-nodes - =* rid resource.q.update - =/ assoc=(unit association:metadata) - (peek-association:met %graph rid) - (check-nodes ~(val by nodes.q.update) rid assoc) - == - :: this is awful, but notification kind should always switch - :: on the index, so hopefully doesn't matter - :: TODO: rethink this - ++ remove-posts - |= [rid=resource indices=(set index:graph-store)] - =/ to-remove - %- ~(gas by *(set [resource index:graph-store])) - (turn ~(tap in indices) (lead rid)) - :_ state(watching (~(dif in watching) to-remove)) - =/ =tube:clay - (get-conversion:ha rid) - %+ roll - ~(tap in indices) - |= [=index:graph-store out=(list card)] - =| =indexed-post:graph-store - =. index.p.indexed-post index - =+ !<(u-notif-kind=(unit notif-kind:hook) (tube !>(indexed-post))) - ?~ u-notif-kind out - =* notif-kind u.u-notif-kind - =/ =stats-index:store - [%graph rid (scag parent.index-len.notif-kind index)] - ?. ?=(%each mode.notif-kind) out - :_ out - (poke-hark %read-each stats-index index) - :: - ++ poke-hark - |= =action:store - ^- card - [%pass / %agent [our.bowl %hark-store] %poke hark-action+!>(action)] - :: - ++ remove-graph - |= rid=resource - =/ unwatched - %- ~(gas in *(set [resource index:graph-store])) - %+ skim ~(tap in watching) - |= [r=resource idx=index:graph-store] - =(r rid) - :_ state(watching (~(dif in watching) unwatched)) - ^- (list card) - :- (poke-hark:ha %remove-graph rid) - %- zing - %+ turn ~(tap in unwatched) - |= [r=resource =index:graph-store] - (give:ha ~[/updates] %ignore r index) - :: - ++ add-graph - |= rid=resource - ^- (quip card _state) - =/ graph=graph:graph-store :: graph in subscription is bunted - (get-graph-mop:gra rid) - =/ node=(unit node:graph-store) - (bind (pry:orm:graph-store graph) |=([@ =node:graph-store] node)) - =/ assoc=(unit association:metadata) - (peek-association:met %graph rid) - =^ cards state - (check-nodes (drop node) rid assoc) - ?. (should-watch:ha rid assoc) - [cards state] - :_ state(watching (~(put in watching) [rid ~])) - (weld cards (give:ha ~[/updates] %listen [rid ~])) - :: - ++ check-nodes - |= $: nodes=(list node:graph-store) - rid=resource - assoc=(unit association:metadata) - == - abet:check:(abed:handle-update:ha rid nodes) - -- -:: -++ on-peek on-peek:def -:: -++ on-leave on-leave:def -++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card _this) - ?+ wire (on-arvo:def wire sign-arvo) - :: - [%validator @ ~] - :_ this - =* validator i.t.wire - =/ =rave:clay [%next %c [%da now.bowl] /[validator]/notification-kind] - [%pass wire %arvo %c %warp our.bowl [%home `rave]]~ - == -++ on-fail on-fail:def --- -:: -|_ =bowl:gall -+* met ~(. mdl bowl) - grp ~(. grouplib bowl) - gra ~(. graph bowl) -:: -++ get-conversion - |= rid=resource - ^- tube:clay - =+ %^ scry [our now]:bowl - ,mark=(unit mark) - /gx/graph-store/graph-mark/(scot %p entity.rid)/[name.rid]/noun - ?~ mark - |=(v=vase !>(~)) - (scry-conversion [our now]:bowl q.byk.bowl u.mark) -:: -++ give - |= [paths=(list path) =update:hook] - ^- (list card) - [%give %fact paths hark-graph-hook-update+!>(update)]~ -:: -++ watch-graph - ^- card - [%pass /graph %agent [our.bowl %graph-store] %watch /updates] -:: -++ poke-hark - |= =action:store - ^- card - =- [%pass / %agent [our.bowl %hark-store] %poke -] - hark-action+!>(action) -:: -++ is-mention - |= contents=(list content:post) - ^- ? - ?. mentions %.n - ?~ contents %.n - ?. ?=(%mention -.i.contents) - $(contents t.contents) - ?: =(our.bowl ship.i.contents) - %.y - $(contents t.contents) -:: -++ should-watch - |= [rid=resource assoc=(unit association:metadata)] - ^- ? - ?~ assoc - %.y - &(watch-on-self =(our.bowl entity.rid)) -:: -++ handle-update - |_ $: rid=resource :: input - updates=(list node:graph-store) - mark=(unit mark) - hark-pokes=(list action:store) :: output - new-watches=(list index:graph-store) - == - ++ update-core . - :: - ++ abed - |= [r=resource upds=(list node:graph-store)] - =/ m=(unit ^mark) - (get-mark:gra r) - update-core(rid r, updates upds, mark m) - :: - ++ get-conversion - :: LA: this tube should be cached in %hark-graph-hook state - :: instead of just trying to keep it warm, as the scry overhead is large - ~+ (^get-conversion rid) - :: - ++ abet - ^- (quip card _state) - :_ state(watching (~(uni in watching) (silt (turn new-watches (lead rid))))) - ^- (list card) - %+ welp (turn (flop hark-pokes) poke-hark) - %- zing - %+ turn (flop new-watches) - |=(=index:graph-store (give ~[/updates] [%listen rid index])) - :: - ++ hark - |= =action:store - ^+ update-core - update-core(hark-pokes [action hark-pokes]) - :: - ++ new-watch - |= [=index:graph-store =watch-for:hook =index-len:hook] - =? new-watches =(%siblings watch-for) - [(scag parent.index-len index) new-watches] - =? new-watches =(%children watch-for) - [(scag self.index-len index) new-watches] - update-core - :: - ++ check - |- ^+ update-core - ?~ updates - update-core - =/ core=_update-core - (check-node i.updates) - =. updates.core t.updates - $(update-core core) - :: - ++ check-node-children - |= =node:graph-store - ^+ update-core - ?: ?=(%empty -.children.node) - update-core - =/ children=(list [=atom =node:graph-store]) - (tap:orm:graph-store p.children.node) - |- ^+ update-core - ?~ children - update-core - =. update-core (check-node node.i.children) - $(children t.children) - :: - ++ check-node - |= =node:graph-store - ^+ update-core - =. update-core (check-node-children node) - ?: ?=(%| -.post.node) - update-core - =* pos p.post.node - =+ !< notif-kind=(unit notif-kind:hook) - %- get-conversion - !>(`indexed-post:graph-store`[0 pos]) - ?~ notif-kind - update-core - =/ desc=@t - ?: (is-mention contents.pos) - %mention - name.u.notif-kind - =* not-kind u.notif-kind - =/ parent=index:post - (scag parent.index-len.not-kind index.pos) - =/ notif-index=index:store - [%graph rid mark desc parent] - ?: =(our.bowl author.pos) - (self-post node notif-index not-kind) - =. update-core - (update-unread-count not-kind notif-index [time-sent index]:pos) - =? update-core - ?| =(desc %mention) - (~(has in watching) [rid parent]) - =(mark `%graph-validator-dm) - == - =/ =contents:store - [%graph (limo pos ~)] - (add-unread notif-index [time-sent.pos %.n contents]) - update-core - :: - ++ update-unread-count - |= [=notif-kind:hook =index:store time=@da ref=index:graph-store] - =/ =stats-index:store - (to-stats-index:store index) - ?- mode.notif-kind - %count (hark %unread-count stats-index time) - %each (hark %unread-each stats-index ref time) - %none update-core - == - :: - ++ self-post - |= $: =node:graph-store - =index:store - =notif-kind:hook - == - ^+ update-core - ?> ?=(%& -.post.node) - =/ =stats-index:store - (to-stats-index:store index) - =. update-core - (hark %seen-index time-sent.p.post.node stats-index) - =? update-core ?=(%count mode.notif-kind) - (hark %read-count stats-index) - =? update-core watch-on-self - (new-watch index.p.post.node [watch-for index-len]:notif-kind) - update-core - :: - ++ add-unread - |= [=index:store =notification:store] - (hark %add-note index notification) - -- --- diff --git a/pkg/arvo/app/hark-store.hoon b/pkg/arvo/app/hark-store.hoon deleted file mode 100644 index ab34ac6f8..000000000 --- a/pkg/arvo/app/hark-store.hoon +++ /dev/null @@ -1,710 +0,0 @@ -:: hark-store: notifications and unread counts [landscape] -:: -:: hark-store can store unread counts differently, depending on the -:: resource. -:: - last seen. This way, hark-store simply stores an index into -:: graph-store, which represents the last "seen" item, useful for -:: high-volume applications which are intrinsically time-ordered. i.e. -:: chats, comments -:: - each. Hark-store will store an index for each item that is unread. -:: Usefull for non-linear, low-volume applications, i.e. blogs, -:: collections -:: -/- post, group-store, metadata-store, store=hark-store -/+ resource, metadata, default-agent, dbug, graph-store, graphl=graph, verb, store=hark-store -:: -:: -~% %hark-store-top ..part ~ -|% -+$ card card:agent:gall -+$ versioned-state - $% state:state-zero:store - state:state-one:store - state-2 - state-3 - state-4 - state-5 - state-6 - state-7 - == -+$ unread-stats - [indices=(set index:graph-store) last=@da] -:: -+$ base-state - $: unreads-each=(jug stats-index:store index:graph-store) - unreads-count=(map stats-index:store @ud) - timeboxes=(map stats-index:store @da) - unread-notes=timebox:store - last-seen=(map stats-index:store @da) - =notifications:store - archive=notifications:store - current-timebox=@da - dnd=_| - == -:: -+$ state-2 - [%2 state-two:store] -:: -+$ state-3 - [%3 state-two:store] -:: -+$ state-4 - [%4 state-three:store] -:: -+$ state-5 - [%5 state-three:store] -:: -+$ state-6 - [%6 state-four:store] -:: -+$ state-7 - [%7 base-state] -:: -:: -++ orm ((ordered-map @da timebox:store) gth) --- -:: -=| state-7 -=* state - -:: -=< -%+ verb | -%- agent:dbug -^- agent:gall -~% %hark-store-agent ..card ~ -|_ =bowl:gall -+* this . - ha ~(. +> bowl) - def ~(. (default-agent this %|) bowl) - met ~(. metadata bowl) - gra ~(. graphl bowl) -:: -++ on-init - :_ this - ~[autoseen-timer] -:: -++ on-save !>(state) -++ on-load - |= =old=vase - ^- (quip card _this) - =/ old - !<(versioned-state old-vase) - =| cards=(list card) - |^ - ^- (quip card _this) - ?- -.old - %7 - :- (flop cards) - this(state old) - :: - %6 - %_ $ - -.old %7 - :: - +.old - %* . *base-state - notifications (notifications:to-five:upgrade:store notifications.old) - archive ~ - unreads-each unreads-each.old - unreads-count unreads-count.old - last-seen last-seen.old - current-timebox current-timebox - dnd dnd.old - == - == - :: - %5 - %_ $ - -.old %6 - notifications.old (notifications:to-four:upgrade:store notifications.old) - archive.old *notifications:state-four:store - == - :: - %4 - %_ $ - -.old %5 - :: - last-seen.old - %- ~(run by last-seen.old) - |=(old=@da (min old now.bowl)) - == - :: - %3 - %_ $ - -.old %4 - notifications.old (notifications:to-three:upgrade:store notifications.old) - archive.old *notifications:state-three:store - == - :: - %2 - %_ $ - -.old %3 - :: - cards - :_ cards - [%pass / %agent [our dap]:bowl %poke noun+!>(%fix-dangling)] - == - :: - %1 - %_ $ - :: - old - %* . *state-2 - unreads-each ((convert-unread ,(set index:graph-store)) uni-by unreads-each.old) - unreads-count ((convert-unread ,@ud) add unreads-count.old) - last-seen ((convert-unread ,@da) max last-seen.old) - notifications notifications.old - archive archive.old - current-timebox current-timebox.old - dnd dnd.old - == - == - :: - %0 - %_ $ - :: - old - %* . *state:state-one:store - notifications (convert-notifications-1 notifications.old) - archive (convert-notifications-1 archive.old) - current-timebox current-timebox.old - dnd dnd.old - == - == - == - :: - ++ uni-by - |= [a=(set index:graph-store) b=(set index:graph-store)] - =/ merged - (~(uni in a) b) - %- ~(gas in *(set index:graph-store)) - %+ skip ~(tap in merged) - |=(=index:graph-store &(=((lent index) 3) !=(-:(flop index) 1))) - :: - ++ convert-unread - |* value=mold - |= [combine=$-([value value] value) unreads=(map index:store value)] - ^- (map stats-index:store value) - %+ roll - ~(tap in unreads) - |= [[=index:store val=value] out=(map stats-index:store value)] - =/ old=value - (~(gut by unreads) index (combine)) - =/ =stats-index:store - (to-stats-index:store index) - (~(put by out) stats-index (combine old val)) - :: - ++ convert-notifications-1 - |= old=notifications:state-zero:store - %+ gas:orm:state-two:store *notifications:state-two:store - ^- (list [@da timebox:state-two:store]) - %+ murn - (tap:orm:state-zero:store old) - |= [time=@da =timebox:state-zero:store] - ^- (unit [@da timebox:state-two:store]) - =/ new-timebox=timebox:state-two:store - (convert-timebox-1 timebox) - ?: =(0 ~(wyt by new-timebox)) - ~ - `[time new-timebox] - :: - ++ convert-timebox-1 - |= =timebox:state-zero:store - ^- timebox:state-two:store - %- ~(gas by *timebox:state-two:store) - ^- (list [index:state-two:store notification:state-two:store]) - %+ murn - ~(tap by timebox) - |= [=index:state-zero:store =notification:state-zero:store] - ^- (unit [index:state-two:store notification:state-two:store]) - =/ new-index=(unit index:state-two:store) - (convert-index-1 index) - =/ new-notification=(unit notification:state-two:store) - (convert-notification-1 notification) - ?~ new-index ~ - ?~ new-notification ~ - `[u.new-index u.new-notification] - :: - ++ convert-index-1 - |= =index:state-zero:store - ^- (unit index:state-two:store) - ?+ -.index `index - %chat ~ - :: - %graph - =, index - `[%graph graph *resource module description ~] - == - :: - ++ convert-notification-1 - |= =notification:state-zero:store - ^- (unit notification:state-two:store) - ?: ?=(%chat -.contents.notification) - ~ - `notification - -- -:: -++ on-watch - |= =path - ^- (quip card _this) - ?> (team:title [src our]:bowl) - |^ - ?+ path (on-watch:def path) - :: - [%updates ~] - :_ this - [%give %fact ~ hark-update+!>(initial-updates)]~ - == - :: - ++ initial-updates - ^- update:store - :- %more - ^- (list update:store) - :~ give-unreads - [%set-dnd dnd] - give-notifications - == - :: - ++ give-notifications - ^- update:store - [%timebox ~ ~(tap by unread-notes)] - :: - ++ give-since-unreads - ^- (list [stats-index:store stats:store]) - %+ turn - ~(tap by unreads-count) - |= [=stats-index:store count=@ud] - :* stats-index - [%count count] - (~(gut by last-seen) stats-index *time) - == - :: - ++ give-each-unreads - ^- (list [stats-index:store stats:store]) - %+ turn - ~(tap by unreads-each) - |= [=stats-index:store indices=(set index:graph-store)] - :* stats-index - [%each indices] - (~(gut by last-seen) stats-index *time) - == - :: - ++ give-unreads - ^- update:store - :- %unreads - ;: weld - give-each-unreads - give-since-unreads - == - -- -:: -++ on-peek - |= =path - ^- (unit (unit cage)) - ?+ path (on-peek:def path) - :: - [%x %recent ?(%archive %inbox) @ @ ~] - =/ is-archive - =(%archive i.t.t.path) - =/ offset=@ud - (slav %ud i.t.t.t.path) - =/ length=@ud - (slav %ud i.t.t.t.t.path) - :^ ~ ~ %hark-update - !> ^- update:store - :- %more - %+ turn - %+ scag length - %+ slag offset - %- tap-nonempty:ha - ?:(is-archive archive notifications) - |= [time=@da =timebox:store] - ^- update:store - [%timebox `time ~(tap by timebox)] - == -:: -++ on-poke - ~/ %hark-store-poke - |= [=mark =vase] - ^- (quip card _this) - |^ - ?> (team:title our.bowl src.bowl) - =^ cards state - ?+ mark (on-poke:def mark vase) - %hark-action (hark-action !<(action:store vase)) - %noun (poke-noun !<(* vase)) - == - [cards this] - :: - ++ poke-noun - |= val=* - ?+ val ~|(%bad-noun-poke !!) - %fix-dangling fix-dangling - %print ~&(+.state [~ state]) - == - :: - ++ fix-dangling - =/ graphs get-keys:gra - :_ state - %+ roll - ~(tap by unreads-each) - |= $: [=stats-index:store indices=(set index:graph-store)] - out=(list card) - == - ?. ?=(%graph -.stats-index) out - ?. (~(has in graphs) graph.stats-index) - :_(out (poke-us %remove-graph graph.stats-index)) - %+ welp out - %+ turn - %+ skip - ~(tap in indices) - |= =index:graph-store - (check-node-existence:gra graph.stats-index index) - |=(=index:graph-store (poke-us %read-each stats-index index)) - :: - ++ poke-us - |= =action:store - ^- card - [%pass / %agent [our dap]:bowl %poke hark-action+!>(action)] - :: - ++ hark-action - |= =action:store - ^- (quip card _state) - abet:translate:(abed:poke-engine:ha action) - -- -:: -++ on-agent on-agent:def -:: -++ on-leave on-leave:def -++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card _this) - ?. ?=([%autoseen ~] wire) - (on-arvo:def wire sign-arvo) - `this -:: -++ on-fail on-fail:def --- -|_ =bowl:gall -+* met ~(. metadata bowl) -++ poke-engine - |_ [in=action:store out=(list update:store) cards=(list card)] - ++ poke-core . - :: - ++ abed - |= =action:store poke-core(in action) - :: - ++ abet - ^- (quip card _state) - :_ state - %+ snoc (flop cards) - [%give %fact ~[/updates] %hark-update !>([%more (flop out)])] - :: - ++ give - |= =update:store poke-core(out [update out]) - :: - ++ emit - |= =card poke-core(cards [card cards]) - :: - ++ translate - ^+ poke-core - ?- -.in - :: - %add-note (add-note +.in) - %archive (do-archive +.in) - :: - %unread-count (unread-count +.in) - %read-count (read-count +.in) - :: - %read-each (read-each +.in) - %unread-each (unread-each +.in) - :: - %read-note (read-note +.in) - :: - %seen-index (seen-index +.in) - %remove-graph (remove-graph +.in) - %set-dnd (set-dnd +.in) - %seen seen - %read-all read-all - :: - == - :: - :: +| %note - :: - :: notification tracking - ++ put-notifs - |= [time=@da =timebox:store] - poke-core(notifications (put:orm notifications time timebox)) - :: - ++ add-note - |= [=index:store =notification:store] - ^+ poke-core - =/ existing-notif - (~(get by unread-notes) index) - =/ new=notification:store - (merge-notification existing-notif notification) - =. unread-notes - (~(put by unread-notes) index new) - =/ timebox=@da - (~(gut by timeboxes) (to-stats-index:store index) current-timebox) - (give %added index new) - :: - ++ do-archive - |= [time=(unit @da) =index:store] - ^+ poke-core - |^ - ?~(time archive-unread (archive-read u.time)) - :: - ++ archive-unread - =. unread-notes - (~(del by unread-notes) index) - (give %archive ~ index) - :: - ++ archive-read - |= time=@da - =/ =timebox:store - (gut-orm notifications time) - =/ =notification:store - (~(got by timebox) index) - =/ new-timebox=timebox:store - (~(del by timebox) index) - =. poke-core - (put-notifs time new-timebox) - (give %archive `time index) - -- - :: - ++ read-note - |= =index:store - =/ =notification:store - (~(got by unread-notes) index) - =. unread-notes - (~(del by unread-notes) index) - =/ =time - (~(gut by timeboxes) (to-stats-index:store index) current-timebox) - =/ =timebox:store - (gut-orm notifications time) - =/ existing-notif - (~(get by timebox) index) - =/ new=notification:store - (merge-notification existing-notif notification) - =. timebox - (~(put by timebox) index new) - =. notifications - (put:orm notifications time timebox) - (give %note-read time index) - :: - :: - :: +| %each - :: - :: each unread tracking - :: - ++ unread-each - |= [=stats-index:store unread=index:graph-store time=@da] - =. poke-core (seen-index time stats-index) - %+ jub-unreads-each:(give %unread-each stats-index unread time) - stats-index - |= indices=(set index:graph-store) - (~(put ^in indices) unread) - :: - ++ read-index-each - |= [=stats-index:store ref=index:graph-store] - %- read-indices - %+ skim - ~(tap ^in ~(key by unread-notes)) - |= =index:store - ?. (stats-index-is-index:store stats-index index) %.n - =/ not=notification:store - (~(got by unread-notes) index) - ?. ?=(%graph -.index) %.n - ?. ?=(%graph -.contents.not) %.n - (lien list.contents.not |=(p=post:post =(index.p ref))) - :: - ++ read-each - |= [=stats-index:store ref=index:graph-store] - =. timeboxes (~(put by timeboxes) stats-index now.bowl) - =. poke-core (read-index-each stats-index ref) - %+ jub-unreads-each:(give %read-each stats-index ref) - stats-index - |= indices=(set index:graph-store) - (~(del ^in indices) ref) - :: - ++ jub-unreads-each - |= $: =stats-index:store - f=$-((set index:graph-store) (set index:graph-store)) - == - poke-core(unreads-each (jub stats-index f)) - :: - ++ unread-count - |= [=stats-index:store time=@da] - =/ new-count - +((~(gut by unreads-count) stats-index 0)) - =. unreads-count - (~(put by unreads-count) stats-index new-count) - (seen-index:(give %unread-count stats-index time) time stats-index) - :: - ++ read-count - |= =stats-index:store - =. unreads-count (~(put by unreads-count) stats-index 0) - =/ times=(list index:store) - (unread-for-stats-index stats-index) - =? timeboxes !(~(has by timeboxes) stats-index) (~(put by timeboxes) stats-index now.bowl) - (give:(read-indices times) %read-count stats-index) - :: - ++ read-indices - |= times=(list =index:store) - |- - ?~ times poke-core - =/ core - (read-note i.times) - $(poke-core core, times t.times) - :: - ++ seen-index - |= [time=@da =stats-index:store] - =/ new-time=@da - (max time (~(gut by last-seen) stats-index 0)) - =. last-seen - (~(put by last-seen) stats-index new-time) - (give %seen-index new-time stats-index) - :: - ++ remove-graph - |= rid=resource - |^ - =/ indices get-stats-indices - =. poke-core - (give %remove-graph rid) - =. poke-core - (remove-notifications indices) - =. unreads-count - ((dif-map-by-key ,@ud) unreads-count indices) - =. unreads-each - %+ (dif-map-by-key ,(set index:graph-store)) - unreads-each indices - =. last-seen - ((dif-map-by-key ,@da) last-seen indices) - poke-core - :: - ++ get-stats-indices - %- ~(gas ^in *(set stats-index:store)) - %+ skim - ;: weld - ~(tap ^in ~(key by unreads-count)) - ~(tap ^in ~(key by last-seen)) - ~(tap ^in ~(key by unreads-each)) - == - |= =stats-index:store - ?. ?=(%graph -.stats-index) %.n - =(graph.stats-index rid) - :: - ++ dif-map-by-key - |* value=mold - |= [=(map stats-index:store value) =(set stats-index:store)] - =/ to-remove ~(tap ^in set) - |- - ?~ to-remove map - =. map - (~(del by map) i.to-remove) - $(to-remove t.to-remove) - :: - ++ remove-notifications - |= =(set stats-index:store) - ^+ poke-core - =/ indices - ~(tap ^in set) - |- - ?~ indices poke-core - =/ times=(list =index:store) - (unread-for-stats-index i.indices) - =. poke-core - (read-indices times) - $(indices t.indices) - -- - :: - ++ seen - =. poke-core - (read-indices ~(tap ^in ~(key by unread-notes))) - poke-core(current-timebox now.bowl, timeboxes ~) - :: - ++ read-all - =: unreads-count (~(run by unreads-count) _0) - unreads-each (~(run by unreads-each) _~) - notifications (~(run by notifications) _~) - == - (give:seen %read-all ~) - :: - ++ set-dnd - |= d=? - (give:poke-core(dnd d) %set-dnd d) - -- -:: -++ unread-for-stats-index - |= =stats-index:store - %+ skim ~(tap in ~(key by unread-notes)) - (cury stats-index-is-index:store stats-index) -:: -++ merge-notification - |= [existing=(unit notification:store) new=notification:store] - ^- notification:store - ?~ existing new - ?- -.contents.u.existing - :: - %graph - ?> ?=(%graph -.contents.new) - u.existing(list.contents (weld list.contents.u.existing list.contents.new)) - :: - %group - ?> ?=(%group -.contents.new) - u.existing(list.contents (weld list.contents.u.existing list.contents.new)) - == -:: -:: +key-orm: +key:by for ordered maps -++ key-orm - |= =notifications:store - ^- (list @da) - (turn (tap:orm notifications) |=([@da *] +<-)) -:: +jub-orm: combo +jab/+gut for ordered maps -:: TODO: move to zuse.hoon -++ jub-orm - |= [=notifications:store time=@da fun=$-(timebox:store timebox:store)] - ^- notifications:store - =/ =timebox:store - (fun (gut-orm notifications time)) - (put:orm notifications time timebox) -++ jub - |= [=stats-index:store f=$-((set index:graph-store) (set index:graph-store))] - ^- (jug stats-index:store index:graph-store) - =/ val=(set index:graph-store) - (~(gut by unreads-each) stats-index ~) - (~(put by unreads-each) stats-index (f val)) -:: +gut-orm: +gut:by for ordered maps -:: TODO: move to zuse.hoon -++ gut-orm - |= [=notifications:store time=@da] - ^- timebox:store - (fall (get:orm notifications time) ~) -:: -++ autoseen-interval ~h3 -++ cancel-autoseen - ^- card - [%pass /autoseen %arvo %b %rest (add current-timebox autoseen-interval)] -:: -++ autoseen-timer - ^- card - [%pass /autoseen %arvo %b %wait (add now.bowl autoseen-interval)] -:: -++ scry - |* [=mold p=path] - ?> ?=(^ p) - ?> ?=(^ t.p) - .^(mold i.p (scot %p our.bowl) i.t.p (scot %da now.bowl) t.t.p) -:: -++ give - |= [paths=(list path) update=update:store] - ^- (list card) - [%give %fact paths [%hark-update !>(update)]]~ -:: -++ tap-nonempty - |= =notifications:store - ^- (list [@da timebox:store]) - %+ skim (tap:orm notifications) - |=([@da =timebox:store] !=(~(wyt by timebox) 0)) --- diff --git a/pkg/arvo/app/herm.hoon b/pkg/arvo/app/herm.hoon index cd791b2af..18a18d855 100644 --- a/pkg/arvo/app/herm.hoon +++ b/pkg/arvo/app/herm.hoon @@ -1,6 +1,8 @@ :: herm: stand-in for term.c with http interface :: /+ default-agent, dbug, verb +/$ blit-to-json %blit %json +/$ json-to-blit %json %blit =, jael |% +$ state-0 [%0 ~] @@ -11,33 +13,15 @@ %+ verb | %- agent:dbug ^- agent:gall -=> |% - ++ request-tube - |= [bowl:gall from=mark to=mark next=?] - ^- card:agent:gall - :* %pass /tube/[from]/[to] - %arvo %c %warp - our q.byk ~ - :: - ?: next - [%next %c da+now /[from]/[to]] - [%sing %c da+now /[from]/[to]] - == - -- |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) :: ++ on-init ^- (quip card:agent:gall _this) - :_ this - :: set up dill session subscription, - :: and ensure the tubes we use are in cache + :: set up dill session subscription :: - :~ [%pass [%view %$ ~] %arvo %d %view ~] - (request-tube bowl %blit %json |) - (request-tube bowl %json %belt |) - == + [[%pass [%view %$ ~] %arvo %d %view ~]~ this] :: ++ on-save !>([%0 ~]) ++ on-load @@ -61,7 +45,9 @@ ++ on-arvo |= [=wire =sign-arvo] ^- (quip card:agent:gall _this) - ?+ wire !! + ?+ wire (on-arvo:def wire sign-arvo) + [%tube *] [~ this] :: we no longer care about these + :: :: pass on dill blits for the session :: [%view %$ ~] @@ -72,17 +58,6 @@ %+ turn p.sign-arvo |= =blit:dill [%give %fact [%session %$ ~]~ %blit !>(blit)] - :: - :: ensure the tubes we need remain in cache - :: - [%tube @ @ ~] - =* from i.t.wire - =* to i.t.t.wire - ?. ?=([%clay %writ *] sign-arvo) - ~| [%unexpected-sign [- +<]:sign-arvo] - !! - :_ this - [(request-tube bowl from to &)]~ == :: ++ on-poke diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index b6567e1f5..d5f861e03 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -2,20 +2,27 @@ /+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln |% +$ state - $: %13 - drum=state:drum - helm=state:helm - kiln=state:kiln - == + $~ [%22 *state:drum *state:helm *state:kiln] + $>(%22 any-state) +:: +$ any-state - $% state - [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] - [%7 drum=state:drum helm=state:helm kiln=state:kiln] - [%8 drum=state:drum helm=state:helm kiln=state:kiln] - [%9 drum=state:drum helm=state:helm kiln=state:kiln] - [%10 drum=state:drum helm=state:helm kiln=state:kiln] - [%11 drum=state:drum helm=state:helm kiln=state:kiln] - [%12 drum=state:drum helm=state:helm kiln=state:kiln] + $% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] + [%7 drum=state-2:drum helm=state:helm kiln=state-0:kiln] + [%8 drum=state-2:drum helm=state:helm kiln=state-0:kiln] + [%9 drum=state-2:drum helm=state:helm kiln=state-0:kiln] + [%10 drum=state-2:drum helm=state:helm kiln=state-0:kiln] + [%11 drum=state-2:drum helm=state:helm kiln=state-0:kiln] + [%12 drum=state-2:drum helm=state:helm kiln=state-0:kiln] + [%13 drum=state-2:drum helm=state:helm kiln=state-1:kiln] + [%14 drum=state-2:drum helm=state:helm kiln=state-1:kiln] + [%15 drum=state-2:drum helm=state:helm kiln=state-2:kiln] + [%16 drum=state-4:drum helm=state:helm kiln=state-3:kiln] + [%17 drum=state-4:drum helm=state:helm kiln=state-4:kiln] + [%18 drum=state-4:drum helm=state:helm kiln=state-5:kiln] + [%19 drum=state-4:drum helm=state:helm kiln=state-6:kiln] + [%20 drum=state-4:drum helm=state:helm kiln=state-7:kiln] + [%21 drum=state-4:drum helm=state:helm kiln=state-8:kiln] + [%22 drum=state-4:drum helm=state:helm kiln=state-9:kiln] == +$ any-state-tuple $: drum=any-state:drum @@ -42,7 +49,8 @@ ++ on-init ^- step:agent:gall =^ d drum.state on-init:drum-core - [d this] + =^ k kiln.state on-init:kiln-core + [:(welp d k) this] :: ++ on-leave on-leave:def ++ on-peek @@ -65,9 +73,9 @@ =-(?>(?=(%kiln -<) ->) (~(got by lac.old) %kiln)) == == - =^ d drum.state (on-load:drum-core -.old drum.tup) - =^ h helm.state (on-load:helm-core -.old helm.tup) - =^ k kiln.state (on-load:kiln-core -.old kiln.tup) + =^ d drum.state (on-load:(drum bowl *state:drum) -.old drum.tup) + =^ h helm.state (on-load:(helm bowl *state:helm) -.old helm.tup) + =^ k kiln.state (on-load:(kiln bowl *state:kiln) -.old kiln.tup) [:(welp d h k) this] :: ++ on-poke @@ -95,24 +103,23 @@ |= =path ^- step:agent:gall ?+ path (on-watch:def +<) - [%drum *] =^(c drum.state (peer:drum-core +<) [c this]) + [%drum *] =^(c drum.state (peer:drum-core t.path) [c this]) + [%kiln *] =^(c kiln.state (peer:kiln-core t.path) [c this]) == :: ++ on-agent - |= [=wire =sign:agent:gall] + |= [=wire syn=sign:agent:gall] ^- step:agent:gall ?+ wire ~|([%hood-bad-wire wire] !!) - [%drum *] =^(c drum.state (take-agent:drum-core +<) [c this]) - [%helm *] =^(c helm.state (take-agent:helm-core +<) [c this]) - [%kiln *] =^(c kiln.state (take-agent:kiln-core +<) [c this]) + [%drum *] =^(c drum.state (take-agent:drum-core t.wire syn) [c this]) + [%helm *] =^(c helm.state (take-agent:helm-core t.wire syn) [c this]) + [%kiln *] =^(c kiln.state (take-agent:kiln-core t.wire syn) [c this]) == -:: TODO: symmetry between adding and stripping wire prefixes :: ++ on-arvo |= [=wire syn=sign-arvo] ^- step:agent:gall ?+ wire ~|([%hood-bad-wire wire] !!) - [%drum *] =^(c drum.state (take-arvo:drum-core t.wire syn) [c this]) [%helm *] =^(c helm.state (take-arvo:helm-core t.wire syn) [c this]) [%kiln *] =^(c kiln.state (take-arvo:kiln-core t.wire syn) [c this]) == diff --git a/pkg/arvo/app/lens.hoon b/pkg/arvo/app/lens.hoon index ed9c93328..74734f42e 100644 --- a/pkg/arvo/app/lens.hoon +++ b/pkg/arvo/app/lens.hoon @@ -25,8 +25,6 @@ ^- (list @tas) :~ %group-store %metadata-store - %contact-store - %contact-hook %invite-store %graph-store == diff --git a/pkg/arvo/app/roller-cli.hoon b/pkg/arvo/app/roller-cli.hoon new file mode 100644 index 000000000..6ce67754a --- /dev/null +++ b/pkg/arvo/app/roller-cli.hoon @@ -0,0 +1,594 @@ +:: roller-cli: CLI for L2 Azimuth Rollers +:: +:: TODO: commands +:: +:: client | roller +:: _________|___________ +:: - CLI command +:: [%track 0x1234.abcd] +:: - init subscriptions to the roller +:: watch --> /point/[0x1234.abcd] - point updates +:: watch --> /tx/[0x1234.abcd] - tx status updates +:: +:: ---------------------- +:: Submit Txs +:: poke --tx--> +take-tx +:: +:: --------------------- +:: Receive Tx status updates +:: watch /tx/[0x1234.abcd] +:: +:: <--(list roller-tx:dice)-- - init +:: <--[address roller-tx:dice]-- - update +:: <--%kick-sub-- ?: ?=(?(%confirmed %failed) tx-status) +:: --------------------- +:: Receive Point updates (i.e. nonces) +:: watch /point/[0x1234.abcd] +:: +:: <-(list point:naive)- - init +:: <-[address point:naive]- - update +:: +/- *dice +/+ *dice, + naive, + lib=naive-transactions, + *fake-roller, + shoe, + verb, + dbug, + default-agent, + ethereum +|% ++$ app-state + $: %0 + :: TODO: keep track of sessions + :: + :: sessions=(map sole-id session) + points=(jug address:ethereum [ship point:naive]) + history=(jug address:ethereum roller-tx) + unsigned-txs=(jug address:ethereum [keccak tx:naive]) + :: TODO: track pub/prv keys + :: + :: keys=(list (pair address:ethereum address:ethereum) + == +:: ++$ card card:shoe +:: ++$ command + $% :: List all possible L2 tx types + :: + [%l2-tx ~] :: ? + :: Loads a new address (login?) + :: — should require signing? + :: - it subscribes to the Roller, for updates to it + :: - innitially receives a list of points (if any) it controls + :: + :: [%track pubkey=address:ethereum prvkey=address:ethereum] + [%track address:ethereum] + :: Table of all submitted txs, by address + :: + [%history address:ethereum] + :: Table of all unsigned txs, by address + :: + [%show-unsigned ~] + :: Signs and Submit an unsigned txs (signed) + :: + [%submit address:ethereum tx:naive] + :: Cancels a submitted (but pending) txs + :: + [%cancel ~] + :: Ships owned by an address + :: + [%ships address:ethereum] + :: Point data for a given ship + :: + [%point address:ethereum ship] + :: Example flow + :: + [%example-flow ~] + == +-- +=| app-state +=* state - +:: +%+ verb | +%- agent:dbug +^- agent:gall +%- (agent:shoe command) +^- (shoe:shoe command) +:: => |% +:: ++ get-address-points +:: |= [roller=@p =address:ethereum] +:: :* %pass +:: /roller-points +:: %agent +:: [roller %azimuth] +:: %watch +:: /address/[address] +:: == +:: -- +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) + des ~(. (default:shoe this command) bowl) +:: +++ on-init on-init:def +++ on-save !>(state) +++ on-load + |= old=vase + ^- (quip card _this) + [~ this(state !<(app-state old))] + :: |^ + :: =+ !<(old-state=app-states old) + :: |- + :: ?- -.old-state + :: %0 $(old-state [%1 ~ ~ ~]) + :: %1 $(old-state [%2 ~ ~ ~]) + :: %2 [~ this(state old-state)] + :: == + :: ++ app-states $%([%0 ~] [%1 *] app-state) + :: -- +:: +++ on-poke + |= [=mark =vase] + ^- (quip card _this) + ~& + =/ addr=@ux + 0x6def.fb0c.afdb.11d1.75f1.23f6.891a.a64f.01c2.4f7d + :: %+ turn + ~(tap in (~(get ju points) addr)) + :: head + [~ this] +++ on-watch on-watch:def +++ on-leave on-leave:def +:: +on-peek: scry paths +:: +:: /x/ships/[0x1234.abcd] -> %noun (list ship) +:: +++ on-peek + |= =path + ^- (unit (unit cage)) + |^ + ?+ path ~ + [%x %ships @ ~] (ships i.t.t.path) + == + :: + ++ ships + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list ship) + ?~ addr=(slaw %ux wat) ~ + %+ turn + ~(tap in (~(get ju points) u.addr)) + head + -- +:: +++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card _this) + |^ + ?+ wire (on-agent:def wire sign) + [%points @ ~] (get-points i.t.wire sign) + [%txs @ ~] (get-txs i.t.wire sign) + == + :: + ++ get-points + |= [wat=@t =sign:agent:gall] + ^- (quip card _this) + ?+ -.sign (on-agent:def wire sign) + %fact + ?+ p.cage.sign (on-agent:def wire sign) + %points + ?~ addr=(slaw %ux wat) (on-agent:def wire sign) + =+ !<(points=(list [ship point:naive]) q.cage.sign) + =. points.state + %- ~(gas ju points.state) + (turn points (cork same (lead u.addr))) + [~ this] + :: + %point + ?~ addr=(slaw %ux wat) (on-agent:def wire sign) + =+ !<(new-point=[=ship =point:naive] q.cage.sign) + :: TODO: handle multiple sole sessions? + :: + :: =/ sez=(list [=sole-id =session]) + :: ~(tap by sessions) + =/ console=tape + "Point update ({(scow %p ship.new-point)})" + =. points.state + :: FIXME: doesn't properly update point + :: handle proper insert/deletion of points + :: to account for ownership changes/nonce updates + :: + =; [is-owner=? old=(unit [=ship =point:naive])] + ?~ old points.state + =. points.state + (~(del ju points.state) u.addr u.old) + ?. is-owner points.state + (~(put ju points.state) [u.addr new-point]) + =/ points=(list [=ship =point:naive]) + ~(tap in (~(get ju points.state) u.addr)) + |- ^- [? (unit [ship point:naive])] + |^ + ?~ points [| ~] + ?. =(ship.i.points ship.new-point) + $(points t.points) + :- is-owner + `[ship.new-point point.i.points] + :: + ++ is-owner + =* own own.point.new-point + ?| =(u.addr address.owner.own) + =(u.addr address.spawn-proxy.own) + =(u.addr address.management-proxy.own) + =(u.addr address.voting-proxy.own) + =(u.addr address.transfer-proxy.own) + == + -- + :: %- ~(run in points) + :: |= old=[=ship =point:naive] + :: ?. =(ship.old ship.new) + :: old + :: point.new + :: (~(put ju points.state) [u.addr point]) + ~& :- %ships + (turn ~(tap in (~(get ju points.state) u.addr)) head) + :_ this + :_ ~ + :- %shoe + :- ~ + :- %sole + ?. =(src our):bowl + [%txt console] + [%klr [[`%br ~ `%g] [(crip console)]~]~] + == + == + :: + ++ get-txs + |= [wat=@t =sign:agent:gall] + ^- (quip card _this) + ?+ -.sign (on-agent:def wire sign) + %fact + ?~ addr=(slaw %ux wat) (on-agent:def wire sign) + ?+ p.cage.sign (on-agent:def wire sign) + %txs + =+ !<(txs=(list roller-tx) q.cage.sign) + =. history.state + %- ~(gas ju history.state) + (turn txs (cork same (lead u.addr))) + [~ this] + :: + %tx + ?~ addr=(slaw %ux wat) (on-agent:def wire sign) + =+ !<(=roller-tx q.cage.sign) + =/ hash=tape + =+ hash=(scow %ux hash.roller-tx) + =+ len=(lent hash) + ;: weld + (swag [0 6] hash) + "..." + (swag [(sub len 4) len] hash) + == + =/ console=tape + "Tx hash: {hash} -> {(trip status.roller-tx)}" + =. history.state (update-tx u.addr roller-tx) + :: ~& console + :_ this + :_ ~ + :- %shoe + :- ~ + :- %sole + ?. =(src our):bowl + [%txt console] + [%klr [[`%br ~ `%g] [(crip console)]~]~] + == + == + :: + ++ update-tx + |= [=address:ethereum =roller-tx] + %. [address roller-tx] + ?+ status.roller-tx ~(put ju history.state) + %pending + ~(put ju history.state) + :: + %sending + %~ put ju + %- ~(del ju history.state) + [address roller-tx(status %pending)] + :: + %confirmed + %~ put ju + %- ~(del ju history.state) + [address roller-tx(status %sending)] + :: + %failed + :: TODO: make it not ugly + :: + %~ put ju + %- %~ del ju + %- ~(del ju history.state) + [address roller-tx(status %sending)] + [address roller-tx(status %pending)] + == + -- +:: +++ on-arvo on-arvo:def +++ on-fail on-fail:def +:: +++ command-parser + |= sole-id=@ta + ^+ |~(nail *(like [? command])) + :: wait for 'enter' to run the command + :: + |^ + %+ stag | + :: (perk %demo %row %table %track %submit %history ~) + ;~ pose + ;~(plug (tag %track) ;~(pfix (jest ' 0x') hex)) + ;~(plug (tag %example-flow) (easy ~)) + ;~(plug (tag %history) ;~(pfix (jest ' 0x') hex)) + ;~((glue ace) (tag %submit) submit) + ;~((glue ace) (tag %ships) address) + ;~((glue ace) (tag %point) address ;~(pfix sig fed:ag)) + == + :: + ++ tag |*(a=@tas (cold a (jest a))) :: TODO (from /app/chat-cli) into stdlib + ++ address ;~(pfix (jest '0x') hex) + ++ sponsorship + %- perk + :~ %escape + %cancel-escape + %adopt + %reject + %detach + == + :: + ++ ownership + %- perk + :~ %set-management-proxy + %set-spawn-proxy + %set-transfer-proxy + == + :: + ++ proxies + (perk %own %spawn %manage %vote %transfer ~) + ++ submit + %+ cook ,[address:naive tx:naive] + ;~ (glue ace) + address + :: from=[ship proxy:naive] + :: + %+ cook ,[ship proxy:naive] + %+ ifix [sel ser] + ;~((glue ace) ;~(pfix sig fed:ag) proxies) + :: skim-tx:naive + :: + %+ cook ,skim-tx:naive + ;~ pose + :: [%transfer-point =address reset=?] + :: + ;~ (glue ace) + (perk %transfer-point ~) + address + ;~(pose (cold & (just 'y')) (cold | (just 'n'))) + == + :: [%spawn ship address:naive] + :: + ;~ (glue ace) + (perk %spawn ~) + ;~(pfix sig fed:ag) + address + == + :: [%configure-keys encrypt=@ auth=@ crypto-suite=@ breach=?] + :: + ;~ (glue ace) + (perk %configure-keys ~) + address + address + dem + ;~(pose (cold & (just 'y')) (cold | (just 'n'))) + == + :: [?([%escape %cancel-escape %adopt %reject %detach]) ship] + :: + ;~((glue ace) sponsorship ;~(pfix sig fed:ag)) + :: $: ?([%set-management-proxy %set-spawn-proxy %set-transfer-proxy]) + :: address + :: == + :: + ;~((glue ace) ownership address) + == + == + -- +:: +++ tab-list + |= sole-id=@ta + ^- (list [@t tank]) + :~ ['txs' leaf+"list available L2 transaction"] + ['submit' leaf+"sends| a L2 transaction to the Roller"] + ['cancel' leaf+"cancels a (pending) L2 transaction"] + ['history' leaf+"shows all current submitted transactions"] + ['track' leaf+"loads an ethereum address and tracks points and L2 txs"] + == +:: +++ on-command + |= [sole-id=@ta =command] + ^- (quip card _this) + |^ + ?+ -.command !! + %track (track +.command) + %submit (submit +.command) + %history (history +.command) + %ships (ships +.command) + %point (point +.command) + %example-flow example-flow + == + :: + ++ example-flow + ^- (quip card _this) + =/ address=@t '0x6deffb0cafdb11d175f123f6891aa64f01c24f7d ' + =/ spawn=@t '0xf48062ae8bafd6ef19cd6cb89db93a0d0ca6ce26' + =/ track=@t 'track 0x6deffb0cafdb11d175f123f6891aa64f01c24f7d' + =/ ships=@t 'ships 0x6deffb0cafdb11d175f123f6891aa64f01c24f7d' + =/ tx1=@t + %- crip + :~ 'submit ' + address + '[~wanzod own] ' + 'set-spawn-proxy ' + address + == + =/ tx2=@t + %- crip + :~ 'submit ' + address + '[~wanzod own] ' + 'spawn ' + '~modlep-fosreg ' + spawn + == + =/ failed-tx=@t + %- crip + :~ 'submit ' + '0x6deffb0cafdb11d175f123f6891aa64f01c24f7d ' + '[~wanzod own] ' + 'spawn ' + '~marzod ' + '0xf' + == + =/ example-a=@t '- lists ships controlled by the given address :: ' + =/ example-b=@t '- receives updates signed by the given address :: ' + =/ example-c=@t '- this tx will fail :: ' + :_ this + :_ ~ + ^- card + :- %shoe + ^- [(list _sole-id) shoe-effect:shoe] + :- [sole-id]~ + ^- shoe-effect:shoe + :- %sole + ?. =(src our):bowl + [%txt "1234"] + :- %mor + :~ [%klr ~[[[~ ~ `%g] [example-a]~] [``~ [ships]~]]] + [%klr ~[[[~ ~ `%b] [example-b]~] [``~ [track]~]]] + [%klr ~[[[~ ~ `%r] [example-c]~] [``~ [failed-tx]~]]] + == + :: + ++ submit + |= [=address:ethereum =tx:naive] + ^- (quip card _this) + =/ owner=(unit [=nonce:naive =point:naive]) + =/ points=(list [=ship =point:naive]) + ~(tap in (~(get ju points) address)) + |- ^- (unit [nonce:naive point:naive]) + ?~ points ~ + ?. =(ship.from.tx ship.i.points) + $(points t.points) + `(get-owner point.i.points proxy.from.tx) + :: =< `[nonce point.i.points] + :: (proxy-from-point:naive proxy.from.tx point.i.points) + ?~ owner ~& "empty points" [~ this] + =/ =keccak + %- hash-tx:lib + (unsigned-tx:lib 1.337 nonce.u.owner (gen-tx-octs:lib tx)) + =/ sig=octs (fake-sig tx address nonce.u.owner) + =. points + %+ ~(put ju points) address + [ship.from.tx point.u.owner] + :_ this + :_ ~ + :* %pass + /pokepath + %agent + [our.bowl %roller] + %poke + roller-action+!>([%submit | address q.sig %don tx]) + == + :: + ++ track + |= =address:ethereum + ^- (quip card _this) + =/ [to=(list _sole-id) fec=shoe-effect:shoe] + :- [sole-id]~ + :- %sole + =/ =tape "Listening to updates for {(scow %ux address)}" + ?. =(src our):bowl + [%txt tape] + [%klr [[`%br ~ `%g] [(crip tape)]~]~] + :: :_ this(keys (snoc keys address)) + :_ this + :~ [%shoe to fec] + :^ %pass /points/[(scot %ux address)] %agent + [[our.bowl %roller] %watch /points/[(scot %ux address)]] + :: + :^ %pass /txs/[(scot %ux address)] %agent + [[our.bowl %roller] %watch /txs/[(scot %ux address)]] + == + :: + ++ history + |= =address:ethereum + ^- (quip card _this) + :_ this + =; [to=(list _sole-id) fec=shoe-effect:shoe] + [%shoe to fec]~ + :- [sole-id]~ + :^ %table + :: ~[t+'address' t+'signing ship' t+'type' t+'status' t+'hash'] + ~[t+'signing ship' t+'type' t+'status' t+'hash' t+'time'] + ~[14 20 9 13 26] + %+ turn + %+ sort ~(tap in (~(get ju history.state) address)) + |=([a=roller-tx b=roller-tx] (lth time.a time.b)) + |= roller-tx + |^ ~[p+ship t+type t+status pack-hash t+(scot %da time)] + :: + ++ pack-address + =+ addr=(scow %ux address) + =+ len=(lent addr) + :- %t + %- crip + ;: weld + (swag [0 6] addr) + "..." + (swag [(sub len 4) len] addr) + == + :: + ++ pack-hash + =+ hash=(scow %ux hash) + =+ len=(lent hash) + :- %t + %- crip + ;: weld + (swag [0 6] hash) + "..." + (swag [(sub len 4) len] hash) + == + -- + :: + ++ ships + |= =address:ethereum + ^- (quip card _this) + ~& ships+(turn ~(tap in (~(get ju points) address)) head) + [~ this] + :: + ++ point + |= [=address:ethereum =ship] + ^- (quip card _this) + =/ points=(set [@p point:naive]) + (~(get ju points.state) address) + ~& %+ skim ~(tap in points) + |=([s=@p =point:naive] =(s ship)) + [~ this] + -- +:: +++ can-connect + |= sole-id=@ta + ^- ? + ?| =(~zod src.bowl) + (team:title [our src]:bowl) + == +:: +++ on-connect on-connect:des +++ on-disconnect on-disconnect:des +-- diff --git a/pkg/arvo/app/roller-rpc.hoon b/pkg/arvo/app/roller-rpc.hoon new file mode 100644 index 000000000..f16f4c403 --- /dev/null +++ b/pkg/arvo/app/roller-rpc.hoon @@ -0,0 +1,355 @@ +:: Roller JSON-RPC API +:: +/- rpc=json-rpc, *dice +/+ naive, + azimuth-roll-rpc, + json-rpc, + *server, + default-agent, + verb, + dbug, + agentio +|% +:: ++$ card card:agent:gall +:: ++$ state-0 [%0 ~] +-- +:: +%+ verb | +%- agent:dbug +:: +=| state-0 +=* state - +:: +^- agent:gall +=< + |_ =bowl:gall + +* this . + do ~(. +> bowl) + def ~(. (default-agent this %|) bowl) + :: + ++ on-init + ^- (quip card _this) + ~& > 'init' + :_ this + [%pass /bind %arvo %e %connect [~ /v1/roller] dap.bowl]~ + :: + ++ on-save !>(state) + ++ on-load + |= old=vase + ^- (quip card _this) + [~ this(state !<(state-0 old))] + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + ?> (team:title our.bowl src.bowl) + ?+ mark (on-poke:def mark vase) + %handle-http-request + =+ !<([id=@ta req=inbound-request:eyre] vase) + :_ this + (handle-http-request id req) + :: + %azimuth-action + =+ !<([%disconnect bind=binding:eyre] vase) + ~& >>> "disconnecting at {}" + :_ this + [%pass /bind %arvo %e %disconnect bind]~ + == + :: + ++ handle-http-request + |= [id=@ta =inbound-request:eyre] + ^- (list card) + |^ + =* req request.inbound-request + =* headers header-list.req + =/ req-line (parse-request-line url.req) + ?. =(method.req %'POST') + :: TODO: method not supported + :: + (give-simple-payload:app id not-found:gen) + ?~ rpc-request=(validate-request:json-rpc body.req) + :: TODO: malformed request + :: + (give-simple-payload:app id not-found:gen) + =/ [data=(list cage) response=simple-payload:http] + (process-rpc-request:do u.rpc-request) + %+ weld + (give-simple-payload:app id response) + |- + ?~ data ~ + :_ $(data t.data) + ^- card + [%pass / %agent [our.bowl %roller] %poke i.data] + -- + -- + :: + ++ on-watch + |= =path + ^- (quip card _this) + ?> (team:title our.bowl src.bowl) + ?+ path (on-watch:def path) + [%http-response *] [~ this] + == + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card _this) + ?+ sign-arvo (on-arvo:def wire sign-arvo) + [%eyre %bound *] + ~? !accepted.sign-arvo + [dap.bowl 'bind rejected!' binding.sign-arvo] + [~ this] + == + :: + ++ on-leave on-leave:def + ++ on-peek on-peek:def + ++ on-agent on-agent:def + ++ on-fail on-fail:def + -- +:: +|_ =bowl:gall +++ process-rpc-request + |= req=batch-request:rpc + ^- [(list cage) simple-payload:http] + |^ + ?- -.req + %o + =/ [data=(unit cage) =response:rpc] + (process p.req) + [(drop data) (render response)] + :: + %a + =| data=(list cage) + =| resp=(list response:rpc) + |- + ?~ p.req + [(flop data) (render %batch (flop resp))] + =/ [dat=(unit cage) res=response:rpc] + (process i.p.req) + =? data ?=(^ dat) [u.dat data] + $(p.req t.p.req, resp [res resp]) + == + :: + ++ render + |= res=response:rpc + %- json-response:gen + (response-to-json:json-rpc res) + :: + ++ process + |= request:rpc + ?. ready:scry + :: TODO: move to lib + :: + `[%error id '-32003' 'Roller is not ready'] + =, azimuth-roll-rpc + ?. ?=([%map *] params) + [~ ~(parse error:json-rpc id)] + =/ method=@tas (enkebab method) + ?: ?=(l2-tx method) + (process-rpc id +.params method over-quota:scry) + ?+ method [~ ~(method error:json-rpc id)] + %get-point `(get-point id +.params point:scry) + %get-ships `(get-ships id +.params ships:scry) + %cancel-transaction (cancel-tx id +.params) + %get-spawned `(get-spawned id +.params spawned:scry) + %get-unspawned `(get-spawned id +.params unspawned:scry) + %get-owned-points `(get-ships id +.params owned:scry) + %get-transferring-for `(get-ships id +.params transfers:scry) + %get-manager-for `(get-ships id +.params manager:scry) + %get-voting-for `(get-ships id +.params voting:scry) + %get-spawning-for `(get-ships id +.params spawning:scry) + %get-all-pending `(all:pending id +.params all:pending:scry) + %get-pending-by-ship `(ship:pending id +.params ship:pending:scry) + %get-pending-by-address `(addr:pending id +.params addr:pending:scry) + %get-pending-tx `(hash:pending id +.params hash:pending:scry) + %get-transaction-status `(status id +.params tx-status:scry) + %when-next-batch `(next-batch id +.params next-batch:scry) + %get-nonce `(nonce id +.params nonce:scry) + %get-history `(history id +.params addr:history:scry) + %get-roller-config `(get-config id +.params config:scry) + %prepare-for-signing `(hash-transaction id +.params chain:scry | &) + %get-unsigned-tx `(hash-transaction id +.params chain:scry & |) + %get-predicted-state `(get-naive id +.params predicted:scry) + %hash-raw-transaction `(hash-raw-transaction id +.params) + :: TODO: deprecated, remove + :: + %hash-transaction `(hash-transaction id +.params chain:scry & |) + == + -- +:: +++ scry + |% + ++ point + |= =ship + .^ (unit point:naive) + %gx + (~(scry agentio bowl) %roller /point/(scot %p ship)/noun) + == + :: + ++ ships + |= =address:naive + .^ (list ship) + %gx + (~(scry agentio bowl) %roller /ships/(scot %ux address)/noun) + == + :: + ++ spawned + |= =ship + .^ (list @p) + %gx + (~(scry agentio bowl) %roller /spawned/(scot %p ship)/noun) + == + :: + ++ unspawned + |= =ship + .^ (list @p) + %gx + (~(scry agentio bowl) %roller /unspawned/(scot %p ship)/noun) + == + :: + ++ owned + |= =address:naive + .^ (list ship) + %gx + (~(scry agentio bowl) %roller /owned/(scot %ux address)/noun) + == + :: + ++ transfers + |= =address:naive + .^ (list ship) + %gx + (~(scry agentio bowl) %roller /transfers/(scot %ux address)/noun) + == + :: + ++ manager + |= =address:naive + .^ (list ship) + %gx + (~(scry agentio bowl) %roller /manager/(scot %ux address)/noun) + == + :: + ++ voting + |= =address:naive + .^ (list ship) + %gx + (~(scry agentio bowl) %roller /voting/(scot %ux address)/noun) + == + :: + ++ spawning + |= =address:naive + .^ (list ship) + %gx + (~(scry agentio bowl) %roller /spawning/(scot %ux address)/noun) + == + :: + ++ pending + |% + ++ all + .^ (list pend-tx) + %gx + (~(scry agentio bowl) %roller /pending/noun) + == + :: + ++ ship + |= =^ship + .^ (list pend-tx) + %gx + (~(scry agentio bowl) %roller /pending/(scot %p ship)/noun) + == + :: + ++ addr + |= =address:naive + .^ (list pend-tx) + %gx + %+ ~(scry agentio bowl) %roller + /pending/[(scot %ux address)]/noun + == + :: + ++ hash + |= keccak=@ux + .^ (unit pend-tx) + %gx + %+ ~(scry agentio bowl) %roller + /pending-tx/[(scot %ux keccak)]/noun + == + -- + :: + ++ history + |% + ++ addr + |= =address:naive + .^ (list hist-tx) + %gx + (~(scry agentio bowl) %roller /history/(scot %ux address)/noun) + == + -- + :: + ++ tx-status + |= keccak=@ux + .^ ^tx-status + %gx + (~(scry agentio bowl) %roller /tx/(scot %ux keccak)/status/noun) + == + :: + ++ next-batch + .^ time + %gx + (~(scry agentio bowl) %roller /next-batch/noun) + == + :: + ++ nonce + |= [=ship =proxy:naive] + .^ (unit @) + %gx + %+ ~(scry agentio bowl) + %roller + /nonce/(scot %p ship)/[proxy]/noun + == + :: + ++ config + ^- [azimuth-config roller-config] + :- refresh + .^ roller-config + %gx + %+ ~(scry agentio bowl) + %roller + /config/noun + == + :: + ++ chain + .^ @ + %gx + %+ ~(scry agentio bowl) + %roller + /chain-id/noun + == + :: + ++ predicted + .^ ^state:naive + %gx + (~(scry agentio bowl) %roller /predicted/noun) + == + :: + ++ refresh + .^ @dr + %gx + (~(scry agentio bowl) %azimuth /refresh/noun) + == + :: + ++ over-quota + |= =ship + .^ ? + %gx + (~(scry agentio bowl) %roller /over-quota/(scot %p ship)/atom) + == + :: + ++ ready + .^ ? + %gx + (~(scry agentio bowl) %roller /ready/atom) + == + -- +-- diff --git a/pkg/arvo/app/roller.hoon b/pkg/arvo/app/roller.hoon new file mode 100644 index 000000000..b93c3822b --- /dev/null +++ b/pkg/arvo/app/roller.hoon @@ -0,0 +1,1280 @@ +:: roller: Azimuth L2 roll aggregator +:: +:: general flow is as described below, to ensure transactions actually go +:: through once we start sending it out, in the dumbest reasonable way. +:: +:: periodic timer fires: +:: if there are no pending l2 txs, do nothing. +:: else kick off tx submission flow: +:: "freeze" pending txs, store alongside nonce, then increment nonce, +:: kick off thread for sending the corresponding l1 tx: +:: if nonce doesn't match on-chain expected nonce, bail. +:: if we can't afford the tx fee, bail. +:: construct, sign, submit the l1 tx. +:: if thread bailed, retry in five minutes. +:: if thread succeeded, retry in five minutes with higher gas price. +:: when retrying, only do so if l2 txs remain in the "frozen" txs group. +:: on %tx diff from naive, remove the matching tx from the frozen group. +:: +::TODO questions: +:: - it's a bit weird how we just assume the raw and tx in raw-tx to match... +:: +/- *dice +/+ azimuth, + naive, + dice, + lib=naive-transactions, + default-agent, + ethereum, + dbug, + verb +:: +|% ++$ app-state + $: %1 + :: pending: the next l2 txs to be sent + :: sending: l2 txs awaiting l2 confirmation, ordered by nonce + :: finding: sig+raw-tx hash reverse lookup for txs in sending map + :: history: status of l2 txs by ethereum address, timestamp sorted + :: ship-quota: number of txs submited per ship in the current slice + :: next-nonce: next l1 nonce to use + :: next-batch: when then next l2 batch will be sent + :: pre: predicted l2 state + :: own: ownership of azimuth points + :: + pending=(list pend-tx) + sending=(tree [l1-tx-pointer send-tx]) + finding=(map keccak ?(%confirmed %failed [=time l1-tx-pointer])) + history=(map address:ethereum (tree hist-tx)) + ship-quota=(map ship @ud) + next-nonce=(unit @ud) + next-batch=time + pre=^state:naive + own=owners + :: + :: pk: private key to send the roll + :: quota: max numbers of transactions per unit of time (slice) + :: slice: unit of time where txs are allowed to be added to pending + :: derive: defer derivation of predicted/ownership state + :: frequency: time to wait between sending batches (TODO fancier) + :: endpoint: ethereum rpc endpoint to use + :: contract: ethereum contract address + :: chain-id: mainnet, ropsten, local (https://chainid.network/) + :: resend-time: time to resend a batch with higher gas prie + :: update-rate: frequency to update the roller's predicted state + :: + pk=@ + slice=@dr + quota=@ud + derive=? + frequency=@dr + endpoint=(unit @t) + contract=@ux + chain-id=@ + resend-time=@dr + update-rate=@dr + == +:: orp: ordered points in naive state by parent ship +:: +++ orp ((on ship point:naive) por:naive) +:: ors: ordered sending map by (increasing) L1 nonce +:: +++ ors ((on l1-tx-pointer send-tx) nonce-order:dice) +:: orh: ordered tx history by (decreasing) timestamp +:: +++ orh ((on time roll-tx) gth) +:: ++$ action + $% :: we need to include the address in submit so pending txs show up + :: in the tx history, but because users can send the wrong + :: address, in +apply-tx:predicted state, we just replace + :: the provided address, with the one used when the message was signed; + :: + :: we need to do it there to know the correct nonce that the signed + :: message should have included. + :: + [%submit force=? =address:naive sig=@ tx=part-tx] + [%cancel sig=@ keccak=@ =l2-tx =ship] + [%commit ~] ::TODO maybe pk=(unit @) later + [%config config] + == +:: ++$ card card:agent:gall +:: +++ lverb & +-- +:: +=| app-state +=* state - +:: +%- agent:dbug +%+ verb | +^- agent:gall +:: +=< + |_ =bowl:gall + +* this . + do ~(. +> bowl) + def ~(. (default-agent this %|) bowl) + :: + ++ on-init + ^- (quip card _this) + =: frequency ~h1 + quota 7 + slice ~d7 + resend-time ~m5 + update-rate ~m5 + contract naive:local-contracts:azimuth + chain-id chain-id:local-contracts:azimuth + == + =^ card next-batch set-roller:timer + :_ this + :~ card + (set-quota:timer slice) + [%pass /azimuth-events %agent [our.bowl %azimuth] %watch /event] + == + :: + ++ on-save !>(state) + ++ on-load + |= old=vase + ^- (quip card _this) + =| cards=(list card) + :: new additions to app-state + :: + =| ship-quota=(map ship @ud) + =/ slice=@dr ~d7 + =/ quota=@ud 7 + =/ resend-time=@dr ~m5 + =/ update-rate=@dr ~m5 + |^ + =+ !<(old-state=app-states old) + =? cards ?=(%0 -.old-state) + [(set-quota:timer slice)]~ + =? old-state ?=(%0 -.old-state) + ^- app-state + =, old-state + :* %1 + pending sending finding history + ship-quota next-nonce next-batch + pre own pk slice quota derive + frequency endpoint contract chain-id + resend-time update-rate + == + ?> ?=(%1 -.old-state) + [cards this(state old-state)] + :: + ++ app-states $%(state-0 app-state) + ++ state-0 + $: %0 + pending=(list pend-tx) + sending=(tree [l1-tx-pointer send-tx]) + finding=(map keccak ?(%confirmed %failed [=time l1-tx-pointer])) + history=(map address:ethereum (tree hist-tx)) + next-nonce=(unit @ud) + next-batch=time + pre=^state:naive + own=owners + derive=? + pk=@ + frequency=@dr + endpoint=(unit @t) + contract=@ux + chain-id=@ + == + -- + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + =^ cards state + ?+ mark (on-poke:def mark vase) + %roller-action + =+ !<(poke=action vase) + (on-action:do poke) + == + [cards this] + :: +on-peek: scry paths + :: + :: /x/pending -> %noun (list pend-tx) + :: /x/pending/[~ship] -> %noun (list pend-tx) + :: /x/pending/[0xadd.ress] -> %noun (list pend-tx) + :: /x/tx/[0xke.ccak]/[@ud]status -> %noun tx-status + :: /x/history/[0xadd.ress] -> %noun (list hist-tx) + :: /x/nonce/[~ship]/[proxy] -> %noun (unit @) + :: /x/spawned/[~star] -> %noun (list ship) + :: /x/unspawned/[~star] -> %noun (list ship) + :: /x/next-batch -> %atom time + :: /x/point/[~ship] -> %noun point:naive + :: /x/ships/[0xadd.ress] -> %noun (list ship) + :: /x/config -> %noun config + :: /x/chain-id -> %atom @ + :: /x/owned/[0xadd.ress] -> %noun (list ship) + :: /x/transfers/[0xadd.ress] -> %noun (list ship) + :: /x/manager/[0xadd.ress] -> %noun (list ship) + :: /x/voting/[0xadd.ress] -> %noun (list ship) + :: /x/spawning/[0xadd.ress] -> %noun (list ship) + :: /x/predicted -> %noun state:naive + :: /x/quota -> %atom @ud + :: /x/slice -> %atom @dr + :: /x/over-quota/[~ship] -> %atom ? + :: /x/ready -> %atom ? + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + |^ + ?+ path ~ + [%x %pending ~] ``noun+!>(pending) + [%x %pending @ ~] (pending-by i.t.t.path) + [%x %tx @ %status ~] (status i.t.t.path) + [%x %pending-tx @ ~] (transaction i.t.t.path) + [%x %history @ ~] (history i.t.t.path) + [%x %nonce @ @ ~] (nonce i.t.t.path i.t.t.t.path) + [%x %spawned @ ~] (spawned i.t.t.path) + [%x %unspawned @ ~] (unspawned i.t.t.path) + [%x %next-batch ~] ``atom+!>(next-batch) + [%x %point @ ~] (point i.t.t.path) + [%x %ships @ ~] (ships i.t.t.path) + [%x %config ~] config + [%x %chain-id ~] ``atom+!>(chain-id) + [%x %owned @ ~] (points-proxy %own i.t.t.path) + [%x %transfers @ ~] (points-proxy %transfer i.t.t.path) + [%x %manager @ ~] (points-proxy %manage i.t.t.path) + [%x %voting @ ~] (points-proxy %vote i.t.t.path) + [%x %spawning @ ~] (points-proxy %spawn i.t.t.path) + [%x %predicted ~] ``noun+!>(pre) + [%x %quota ~] ``atom+!>(quota) + [%x %slice ~] ``atom+!>(slice) + [%x %over-quota @ ~] (over-quota i.t.t.path) + [%x %ready ~] ``atom+!>(?=(^ points.pre)) + == + :: + ++ pending-by + |= wat=@t + ?~ who=(slaw %p wat) + :: by-address + :: + ?~ wer=(slaw %ux wat) + [~ ~] + =; pending=(list pend-tx) + ``noun+!>(pending) + %+ skim pending + |= pend-tx + :: TODO: use this instead? =(u.wer address) + :: + ?~ addr=(get-l1-address tx.raw-tx pre) | + =(u.wer u.addr) + :: by-ship + :: + =; pending=(list pend-tx) + ``noun+!>(pending) + %+ skim pending + |= pend-tx + =(u.who ship.from.tx.raw-tx) + :: + ++ status + |= wat=@t + ?~ keccak=(slaw %ux wat) + [~ ~] + :+ ~ ~ + :- %noun + !> ^- tx-status + ?^ status=(~(get by finding) u.keccak) + ?@ u.status [u.status ~] + [%sending `+.u.status] + :: TODO: potentially slow! + =; known=? + [?:(known %pending %unknown) ~] + %+ lien pending + |= pend-tx + =(u.keccak (hash-raw-tx:lib raw-tx)) + :: + ++ transaction + |= wat=@t + ?~ keccak=(slaw %ux wat) + [~ ~] + :+ ~ ~ + :- %noun + !> ^- (unit pend-tx) + :: TODO: potentially slow! + |- + ?~ pending ~ + =* tx i.pending + ?: =(u.keccak (hash-tx:lib raw.raw-tx.tx)) + `tx + $(pending t.pending) + :: + ++ history + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list hist-tx) + ?~ addr=(slaw %ux wat) ~ + ?~ hist=(~(get by ^history) u.addr) ~ + (tap:orh u.hist) + :: + ++ nonce + |= [who=@t proxy=@t] + ?~ who=(slaw %p who) + [~ ~] + ?. ?=(proxy:naive proxy) + [~ ~] + :+ ~ ~ + :- %noun + !> ^- (unit @) + ?~ point=(get:orp points.pre u.who) + ~ + =< `nonce + (proxy-from-point:naive proxy u.point) + :: + ++ spawned + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list @p) + ?~ star=(slaw %p wat) ~ + =; range + (turn range head) + :: range exclusive [star first-moon-last-planet] + :: + %- tap:orp + (lot:orp points.pre [`u.star `(cat 3 u.star 0x1.ffff)]) + :: + ++ unspawned + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list @p) + ?~ star=(slaw %p wat) ~ + =/ spawned=(set @p) + =; points + (~(gas in *(set @p)) (turn points head)) + %- tap:orp + (lot:orp points.pre [`u.star `(cat 3 u.star 0x1.ffff)]) + =/ children=(list @p) + (turn (gulf 0x1 0xffff) |=(a=@ (cat 3 u.star a))) + %+ murn children + |= =ship + ?: (~(has in spawned) ship) ~ + `ship + :: + ++ point + |= wat=@t + ?~ ship=(rush wat ;~(pfix sig fed:ag)) + ``noun+!>(*(unit point:naive)) + ``noun+!>((get:orp points.pre u.ship)) + :: + ++ ships + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list ship) + ?~ addr=(slaw %ux wat) + ~ + =/ proxies=(list proxy:naive) + ~[%own %spawn %manage %vote %transfer] + %+ roll proxies + |= [=proxy:naive ships=(list ship)] + %+ weld ships + ~(tap in (~(get ju own) [proxy u.addr])) + :: + ++ config + :+ ~ ~ + :- %noun + !> ^- roller-config + :* next-batch + frequency + resend-time + update-rate + contract + chain-id + slice + quota + == + :: + ++ points-proxy + |= [=proxy:naive wat=@t] + :+ ~ ~ + :- %noun + !> ^- (list ship) + ?~ addr=(slaw %ux wat) + ~ + ~(tap in (~(get ju own) [proxy u.addr])) + :: + ++ over-quota + |= wat=@t + ?~ who=(slaw %p wat) [~ ~] + =/ [exceeded=? *] (quota-exceeded u.who) + ``atom+!>(exceeded) + :: + -- + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card _this) + ?+ wire (on-arvo:def wire sign-arvo) + [%timer ~] + ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) + %wake =^(cards state on-timer:do [cards this]) + == + [%quota-timer ~] + ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) + %wake =^(cards state on-quota-timer:do [cards this]) + == + :: + [%predict ~] + ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) + %wake + =. own.state canonical-owners:do + =^ effects state + (predicted-state canonical-state):do + [(emit effects) this(derive &)] + == + :: + [%resend @ @ ~] + =/ [address=@ux nonce=@ud] + [(slav %ux i.t.wire) (rash i.t.t.wire dem)] + ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) + %wake [(send-roll:do address nonce) this] + == + == + :: + ++ on-fail + |= [=term =tang] + ::TODO if crashed during timer, set new timer? how to detect? + (on-fail:def term tang) + :: + ++ on-watch + |= =path + ^- (quip card _this) + :_ this + |^ + ?+ path (on-watch:def path) + [%txs @ ~] [%give %fact ~ (give-txs i.t.path)]~ + [%points @ ~] [%give %fact ~ (give-points i.t.path)]~ + == + :: + ++ give-points + |= wat=@t + ^- cage + :- %points + !> ^- (list [ship point:naive]) + ?~ addr=(slaw %ux wat) ~ + =/ proxies=(list proxy:naive) + ~[%own %spawn %manage %vote %transfer] + %+ roll proxies + |= [=proxy:naive points=(list [ship point:naive])] + %+ weld points + :: + %+ roll ~(tap in (~(get ju own) [proxy u.addr])) + |= [=ship points=_points] + %+ snoc points + [ship (need (get:orp points.pre ship))] + :: + ++ give-txs + |= wat=@t + ^- cage + :- %txs + !> ^- (list hist-tx) + ?~ addr=(slaw %ux wat) ~ + ?~ hist=(~(get by history) u.addr) ~ + (tap:orh u.hist) + -- + :: + ++ on-leave on-leave:def + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card _this) + |^ + ?+ wire (on-agent:def wire sign) + [%send @ @ *] (send-batch i.t.wire i.t.t.wire sign) + [%azimuth-events ~] (azimuth-event sign) + [%nonce ~] (nonce sign) + [%refresh-nonce @ ~] (refresh i.t.wire sign) + == + :: + ++ send-batch + |= [address=@t nonce=@t =sign:agent:gall] + ^- (quip card _this) + =/ [address=@ux nonce=@ud] + [(slav %ux address) (rash nonce dem)] + ?- -.sign + %poke-ack + ?~ p.sign + %- (slog leaf+"Send batch thread started successfully" ~) + [~ this] + %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) + :_ this + [(leave:spider:do wire)]~ + :: + %watch-ack + ?~ p.sign + [~ this] + =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to thread" + %- (slog tank u.p.sign) + [~ this] + :: + %kick + [~ this] + :: + %fact + ?+ p.cage.sign (on-agent:def wire sign) + %thread-fail + =+ !<([=term =tang] q.cage.sign) + %- (slog leaf+"{(trip dap.bowl)} failed" leaf+ tang) + =^ cards state + (on-batch-result:do address nonce %.n^[%error 'thread failed']) + [cards this] + :: + %thread-done + =+ !<(result=(each @ud [term @t]) q.cage.sign) + =^ cards state + (on-batch-result:do address nonce result) + [cards this] + == + == + :: + ++ azimuth-event + |= =sign:agent:gall + ^- (quip card _this) + ?+ -.sign [~ this] + %watch-ack + ?~ p.sign [~ this] + =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to %azimuth" + %- (slog tank u.p.sign) + [~ this] + :: + %fact + ?+ p.cage.sign (on-agent:def wire sign) + %naive-diffs + =+ !<(=diff:naive q.cage.sign) + =^ cards state + (on-naive-diff:do diff) + [cards this] + :: + %naive-state + ~& > %received-azimuth-state + :: cache naive and ownership state + :: + =^ nas own.state + !<([^state:naive owners] q.cage.sign) + =^ effects state + (predicted-state:do nas) + [(emit effects) this] + == + == + :: + ++ nonce + |= =sign:agent:gall + ^- (quip card _this) + ?- -.sign + %poke-ack + ?~ p.sign + %- (slog leaf+"Nonce thread started successfully" ~) + [~ this] + %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) + :_ this + [(leave:spider:do wire)]~ + :: + %watch-ack + ?~ p.sign + [~ this] + =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to thread" + %- (slog tank u.p.sign) + [~ this] + :: + %kick + [~ this] + :: + %fact + ?+ p.cage.sign (on-agent:def wire sign) + %thread-fail + =+ !<([=term =tang] q.cage.sign) + %- (slog leaf+"{(trip dap.bowl)} failed" leaf+ tang) + [~ this] + :: + %thread-done + =+ !<(nonce=@ud q.cage.sign) + [~ this(next-nonce `nonce)] + == + == + :: + ++ refresh + |= [nonce=@t =sign:agent:gall] + ^- (quip card _this) + =/ failed-nonce=@ud (rash nonce dem) + ?- -.sign + %poke-ack + ?~ p.sign + %- (slog leaf+"Refresh Nonce thread started successfully" ~) + [~ this] + %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) + :_ this + [(leave:spider:do wire)]~ + :: + %watch-ack + ?~ p.sign + [~ this] + =/ =tank leaf+"{(trip dap.bowl)} couldn't start listen to thread" + %- (slog tank u.p.sign) + [~ this] + :: + %kick + [~ this] + :: + %fact + ?+ p.cage.sign (on-agent:def wire sign) + %thread-fail + =+ !<([=term =tang] q.cage.sign) + %- (slog leaf+"{(trip dap.bowl)} failed" leaf+ tang) + [~ this] + :: + %thread-done + =+ !<(nonce=@ud q.cage.sign) + =^ cards state + (on-out-of-sync:do nonce failed-nonce) + [cards this] + == + == + -- + -- +:: +|_ =bowl:gall +::TODO /lib/sys.hoon? +++ sys + |% + ++ b + |% + ++ wait + |= [=wire =time] + ^- card + [%pass wire %arvo %b %wait time] + -- + -- +::TODO /lib/spider.hoon? +++ spider + |% + ++ start-thread + |= [=wire thread=term arg=vase] + ^- (list card) + =/ =beak byk.bowl(r da+now.bowl) + =/ tid=@ta (rap 3 thread '--' (scot %uv eny.bowl) ~) + =/ args [~ `tid beak thread arg] + :~ [%pass wire %agent [our.bowl %spider] %watch /thread-result/[tid]] + [%pass wire %agent [our.bowl %spider] %poke %spider-start !>(args)] + == + :: + ++ leave + |= =path + ^- card + [%pass path %agent [our.bowl %spider] %leave ~] + -- +:: +:: +++ emit + |= updates=(list update) + |- ^- (list card) + ?~ updates ~ + =* up i.updates + =/ [address=@t last-owner=(unit @t)] + ?- -.up + %tx + :_ ~ + (scot %ux address.up) + :: + %point + :- (scot %ux address.new.up) + ?~(old.up ~ `(scot %ux address.u.old.up)) + == + %+ weld + $(updates t.updates) + ^- (list card) + ?- -.i.updates + %tx + [%give %fact ~[/txs/[address]] tx+!>(roll-tx.up)]~ + :: + %point + %+ weld + [%give %fact ~[/points/[address]] point+!>([ship point]:up)]~ + ?~ last-owner ~ + [%give %fact ~[/points/[u.last-owner]] point+!>([ship point]:up)]~ + == +:: +++ part-tx-to-full + |= =part-tx + ^- [octs tx:naive] + ?- -.part-tx + %raw + ?~ batch=(parse-raw-tx:naive 0 q.raw.part-tx) + ~? lverb [dap.bowl %parse-failed] + :: TODO: maybe return a unit if parsing fails? + :: + !! + [raw tx]:-.u.batch + :: + %don [(gen-tx-octs:lib +.part-tx) +.part-tx] + %ful +.part-tx + == +:: +canonical-state: current l2 state from /app/azimuth +:: +++ canonical-state + .^ ^state:naive + %gx + (scot %p our.bowl) + %azimuth + (scot %da now.bowl) + /nas/noun + == +:: +canonical-owners: current azimuth point ownership +:: +++ canonical-owners + .^ owners + %gx + (scot %p our.bowl) + %azimuth + (scot %da now.bowl) + /own/noun + == +:: +predicted-state +:: +:: derives predicted state from applying pending & sending txs to +:: the provided naive state, discarding invalid txs in the process +:: +++ predicted-state + |= nas=^state:naive + ^- (quip update _state) + =: pre nas + own canonical-owners + == + |^ + =^ [nes=_sending updates-1=(list update)] state + apply-sending + =^ [nep=_pending updates-2=(list update)] state + apply-pending + :- (welp updates-1 updates-2) + state(sending nes, pending nep) + :: + ++ apply-pending + (apply-txs pending %pending next-nonce.state) + :: + ++ apply-sending + =| ups=(list update) + =/ valid=_sending ~ + =+ sorted=(tap:ors sending) + |- ^+ [[valid ups] state] + ?~ sorted [[valid ups] state] + :: + =* key key.i.sorted + =* val val.i.sorted + =+ txs=(turn txs.val |=(=raw-tx:naive [| 0x0 *time raw-tx])) + =^ [new-valid=_txs nups=_ups] state + (apply-txs txs %sending `nonce.key) + :: we only hear updates for this nonce if it has been sent + :: + =. valid ::=? valid sent.val + %^ put:ors valid + key + :: TODO: too much functional hackery? + val(txs (turn new-valid (cork tail (cork tail tail)))) + $(sorted t.sorted, ups (welp ups nups)) + :: + ++ apply-txs + |= [txs=(list pend-tx) type=?(%pending %sending) nonce=(unit @ud)] + =/ valid=_txs ~ + =| ups=(list update) + |- ^+ [[valid ups] state] + ?~ txs [[(flop valid) ups] state] + :: + =* tx i.txs + =* raw-tx raw-tx.i.txs + =* ship ship.from.tx.raw-tx.i.txs + =/ =keccak (hash-raw-tx:lib raw-tx) + =/ sign-address=(unit @ux) + (extract-address:lib raw-tx pre chain-id) + =^ [gud=? nups=_ups] state + (try-apply pre force.tx raw-tx) + :: TODO: only replace address if !=(address.tx sign-address)? + :: + =? tx &(gud ?=(^ sign-address)) + tx(address u.sign-address) + =/ =roll-tx [ship type keccak (l2-tx +<.tx.raw-tx)] + =? nups !gud + %+ snoc nups + [%tx address.tx roll-tx(status %failed)] + =? valid gud [tx valid] + =? history !gud + =/ =time + ?: ?=(%pending type) time.tx + =+ wer=(~(got by finding) keccak) + ?>(?=(^ wer) time.wer) + =+ txs=(~(got by history) address.tx) + =. txs +:(del:orh txs time) + %+ ~(put by history) address.tx + %+ put:orh txs + [time roll-tx(status %failed)] + =? finding !gud (~(put by finding) keccak %failed) + $(txs t.txs, ups (weld ups nups)) + -- +:: +try-apply: maybe apply the given l2 tx to the naive state +:: +++ try-apply + |= [nas=^state:naive force=? =raw-tx:naive] + ^- [[? ups=(list update)] _state] + =/ [success=? predicted=_nas ups=(list update) owners=_own] + (apply-raw-tx:dice force raw-tx nas own chain-id) + :- [success ups] + state(pre predicted, own owners) +:: +++ get-l1-address + |= [=tx:naive nas=^state:naive] + ^- (unit address:ethereum) + ?~ point=(get:orp points.nas ship.from.tx) ~ + =< `address + (proxy-from-point:naive proxy.from.tx u.point) +:: +++ on-action + |= =action + ^- (quip card _state) + =+ local=(team:title our.bowl src.bowl) + ?- -.action + %commit ?>(local on-timer) + %config ?>(local (on-config +.action)) + %cancel (cancel-tx +.action) + :: + %submit + :: TODO: return [~ state] instead of crashing + :: if naive state hasn't being retrieved yet? + :: + ?> ?=(^ points.pre) + %- take-tx + :* force.action + address.action + now.bowl + sig.action + (part-tx-to-full tx.action) + == + == +:: +++ on-config + |= =config + ^- (quip card _state) + ?- -.config + %frequency [~ state(frequency frequency.config)] + %resend-time [~ state(resend-time time.config)] + %update-rate [~ state(update-rate rate.config)] + %slice [~ state(slice slice.config)] + %quota [~ state(quota quota.config)] + :: + %endpoint + :- ~ + =/ [contract=@ux chain-id=@] + =< [naive chain-id] + =, azimuth + ?- net.config + %mainnet mainnet-contracts + %ropsten ropsten-contracts + %local local-contracts + == + %_ state + contract contract + chain-id chain-id + endpoint `endpoint.config + == + :: + %setkey + ?~ pk=(de:base16:mimes:html pk.config) + `state + [(get-nonce q.u.pk /nonce) state(pk q.u.pk)] + == +:: TODO: move address to state? +:: +++ get-address + ^- address:ethereum + (address-from-prv:key:ethereum pk) +:: +cancel-tx: cancel a pending transaction +:: +++ cancel-tx + |= [sig=@ =keccak =l2-tx =ship] + ^- (quip card _state) + ?^ status=(~(get by finding) keccak) + ~? lverb [dap.bowl %tx-not-pending status+u.status] + [~ state] + :: "cancel: 0x1234abcd" + :: + =/ message=octs + %: cad:naive 3 + 8^'cancel: ' + :: + =; hash=@t + (met 3 hash)^hash + (crip "0x{((x-co:co 65) keccak)}") + :: + ~ + == + ?~ addr=(verify-sig:lib sig message) + ~? lverb [dap.bowl %cancel-sig-fail] + [~ state] + =^ time pending + =| nep=(list pend-tx) + |- ^- [(unit time) _nep] + ?~ pending [~ (flop nep)] + ?: =(keccak (hash-raw-tx:lib raw-tx.i.pending)) + [`time.i.pending (weld (flop nep) t.pending)] + $(pending t.pending, nep [i.pending nep]) + ?~ time + ~? lverb [dap.bowl %weird-tx-not-pending] + [~ state] + :- ~ + %_ state + history + =+ txs=(~(got by history) u.addr) + =. txs +:(del:orh txs u.time) + %+ ~(put by history) u.addr + %^ put:orh txs + u.time + [ship %cancelled keccak l2-tx] + == +:: +take-tx: accept submitted l2 tx into the :pending list +:: +++ take-tx + |= =pend-tx + ^- (quip card _state) + =* ship ship.from.tx.raw-tx.pend-tx + =/ [exceeded=? next-quota=@] (quota-exceeded ship) + ?: exceeded [~ state] + =: pending (snoc pending pend-tx) + ship-quota (~(put by ship-quota) ship next-quota) + == + =^ [gud=? cards-1=(list update)] state + (try-apply pre [force raw-tx]:pend-tx) + ?. gud + :_ state + :: %point and (%failed) %tx updates + :: + (emit cards-1) + =^ cards-2 history + (update-history [pend-tx]~ %pending) + :: toggle derivation + :: + :_ state(derive ?:(derive | derive)) + ;: welp + (emit cards-1) :: %point updates + (emit cards-2) :: %tx updates + :: + ?. derive ~ + :: defer updating predicted naive/ownership state from canonical + :: + [(wait:b:sys /predict (add update-rate now.bowl))]~ + == +:: +++ timer + |% + :: +set-roller: %wait until next whole :frequency + :: + ++ set-roller + ^- [=card =time] + =+ time=(mul +((div now.bowl frequency)) frequency) + [(wait:b:sys /timer time) time] + :: +set-roller: %wait until next whole :slice + :: + ++ set-quota + |= slice=@dr + ^- card + =+ time=(mul +((div now.bowl slice)) slice) + (wait:b:sys /quota-timer time) + -- +:: +on-timer: every :frequency, freeze :pending txs roll and start sending it +:: +++ on-timer + ^- (quip card _state) + =^ updates-1 state + (predicted-state canonical-state) + =^ cards state + ?: =(~ pending) [~ state] + ?~ next-nonce + ~? lverb [dap.bowl %missing-roller-nonce] [~ state] + :: this guarantees that next-nonce is only incremented + :: when the thread that's sending the previous batch + :: has come back and confirms that it was sent to L1 + :: + ?: out-of-sync + :: this would postpone sending the batch for a whole "frequency" + :: TODO: set up a timer to retry this in ~mX ? + :: + ~? lverb [dap.bowl %nonce-out-sync] [~ state] + =/ nonce=@ud u.next-nonce + =^ updates-2 history (update-history pending %sending) + =: pending ~ + derive & + next-nonce `+(u.next-nonce) + :: + sending + %^ put:ors sending + [get-address nonce] + [0 | (turn pending (cork tail (cork tail tail)))] + :: + finding + %- ~(gas by finding) + %+ turn pending + |= pend-tx + (hash-raw-tx:lib raw-tx)^[time address nonce] + == + :_ state + ;: welp + (emit updates-1) + (emit updates-2) + (send-roll get-address nonce) + == + =^ card next-batch set-roller:timer + [[card cards] state] +:: +on-quota-timer: resets tx quota for all ships +:: +++ on-quota-timer + ^- (quip card _state) + :- [(set-quota:timer slice)]~ + state(ship-quota *(map ship @ud)) +:: +++ update-history + |= [txs=(list pend-tx) =status] + ^- [(list update) _history] + %+ roll txs + |= [pend-tx ups=(list update) sih=_history] + =/ =roll-tx + :* ship.from.tx.raw-tx + status + (hash-raw-tx:lib raw-tx) + (l2-tx +<.tx.raw-tx) + == + =/ txs=(tree hist-tx) + ?~ txs=(~(get by sih) address) ~ + u.txs + =? txs ?=(^ txs) +:(del:orh txs time) + :- (snoc ups tx+[address roll-tx]) + %+ ~(put by sih) address + (put:orh txs [time roll-tx]) +:: +get-nonce: retrieves the latest nonce +:: +++ get-nonce + |= [pk=@ =wire] + ^- (list card) + ?~ endpoint ~?(lverb [dap.bowl %no-endpoint] ~) + (start-thread:spider wire [%roller-nonce !>([u.endpoint pk])]) +:: +++ quota-exceeded + |= =ship + ^- [? @ud] + ?~ quota=(~(get by ship-quota) ship) + [| 1] + [(gte u.quota quota.state) +(u.quota)] +:: +out-of-sync: checks if the previous nonce has been sent +:: +++ out-of-sync + ^- ? + ?~ newest-batch=(ram:ors sending) | + !=(sent.val.u.newest-batch &) +:: +on-out-of-sync +:: +++ on-out-of-sync + |= [nonce=@ud failed-nonce=@ud] + :: we only care about nonces >= than the one that failed + :: + =/ failed-sending=(list [l1-tx-pointer send-tx]) + %- tap:ors + :: (range exclusive) + :: + (lot:ors sending [`[get-address (dec failed-nonce)] ~]) + =/ confirmed-sending=_sending + (lot:ors sending [~ `[get-address failed-nonce]]) + =/ [nes=_sending nif=_finding sih=_history] + %- tail + %+ roll failed-sending + |= $: [p=l1-tx-pointer q=send-tx] + new-nonce=_nonce + sending=_confirmed-sending + finding=_finding + history=_history + == + |^ + =* nonce nonce.p + =* txs txs.q + :: TODO: this shouldn't be needed + ?: (lth nonce.p failed-nonce) + ~& ["weird case" nonce+nonce.p] + [new-nonce sending finding history] + :+ +(new-nonce) + update-sending + process-l2-txs + :: + ++ update-sending + (put:ors sending [p(nonce new-nonce) q(sent %.n)]) + :: + ++ process-l2-txs + %+ roll txs.q + |= [=raw-tx:naive nif=_finding sih=_history] + =/ =keccak (hash-raw-tx:lib raw-tx) + |^ + ?~ val=(~(get by nif) keccak) + [nif sih] + ?. ?=(^ u.val) [nif sih] + :- (update-finding u.val) + (update-history time.u.val address.u.val) + :: + ++ update-finding + |= val=[time l1-tx-pointer] + ^+ nif + (~(put by nif) keccak val(nonce.+ new-nonce)) + :: + ++ update-history + |= [=time =address:ethereum] + ^+ sih + =* ship ship.from.tx.raw-tx + =/ l2-tx (l2-tx +<.tx.raw-tx) + =/ =roll-tx [ship %sending keccak l2-tx] + =+ txs=(~(got by sih) address) + =. txs +:(del:orh txs time) + %+ ~(put by sih) address + (put:orh txs [time roll-tx]) + -- + -- + =: sending nes + finding nif + history sih + next-nonce `+(nonce) + == + [(send-roll get-address nonce) state] +:: +send-roll: start thread to submit roll from :sending to l1 +:: +++ send-roll + |= [=address:ethereum =nonce:naive] + ^- (list card) + :: if this nonce isn't in the sending queue anymore, it's done + :: + ?. (has:ors sending [address nonce]) + ~? lverb [dap.bowl %done-sending [address nonce]] + ~ + ?~ endpoint + ~? lverb [dap.bowl %no-endpoint] + ~ + :: start the thread, passing in the l2 txs to use + :: TODO should go ahead and set resend timer in case thread hangs, or nah? + :: + %+ start-thread:spider + /send/(scot %ux address)/(scot %ud nonce) + :- %roller-send + !> ^- rpc-send-roll + :* u.endpoint + contract + chain-id + pk + nonce + :: + =< [next-gas-price txs] + (got:ors sending [address nonce]) + == +:: +on-batch-result: await resend after thread success or failure +:: +++ on-batch-result + |= [=address:ethereum nonce=@ud result=(each @ud [term @t])] + ^- (quip card _state) + :: print error if there was one + :: + ~? ?=(%| -.result) [dap.bowl %send-error +.p.result] + =/ =send-tx (got:ors sending [address nonce]) + =? sending ?=(%& -.result) + %^ put:ors sending + [address nonce] + :: update gas price for this tx in state + :: and set it as sent to L1 + :: + send-tx(next-gas-price p.result, sent &) + :_ state + ?: ?| ?=(%& -.result) + :: a general error shouldn't innitiate + :: the out-of-sync nonce thread + :: + ?=([%| %error *] result) + :: this accounts for a resend with higher gas + :: for a previous nonce, so we shouldn't start + :: the out-of-sync nonce thread + :: + ?& sent.send-tx + ?=([%| %not-sent *] result) + == == + :_ ~ + :: resend the l1 tx in five minutes + :: + %+ wait:b:sys + /resend/(scot %ux address)/(scot %ud nonce) + (add resend-time now.bowl) + :: TODO: this only accounts for the case where the nonce is out of sync, + :: reaching this because of lower funds needs to be addressed manually + :: + ?> ?=(%not-sent -.p.result) + (get-nonce pk.state /refresh-nonce/(scot %ud nonce)) +:: +on-naive-diff: process l2 tx confirmations +:: +++ on-naive-diff + |= =diff:naive + ^- (quip card _state) + ?. |(?=(%point -.diff) ?=(%tx -.diff)) + [~ state] + =; [cards=(list card) =_state] + :_ state(derive ?:(derive | derive)) + %+ weld cards + ?. derive ~ + :: defer updating predicted naive/ownership state from canonical + :: + [(wait:b:sys /predict (add update-rate now.bowl))]~ + :: + ?: ?=(%point -.diff) [~ state] + ?> ?=(%tx -.diff) + =/ =keccak (hash-raw-tx:lib raw-tx.diff) + ?~ wer=(~(get by finding) keccak) + :: tx not submitted by this roller + :: + [~ state] + ?@ u.wer + ~? &(?=(%confirmed u.wer) ?=(~ err.diff)) + [dap.bowl %weird-double-confirm from.tx.raw-tx.diff] + [~ state] + =* nonce nonce.u.wer + =* address address.u.wer + =* ship ship.from.tx.raw-tx.diff + =* time time.u.wer + =* tx tx.raw-tx.diff + =/ l2-tx (l2-tx +<.tx) + :: remove the tx from the sending map + :: + =. sending + ?~ sen=(get:ors sending [get-address nonce]) + ~? lverb [dap.bowl %weird-double-remove nonce+nonce] + sending + ?~ nin=(find [raw-tx.diff]~ txs.u.sen) + ~? lverb [dap.bowl %weird-unknown nonce+nonce] + sending + =. txs.u.sen (oust [u.nin 1] txs.u.sen) + ?~ txs.u.sen + ~? lverb [dap.bowl %done-with-nonce [get-address nonce]] + =^ * sending + (del:ors sending [get-address nonce]) + sending + ^+ sending + (put:ors sending [get-address nonce] u.sen) + :: update the finding map with the new status + :: + =. finding + %+ ~(put by finding) keccak + ?~ err.diff %confirmed + :: if we kept the forced flag around for longer, we could notify of + :: unexpected tx failures here. would that be useful? probably not? + :: ~? !forced [dap.bowl %aggregated-tx-failed-anyway err.diff] + %failed + :: + =^ updates history + %+ update-history + [| address time raw-tx.diff]~ + ?~(err.diff %confirmed %failed) + [(emit updates) state] +:: +-- diff --git a/pkg/arvo/app/settings-store.hoon b/pkg/arvo/app/settings-store.hoon deleted file mode 100644 index 2dbb0778b..000000000 --- a/pkg/arvo/app/settings-store.hoon +++ /dev/null @@ -1,186 +0,0 @@ -/- *settings -/+ verb, dbug, default-agent, agentio -|% -+$ card card:agent:gall -+$ versioned-state - $% state-0 - state-1 - == -+$ state-0 [%0 settings=settings-0] -+$ state-1 [%1 =settings] --- -=| state-1 -=* state - -:: -%- agent:dbug -%+ verb | -^- agent:gall -=< - |_ bol=bowl:gall - +* this . - do ~(. +> bol) - def ~(. (default-agent this %|) bol) - io ~(. agentio bol) - :: - ++ on-init - ^- (quip card _this) - =^ cards state - (put-entry:do %tutorial %seen b+|) - [cards this] - - :: - ++ on-save !>(state) - :: - ++ on-load - |= =old=vase - ^- (quip card _this) - =/ old !<(versioned-state old-vase) - |- - ?- -.old - %0 $(old [%1 +.old]) - %1 [~ this(state old)] - == - :: - ++ on-poke - |= [mar=mark vas=vase] - ^- (quip card _this) - ?> (team:title our.bol src.bol) - ?. ?=(%settings-event mar) - (on-poke:def mar vas) - =/ evt=event !<(event vas) - =^ cards state - ?- -.evt - %put-bucket (put-bucket:do key.evt bucket.evt) - %del-bucket (del-bucket:do key.evt) - %put-entry (put-entry:do buc.evt key.evt val.evt) - %del-entry (del-entry:do buc.evt key.evt) - == - [cards this] - :: - ++ on-watch - |= pax=path - ^- (quip card _this) - ?> (team:title our.bol src.bol) - ?+ pax (on-watch:def pax) - [%all ~] - [~ this] - :: - [%bucket @ ~] - =* bucket-key i.t.pax - ?> (~(has by settings) bucket-key) - [~ this] - :: - [%entry @ @ ~] - =* bucket-key i.t.pax - =* entry-key i.t.t.pax - =/ bucket (~(got by settings) bucket-key) - ?> (~(has by bucket) entry-key) - [~ this] - == - :: - ++ on-peek - |= pax=path - ^- (unit (unit cage)) - ?+ pax (on-peek:def pax) - [%x %all ~] - ``settings-data+!>(all+settings) - :: - [%x %bucket @ ~] - =* buc i.t.t.pax - =/ bucket=(unit bucket) (~(get by settings) buc) - ?~ bucket [~ ~] - ``settings-data+!>(bucket+u.bucket) - :: - [%x %entry @ @ ~] - =* buc i.t.t.pax - =* key i.t.t.t.pax - =/ =bucket (fall (~(get by settings) buc) ~) - =/ entry=(unit val) (~(get by bucket) key) - ?~ entry [~ ~] - ``settings-data+!>(entry+u.entry) - :: - [%x %has-bucket @ ~] - =* buc i.t.t.pax - =/ has-bucket=? (~(has by settings) buc) - ``noun+!>(has-bucket) - :: - [%x %has-entry @ @ ~] - =* buc i.t.t.pax - =* key i.t.t.t.pax - =/ =bucket (fall (~(get by settings) buc) ~) - =/ has-entry=? (~(has by bucket) key) - ``noun+!>(has-entry) - == - :: - ++ on-agent on-agent:def - ++ on-leave on-leave:def - ++ on-arvo on-arvo:def - ++ on-fail on-fail:def - -- -:: -|_ bol=bowl:gall -:: -:: +put-bucket: put a bucket in the top level settings map, overwriting if it -:: already exists -:: -++ put-bucket - |= [=key =bucket] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /bucket/[key] - == - :- [(give-event pas %put-bucket key bucket)]~ - state(settings (~(put by settings) key bucket)) -:: -:: +del-bucket: delete a bucket from the top level settings map -:: -++ del-bucket - |= =key - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /bucket/[key] - == - :- [(give-event pas %del-bucket key)]~ - state(settings (~(del by settings) key)) -:: -:: +put-entry: put an entry in a bucket, overwriting if it already exists -:: if bucket does not yet exist, create it -:: -++ put-entry - |= [buc=key =key =val] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /bucket/[buc] - /entry/[buc]/[key] - == - =/ =bucket (fall (~(get by settings) buc) ~) - =. bucket (~(put by bucket) key val) - :- [(give-event pas %put-entry buc key val)]~ - state(settings (~(put by settings) buc bucket)) -:: -:: +del-entry: delete an entry from a bucket, fail quietly if bucket does not -:: exist -:: -++ del-entry - |= [buc=key =key] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /bucket/[buc] - /entry/[buc]/[key] - == - =/ bucket=(unit bucket) (~(get by settings) buc) - ?~ bucket - [~ state] - =. u.bucket (~(del by u.bucket) key) - :- [(give-event pas %del-entry buc key)]~ - state(settings (~(put by settings) buc u.bucket)) -:: -++ give-event - |= [pas=(list path) evt=event] - ^- card - [%give %fact pas %settings-event !>(evt)] --- diff --git a/pkg/arvo/app/spider.hoon b/pkg/arvo/app/spider.hoon index 834a2c0a5..83e360d2d 100644 --- a/pkg/arvo/app/spider.hoon +++ b/pkg/arvo/app/spider.hoon @@ -1,6 +1,7 @@ /- spider -/+ libstrand=strand, default-agent, verb, server +/+ libstrand=strand, default-agent, verb, server, dbug =, strand=strand:libstrand +~% %spider-top ..part ~ |% +$ card card:agent:gall +$ thread thread:spider @@ -17,17 +18,35 @@ $: starting=(map yarn [=trying =vase]) running=trie tid=(map tid yarn) - serving=(map tid [@ta =mark]) + serving=(map tid [(unit @ta) =mark =desk]) == :: +$ clean-slate-any $^ clean-slate-ket $% clean-slate-sig clean-slate-1 + clean-slate-2 + clean-slate-3 clean-slate == :: +$ clean-slate + $: %4 + starting=(map yarn [=trying =vase]) + running=(list yarn) + tid=(map tid yarn) + serving=(map tid [(unit @ta) =mark =desk]) + == +:: ++$ clean-slate-3 + $: %3 + starting=(map yarn [=trying =vase]) + running=(list yarn) + tid=(map tid yarn) + serving=(map tid [@ta =mark =desk]) + == +:: ++$ clean-slate-2 $: %2 starting=(map yarn [=trying =vase]) running=(list yarn) @@ -55,11 +74,12 @@ == :: +$ start-args - [parent=(unit tid) use=(unit tid) file=term =vase] + [parent=(unit tid) use=(unit tid) =beak file=term =vase] -- :: :: Trie operations :: +~% %spider ..card ~ |% ++ get-yarn |= [=trie =yarn] @@ -133,17 +153,20 @@ (welp next-1 next-2) -- :: +%- agent:dbug ^- agent:gall =| =state =< %+ verb | + ~% %spider-agent ..bind-eyre ~ |_ =bowl:gall +* this . spider-core +> sc ~(. spider-core bowl) def ~(. (default-agent this %|) bowl) + bec byk.bowl(r da+now.bowl) :: - ++ on-init + ++ on-init ^- (quip card _this) :_ this ~[bind-eyre:sc] @@ -154,9 +177,11 @@ =+ !<(any=clean-slate-any old-state) =? any ?=(^ -.any) (old-to-1 any) =? any ?=(~ -.any) (old-to-1 any) - =^ upgrade-cards any + =^ upgrade-cards any (old-to-2 any) - ?> ?=(%2 -.any) + =. any (old-to-3 any) + =. any (old-to-4 any) + ?> ?=(%4 -.any) :: =. tid.state tid.any =/ yarns=(list yarn) @@ -178,9 +203,9 @@ :: ++ old-to-2 |= old=clean-slate-any - ^- (quip card clean-slate) - ?> ?=(?(%1 %2) -.old) - ?: ?=(%2 -.old) + ^- (quip card clean-slate-any) + ?> ?=(?(%1 %2 %3 %4) -.old) + ?: ?=(?(%2 %3 %4) -.old) `old :- ~[bind-eyre:sc] :* %2 @@ -189,9 +214,35 @@ tid.old ~ == + :: + ++ old-to-3 + |= old=clean-slate-any + ^- clean-slate-any + ?> ?=(?(%2 %3 %4) -.old) + ?: ?=(?(%3 %4) -.old) + old + :* %3 + starting.old + running.old + tid.old + (~(run by serving.old) |=([id=@ta =mark] [id mark q.byk.bowl])) + == + ++ old-to-4 + |= old=clean-slate-any + ^- clean-slate + ?> ?=(?(%3 %4) -.old) + ?: ?=(%4 -.old) + old + :* %4 + starting.old + running.old + tid.old + (~(run by serving.old) |=([id=@ta =mark =desk] [`id mark q.byk.bowl])) + == -- :: ++ on-poke + ~/ %on-poke |= [=mark =vase] ^- (quip card _this) ?: ?=(%spider-kill mark) @@ -202,12 +253,13 @@ %spider-start (handle-start-thread:sc !<(start-args vase)) %spider-stop (handle-stop-thread:sc !<([tid ?] vase)) :: - %handle-http-request + %handle-http-request (handle-http-request:sc !<([@ta =inbound-request:eyre] vase)) == [cards this] :: ++ on-watch + ~/ %on-watch |= =path ^- (quip card _this) =^ cards state @@ -220,6 +272,7 @@ :: ++ on-leave on-leave:def ++ on-peek + ~/ %on-peek |= =path ^- (unit (unit cage)) ?+ path (on-peek:def path) @@ -234,6 +287,7 @@ == :: ++ on-agent + ~/ %on-agent |= [=wire =sign:agent:gall] ^- (quip card _this) =^ cards state @@ -243,6 +297,7 @@ [cards this] :: ++ on-arvo + ~/ %on-arvo |= [=wire =sign-arvo] ^- (quip card _this) =^ cards state @@ -261,8 +316,9 @@ (on-load on-save) -- :: +~% %spider-helper ..get-yarn ~ |_ =bowl:gall -:: +++ bec `beak`byk.bowl(r da+now.bowl) ++ bind-eyre ^- card [%pass /bind %arvo %e %connect [~ /spider] %spider] @@ -272,33 +328,29 @@ :((cury cat 3) file '--' (scot %uv (sham eny.bowl))) :: ++ handle-http-request + ~/ %handle-http-request |= [eyre-id=@ta =inbound-request:eyre] ^- (quip card _state) - ?> authenticated.inbound-request - =/ url + ::?> authenticated.inbound-request + =/ url (parse-request-line:server url.request.inbound-request) - ?> ?=([%spider @t @t @t ~] site.url) - =* input-mark i.t.site.url - =* thread i.t.t.site.url - =* output-mark i.t.t.t.site.url + ?> ?=([%spider @t @t @t @t ~] site.url) + =* desk i.t.site.url + =* input-mark i.t.t.site.url + =* thread i.t.t.t.site.url + =* output-mark i.t.t.t.t.site.url =/ =tid (new-thread-id thread) =. serving.state - (~(put by serving.state) tid [eyre-id output-mark]) - =+ .^ - =tube:clay - %cc - /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/json/[input-mark] - == + (~(put by serving.state) tid [`eyre-id output-mark desk]) + :: TODO: speed this up somehow. we spend about 15ms in this arm alone + :: + =/ tube (convert-tube %json input-mark desk bowl) ?> ?=(^ body.request.inbound-request) - =/ body=json - (need (de-json:html q.u.body.request.inbound-request)) - =/ input=vase - (slop !>(~) (tube !>(body))) - =/ =start-args - [~ `tid thread input] - =^ cards state - (handle-start-thread start-args) - [cards state] + =/ body=json (need (de-json:html q.u.body.request.inbound-request)) + =/ input=vase (slop !>(~) (tube !>(body))) + =/ boc bec + =/ =start-args [~ `tid boc(q desk, r da+now.bowl) thread input] + (handle-start-thread start-args) :: ++ on-poke-input |= input @@ -315,6 +367,7 @@ `state :: ++ handle-sign + ~/ %handle-sign |= [=tid =wire =sign-arvo] =/ yarn (~(get by tid.state) tid) ?~ yarn @@ -331,7 +384,8 @@ (take-input u.yarn ~ %agent wire sign) :: ++ handle-start-thread - |= [parent-tid=(unit tid) use=(unit tid) file=term =vase] + ~/ %handle-start-thread + |= [parent-tid=(unit tid) use=(unit tid) =beak file=term =vase] ^- (quip card ^state) =/ parent-yarn=yarn ?~ parent-tid @@ -347,18 +401,22 @@ ~| [%already-starting yarn] !! :: + =? serving.state !(~(has by serving.state) new-tid) + (~(put by serving.state) new-tid [~ %noun q.beak]) + :: =: starting.state (~(put by starting.state) yarn [%build vase]) tid.state (~(put by tid.state) new-tid yarn) - == + == =/ pax=path ~| no-file-for-thread+file - (need (get-fit:clay [our q.byk da+now]:bowl %ted file)) - =/ =card - :+ %pass /build/[new-tid] - [%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl pax] - [[card ~] state] + (need (get-fit:clay beak %ted file)) + :_ state + :_ ~ + :+ %pass /build/[new-tid] + [%arvo %c %warp p.beak q.beak ~ %sing %a r.beak pax] :: ++ handle-build + ~/ %handle-build |= [=tid =sign-arvo] ^- (quip card ^state) =/ =yarn (~(got by tid.state) tid) @@ -377,6 +435,7 @@ (start-thread yarn p.maybe-thread) :: ++ start-thread + ~/ %start-thread |= [=yarn =thread] ^- (quip card ^state) =/ =vase vase:(~(got by starting.state) yarn) @@ -411,11 +470,12 @@ (thread-fail u.yarn %cancelled ~) :: ++ take-input + ~/ %take-input |= [=yarn input=(unit input:strand)] ^- (quip card ^state) =/ m (strand ,vase) ?. (has-yarn running.state yarn) - %- (slog leaf+"spider got input for non-existent {} 2" ~) + %- (slog leaf+"spider got input for non-existent {}" ~) `state =/ =eval-form:eval:m thread-form:(need (get-yarn running.state yarn)) @@ -461,7 +521,7 @@ =/ moz (thread-say-fail tid term tang) ?. ?=([~ %build *] (~(get by starting.state) yarn)) moz - :_(moz [%pass /build/[tid] %arvo %c %warp our.bowl %home ~]) + :_(moz [%pass /build/[tid] %arvo %c %warp our.bowl %base ~]) :: ++ thread-say-fail |= [=tid =term =tang] @@ -473,11 +533,13 @@ |= [=tid =term =tang] ^- (quip card ^state) =- (fall - `state) - %+ bind + %+ bind (~(get by serving.state) tid) - |= [eyre-id=@ta output=mark] + |= [eyre-id=(unit @ta) output=mark =desk] :_ state(serving (~(del by serving.state) tid)) - %+ give-simple-payload:app:server eyre-id + ?~ eyre-id + ~ + %+ give-simple-payload:app:server u.eyre-id ^- simple-payload:http :_ ~ :_ ~ ?. ?=(http-error:spider term) @@ -503,16 +565,14 @@ |= [=tid =vase] ^- (quip card ^state) =- (fall - `state) - %+ bind + %+ bind (~(get by serving.state) tid) - |= [eyre-id=@ta output=mark] - =+ .^ - =tube:clay - %cc - /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[output]/json - == + |= [eyre-id=(unit @ta) output=mark =desk] + ?~ eyre-id + `state + =/ tube (convert-tube output %json desk bowl) :_ state(serving (~(del by serving.state) tid)) - %+ give-simple-payload:app:server eyre-id + %+ give-simple-payload:app:server u.eyre-id (json-response:gen:server !<(json (tube vase))) :: ++ thread-done @@ -543,6 +603,7 @@ =/ =tid (yarn-to-tid yarn) =: running.state (del-yarn running.state yarn) tid.state (~(del by tid.state) tid) + serving.state (~(del by serving.state) (yarn-to-tid yarn)) == :_ state %+ murn ~(tap by wex.bowl) @@ -559,14 +620,14 @@ |= [=yarn =bowl:gall] ^- bowl:spider :* our.bowl - src.bowl + src.bowl (yarn-to-tid yarn) (yarn-to-parent yarn) wex.bowl sup.bowl eny.bowl now.bowl - byk.bowl + (yarn-to-byk yarn bowl) == :: ++ yarn-to-tid @@ -585,7 +646,25 @@ ~ `i.t.nary :: +++ yarn-to-byk + |= [=yarn =bowl:gall] + + =/ [* * =desk] + ~| "no desk associated with {}" + %- ~(got by serving.state) (yarn-to-tid yarn) + =/ boc bec + boc(q desk) +:: ++ clean-state !> ^- clean-slate - 2+state(running (turn (tap-yarn running.state) head)) + 4+state(running (turn (tap-yarn running.state) head)) +:: +++ convert-tube + |= [from=mark to=mark =desk =bowl:gall] + .^ + tube:clay + %cc + /(scot %p our.bowl)/[desk]/(scot %da now.bowl)/[from]/[to] + == + -- diff --git a/pkg/arvo/desk.bill b/pkg/arvo/desk.bill new file mode 100644 index 000000000..b4d897254 --- /dev/null +++ b/pkg/arvo/desk.bill @@ -0,0 +1,11 @@ +:~ %acme + %azimuth + %dbug + %dojo + %eth-watcher + %hood + %herm + %lens + %ping + %spider +== diff --git a/pkg/arvo/gen/agents.hoon b/pkg/arvo/gen/agents.hoon new file mode 100644 index 000000000..dc473b3b8 --- /dev/null +++ b/pkg/arvo/gen/agents.hoon @@ -0,0 +1,11 @@ +/- hood +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[=desk ~] ~] + == +:- %tang +%+ turn (get-apps-have:hood p.bec desk now) +|= [=dude:gall live=?] +^- tank +=/ liv ?:(live "running " "archived") +[%leaf "status: {liv} {}"] diff --git a/pkg/arvo/gen/aqua/dojo.hoon b/pkg/arvo/gen/aqua/dojo.hoon index 9850f34bf..03d63f505 100644 --- a/pkg/arvo/gen/aqua/dojo.hoon +++ b/pkg/arvo/gen/aqua/dojo.hoon @@ -5,10 +5,10 @@ :- %aqua-events %+ turn ^- (list unix-event) - :~ [//term/1 %belt %ctl `@c`%e] - [//term/1 %belt %ctl `@c`%u] - [//term/1 %belt %txt ((list @c) command)] - [//term/1 %belt %ret ~] + :~ [/d/term/1 %belt %ctl `@c`%e] + [/d/term/1 %belt %ctl `@c`%u] + [/d/term/1 %belt %txt ((list @c) command)] + [/d/term/1 %belt %ret ~] == |= ue=unix-event [%event her ue] diff --git a/pkg/arvo/gen/aqua/file.hoon b/pkg/arvo/gen/aqua/file.hoon index 6486b1911..4b0958c5c 100644 --- a/pkg/arvo/gen/aqua/file.hoon +++ b/pkg/arvo/gen/aqua/file.hoon @@ -7,5 +7,5 @@ :+ %event her ?> ?=([@ @ @ *] pax) =/ file [/text/plain (as-octs:mimes:html .^(@ %cx pax))] -:- //sync/0v1n.2m9vh +:- /c/sync/0v1n.2m9vh [%into `desk`i.t.pax | `mode:clay`[t.t.t.pax `file]~] diff --git a/pkg/arvo/gen/aqua/init.hoon b/pkg/arvo/gen/aqua/init.hoon index 2eec2fba2..4d7f922a2 100644 --- a/pkg/arvo/gen/aqua/init.hoon +++ b/pkg/arvo/gen/aqua/init.hoon @@ -1,6 +1,8 @@ +:: Start an aqua ship +:: /- aquarium =, aquarium :- %say -|= [* [her=ship ~] ~] +|= [* [her=ship fake=? ~] ~] :- %aqua-events -[%init-ship her `*dawn-event:jael]~ +[%init-ship her fake]~ diff --git a/pkg/arvo/gen/azimuth/watch.hoon b/pkg/arvo/gen/azimuth/watch.hoon index b1455cc23..5fdecb67c 100644 --- a/pkg/arvo/gen/azimuth/watch.hoon +++ b/pkg/arvo/gen/azimuth/watch.hoon @@ -1,4 +1,4 @@ -:: Change node url for azimuth +:: Change node url and network for azimuth :- %say -|= [* [url=@ta ~] ~] -[%azimuth-poke %watch url] +|= [* [url=@ta net=?(%mainnet %ropsten %local) ~] ~] +[%azimuth-poke %watch url net] diff --git a/pkg/arvo/gen/brass.hoon b/pkg/arvo/gen/brass.hoon index b6aa3e4cb..67a1cd8f0 100644 --- a/pkg/arvo/gen/brass.hoon +++ b/pkg/arvo/gen/brass.hoon @@ -9,17 +9,43 @@ !: :- %say |= $: [now=@da eny=@uvJ bec=beak] - arg=$@(~ [top=path ~]) + :: + :: arg: desks to build pill from + :: + :: list of desks. defaults to [%base]~. + :: the first desk in this list will become the pill's base desk. + :: optionally, the first desk may be replaced with a fully + :: qualified path to the new boot system (typically in sys). + :: the rest of the desks will be installed through kiln. + :: + $= arg + $@ ~ + $: base=$@(desk [@ta @ta @ta path]) + rest=(list desk) + == + :: ~ == -:- %noun +:- %boot-pill ^- pill:pill -:: :: sys: root path to boot system, `/~me/[desk]/now/sys` +:: bas: root path to boot system' desk +:: dez: secondary desks and their root paths :: =/ sys=path - ?^ arg top.arg - /(scot %p p.bec)/[q.bec]/(scot %da now)/sys + ?: ?=([^ *] arg) + `path`base.arg + =/ =desk + ?~ arg %base + ?>(?=(@ base.arg) base.arg) + /(scot %p p.bec)/[desk]/(scot %da now)/sys +=/ bas=path + (scag 3 sys) +=/ dez=(list [desk path]) + ?~ arg ~ + %+ turn rest.arg + |= =desk + [desk /(scot %p p.bec)/[desk]/(scot %da now)] :: :: compiler-source: hoon source file producing compiler, `sys/hoon` :: @@ -52,10 +78,11 @@ == :: a pill is a 3-tuple of event-lists: [boot kernel userspace] :: -=/ bas=path (flop (tail (flop sys))) :+ %pill %brass :+ boot-ova :~ (boot-ovum:pill compiler-source arvo-source) (file-ovum2:pill bas) == -[(file-ovum:pill bas) ~] +%+ turn + (snoc dez [%base bas]) +file-ovum:pill diff --git a/pkg/arvo/gen/desk-jam.hoon b/pkg/arvo/gen/desk-jam.hoon new file mode 100644 index 000000000..77ba234c9 --- /dev/null +++ b/pkg/arvo/gen/desk-jam.hoon @@ -0,0 +1,10 @@ +:: +desk-jam: jam ankh from desk +:: +/+ jammer=desk-jam +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [=desk ~] + ~ + == +:- %jam +(jam-desk:jammer p.bec desk now) diff --git a/pkg/arvo/gen/hood/bump.hoon b/pkg/arvo/gen/hood/bump.hoon new file mode 100644 index 000000000..4811c2f35 --- /dev/null +++ b/pkg/arvo/gen/hood/bump.hoon @@ -0,0 +1,7 @@ +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + ~ + force=_| + except=(set desk) + == +[%kiln-bump except force] diff --git a/pkg/arvo/gen/hood/crunch.hoon b/pkg/arvo/gen/hood/crunch.hoon new file mode 100644 index 000000000..6998e7bf2 --- /dev/null +++ b/pkg/arvo/gen/hood/crunch.hoon @@ -0,0 +1,30 @@ +/- ms=metadata-store +/+ crunch +:- %say +|= [[now=@da * bec=beak] [csv-path=path from=@da ~] [to=@da groups=(list path) content=(unit ?) ~]] +=/ our=@p p.bec +:: check given path has `csv` mark +:: +?> =(%csv (snag (dec (lent csv-path)) csv-path)) +:: get all graph associations ship is a part of +:: +=/ associations=associations:ms + (~(scry-graph-associations crunch [our now])) +:: filter by input groups, if any (default: all from scry) +:: +=/ filtered-associations=associations:ms + ?~ groups + associations + %+ filter-associations-by-group-resources.crunch + associations + (paths-to-resources.crunch groups) +:: walk graphs to extract content +:: +=/ file-content=wain + %: ~(walk-graph-associations crunch [our now]) + filtered-associations + ?~ content %.n u.content + from + ?: =(*@da to) now to + == +[%helm-pass (note-write-csv-to-clay.crunch csv-path file-content)] diff --git a/pkg/arvo/gen/hood/fuse-list.hoon b/pkg/arvo/gen/hood/fuse-list.hoon new file mode 100644 index 000000000..20d3a4644 --- /dev/null +++ b/pkg/arvo/gen/hood/fuse-list.hoon @@ -0,0 +1,20 @@ +:: Kiln: Fuse local desk from (optionally-)foreign sources +:: +:::: /hoon/fuse/hood/gen + :: +/+ *hood-kiln +/* help-text %txt /gen/hood/fuse/help/txt +=, clay +:: +:::: + :: +=> +|% ++$ fuse-list-arg $@(~ [des=desk ~]) +-- +:- %say +|= [* [arg=fuse-list-arg] ~] +:- %kiln-fuse-list +?~ arg + ~ +`des.arg diff --git a/pkg/arvo/gen/hood/fuse.hoon b/pkg/arvo/gen/hood/fuse.hoon index 870b38d2a..59940b363 100644 --- a/pkg/arvo/gen/hood/fuse.hoon +++ b/pkg/arvo/gen/hood/fuse.hoon @@ -2,14 +2,59 @@ :: :::: /hoon/fuse/hood/gen :: +/+ *hood-kiln /* help-text %txt /gen/hood/fuse/help/txt =, clay :: :::: :: +=> +|% ++$ fuse-arg + $: des=desk + :: specified as [germ path] instead of [path germ] so + :: users can write mate//=home= instead of [/=home= %mate] + :: + res=[?([%cancel ~] [bas=path con=(list [germ path])])] + == +:: +++ parse-fuse-source + |= bec=beak + ^- fuse-source + :: This is a slight overload of the label, but + :: it provides a nicer interface for the user so + :: we'll go with it. + :: + ?: ?=([%tas *] r.bec) + ?: =(p.r.bec %track) + [p.bec q.bec %trak] + bec + bec +:: +++ de-beak + |= pax=path + ^- beak + =/ bem=beam (need (de-beam pax)) + ?> =(s.bem /) + -.bem +:: +++ path-to-fuse-source + |= pax=path + ^- fuse-source + (parse-fuse-source (de-beak pax)) +-- :- %say -|= [[now=@da eny=@uvJ bec=beak] [arg=[?(~ [des=desk bas=beak con=(list [beak germ]) ~])]] ~] +|= [* [arg=[?(~ fuse-arg)]] [overwrite=$~(| flag) ~]] :- %kiln-fuse ?~ arg ((slog (turn `wain`help-text |=(=@t leaf+(trip t)))) ~) -[des bas con]:arg +:- des.arg +?: ?=([%cancel ~] res.arg) + ~ +:+ overwrite + (path-to-fuse-source bas.res.arg) +%+ turn + con.res.arg +|= [g=germ pax=path] +^- [fuse-source germ] +[(path-to-fuse-source pax) g] diff --git a/pkg/arvo/gen/hood/fuse/help.txt b/pkg/arvo/gen/hood/fuse/help.txt index 9e18eb80e..009a7e035 100644 --- a/pkg/arvo/gen/hood/fuse/help.txt +++ b/pkg/arvo/gen/hood/fuse/help.txt @@ -1,8 +1,21 @@ Usage: - |fuse %destination-desk base-beak ~[[source-beak %some-germ] [another-beak %another-germ]] + |fuse %dest /=kids= mate//~nel/home= meet//~zod/kids/track + |fuse %old-desk /=kids= only-that//~nus/test=, =overwrite & + |fuse %desk-to-cancel-fuse-into %cancel -A fuse replaces the contents of %destination-desk with the merge of the -specified beaks according to their merge strategies. This has no dependence -on the previous state of %destination-desk so any commits/work there will -be overwritten. +A %fuse request in clay replaces the contents of %destination-desk +with the merge of the specified beaks according to their merge +strategies. This has no dependence on the previous state of %dest +so any commits/work there will be overwritten. + +|fuse extends this concept with the idea of a tracked source. When +specifying beaks to include in your fuse, specify %track instead of +a case. This will tell |fuse to retrieve the latest version of the +source beak AND to rerun the %fuse request whenever that tracked +source changes. A fuse can have many tracked sources, or none. The +base may be tracked as well. + +The overwrite flag allows you to overwrite a currently ongoing fuse. +Without this flag, attempting a fuse into a desk that you already +|fuse'd into will error. diff --git a/pkg/arvo/gen/hood/install.hoon b/pkg/arvo/gen/hood/install.hoon new file mode 100644 index 000000000..c243cf90a --- /dev/null +++ b/pkg/arvo/gen/hood/install.hoon @@ -0,0 +1,14 @@ +:: |install: install the .rem desk from .her into local .lac desk +:: +:: > |install ~zod %landscape +:: installs ~zod's %landscape desk into our %landscape desk. +:: +:: > |install ~zod %landscape, =local %portrait +:: installs ~zod's %landscape desk into our %portrait desk. +:: +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[her=@p rem=desk ~] local=@tas] + == +=/ loc=desk ?:(=(%$ local) rem local) +[%kiln-install loc her rem] diff --git a/pkg/arvo/gen/hood/mount.hoon b/pkg/arvo/gen/hood/mount.hoon index a063fb7e7..07d638a76 100644 --- a/pkg/arvo/gen/hood/mount.hoon +++ b/pkg/arvo/gen/hood/mount.hoon @@ -7,11 +7,21 @@ :::: :: :- %say +=> |% + +$ bath + $@ desk + (lest knot) + -- |= $: [now=@da eny=@uvJ bec=beak] - [[pax=path pot=$@(~ [v=@tas ~])] ~] + [=bath pot=$@(~ [v=@tas ~])] + ~ == -?~ pot - =+ bem=(need (de-beam pax)) - $(pot ~[?^(s.bem (rear s.bem) q.bem)]) -:- %kiln-mount -[pax v.pot] +=/ bem=beam + ?@ bath [bec(q bath) /] + (need (de-beam `path`bath)) +:: +=/ =desk + ?^ pot v.pot + ?^(s.bem (rear s.bem) q.bem) +:: +[%kiln-mount (en-beam bem) desk] diff --git a/pkg/arvo/gen/hood/nuke.hoon b/pkg/arvo/gen/hood/nuke.hoon new file mode 100644 index 000000000..8cc54bffd --- /dev/null +++ b/pkg/arvo/gen/hood/nuke.hoon @@ -0,0 +1,34 @@ +:: |nuke: wipe agent state & subscriptions after confirmation +:: +/+ *generators +:- %ask +|= $: [now=@da eny=@uvJ bec=beak] + [=term ~] + [desk=_| hard=_|] + == +?: hard (produce %kiln-nuke term desk) +=/ m1 + 'nuking agents will permanently delete all their state and subscriptions.' +=/ m2 + 'if other agents depend on the one(s) you nuke, \ + /their behavior could be negatively impacted. \ + /if you do not understand the risks, you may \ + /want to contact the agent\'s developers.' +=/ m3 + %+ rap 3 + :~ 'are you sure you want to continue and nuke ' + :: + ?. desk (cat 3 '%' term) + (cat 3 'all agents in ' term) + :: + '?' + == +::NOTE yes, printing order is weird +%+ print m3 +%+ print m2 +%+ print m1 +%+ prompt [%& %prompt "nuke? (y/N) "] +|= in=tape +?. |(=("y" in) =("Y" in) =("yes" in)) + no-product +(produce %kiln-nuke term desk) diff --git a/pkg/arvo/gen/hood/ota.hoon b/pkg/arvo/gen/hood/ota.hoon index fcccb68a8..d7bb38906 100644 --- a/pkg/arvo/gen/hood/ota.hoon +++ b/pkg/arvo/gen/hood/ota.hoon @@ -8,11 +8,11 @@ :: :- %say |= $: [now=@da eny=@uvJ bec=beak] - [arg=?(~ [%disable ~] [her=@p sud=@tas ~]) ~] + arg=?([%disable ~] [her=@p sud=?(~ [@tas ~])]) + ~ == -?~ arg - :- %kiln-ota-info ~ -:- %kiln-ota +:- %kiln-install ?: ?=([%disable ~] arg) - ~ -`[her sud]:arg + [%base p.bec %base] +:+ %base her.arg +?@(sud.arg %kids -.sud.arg) diff --git a/pkg/arvo/gen/hood/pause.hoon b/pkg/arvo/gen/hood/pause.hoon new file mode 100644 index 000000000..5584c52eb --- /dev/null +++ b/pkg/arvo/gen/hood/pause.hoon @@ -0,0 +1,5 @@ +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[=desk ~] ~] + == +[%kiln-pause desk] diff --git a/pkg/arvo/gen/hood/rein.hoon b/pkg/arvo/gen/hood/rein.hoon new file mode 100644 index 000000000..d3477ec5e --- /dev/null +++ b/pkg/arvo/gen/hood/rein.hoon @@ -0,0 +1,16 @@ +/- hood +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + $: =desk + arg=(list [? dude:gall]) + == + liv=_& + == +:- %kiln-rein +:- desk +%+ roll arg +=| =rein:hood +|: [*[on=? =dude:gall] rein(liv liv)] +?: on + rein(add (~(put in add.rein) dude)) +rein(sub (~(put in sub.rein) dude)) diff --git a/pkg/arvo/gen/hood/resume.hoon b/pkg/arvo/gen/hood/resume.hoon new file mode 100644 index 000000000..a16f8e210 --- /dev/null +++ b/pkg/arvo/gen/hood/resume.hoon @@ -0,0 +1,5 @@ +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[=desk ~] ~] + == +[%kiln-resume desk] diff --git a/pkg/arvo/gen/hood/revive.hoon b/pkg/arvo/gen/hood/revive.hoon new file mode 100644 index 000000000..0fe0ff245 --- /dev/null +++ b/pkg/arvo/gen/hood/revive.hoon @@ -0,0 +1,5 @@ +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[=desk ~] ~] + == +[%kiln-revive desk] diff --git a/pkg/arvo/gen/hood/suspend.hoon b/pkg/arvo/gen/hood/suspend.hoon new file mode 100644 index 000000000..cd5736f73 --- /dev/null +++ b/pkg/arvo/gen/hood/suspend.hoon @@ -0,0 +1,5 @@ +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[=desk ~] ~] + == +[%kiln-suspend desk] diff --git a/pkg/arvo/gen/hood/uninstall.hoon b/pkg/arvo/gen/hood/uninstall.hoon new file mode 100644 index 000000000..f4a3db893 --- /dev/null +++ b/pkg/arvo/gen/hood/uninstall.hoon @@ -0,0 +1,5 @@ +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [[=desk ~] ~] + == +[%kiln-uninstall desk] diff --git a/pkg/arvo/gen/kick.hoon b/pkg/arvo/gen/kick.hoon index e5a469bdd..807b00227 100644 --- a/pkg/arvo/gen/kick.hoon +++ b/pkg/arvo/gen/kick.hoon @@ -2,6 +2,7 @@ :- %say |= $: [now=@da eny=@uvJ bec=beak] ~ - ~ + nice=? + == -[%kick %kick] +[%kick nice] diff --git a/pkg/arvo/gen/roller/commit.hoon b/pkg/arvo/gen/roller/commit.hoon new file mode 100644 index 000000000..f04a62e11 --- /dev/null +++ b/pkg/arvo/gen/roller/commit.hoon @@ -0,0 +1,5 @@ +:: Submits a new L2 batch with all pending transactions +:: +:- %say +|= * +[%roller-action %commit ~] diff --git a/pkg/arvo/gen/roller/config.hoon b/pkg/arvo/gen/roller/config.hoon new file mode 100644 index 000000000..261514635 --- /dev/null +++ b/pkg/arvo/gen/roller/config.hoon @@ -0,0 +1,7 @@ +:: Updates a configuration option for /app/roller +:: +/- *dice +:: +:- %say +|= [* [=config ~] ~] +[%roller-action %config config] diff --git a/pkg/arvo/gen/roller/endpoint.hoon b/pkg/arvo/gen/roller/endpoint.hoon new file mode 100644 index 000000000..ce59f3073 --- /dev/null +++ b/pkg/arvo/gen/roller/endpoint.hoon @@ -0,0 +1,4 @@ +:: +:- %say +|= [* [url=@t net=?(%mainnet %ropsten %local) ~] ~] +[%roller-action %config %endpoint url net] diff --git a/pkg/arvo/gen/roller/frequency.hoon b/pkg/arvo/gen/roller/frequency.hoon new file mode 100644 index 000000000..b4485a309 --- /dev/null +++ b/pkg/arvo/gen/roller/frequency.hoon @@ -0,0 +1,4 @@ +:: +:- %say +|= [* [freq=@dr ~] ~] +[%roller-action %config %frequency freq] diff --git a/pkg/arvo/gen/roller/local.hoon b/pkg/arvo/gen/roller/local.hoon new file mode 100644 index 000000000..f1202a8ed --- /dev/null +++ b/pkg/arvo/gen/roller/local.hoon @@ -0,0 +1,5 @@ +:: Configures /app/roller to listen to a local Ethereum node +:: +:- %say +|= * +[%roller-action %config %endpoint 'http://0.0.0.0:8545' %local] diff --git a/pkg/arvo/gen/roller/network.hoon b/pkg/arvo/gen/roller/network.hoon new file mode 100644 index 000000000..8d625c287 --- /dev/null +++ b/pkg/arvo/gen/roller/network.hoon @@ -0,0 +1,4 @@ +:: +:- %say +|= [* [net=?(%mainnet %ropsten %local) ~] ~] +[%roller-action %config %network net] diff --git a/pkg/arvo/gen/roller/quota.hoon b/pkg/arvo/gen/roller/quota.hoon new file mode 100644 index 000000000..a5ca7845b --- /dev/null +++ b/pkg/arvo/gen/roller/quota.hoon @@ -0,0 +1,5 @@ +:: Modifies the number of txs a ship is allowed to send, per unit of time (slice) +:: +:- %say +|= [* [quota=@ud ~] ~] +[%roller-action %config %quota quota] diff --git a/pkg/arvo/gen/roller/ropsten.hoon b/pkg/arvo/gen/roller/ropsten.hoon new file mode 100644 index 000000000..af363f0dd --- /dev/null +++ b/pkg/arvo/gen/roller/ropsten.hoon @@ -0,0 +1,10 @@ +:: Configures /app/roller to listen to a Ropsten Infura node +:: +:- %say +|= * +:* %roller-action + %config + %endpoint + 'https://ropsten.infura.io/v3/2599df54929b47099bda360958d75aaf' + %ropsten +== diff --git a/pkg/arvo/gen/roller/setkey.hoon b/pkg/arvo/gen/roller/setkey.hoon new file mode 100644 index 000000000..7e884027b --- /dev/null +++ b/pkg/arvo/gen/roller/setkey.hoon @@ -0,0 +1,5 @@ +:: Loads a private key into the roller and retrieves its L1 nonce +:: +:- %say +|= [* [pk=@t ~] ~] +[%roller-action %config %setkey pk] diff --git a/pkg/arvo/gen/roller/slice.hoon b/pkg/arvo/gen/roller/slice.hoon new file mode 100644 index 000000000..1b0de984e --- /dev/null +++ b/pkg/arvo/gen/roller/slice.hoon @@ -0,0 +1,5 @@ +:: Modifies the unit of time (e.g. ~d1) for each ship's quota +:: +:- %say +|= [* [slice=@dr ~] ~] +[%roller-action %config %slice slice] diff --git a/pkg/arvo/gen/show-vat.hoon b/pkg/arvo/gen/show-vat.hoon new file mode 100644 index 000000000..2f2e7f725 --- /dev/null +++ b/pkg/arvo/gen/show-vat.hoon @@ -0,0 +1,15 @@ +/- *bill +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [=desk ~] + ~ + == +:- %tang +%- flop ^- tang +=/ pax=path /(scot %p p.bec)/[desk]/(scot %da now) +=+ .^([lal=@tas num=@ud] cx+(weld pax /sys/kelvin)) +:~ 'sys.kelvin:' + leaf/"[%{} %{}]" + 'desk.bill:' + (sell !>(.^(bill cx+(weld pax /desk/bill)))) +== diff --git a/pkg/arvo/gen/solid.hoon b/pkg/arvo/gen/solid.hoon index 1e12d3cce..5a747004e 100644 --- a/pkg/arvo/gen/solid.hoon +++ b/pkg/arvo/gen/solid.hoon @@ -12,16 +12,43 @@ !: :- %say |= $: [now=@da eny=@uvJ bec=beak] - arg=$@(~ [top=path ~]) + :: + :: arg: desks to build pill from + :: + :: list of desks. defaults to [%base]~. + :: the first desk in this list will become the pill's base desk. + :: optionally, the first desk may be replaced with a fully + :: qualified path to the new boot system (typically in sys). + :: the rest of the desks will be installed through kiln. + :: + $= arg + $@ ~ + $: base=$@(desk [@ta @ta @ta path]) + rest=(list desk) + == + :: dub=_| == -:- %pill +:- %boot-pill ^- pill:pill :: sys: root path to boot system, `/~me/[desk]/now/sys` +:: bas: root path to boot system' desk +:: dez: secondary desks and their root paths :: =/ sys=path - ?^ arg top.arg - /(scot %p p.bec)/[q.bec]/(scot %da now)/sys + ?: ?=([^ *] arg) + `path`base.arg + =/ =desk + ?~ arg %base + ?>(?=(@ base.arg) base.arg) + /(scot %p p.bec)/[desk]/(scot %da now)/sys +=/ bas=path + (scag 3 sys) +=/ dez=(list [desk path]) + ?~ arg ~ + %+ turn rest.arg + |= =desk + [desk /(scot %p p.bec)/[desk]/(scot %da now)] :: =/ compiler-path (weld sys /hoon) =/ arvo-path (weld sys /arvo) @@ -65,9 +92,10 @@ =< q %^ spin ^- (list ovum) - :~ (boot-ovum:pill compiler-src arvo-src) - (file-ovum2:pill (flop (tail (flop sys)))) - == + :- (boot-ovum:pill compiler-src arvo-src) + %+ turn + (snoc (turn dez tail) bas) + file-ovum2:pill .*(0 arvo-formula) |= [ovo=ovum ken=*] [~ (slum ken [now ovo])] @@ -99,5 +127,6 @@ :: :+ %pill %solid :+ boot-ova ~ -=/ bas (flop (tail (flop sys))) -[(file-ovum:pill bas) ~] +%+ turn + (snoc dez [%base bas]) +file-ovum:pill diff --git a/pkg/arvo/gen/spider/start.hoon b/pkg/arvo/gen/spider/start.hoon index e7607bde3..1aa4a7ce7 100644 --- a/pkg/arvo/gen/spider/start.hoon +++ b/pkg/arvo/gen/spider/start.hoon @@ -1,4 +1,7 @@ :: Start a thread :- %say -|= [* [name=term vase=$@(~ [vase ~])] ~] -[%spider-start ~ ~ name ?~(vase *^vase -.vase)] +|= $: [now=@da eny=@uvJ bec=beak] + [name=term vase=$@(~ [vase ~])] + ~ + == +[%spider-start ~ ~ bec name ?~(vase *^vase -.vase)] diff --git a/pkg/arvo/gen/trouble.hoon b/pkg/arvo/gen/trouble.hoon deleted file mode 100644 index 7eff7e13a..000000000 --- a/pkg/arvo/gen/trouble.hoon +++ /dev/null @@ -1,76 +0,0 @@ -:: Print useful diagnostic information -:: -:: base-hash: loosely, the most recent successfully applied update. -:: Technically, the mergebase of %home with OTA source -:: sour-hash: most recently downloaded update (not necessarily applied) -:: home-hash: hash of %home desk, which may differ if you have changed -:: it, for example with notebooks or 3rd party apps -:: kids-hash: hash of the %kids desk, which is what you serve to your -:: children -:: glob-hash: hash of the glob, which is the js for landscape -:: -/- glob -/+ version -:- %say -|= [[now=time * bec=beak] ~ ~] -=* our p.bec -=/ sponsor (sein:title our now our) -:- %noun -=< -:~ - [%base-hash (base-hash:version our now)] - [%sour-hash sour-hash] - [%home-hash .^(@uv %cz (pathify ~.home ~))] - [%kids-hash .^(@uv %cz (pathify ~.kids ~))] - [%glob-hash glob-state] - :: - (info %our our) - (info %sponsor sponsor) - (info %dopzod ~dopzod) - :: - ["Compare lifes and rifts to values here:"] - ["https://etherscan.io/address/azimuth.eth#readContract"] - [" life - getKeyRevisionNumber"] - [" rift - getContinuityNumber"] -== -|% -++ pathify - |= [a=@ta b=(unit ship)] - ^- path - =/ o=@ta (scot %p our) - =/ n=@ta (scot %da now) - ?~ b ~[o a n] - ~[o a n (scot %p u.b)] -:: -++ info - |= [=term =ship] - :: unitized life and rift - =/ lyfe .^((unit @ud) %j (pathify ~.lyfe `ship)) - =/ ryft .^((unit @ud) %j (pathify ~.ryft `ship)) - :* term - ship=ship - point=(crip (slag 2 (scow %ui ship))) - :: report as units - life=lyfe - rift=ryft - == -:: -++ sour-hash - =+ .^ ota=(unit [=ship =desk =aeon:clay]) - %gx /(scot %p our)/hood/(scot %da now)/kiln/ota/noun - == - ?~ ota - *@uv - =/ parent (scot %p ship.u.ota) - =+ .^(=cass:clay %cs /[parent]/[desk.u.ota]/1/late/foo) - .^(@uv %cz /[parent]/[desk.u.ota]/(scot %ud ud.cass)) -:: -++ glob-state - ^- (list [path @uv @tas]) - =+ !< [@ud =globs:glob] - .^(vase %gx (weld (pathify ~.glob ~) /dbug/state/noun)) - %+ turn ~(tap by globs) - |= [srv=path hash=@uv glob=(unit [? *])] - ^- [path @uv @tas] - [srv hash ?~(glob %waiting ?:(-.u.glob %done %trying))] --- diff --git a/pkg/arvo/gen/trouble.hoon b/pkg/arvo/gen/trouble.hoon new file mode 120000 index 000000000..5374c353e --- /dev/null +++ b/pkg/arvo/gen/trouble.hoon @@ -0,0 +1 @@ +vats.hoon \ No newline at end of file diff --git a/pkg/arvo/gen/vats.hoon b/pkg/arvo/gen/vats.hoon new file mode 100644 index 000000000..67046c460 --- /dev/null +++ b/pkg/arvo/gen/vats.hoon @@ -0,0 +1,6 @@ +/- *hood +:- %say +|= $: [now=@da eny=@uvJ bec=beak] + [arg=~ ~] + == +[%tang (report-vats p.bec now)] diff --git a/pkg/arvo/lib/agentio.hoon b/pkg/arvo/lib/agentio.hoon deleted file mode 100644 index bd09905f7..000000000 --- a/pkg/arvo/lib/agentio.hoon +++ /dev/null @@ -1,125 +0,0 @@ -=> - |% - ++ card card:agent:gall - -- -:: -|_ =bowl:gall -++ scry - |= [desk=@tas =path] - %+ weld - /(scot %p our.bowl)/[desk]/(scot %da now.bowl) - path -:: -++ pass - |_ =wire - ++ poke - |= [=dock =cage] - [%pass wire %agent dock %poke cage] - :: - ++ poke-our - |= [app=term =cage] - ^- card - (poke [our.bowl app] cage) - :: - ++ poke-self - |= =cage - ^- card - (poke-our dap.bowl cage) - :: - ++ arvo - |= =note-arvo - ^- card - [%pass wire %arvo note-arvo] - :: - ++ watch - |= [=dock =path] - [%pass (watch-wire path) %agent dock %watch path] - :: - ++ watch-our - |= [app=term =path] - (watch [our.bowl app] path) - :: - ++ watch-wire - |= =path - ^+ wire - ?. ?=(~ wire) - wire - agentio-watch+path - :: - ++ leave - |= =dock - [%pass wire %agent dock %leave ~] - :: - ++ leave-our - |= app=term - (leave our.bowl app) - :: - ++ leave-path - |= [=dock =path] - =. wire - (watch-wire path) - (leave dock) - :: - ++ wait - |= p=@da - (arvo %b %wait p) - :: - ++ rest - |= p=@da - (arvo %b %wait p) - :: - ++ warp - |= [wer=ship =riff:clay] - (arvo %c %warp wer riff) - :: - ++ warp-our - |= =riff:clay - (warp our.bowl riff) - :: - :: right here, right now - ++ warp-slim - |= [genre=?(%sing %next) =care:clay =path] - =/ =mood:clay - [care r.byk.bowl path] - =/ =rave:clay - ?:(?=(%sing genre) [genre mood] [genre mood]) - (warp-our q.byk.bowl `rave) - -- -:: -++ fact-curry - |* [=mark =mold] - |= [paths=(list path) fac=mold] - (fact mark^!>(fac) paths) -:: -++ fact-kick - |= [=path =cage] - ^- (list card) - :~ (fact cage ~[path]) - (kick ~[path]) - == -:: -++ fact-init - |= =cage - ^- card - [%give %fact ~ cage] -:: -++ fact-init-kick - |= =cage - ^- (list card) - :~ (fact cage ~) - (kick ~) - == -:: -++ fact - |= [=cage paths=(list path)] - ^- card - [%give %fact paths cage] -:: -++ kick - |= paths=(list path) - [%give %kick paths ~] -:: -++ kick-only - |= [=ship paths=(list path)] - [%give %kick paths `ship] --- diff --git a/pkg/arvo/lib/agentio.hoon b/pkg/arvo/lib/agentio.hoon new file mode 120000 index 000000000..959a49843 --- /dev/null +++ b/pkg/arvo/lib/agentio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/agentio.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/aqua-azimuth.hoon b/pkg/arvo/lib/aqua-azimuth.hoon index 7a2a46db5..4aec08d1c 100644 --- a/pkg/arvo/lib/aqua-azimuth.hoon +++ b/pkg/arvo/lib/aqua-azimuth.hoon @@ -122,7 +122,7 @@ :_ ~ :* %event her - //http-client/0v1n.2m9vh + /i/http-client/0v1n.2m9vh %receive num.u.ask [%start [200 ~] `(as-octs:mimes:html resp) &] diff --git a/pkg/arvo/lib/azimuth-rpc.hoon b/pkg/arvo/lib/azimuth-roll-rpc.hoon similarity index 53% rename from pkg/arvo/lib/azimuth-rpc.hoon rename to pkg/arvo/lib/azimuth-roll-rpc.hoon index 218226cbd..31e16eb6d 100644 --- a/pkg/arvo/lib/azimuth-rpc.hoon +++ b/pkg/arvo/lib/azimuth-roll-rpc.hoon @@ -1,6 +1,6 @@ -:: azimuth-rpc: command parsing and utilities +:: azimuth/roll rpc: command parsing and utilities :: -/- rpc=json-rpc, *aggregator +/- rpc=json-rpc, *dice /+ naive, json-rpc, lib=naive-transactions :: => :: Utilities @@ -20,26 +20,13 @@ %set-transfer-proxy == :: - ++ pk - ^- @ - =; key=@t - q:(need (de:base16:mimes:html key)) - :: 'a44de2416ee6beb2f323fab48b432925c9785808d33a6ca6d7ba00b45e9370c3' - '2480c5256d843c73cba67cc966a11a647c943a41db2fa138de4e4f16d0861a6b' - :: - ++ fake-raw - |= [nonce=@ud =tx:naive] - :: ~& nonce+nonce - ^- octs - (gen-tx:lib nonce tx pk) - :: ++ parse-ship |= jon=json ^- (unit @p) ?: ?=([%n *] jon) - `(rash p.jon dem) + (rush p.jon dem) ?. ?=([%s *] jon) ~ - `(rash p.jon ;~(pfix sig fed:ag)) + (rush p.jon ;~(pfix sig fed:ag)) :: TODO: from /lib/group-store (move to zuse?) ++ enkebab |= str=cord @@ -62,20 +49,24 @@ ++ from-json =, dejs-soft:format |% - ++ keys - |= params=(map @t json) - ^- (unit [encrypt=@ auth=@ crypto-suite=@ breach=?]) - ?~ data=(~(get by params) 'data') ~ - %. u.data - %- ot - :~ ['encrypt' so] - ['auth' so] - ['cryptoSuite' so] - ['breach' bo] - == - :: ++ data |% + ++ keys + |= params=(map @t json) + ^- (unit [encrypt=@ auth=@ crypto-suite=@ breach=?]) + ?~ data=(~(get by params) 'data') ~ + =; ans=(unit [cryp=(unit @ux) auth=(unit @ux) suit=@ brec=?]) + ?~ ans ~ + ?: |(?=(~ cryp.u.ans) ?=(~ auth.u.ans)) ~ + (some [u.cryp.u.ans u.auth.u.ans suit.u.ans brec.u.ans]) + %. u.data + %- ot + :~ ['encrypt' (cu to-hex so)] + ['auth' (cu to-hex so)] + ['cryptoSuite' (su dem)] + ['breach' bo] + == + :: ++ address-transfer |= params=(map @t json) ^- (unit [@ux ?]) @@ -117,6 +108,16 @@ ?~ data=(~(get by params) 'data') ~ %. u.data (ot ['ship' parse-ship]~) + :: + ++ cancel + |= params=(map @t json) + ^- (unit [l2-tx @p]) + ?~ data=(~(get by params) 'data') ~ + %. u.data + %- ot + :~ ['type' (cu l2-tx so)] + ['ship' parse-ship] + == -- :: ++ ship @@ -164,43 +165,49 @@ ?~ u.ans ~ (some (as-octs:mimes:html u.u.ans)) :: - ++ l2-tx + ++ tx |= params=(map @t json) - ^- (unit ^l2-tx) - ?~ type=(~(get by params) 'type') ~ - %. u.type - (cu ^l2-tx so) + ^- (unit l2-tx) + ?~ data=(~(get by params) 'tx') ~ + ?~ tx=(so u.data) ~ + =/ method=@tas (enkebab u.tx) + ?. ?=(l2-tx method) ~ + `method + :: + ++ nonce + |= params=(map @t json) + ^- (unit @ud) + ?~ nonce=(~(get by params) 'nonce') ~ + (ni u.nonce) -- :: ++ to-json =, enjs:format |% - ++ pending - |= pending=(list pend-tx) - ^- json - :- %a - %+ turn pending + ++ pending-tx |= pend-tx ^- json %- pairs :~ ['force' b+force] - ['address' s+(crip "0x{((x-co:co 20) address)}")] - :: - :- 'rawTx' - %- pairs - :~ ['tx' (tx:to-json tx.raw-tx)] - :: - :+ 'sig' %s - %- crip - "0x{((x-co:co (met 3 sig.raw-tx)) sig.raw-tx)}" - == == + ['time' (^time time)] + ['rawTx' (^raw-tx raw-tx)] + (en-address address) + == :: - ++ tx - |= =tx:naive + ++ pending-txs + |= pending=(list pend-tx) + ^- json + a+(turn pending pending-tx) + :: + ++ en-address |=(a=@ux address+(hex 20 a)) + :: + ++ raw-tx + |= raw-tx:naive ^- json |^ %- pairs :~ ['tx' (parse-tx +.tx)] + ['sig' (hex (as-octs:mimes:html sig))] :: :- 'from' %- pairs @@ -229,8 +236,7 @@ %set-transfer-proxy ~[(en-address address.tx)] == == :: - ++ en-ship |=(s=@p ship+(ship s)) - ++ en-address |=(a=@ux address+s+(crip "0x{((x-co:co 20) a)}")) + ++ en-ship |=(s=@p ship+(numb `@ud`s)) ++ en-spawn |=([s=@p a=@ux] ~[(en-ship s) (en-address a)]) ++ en-transfer |=([a=@ux r=?] ~[(en-address a) reset+b+r]) ++ en-keys @@ -243,23 +249,19 @@ == -- :: - ++ txs - |= txs=(list tx:naive) - ^- json - a+(turn txs |=(=tx:naive (tx:to-json tx))) - :: - ++ roller-txs - |= txs=(list roller-tx) + ++ hist-txs + |= txs=(list hist-tx) ^- json :- %a %+ turn txs - |= roller-tx + |= hist-tx ^- json %- pairs - :: [status=tx-status hash=keccak type=l2-tx] - :~ ['status' s+status.status] - ['hash' s+(crip "0x{((x-co:co 20) hash)}")] - ['type' s+type] + :~ ['time' (time p)] + ['status' s+status.q] + ['hash' (hex (as-octs:mimes:html hash.q))] + ['type' s+type.q] + ['ship' (ship ship.q)] == :: ++ point @@ -282,25 +284,30 @@ :- 'network' %- pairs =* net net.point - :* ['rift' (numb rift.net)] + :* ['rift' s+(json-number rift.net)] :: :- 'keys' %- pairs - :~ ['life' (numb life.keys.net)] - ['suite' (numb suite.keys.net)] - ['auth' s+(crip "0x{((x-co:co 20) auth.keys.net)}")] - ['crypt' s+(crip "0x{((x-co:co 20) crypt.keys.net)}")] + :~ ['life' s+(json-number life.keys.net)] + ['suite' s+(json-number suite.keys.net)] + ['auth' (hex 32 auth.keys.net)] + ['crypt' (hex 32 crypt.keys.net)] == :: - ['rift' (numb rift.net)] :- 'sponsor' %- pairs - ~[['has' b+has.sponsor.net] ['who' (ship who.sponsor.net)]] + ~[['has' b+has.sponsor.net] ['who' (numb `@ud`who.sponsor.net)]] :: ?~ escape.net ~ - ['escape' (ship u.escape.net)]~ + ['escape' (numb `@ud`u.escape.net)]~ == == :: + ++ json-number + |= num=@ + ^- @t + =/ jon=json (numb num) + ?>(?=([%n *] jon) p.jon) + :: ++ points |= points=(list [@p point:naive]) ^- json @@ -312,11 +319,16 @@ ['point' (^point point)] == :: + ++ ships + |= ships=(list @p) + ^- json + a+(turn ships (cork @ud numb)) + :: ++ ownership |= [=address:naive =nonce:naive] ^- json %- pairs - :~ ['address' s+(crip "0x{((x-co:co 20) address)}")] + :~ (en-address address) ['nonce' (numb nonce)] == :: @@ -325,89 +337,106 @@ ^- json :- %a %+ turn children - |= [child=@p addr=@ux] + |= [child=@p address=@ux] %- pairs :~ ['ship' (ship child)] - ['address' s+(crip "0x{((x-co:co 20) addr)}")] + (en-address address) == :: ++ tx-status |=(=^tx-status ^-(json s+status.tx-status)) :: - ++ config - |= roller-config + ++ roller-config + |= [az=^azimuth-config ro=^roller-config] ^- json %- pairs - :~ ['nextBatch' (time next-batch)] - ['frequency' (numb (div frequency ~s1))] - ['refreshTime' (numb (div refresh-time ~s1))] - ['contract' s+(crip "0x{((x-co:co 20) contract)}")] - ['chainId' (numb chain-id)] + :~ ['azimuthRefreshRate' (numb (div refresh-rate.az ~s1))] + ['nextBatch' (time next-batch.ro)] + ['frequency' (numb (div frequency.ro ~s1))] + ['rollerResendTime' (numb (div resend-time.ro ~s1))] + ['rollerUpdateRate' (numb (div update-rate.ro ~s1))] + ['contract' (hex 20 contract.ro)] + ['chainId' (numb chain-id.ro)] + ['timeSlice' (numb (div slice.ro ~s1))] + ['rollerQuota' (numb quota.ro)] == + :: + ++ azimuth-config + |= config=^azimuth-config + ^- json + %- pairs + ['refreshRate' (numb (div refresh-rate.config ~s1))]~ + :: + ++ hex + |= [p=@ q=@] + ^- json + s+(crip ['0' 'x' ((x-co:co (mul 2 p)) q)]) + :: + ++ naive-state + |= =^state:naive + ^- json + |^ + %- pairs + :~ ['points' (points (tap:orp points.state))] + ['operators' (operators operators.state)] + ['dns' a+(turn dns.state (lead %s))] + == + :: + ++ orp ((on ^ship point:naive) por:naive) + :: + ++ operators + |= =operators:naive + ^- json + :- %a + %+ turn ~(tap by operators) + |= [op=@ux addrs=(set @ux)] + ^- json + %- pairs + :~ ['operator' (hex 20 op)] + ['addresses' a+(turn ~(tap in addrs) (cury hex 20))] + == + -- -- :: ++ to-hex |= =cord ^- (unit @ux) + ?. =((end [3 2] cord) '0x') ~ (rush (rsh [3 2] cord) hex) :: - ++ rpc-res - |% - ++ sponsor - |= [id=@t params=(map @t json) action=spawn-action] - ^- [(unit cage) response:rpc] - ?. (params:validate params) - [~ ~(params error:json-rpc id)] - =/ sig=(unit @) (sig:from-json params) - =/ from=(unit [@p proxy:naive]) (from:from-json params) - =/ raw=(unit octs) (raw:from-json params) - =/ data=(unit @p) (ship:data:from-json params) - ?. &(?=(^ sig) ?=(^ from) ?=(^ raw) ?=(^ data)) - [~ ~(parse error:json-rpc id)] - :_ [%result id s+'ok'] - %- some - :- %aggregator-action - !> - =; =skim-tx:naive - [%submit | u.sig %ful u.raw u.from skim-tx] - ?- action - %escape [%escape u.data] - %cancel-escape [%cancel-escape u.data] - %adopt [%adopt u.data] - %reject [%reject u.data] - %detach [%detach u.data] + ++ build-l2-tx + |= [=l2-tx from=[@p proxy:naive] params=(map @t json)] + ^- (unit tx:naive) + ?: =(l2-tx %transfer-point) + ?~ data=(address-transfer:data:from-json params) + ~ + `[from %transfer-point u.data] + ?: =(l2-tx %spawn) + ?~ data=(address-ship:data:from-json params) + ~ + `[from %spawn u.data] + ?: =(l2-tx %configure-keys) + ?~ data=(keys:data:from-json params) + ~ + `[from %configure-keys u.data] + ?: ?=(spawn-action l2-tx) + ?~ data=(ship:data:from-json params) + ~ + ?- l2-tx + %escape `[from %escape u.data] + %cancel-escape `[from %cancel-escape u.data] + %adopt `[from %adopt u.data] + %reject `[from %reject u.data] + %detach `[from %detach u.data] == - :: - ++ proxy - |= [id=@t params=(map @t json) action=proxy-action] - ^- [(unit cage) response:rpc] - ?. (params:validate params) - [~ ~(params error:json-rpc id)] - =/ sig=(unit @) (sig:from-json params) - =/ from=(unit [@p proxy:naive]) (from:from-json params) - =/ raw=(unit octs) (raw:from-json params) - =/ data=(unit @ux) (address:data:from-json params) - ?. &(?=(^ sig) ?=(^ from) ?=(^ raw) ?=(^ data)) - [~ ~(parse error:json-rpc id)] - :_ [%result id s+'ok'] - %- some - :- %aggregator-action - !> - =; =skim-tx:naive - [%submit | u.sig %ful u.raw u.from skim-tx] - ?- action - %set-management-proxy [%set-management-proxy u.data] - %set-spawn-proxy [%set-spawn-proxy u.data] - %set-transfer-proxy [%set-transfer-proxy u.data] - == - -- - :: - ++ validate - |% - ++ params - |= params=(map @t json) - ^- ? - =((lent ~(tap by params)) 4) - -- + ?. ?=(proxy-action l2-tx) + ~ + ?~ data=(address:data:from-json params) + ~ + ?- l2-tx + %set-management-proxy `[from %set-management-proxy u.data] + %set-spawn-proxy `[from %set-spawn-proxy u.data] + %set-transfer-proxy `[from %set-transfer-proxy u.data] + == -- |% ++ get-point @@ -423,15 +452,14 @@ ~(not-found error:json-rpc id) [%result id (point:to-json u.point)] :: -++ get-points - |= [id=@t params=(map @t json) scry=$-(@ux (list [@p point:naive]))] +++ get-ships + |= [id=@t params=(map @t json) scry=$-(@ux (list @p))] ^- response:rpc - ~& ~(wyt by params) ?. =(~(wyt by params) 1) ~(params error:json-rpc id) ?~ address=(address:from-json params) ~(parse error:json-rpc id) - [%result id (points:to-json (scry u.address))] + [%result id (ships:to-json (scry u.address))] :: ++ get-dns |= [id=@t params=(map @t json) dns=(list @t)] @@ -440,89 +468,50 @@ ~(params error:json-rpc id) [%result id a+(turn dns (cork same (lead %s)))] :: -++ transfer-point - |= [id=@t params=(map @t json)] - ^- [(unit cage) response:rpc] - ?. (params:validate params) - [~ ~(params error:json-rpc id)] - =/ sig=(unit @) (sig:from-json params) - =/ from=(unit [ship proxy:naive]) (from:from-json params) - =/ raw=(unit octs) (raw:from-json params) - =/ data=(unit [@ux ?]) (address-transfer:data:from-json params) - ?: |(?=(~ sig) ?=(~ from) ?=(~ raw) ?=(~ data)) - [~ ~(parse error:json-rpc id)] - :_ [%result id s+'ok'] - %- some - :- %aggregator-action - !>([%submit | u.sig %ful u.raw u.from %transfer-point u.data]) -:: ++ cancel-tx |= [id=@t params=(map @t json)] ^- [(unit cage) response:rpc] ?. =(~(wyt by params) 3) [~ ~(params error:json-rpc id)] - =/ sig=(unit @) (sig:from-json params) - =/ keccak=(unit @ux) (hash:from-json params) - =/ l2=(unit l2-tx) (l2-tx:from-json params) - ?. &(?=(^ sig) ?=(^ keccak) ?=(^ l2)) + =/ sig=(unit @) (sig:from-json params) + =/ keccak=(unit @ux) (hash:from-json params) + =/ data=(unit [l2-tx ship]) (cancel:data:from-json params) + ?. &(?=(^ sig) ?=(^ keccak) ?=(^ data)) [~ ~(parse error:json-rpc id)] :_ [%result id s+'ok'] %- some - :- %aggregator-action - !>([%cancel u.sig u.keccak u.l2]) + roller-action+!>([%cancel u.sig u.keccak u.data]) :: ++ get-spawned - |= [id=@t params=(map @t json) scry=$-(ship (list [ship @ux]))] + |= [id=@t params=(map @t json) scry=$-(@p (list @p))] ^- response:rpc ?. =((lent ~(tap by params)) 1) ~(params error:json-rpc id) - ?~ ship=(~(get by params) 'ship') + ?~ ship=(ship:from-json params) ~(params error:json-rpc id) - ?~ ship=(parse-ship u.ship) - ~(params error:json-rpc id) - [%result id (spawned:to-json (scry u.ship))] + [%result id (ships:to-json (scry u.ship))] :: -++ configure-keys - |= [id=@t params=(map @t json)] +++ process-rpc + |= [id=@t params=(map @t json) action=l2-tx over-quota=$-(@p ?)] ^- [(unit cage) response:rpc] - ?. (params:validate params) + ?. =((lent ~(tap by params)) 4) [~ ~(params error:json-rpc id)] - =/ sig=(unit @) (sig:from-json params) - =/ from=(unit [ship proxy:naive]) (from:from-json params) - =/ raw=(unit octs) (raw:from-json params) - =/ data=(unit [encrypt=@ auth=@ crypto-suite=@ breach=?]) - (keys:data:from-json params) - ?. &(?=(^ sig) ?=(^ from) ?=(^ raw) ?=(^ data)) + =+ ^- $: sig=(unit @) + from=(unit [=ship proxy:naive]) + addr=(unit @ux) + == + =, from-json + [(sig params) (from params) (address params)] + ?: |(?=(~ sig) ?=(~ from) ?=(~ addr)) [~ ~(parse error:json-rpc id)] - :_ [%result id s+'ok'] + ?: (over-quota ship.u.from) + `[%error id '-32002' 'Max tx quota exceeded'] + =/ tx=(unit tx:naive) (build-l2-tx action u.from params) + ?~ tx [~ ~(parse error:json-rpc id)] + =+ (gen-tx-octs:lib u.tx) + :_ [%result id (hex:to-json 32 (hash-tx:lib p q))] %- some - :- %aggregator-action - !>([%submit | u.sig %ful u.raw u.from %configure-keys u.data]) -:: -++ spawn - |= [id=@t params=(map @t json)] - ^- [(unit cage) response:rpc] - ?. (params:validate params) - [~ ~(params error:json-rpc id)] - =/ sig=(unit @) (sig:from-json params) - =/ from=(unit [@p proxy:naive]) (from:from-json params) - =/ raw=(unit octs) (raw:from-json params) - =/ data=(unit [@p @ux]) (address-ship:data:from-json params) - ?. &(?=(^ sig) ?=(^ from) ?=(^ raw) ?=(^ data)) - [~ ~(parse error:json-rpc id)] - :_ [%result id s+'ok'] - %- some - :- %aggregator-action - !>([%submit | u.sig %ful u.raw u.from %spawn u.data]) -:: -++ escape sponsor:rpc-res -++ cancel-escape sponsor:rpc-res -++ adopt sponsor:rpc-res -++ detach sponsor:rpc-res -++ reject sponsor:rpc-res -++ management-proxy proxy:rpc-res -++ spawn-proxy proxy:rpc-res -++ transfer-proxy proxy:rpc-res + roller-action+!>([%submit | u.addr u.sig %don u.tx]) :: ++ nonce |= [id=@t params=(map @t json) scry=$-([ship proxy:naive] (unit @))] @@ -543,7 +532,7 @@ ^- response:rpc ?. =((lent ~(tap by params)) 0) ~(params error:json-rpc id) - [%result id (pending:to-json pending)] + [%result id (pending-txs:to-json pending)] :: ++ ship |= [id=@t params=(map @t json) scry=$-(@p (list pend-tx))] @@ -552,7 +541,7 @@ ~(params error:json-rpc id) ?~ ship=(ship:from-json params) ~(parse error:json-rpc id) - [%result id (pending:to-json (scry u.ship))] + [%result id (pending-txs:to-json (scry u.ship))] :: ++ addr |= [id=@t params=(map @t json) scry=$-(@ux (list pend-tx))] @@ -561,7 +550,18 @@ ~(params error:json-rpc id) ?~ address=(address:from-json params) ~(parse error:json-rpc id) - [%result id (pending:to-json (scry u.address))] + [%result id (pending-txs:to-json (scry u.address))] + :: + ++ hash + |= [id=@t params=(map @t json) scry=$-(@ux (unit pend-tx))] + ^- response:rpc + ?. =((lent ~(tap by params)) 1) + ~(params error:json-rpc id) + ?~ hash=(hash:from-json params) + ~(parse error:json-rpc id) + ?~ tx=(scry u.hash) + ~(not-found error:json-rpc id) + [%result id (pending-tx:to-json u.tx)] -- :: ++ status @@ -581,18 +581,78 @@ [%result id (time:enjs:format when)] :: ++ history - |= [id=@t params=(map @t json) scry=$-(address:naive (list roller-tx))] + |= [id=@t params=(map @t json) scry=$-(address:naive (list hist-tx))] ^- response:rpc ?. =((lent ~(tap by params)) 1) ~(params error:json-rpc id) ?~ address=(address:from-json params) ~(parse error:json-rpc id) - [%result id (roller-txs:to-json (scry u.address))] + [%result id (hist-txs:to-json (scry u.address))] :: ++ get-config - |= [id=@t params=(map @t json) =roller-config] + |= [id=@t params=(map @t json) config=[azimuth-config roller-config]] ^- response:rpc ?. =((lent ~(tap by params)) 0) ~(params error:json-rpc id) - [%result id (config:to-json roller-config)] + [%result id (roller-config:to-json config)] +:: +++ hash-transaction + |= [id=@t params=(map @t json) chain-id=@ header=? reverse=?] + ^- response:rpc + ?. =((lent ~(tap by params)) 4) + ~(params error:json-rpc id) + =+ ^- $: l2-tx=(unit l2-tx) + nonce=(unit @ud) + from=(unit [@p proxy:naive]) + == + =, from-json + [(tx params) (nonce params) (from params)] + ?: |(?=(~ nonce) ?=(~ from) ?=(~ l2-tx)) + ~(parse error:json-rpc id) + =/ tx=(unit tx:naive) (build-l2-tx u.l2-tx u.from params) + ?~ tx ~(parse error:json-rpc id) + =/ =octs (gen-tx-octs:lib u.tx) + :+ %result id + =; =keccak + %+ hex:to-json 32 + ?. reverse keccak + (reverse-hash:lib keccak) + %- hash-tx:lib + %. [chain-id u.nonce octs] + ?: header + unsigned-tx:lib + prepare-for-sig:lib +:: +++ hash-raw-transaction + |= [id=@t params=(map @t json)] + ^- response:rpc + ?. =((lent ~(tap by params)) 4) + ~(params error:json-rpc id) + =+ ^- $: sig=(unit @) + l2-tx=(unit l2-tx) + from=(unit [=ship proxy:naive]) + == + =, from-json + [(sig params) (tx params) (from params)] + ?: |(?=(~ sig) ?=(~ from) ?=(~ l2-tx)) + ~(parse error:json-rpc id) + =/ tx=(unit tx:naive) (build-l2-tx u.l2-tx u.from params) + ?~ tx ~(parse error:json-rpc id) + :+ %result id + %+ hex:to-json 32 + (hash-raw-tx:lib u.sig (gen-tx-octs:lib u.tx) u.tx) +:: +++ get-naive + |= [id=@t params=(map @t json) =^state:naive] + ^- response:rpc + ?. =((lent ~(tap by params)) 0) + ~(params error:json-rpc id) + [%result id (naive-state:to-json state)] +:: +++ get-refresh + |= [id=@t params=(map @t json) =azimuth-config] + ^- response:rpc + ?. =((lent ~(tap by params)) 0) + ~(params error:json-rpc id) + [%result id (azimuth-config:to-json azimuth-config)] -- diff --git a/pkg/arvo/lib/azimuth.hoon b/pkg/arvo/lib/azimuth.hoon index 96e9967ea..75ee6f356 100644 --- a/pkg/arvo/lib/azimuth.hoon +++ b/pkg/arvo/lib/azimuth.hoon @@ -87,7 +87,7 @@ 0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb :: ++ ecliptic - 0x6ac0.7b7c.4601.b5ce.11de.8dfe.6335.b871.c7c4.dd4d + 0xa5b6.109a.d2d3.5191.b3bc.32c0.0e45.26be.56fe.321f :: ++ linear-star-release 0x86cd.9cd0.992f.0423.1751.e376.1de4.5cec.ea5d.1801 @@ -132,7 +132,7 @@ 0x3e8c.a510.354b.c2fd.bbd6.1502.52d9.3105.c9c2.7bbe :: ++ naive - 0xb581.01cd.3bbb.cc6f.a40b.cdb0.4bb7.1623.b5c7.d39b + 0xe7cf.4b83.06d3.11ba.ca15.585f.e3f0.7cd0.441c.21d1 :: ++ launch 4.601.630 ++ public launch @@ -146,9 +146,9 @@ :: ++ local-contracts |% - ++ ecliptic + ++ ecliptic 0x56db.68f2.9203.ff44.a803.faa2.404a.44ec.bb7a.7480 - ++ azimuth + ++ azimuth 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 ++ delegated-sending 0xb71c.0b6c.ee1b.cae5.6dfe.95cd.9d3e.41dd.d7ea.fc43 @@ -157,7 +157,7 @@ ++ conditional-star-release 0x35eb.3b10.2d9c.1b69.ac14.69c1.b1fe.1799.850c.d3eb ++ naive - 0xe604.2703.475d.0dd1.bc2e.b564.a55f.1832.c252.7171 + 0x6bb8.8a9b.bd82.be7a.997f.eb01.929c.6ec7.8988.fe12 ++ launch 0 ++ public 0 ++ chain-id 1.337 diff --git a/pkg/arvo/lib/azimuthio.hoon b/pkg/arvo/lib/azimuthio.hoon deleted file mode 100644 index 979c34704..000000000 --- a/pkg/arvo/lib/azimuthio.hoon +++ /dev/null @@ -1,146 +0,0 @@ -/- rpc=json-rpc -/+ ethereum, azimuth, strandio -=, strand=strand:strandio -=, jael -|% -++ tract azimuth:contracts:azimuth -++ fetch-point - |= [url=@ta who=ship] - =/ m (strand ,point:azimuth) - ^- form:m - =/ =request:rpc:ethereum - :+ %eth-call - =- [from=~ to=tract gas=~ price=~ value=~ data=-] - (encode-call:rpc:ethereum 'points(uint32)' [%uint `@`who]~) - [%label %latest] - ;< jon=json bind:m (request-rpc url `'point' request) - =/ res=cord (so:dejs:format jon) - =/ =point:eth-noun:azimuth - (decode-results:abi:ethereum res point:eth-type:azimuth) - :: - =/ =request:rpc:ethereum - :+ %eth-call - =- [from=~ to=tract gas=~ price=~ value=~ data=-] - (encode-call:rpc:ethereum 'rights(uint32)' [%uint `@`who]~) - [%label %latest] - ;< jon=json bind:m (request-rpc url `'deed' request) - =/ res=cord (so:dejs:format jon) - =/ =deed:eth-noun:azimuth - (decode-results:abi:ethereum res deed:eth-type:azimuth) - :: - (pure:m (point-from-eth:azimuth who point deed)) -:: -++ request-rpc - |= [url=@ta id=(unit @t) req=request:rpc:ethereum] - =/ m (strand ,json) - ^- form:m - %+ (retry json) `10 - =/ m (strand ,(unit json)) - ^- form:m - |^ - =/ =request:http - :* method=%'POST' - url=url - header-list=['Content-Type'^'application/json' ~] - ^= body - %- some %- as-octt:mimes:html - %- en-json:html - (request-to-json:rpc:ethereum id req) - == - ;< ~ bind:m (send-request:strandio request) - ;< rep=(unit client-response:iris) bind:m - take-maybe-response:strandio - ?~ rep - (pure:m ~) - (parse-response u.rep) - :: - ++ parse-response - |= =client-response:iris - =/ m (strand ,(unit json)) - ^- form:m - ?> ?=(%finished -.client-response) - ?~ full-file.client-response - (pure:m ~) - =/ body=@t q.data.u.full-file.client-response - =/ jon=(unit json) (de-json:html body) - ?~ jon - (pure:m ~) - =, dejs-soft:format - =/ array=(unit (list response:rpc)) - ((ar parse-one-response) u.jon) - ?~ array - =/ res=(unit response:rpc) (parse-one-response u.jon) - ?~ res - (strand-fail:strandio %request-rpc-parse-error >id< ~) - ?: ?=(%error -.u.res) - (strand-fail:strandio %request-rpc-error >id< >+.res< ~) - ?. ?=(%result -.u.res) - (strand-fail:strandio %request-rpc-fail >u.res< ~) - (pure:m `res.u.res) - (strand-fail:strandio %request-rpc-batch >%not-implemented< ~) - :: (pure:m `[%batch u.array]) - :: - ++ parse-one-response - |= =json - ^- (unit response:rpc) - =/ res=(unit [@t ^json]) - %. json - =, dejs-soft:format - (ot id+so result+some ~) - ?^ res `[%result u.res] - ~| parse-one-response=json - :+ ~ %error %- need - %. json - =, dejs-soft:format - (ot id+so error+(ot code+no message+so ~) ~) - -- -:: -++ retry - |* result=mold - |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))] - =/ m (strand ,result) - =| try=@ud - |- ^- form:m - =* loop $ - ?: =(crash-after `try) - (strand-fail:strandio %retry-too-many ~) - ;< ~ bind:m (backoff:strandio try ~m1) - ;< res=(unit result) bind:m computation - ?^ res - (pure:m u.res) - loop(try +(try)) -:: -++ get-latest-block - |= url=@ta - =/ m (strand ,block) - ^- form:m - ;< =json bind:m (request-rpc url `'block number' %eth-block-number ~) - (get-block-by-number url (parse-eth-block-number:rpc:ethereum json)) -:: -++ get-block-by-number - |= [url=@ta =number:block] - =/ m (strand ,block) - ^- form:m - |^ - ;< =json bind:m - (request-rpc url `'block by number' %eth-get-block-by-number number |) - =/ =block (parse-block json) - ?. =(number number.id.block) - (strand-fail:strandio %reorg-detected >number< >block< ~) - (pure:m block) - :: - ++ parse-block - |= =json - ^- block - =< [[&1 &2] |2] - ^- [@ @ @] - ~| json - %. json - =, dejs:format - %- ot - :~ hash+parse-hex-result:rpc:ethereum - number+parse-hex-result:rpc:ethereum - 'parentHash'^parse-hex-result:rpc:ethereum - == - -- --- diff --git a/pkg/arvo/lib/azimuthio.hoon b/pkg/arvo/lib/azimuthio.hoon new file mode 120000 index 000000000..0b5df7063 --- /dev/null +++ b/pkg/arvo/lib/azimuthio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/azimuthio.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bip/b158.hoon b/pkg/arvo/lib/bip/b158.hoon deleted file mode 100644 index bf7ac0bad..000000000 --- a/pkg/arvo/lib/bip/b158.hoon +++ /dev/null @@ -1,247 +0,0 @@ -/- bc=bitcoin -/+ bcu=bitcoin-utils -|% -++ params - |% - ++ p 19 - ++ m 784.931 - -- -:: -++ siphash - |= [k=byts m=byts] - ^- byts - |^ - ?> =(wid.k 16) - ?> (lte (met 3 dat.k) wid.k) - ?> (lte (met 3 dat.m) wid.m) - =. k (flim:sha k) - =. m (flim:sha m) - (flim:sha (fin (comp m (init dat.k)))) - :: Initialise internal state - :: - ++ init - |= k=@ - ^- [@ @ @ @] - =/ k0=@ (end [6 1] k) - =/ k1=@ (cut 6 [1 1] k) - :^ (mix k0 0x736f.6d65.7073.6575) - (mix k1 0x646f.7261.6e64.6f6d) - (mix k0 0x6c79.6765.6e65.7261) - (mix k1 0x7465.6462.7974.6573) - :: - :: Compression rounds - ++ comp - |= [m=byts v=[v0=@ v1=@ v2=@ v3=@]] - ^- [@ @ @ @] - =/ len=@ud (div wid.m 8) - =/ last=@ (lsh [3 7] (mod wid.m 256)) - =| i=@ud - =| w=@ - |- - =. w (cut 6 [i 1] dat.m) - ?: =(i len) - =. v3.v (mix v3.v (mix last w)) - =. v (rnd (rnd v)) - =. v0.v (mix v0.v (mix last w)) - v - %= $ - v =. v3.v (mix v3.v w) - =. v (rnd (rnd v)) - =. v0.v (mix v0.v w) - v - i (add i 1) - == - :: - :: Finalisation rounds - ++ fin - |= v=[v0=@ v1=@ v2=@ v3=@] - ^- byts - =. v2.v (mix v2.v 0xff) - =. v (rnd (rnd (rnd (rnd v)))) - :- 8 - :(mix v0.v v1.v v2.v v3.v) - :: - :: Sipround - ++ rnd - |= [v0=@ v1=@ v2=@ v3=@] - ^- [@ @ @ @] - =. v0 (~(sum fe 6) v0 v1) - =. v2 (~(sum fe 6) v2 v3) - =. v1 (~(rol fe 6) 0 13 v1) - =. v3 (~(rol fe 6) 0 16 v3) - =. v1 (mix v1 v0) - =. v3 (mix v3 v2) - =. v0 (~(rol fe 6) 0 32 v0) - =. v2 (~(sum fe 6) v2 v1) - =. v0 (~(sum fe 6) v0 v3) - =. v1 (~(rol fe 6) 0 17 v1) - =. v3 (~(rol fe 6) 0 21 v3) - =. v1 (mix v1 v2) - =. v3 (mix v3 v0) - =. v2 (~(rol fe 6) 0 32 v2) - [v0 v1 v2 v3] - -- -:: +str: bit streams -:: read is from the front -:: write appends to the back -:: -++ str - |% - ++ read-bit - |= s=bits:bc - ^- [bit=@ub rest=bits:bc] - ?> (gth wid.s 0) - :* ?:((gth wid.s (met 0 dat.s)) 0b0 0b1) - [(dec wid.s) (end [0 (dec wid.s)] dat.s)] - == - :: - ++ read-bits - |= [n=@ s=bits:bc] - ^- [bits:bc rest=bits:bc] - =| bs=bits:bc - |- - ?: =(n 0) [bs s] - =^ b s (read-bit s) - $(n (dec n), bs (write-bits bs [1 b])) - :: - ++ write-bits - |= [s1=bits:bc s2=bits:bc] - ^- bits:bc - [(add wid.s1 wid.s2) (can 0 ~[s2 s1])] - -- -:: +gol: Golomb-Rice encoding/decoding -:: -++ gol - |% - :: +en: encode x and append to end of s - :: - s: bits stream - :: - x: number to add to the stream - :: - p: golomb-rice p param - :: - ++ en - |= [s=bits:bc x=@ p=@] - ^- bits:bc - =+ q=(rsh [0 p] x) - =+ unary=[+(q) (lsh [0 1] (dec (bex q)))] - =+ r=[p (end [0 p] x)] - %+ write-bits:str s - (write-bits:str unary r) - :: - ++ de - |= [s=bits:bc p=@] - ^- [delta=@ rest=bits:bc] - |^ ?> (gth wid.s 0) - =^ q s (get-q s) - =^ r s (read-bits:str p s) - [(add dat.r (lsh [0 p] q)) s] - :: - ++ get-q - |= s=bits:bc - =| q=@ - =^ first-bit s (read-bit:str s) - |- - ?: =(0 first-bit) [q s] - =^ b s (read-bit:str s) - $(first-bit b, q +(q)) - -- - -- -:: +hsh -:: -++ hsh - |% - :: +to-range - :: - item: scriptpubkey to hash - :: - f: N*M - :: - k: key for siphash (end of blockhash, reversed) - :: - ++ to-range - |= [item=byts f=@ k=byts] - ^- @ - (rsh [0 64] (mul f (swp 3 dat:(siphash k item)))) - :: +set-construct: return sorted hashes of scriptpubkeys - :: - ++ set-construct - |= [items=(list byts) k=byts f=@] - ^- (list @) - %+ sort - %+ turn items - |= item=byts - (to-range item f k) - lth - -- -:: -++ parse-filter - |= filter=hexb:bc - ^- [n=@ux gcs-set=bits:bc] - =/ n n:(de:csiz:bcu filter) - =/ lead=@ ?:(=(1 wid.n) 1 +(wid.n)) - :- dat.n - [(mul 8 (sub wid.filter lead)) `@ub`dat:(drop:byt:bcu lead filter)] -:: +to-key: blockhash (little endian) to key for siphash -:: -++ to-key - |= blockhash=tape - ^- byts - %+ take:byt:bcu 16 - %- flip:byt:bcu - (from-cord:hxb:bcu (crip blockhash)) -:: +match: whether block filter matches *any* target scriptpubkeys -:: - filter: full block filter, with leading N -:: - k: key for siphash (end of blockhash, reversed) -:: - targets: scriptpubkeys to match -:: -++ match - |= [filter=hexb:bc k=byts targets=(list byts)] - ^- ? - =/ [p=@ m=@] [p:params m:params] - =/ [n=@ux gcs-set=bits:bc] (parse-filter filter) - =+ target-hs=(set-construct:hsh targets k (mul n m)) - =+ last-val=0 - |- - ?~ target-hs %.n - ?: =(last-val i.target-hs) - %.y - ?: (gth last-val i.target-hs) - $(target-hs t.target-hs) - :: last-val is less than target: check next val in GCS, if any - :: - ?: (lth wid.gcs-set p) %.n - =^ delta gcs-set - (de:gol gcs-set p) - $(last-val (add delta last-val)) -:: +all-match: returns all target byts that match -:: - filter: full block filter, with leading N -:: - k: key for siphash (end of blockhash, reversed) -:: - targets: scriptpubkeys to match -:: -++ all-match - |= [filter=hexb:bc k=byts targets=(list byts)] - ^- (set hexb:bc) - %- ~(gas in *(set hexb:bc)) - =/ [p=@ m=@] [p:params m:params] - =/ [n=@ux gcs-set=bits:bc] (parse-filter filter) - =/ target-map=(map @ hexb:bc) - %- ~(gas by *(map @ hexb:bc)) - %+ turn targets - |=(t=hexb:bc [(to-range:hsh t (mul n m) k) t]) - =+ target-hs=(sort ~(tap in ~(key by target-map)) lth) - =+ last-val=0 - =| matches=(list @) - |- - ?~ target-hs - (murn matches ~(get by target-map)) - ?: =(last-val i.target-hs) - %= $ - target-hs t.target-hs - matches [last-val matches] - == - ?: (gth last-val i.target-hs) - $(target-hs t.target-hs) - :: last-val is less than target: get next val in GCS, if any - :: - ?: (lth wid.gcs-set p) - (murn matches ~(get by target-map)) - =^ delta gcs-set - (de:gol gcs-set p) - $(last-val (add delta last-val)) --- diff --git a/pkg/arvo/lib/bip/b158.hoon b/pkg/arvo/lib/bip/b158.hoon new file mode 120000 index 000000000..cba919a85 --- /dev/null +++ b/pkg/arvo/lib/bip/b158.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip/b158.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bip/b173.hoon b/pkg/arvo/lib/bip/b173.hoon deleted file mode 100644 index e2c46db1a..000000000 --- a/pkg/arvo/lib/bip/b173.hoon +++ /dev/null @@ -1,144 +0,0 @@ -:: BIP173: Bech32 Addresses -:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki -:: -:: Heavily copies: -:: https://github.com/bitcoinjs/bech32/blob/master/index.js -:: -/- sur=bitcoin -/+ bcu=bitcoin-utils -=, sur -=, bcu -|% -++ prefixes - ^- (map network tape) - (my [[%main "bc"] [%testnet "tb"] ~]) -++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l" -+$ raw-decoded [hrp=tape data=(list @) checksum=(list @)] -:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js -:: -++ polymod - |= values=(list @) - |^ ^- @ - =/ gen=(list @ux) - ~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3] - =/ chk=@ 1 - |- ?~ values chk - =/ top (rsh [0 25] chk) - =. chk - (mix i.values (lsh [0 5] (dis chk 0x1ff.ffff))) - $(values t.values, chk (update-chk chk top gen)) -:: - ++ update-chk - |= [chk=@ top=@ gen=(list @ux)] - =/ is (gulf 0 4) - |- ?~ is chk - ?: =(1 (dis 1 (rsh [0 i.is] top))) - $(is t.is, chk (mix chk (snag i.is gen))) - $(is t.is) - -- -:: -++ expand-hrp - |= hrp=tape - ^- (list @) - =/ front (turn hrp |=(p=@tD (rsh [0 5] p))) - =/ back (turn hrp |=(p=@tD (dis 31 p))) - (zing ~[front ~[0] back]) -:: -++ verify-checksum - |= [hrp=tape data-and-checksum=(list @)] - ^- ? - %- |=(a=@ =(1 a)) - %- polymod - (weld (expand-hrp hrp) data-and-checksum) -:: -++ checksum - |= [hrp=tape data=(list @)] - ^- (list @) - :: xor 1 with the polymod - :: - =/ pmod=@ - %+ mix 1 - %- polymod - (zing ~[(expand-hrp hrp) data (reap 6 0)]) - %+ turn (gulf 0 5) - |=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod))) -:: -++ charset-to-value - |= c=@tD - ^- (unit @) - (find ~[c] charset) -++ value-to-charset - |= value=@ - ^- (unit @tD) - ?: (gth value 31) ~ - `(snag value charset) -:: -++ is-valid - |= [bech=tape last-1-pos=@] ^- ? - ?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech - (gte last-1-pos 1) - (lte (add last-1-pos 7) (lent bech)) - (lte (lent bech) 90) - (levy bech |=(c=@tD (gte c 33))) - (levy bech |=(c=@tD (lte c 126))) - == -:: data should be 5bit words -:: -++ encode-raw - |= [hrp=tape data=(list @)] - ^- cord - =/ combined=(list @) - (weld data (checksum hrp data)) - %- crip - (zing ~[hrp "1" (tape (murn combined value-to-charset))]) -++ decode-raw - |= body=cord - ^- (unit raw-decoded) - =/ bech (cass (trip body)) :: to lowercase - =/ pos (flop (fand "1" bech)) - ?~ pos ~ - =/ last-1=@ i.pos - ?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum) - ~ - =/ hrp (scag last-1 bech) - =/ encoded-data-and-checksum=(list @) - (slag +(last-1) bech) - =/ data-and-checksum=(list @) - %+ murn encoded-data-and-checksum - charset-to-value - ?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET - ~ - ?. (verify-checksum hrp data-and-checksum) - ~ - =/ checksum-pos (sub (lent data-and-checksum) 6) - `[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)] -:: +from-address: BIP173 bech32 address encoding to hex -:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki -:: expects to drop a leading 5-bit 0 (the witness version) -:: -++ from-address - |= body=cord - ^- hexb - ~| "Invalid bech32 address" - =/ d=(unit raw-decoded) (decode-raw body) - ?> ?=(^ d) - =/ bs=bits (from-atoms:bit 5 data.u.d) - =/ byt-len=@ (div (sub wid.bs 5) 8) - ?> =(5^0b0 (take:bit 5 bs)) - ?> ?| =(20 byt-len) - =(32 byt-len) - == - [byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))] -:: pubkey is the 33 byte ECC compressed public key -:: -++ encode-pubkey - |= [=network pubkey=byts] - ^- (unit cord) - ?. =(33 wid.pubkey) - ~|('pubkey must be a 33 byte ECC compressed public key' !!) - =/ prefix (~(get by prefixes) network) - ?~ prefix ~ - :- ~ - %+ encode-raw u.prefix - [0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])] --- diff --git a/pkg/arvo/lib/bip/b173.hoon b/pkg/arvo/lib/bip/b173.hoon new file mode 120000 index 000000000..2999150e2 --- /dev/null +++ b/pkg/arvo/lib/bip/b173.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip/b173.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bip/b174.hoon b/pkg/arvo/lib/bip/b174.hoon deleted file mode 100644 index 3bae71d92..000000000 --- a/pkg/arvo/lib/bip/b174.hoon +++ /dev/null @@ -1,182 +0,0 @@ -:: BIP174: PSBTs -:: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki -:: -/- sur=bitcoin -/+ bcu=bitcoin-utils -=, sur -=, bcu -|% -++ en - |% - ++ globals - |= rawtx=hexb - ^- map:psbt - :~ [[1 0x0] rawtx] - == - :: - ++ input - |= [only-witness=? i=in:psbt] - ^- map:psbt - %+ weld - ?: only-witness ~ - ~[[1^0x0 rawtx.i]] - :~ (witness-tx i) - (hdkey %input hdkey.i) - == - :: - ++ output - |= =out:psbt - ^- map:psbt - ?~ hk.out ~ - :~ (hdkey %output u.hk.out) - == - :: - ++ witness-tx - |= i=in:psbt - ^- keyval:psbt - :- [1 0x1] - %- cat:byt - :~ (flip:byt 8^value.utxo.i) - 1^0x16 - 2^0x14 - (hash-160 pubkey.hdkey.i) - == - :: - ++ hdkey - |= [=target:psbt h=^hdkey] - ^- keyval:psbt - =/ typ=@ux - ?- target - %input 0x6 - %output 0x2 - == - =/ coin-type=hexb - ?- network.h - %main - 1^0x0 - %testnet - 1^0x1 - == - :- (cat:byt ~[1^typ pubkey.h]) - %- cat:byt - :~ fprint.h - 1^`@ux`bipt.h 3^0x80 - coin-type 3^0x80 - 4^0x80 - 1^`@ux`chyg.h 3^0x0 - (flip:byt 4^idx.h) - == - :: - ++ keyval-byts - |= kv=keyval:psbt - ^- hexb - %- cat:byt - :~ 1^wid.key.kv - key.kv - 1^wid.val.kv - val.kv - == - :: - ++ map-byts - |= m=map:psbt - ^- (unit hexb) - ?~ m ~ - :- ~ - %- cat:byt - (turn m keyval-byts) - -- - ++ base64 - |= b=hexb - ^- base64:psbt - %- en:base64:mimes:html - (flip:byt b) -:: +encode: make base64 cord of PSBT -:: - only-witness: don't include non-witness UTXO -:: -++ encode - |= $: only-witness=? - rawtx=hexb - txid=hexb - inputs=(list in:psbt) - outputs=(list out:psbt) - == - ^- base64:psbt - =/ sep=(unit hexb) `1^0x0 - =/ final=(list (unit hexb)) - %+ join sep - %+ turn - %- zing - :~ ~[(globals:en rawtx)] - (turn inputs (cury input:en only-witness)) - (turn outputs output:en) - == - map-byts:en - %- base64:en - ^- byts - %- cat:byt - %+ weld ~[[5 0x70.7362.74ff]] - (murn (snoc final sep) same) -:: -++ parse - |= psbt-base64=cord - ^- (list map:psbt) - =/ todo=hexb - (drop:byt 5 (to-byts psbt-base64)) - =| acc=(list map:psbt) - =| m=map:psbt - |- - ?: =(wid.todo 0) - (snoc acc m) - :: 0x0: map separator - :: - ?: =(1^0x0 (take:byt 1 todo)) - $(acc (snoc acc m), m *map:psbt, todo (drop:byt 1 todo)) - =^ kv todo (next-keyval todo) - $(m (snoc m kv)) -:: +get-txid: extract txid from a valid PSBT -:: -++ get-txid - |= psbt-base64=cord - ^- hexb - =/ tx=hexb - %- raw-tx - %+ drop:byt 5 - (to-byts psbt-base64) - %- flip:byt - (dsha256 tx) -:: +raw-tx: extract hex transaction -:: looks for key 0x0 in global map -:: crashes if tx not in hex -:: -++ raw-tx - |= b=hexb - ^- hexb - |- - ?: =(wid.b 0) !! - ?: =(1^0x0 (take:byt 1 b)) !! - =/ nk (next-keyval b) - ?: =(0x0 dat.key.kv.nk) - val.kv.nk - $(b rest.nk) -:: +next-keyval: returns next key-val in a PSBT map -:: input first byte must be a map key length -:: -++ next-keyval - |= b=hexb - ^- [kv=keyval:psbt rest=hexb] - =/ klen dat:(take:byt 1 b) - =/ k (take:byt klen (drop:byt 1 b)) - =/ vlen dat:(take:byt 1 (drop:byt (add 1 klen) b)) - =/ v (take:byt vlen (drop:byt (add 2 klen) b)) - ?> ?&((gth wid.k 0) (gth wid.v 0)) - :- [k v] - (drop:byt ;:(add 2 klen vlen) b) -:: -++ to-byts - |= psbt-base64=cord - ^- hexb - ~| "Invalid PSBT" - =+ p=(de:base64:mimes:html psbt-base64) - ?~ p !! - (flip:byt u.p) --- diff --git a/pkg/arvo/lib/bip/b174.hoon b/pkg/arvo/lib/bip/b174.hoon new file mode 120000 index 000000000..bc6cae53b --- /dev/null +++ b/pkg/arvo/lib/bip/b174.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip/b174.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bip32.hoon b/pkg/arvo/lib/bip32.hoon deleted file mode 100644 index 02187ad87..000000000 --- a/pkg/arvo/lib/bip32.hoon +++ /dev/null @@ -1,243 +0,0 @@ -:: bip32 implementation in hoon -:: -:: to use, call one of the core initialization arms. -:: using the produced core, derive as needed and take out the data you want. -:: -::NOTE tested to be correct against -:: https://en.bitcoin.it/wiki/BIP_0032_TestVectors -:: -=, hmac:crypto -=, secp:crypto -=+ ecc=secp256k1 -:: -:: prv: private key -:: pub: public key -:: cad: chain code -:: dep: depth in chain -:: ind: index at depth -:: pif: parent fingerprint (4 bytes) -|_ [prv=@ pub=point.ecc cad=@ dep=@ud ind=@ud pif=@] -:: -+$ keyc [key=@ cai=@] :: prv/pub key + chain code -:: -:: elliptic curve operations and values -:: -++ point priv-to-pub.ecc -:: -++ ser-p compress-point.ecc -:: -++ n n:t.ecc -:: -:: core initialization -:: -++ from-seed - |= byts - ^+ +> - =+ der=(hmac-sha512l [12 'dees nioctiB'] [wid dat]) - =+ pri=(cut 3 [32 32] der) - +>.$(prv pri, pub (point pri), cad (cut 3 [0 32] der)) -:: -++ from-private - |= keyc - +>(prv key, pub (point key), cad cai) -:: -++ from-public - |= keyc - +>(pub (decompress-point.ecc key), cad cai) -:: -++ from-public-point - |= [pon=point.ecc cai=@] - +>(pub pon, cad cai) -:: -++ from-extended - |= t=tape - =+ x=(de-base58check 4 t) - => |% - ++ take - |= b=@ud - ^- [v=@ x=@] - :- (end [3 b] x) - (rsh [3 b] x) - -- - =^ k x (take 33) - =^ c x (take 32) - =^ i x (take 4) - =^ p x (take 4) - =^ d x (take 1) - ?> =(0 x) :: sanity check - %. [d i p] - =< set-metadata - =+ v=(swag [1 3] t) - ?: =("prv" v) (from-private k c) - ?: =("pub" v) (from-public k c) - !! -:: -++ set-metadata - |= [d=@ud i=@ud p=@] - +>(dep d, ind i, pif p) -:: -:: derivation -:: -++ derivation-path - ;~ pfix - ;~(pose (jest 'm/') (easy ~)) - %+ most fas - ;~ pose - %+ cook - |=(i=@ (add i (bex 31))) - ;~(sfix dem soq) - :: - dem - == == -:: -++ derive-path - |= t=tape - %- derive-sequence - (scan t derivation-path) -:: -++ derive-sequence - |= j=(list @u) - ?~ j +> - =. +> (derive i.j) - $(j t.j) -:: -++ derive - ?: =(0 prv) - derive-public - derive-private -:: -++ derive-private - |= i=@u - ^+ +> - :: we must have a private key to derive the next one - ?: =(0 prv) - ~| %know-no-private-key - !! - :: derive child at i - =/ [left=@ right=@] - =- [(cut 3 [32 32] -) (cut 3 [0 32] -)] - %+ hmac-sha512l [32 cad] - :- 37 - ?: (gte i (bex 31)) - :: hardened child - (can 3 ~[4^i 32^prv 1^0]) - :: normal child - (can 3 ~[4^i 33^(ser-p (point prv))]) - =+ key=(mod (add left prv) n) - :: rare exception, invalid key, go to the next one - ?: |(=(0 key) (gte left n)) $(i +(i)) - %_ +>.$ - prv key - pub (point key) - cad right - dep +(dep) - ind i - pif fingerprint - == -:: -++ derive-public - |= i=@u - ^+ +> - :: public keys can't be hardened - ?: (gte i (bex 31)) - ~| %cant-derive-hardened-public-key - !! - :: derive child at i - =/ [left=@ right=@] - =- [(cut 3 [32 32] -) (cut 3 [0 32] -)] - %+ hmac-sha512l [32 cad] - 37^(can 3 ~[4^i 33^(ser-p pub)]) - :: rare exception, invalid key, go to the next one - ?: (gte left n) $(i +(i)) ::TODO or child key is "point at infinity" - %_ +>.$ - pub (add-points.ecc (point left) pub) - cad right - dep +(dep) - ind i - pif fingerprint - == -:: -:: rendering -:: -++ private-key ?.(=(0 prv) prv ~|(%know-no-private-key !!)) -++ public-key (ser-p pub) -++ chain-code cad -++ private-chain [private-key cad] -++ public-chain [public-key cad] -:: -++ identity (hash160 public-key) -++ fingerprint (cut 3 [16 4] identity) -:: -++ address - |= network=?(%main %regtest %testnet) - ^- @uc - :: removes checksum - :: - %+ rsh [3 4] - %+ en-base58check - [4 (version-bytes network %pub %.n)] - [20 identity] -:: -++ prv-extended - |= network=?(%main %regtest %testnet) - %+ en-b58c-bip32 (version-bytes network %prv %.y) - (build-extended private-key) -:: -++ pub-extended - |= network=?(%main %regtest %testnet) - %+ en-b58c-bip32 (version-bytes network %pub %.y) - (build-extended public-key) -:: -++ build-extended - |= key=@ - %+ can 3 - :~ 33^key - 32^cad - 4^ind - 4^pif - 1^dep - == -:: -++ en-b58c-bip32 - |= [v=@ k=@] - %- en-base58:mimes:html - (en-base58check [4 v] [74 k]) -:: -:: base58check -:: -++ en-base58check - :: v: version bytes - :: d: data - |= [v=byts d=byts] - =+ p=[(add wid.v wid.d) (can 3 ~[d v])] - =- (can 3 ~[4^- p]) - %+ rsh [3 28] - (sha-256l:sha 32 (sha-256l:sha p)) -:: -++ de-base58check - :: vw: amount of version bytes - |= [vw=@u t=tape] - =+ x=(de-base58:mimes:html t) - =+ hash=(sha-256l:sha 32 (sha-256:sha (rsh [3 4] x))) - ?> =((end [3 4] x) (rsh [3 28] hash)) - (cut 3 [vw (sub (met 3 x) (add 4 vw))] x) -:: -++ hash160 - |= d=@ - (ripemd-160:ripemd:crypto 32 (sha-256:sha d)) -:: -++ version-bytes - |= [network=?(%main %regtest %testnet) type=?(%pub %prv) bip32=?] - ^- @ux - |^ - ?- type - %pub ?:(bip32 xpub-key pay-to-pubkey) - %prv ?:(bip32 xprv-key private-key) - == - :: - ++ pay-to-pubkey ?:(=(network %main) 0x0 0x6f) - ++ private-key ?:(=(network %main) 0x80 0xef) - ++ xpub-key ?:(=(network %main) 0x488.b21e 0x435.87cf) - ++ xprv-key ?:(=(network %main) 0x488.ade4 0x435.8394) - -- --- diff --git a/pkg/arvo/lib/bip32.hoon b/pkg/arvo/lib/bip32.hoon new file mode 120000 index 000000000..1cbb7f892 --- /dev/null +++ b/pkg/arvo/lib/bip32.hoon @@ -0,0 +1 @@ +../../base-dev/lib/bip32.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bip39.hoon b/pkg/arvo/lib/bip39.hoon deleted file mode 100644 index cc33fe479..000000000 --- a/pkg/arvo/lib/bip39.hoon +++ /dev/null @@ -1,46 +0,0 @@ -:: bip39 implementation in hoon -:: -/+ bip39-english -:: -|% -++ from-entropy - |= byts - ^- tape - =. wid (mul wid 8) - ~| [%unsupported-entropy-bit-length wid] - ?> &((gte wid 128) (lte wid 256)) - :: - =+ cs=(div wid 32) - =/ check=@ - %+ rsh [0 (sub 256 cs)] - (sha-256l:sha (div wid 8) dat) - =/ bits=byts - :- (add wid cs) - %+ can 0 - :~ cs^check - wid^dat - == - :: - =/ pieces - |- ^- (list @) - :- (end [0 11] dat.bits) - ?: (lte wid.bits 11) ~ - $(bits [(sub wid.bits 11) (rsh [0 11] dat.bits)]) - :: - =/ words=(list tape) - %+ turn pieces - |= ind=@ud - (snag ind `(list tape)`bip39-english) - :: - %+ roll (flop words) - |= [nex=tape all=tape] - ?~ all nex - :(weld all " " nex) -:: -::NOTE always produces a 512-bit result -++ to-seed - |= [mnem=tape pass=tape] - ^- @ - %- hmac-sha512t:pbkdf:crypto - [(crip mnem) (crip (weld "mnemonic" pass)) 2.048 64] --- diff --git a/pkg/arvo/lib/bip39.hoon b/pkg/arvo/lib/bip39.hoon new file mode 120000 index 000000000..36c4b7e83 --- /dev/null +++ b/pkg/arvo/lib/bip39.hoon @@ -0,0 +1 @@ +../../base-dev/lib/bip39.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bip39/english.hoon b/pkg/arvo/lib/bip39/english.hoon deleted file mode 100644 index 60de89317..000000000 --- a/pkg/arvo/lib/bip39/english.hoon +++ /dev/null @@ -1,2052 +0,0 @@ -:: english wordlist for use in bip39 -^- (list tape) -:~ - "abandon" - "ability" - "able" - "about" - "above" - "absent" - "absorb" - "abstract" - "absurd" - "abuse" - "access" - "accident" - "account" - "accuse" - "achieve" - "acid" - "acoustic" - "acquire" - "across" - "act" - "action" - "actor" - "actress" - "actual" - "adapt" - "add" - "addict" - "address" - "adjust" - "admit" - "adult" - "advance" - "advice" - "aerobic" - "affair" - "afford" - "afraid" - "again" - "age" - "agent" - "agree" - "ahead" - "aim" - "air" - "airport" - "aisle" - "alarm" - "album" - "alcohol" - "alert" - "alien" - "all" - "alley" - "allow" - "almost" - "alone" - "alpha" - "already" - "also" - "alter" - "always" - "amateur" - "amazing" - "among" - "amount" - "amused" - "analyst" - "anchor" - "ancient" - "anger" - "angle" - "angry" - "animal" - "ankle" - "announce" - "annual" - "another" - "answer" - "antenna" - "antique" - "anxiety" - "any" - "apart" - "apology" - "appear" - "apple" - "approve" - "april" - "arch" - "arctic" - "area" - "arena" - "argue" - "arm" - "armed" - "armor" - "army" - "around" - "arrange" - "arrest" - "arrive" - "arrow" - "art" - "artefact" - "artist" - "artwork" - "ask" - "aspect" - "assault" - "asset" - "assist" - "assume" - "asthma" - "athlete" - "atom" - "attack" - "attend" - "attitude" - "attract" - "auction" - "audit" - "august" - "aunt" - "author" - "auto" - "autumn" - "average" - "avocado" - "avoid" - "awake" - "aware" - "away" - "awesome" - "awful" - "awkward" - "axis" - "baby" - "bachelor" - "bacon" - "badge" - "bag" - "balance" - "balcony" - "ball" - "bamboo" - "banana" - "banner" - "bar" - "barely" - "bargain" - "barrel" - "base" - "basic" - "basket" - "battle" - "beach" - "bean" - "beauty" - "because" - "become" - "beef" - "before" - "begin" - "behave" - "behind" - "believe" - "below" - "belt" - "bench" - "benefit" - "best" - "betray" - "better" - "between" - "beyond" - "bicycle" - "bid" - "bike" - "bind" - "biology" - "bird" - "birth" - "bitter" - "black" - "blade" - "blame" - "blanket" - "blast" - "bleak" - "bless" - "blind" - "blood" - "blossom" - "blouse" - "blue" - "blur" - "blush" - "board" - "boat" - "body" - "boil" - "bomb" - "bone" - "bonus" - "book" - "boost" - "border" - "boring" - "borrow" - "boss" - "bottom" - "bounce" - "box" - "boy" - "bracket" - "brain" - "brand" - "brass" - "brave" - "bread" - "breeze" - "brick" - "bridge" - "brief" - "bright" - "bring" - "brisk" - "broccoli" - "broken" - "bronze" - "broom" - "brother" - "brown" - "brush" - "bubble" - "buddy" - "budget" - "buffalo" - "build" - "bulb" - "bulk" - "bullet" - "bundle" - "bunker" - "burden" - "burger" - "burst" - "bus" - "business" - "busy" - "butter" - "buyer" - "buzz" - "cabbage" - "cabin" - "cable" - "cactus" - "cage" - "cake" - "call" - "calm" - "camera" - "camp" - "can" - "canal" - "cancel" - "candy" - "cannon" - "canoe" - "canvas" - "canyon" - "capable" - "capital" - "captain" - "car" - "carbon" - "card" - "cargo" - "carpet" - "carry" - "cart" - "case" - "cash" - "casino" - "castle" - "casual" - "cat" - "catalog" - "catch" - "category" - "cattle" - "caught" - "cause" - "caution" - "cave" - "ceiling" - "celery" - "cement" - "census" - "century" - "cereal" - "certain" - "chair" - "chalk" - "champion" - "change" - "chaos" - "chapter" - "charge" - "chase" - "chat" - "cheap" - "check" - "cheese" - "chef" - "cherry" - "chest" - "chicken" - "chief" - "child" - "chimney" - "choice" - "choose" - "chronic" - "chuckle" - "chunk" - "churn" - "cigar" - "cinnamon" - "circle" - "citizen" - "city" - "civil" - "claim" - "clap" - "clarify" - "claw" - "clay" - "clean" - "clerk" - "clever" - "click" - "client" - "cliff" - "climb" - "clinic" - "clip" - "clock" - "clog" - "close" - "cloth" - "cloud" - "clown" - "club" - "clump" - "cluster" - "clutch" - "coach" - "coast" - "coconut" - "code" - "coffee" - "coil" - "coin" - "collect" - "color" - "column" - "combine" - "come" - "comfort" - "comic" - "common" - "company" - "concert" - "conduct" - "confirm" - "congress" - "connect" - "consider" - "control" - "convince" - "cook" - "cool" - "copper" - "copy" - "coral" - "core" - "corn" - "correct" - "cost" - "cotton" - "couch" - "country" - "couple" - "course" - "cousin" - "cover" - "coyote" - "crack" - "cradle" - "craft" - "cram" - "crane" - "crash" - "crater" - "crawl" - "crazy" - "cream" - "credit" - "creek" - "crew" - "cricket" - "crime" - "crisp" - "critic" - "crop" - "cross" - "crouch" - "crowd" - "crucial" - "cruel" - "cruise" - "crumble" - "crunch" - "crush" - "cry" - "crystal" - "cube" - "culture" - "cup" - "cupboard" - "curious" - "current" - "curtain" - "curve" - "cushion" - "custom" - "cute" - "cycle" - "dad" - "damage" - "damp" - "dance" - "danger" - "daring" - "dash" - "daughter" - "dawn" - "day" - "deal" - "debate" - "debris" - "decade" - "december" - "decide" - "decline" - "decorate" - "decrease" - "deer" - "defense" - "define" - "defy" - "degree" - "delay" - "deliver" - "demand" - "demise" - "denial" - "dentist" - "deny" - "depart" - "depend" - "deposit" - "depth" - "deputy" - "derive" - "describe" - "desert" - "design" - "desk" - "despair" - "destroy" - "detail" - "detect" - "develop" - "device" - "devote" - "diagram" - "dial" - "diamond" - "diary" - "dice" - "diesel" - "diet" - "differ" - "digital" - "dignity" - "dilemma" - "dinner" - "dinosaur" - "direct" - "dirt" - "disagree" - "discover" - "disease" - "dish" - "dismiss" - "disorder" - "display" - "distance" - "divert" - "divide" - "divorce" - "dizzy" - "doctor" - "document" - "dog" - "doll" - "dolphin" - "domain" - "donate" - "donkey" - "donor" - "door" - "dose" - "double" - "dove" - "draft" - "dragon" - "drama" - "drastic" - "draw" - "dream" - "dress" - "drift" - "drill" - "drink" - "drip" - "drive" - "drop" - "drum" - "dry" - "duck" - "dumb" - "dune" - "during" - "dust" - "dutch" - "duty" - "dwarf" - "dynamic" - "eager" - "eagle" - "early" - "earn" - "earth" - "easily" - "east" - "easy" - "echo" - "ecology" - "economy" - "edge" - "edit" - "educate" - "effort" - "egg" - "eight" - "either" - "elbow" - "elder" - "electric" - "elegant" - "element" - "elephant" - "elevator" - "elite" - "else" - "embark" - "embody" - "embrace" - "emerge" - "emotion" - "employ" - "empower" - "empty" - "enable" - "enact" - "end" - "endless" - "endorse" - "enemy" - "energy" - "enforce" - "engage" - "engine" - "enhance" - "enjoy" - "enlist" - "enough" - "enrich" - "enroll" - "ensure" - "enter" - "entire" - "entry" - "envelope" - "episode" - "equal" - "equip" - "era" - "erase" - "erode" - "erosion" - "error" - "erupt" - "escape" - "essay" - "essence" - "estate" - "eternal" - "ethics" - "evidence" - "evil" - "evoke" - "evolve" - "exact" - "example" - "excess" - "exchange" - "excite" - "exclude" - "excuse" - "execute" - "exercise" - "exhaust" - "exhibit" - "exile" - "exist" - "exit" - "exotic" - "expand" - "expect" - "expire" - "explain" - "expose" - "express" - "extend" - "extra" - "eye" - "eyebrow" - "fabric" - "face" - "faculty" - "fade" - "faint" - "faith" - "fall" - "false" - "fame" - "family" - "famous" - "fan" - "fancy" - "fantasy" - "farm" - "fashion" - "fat" - "fatal" - "father" - "fatigue" - "fault" - "favorite" - "feature" - "february" - "federal" - "fee" - "feed" - "feel" - "female" - "fence" - "festival" - "fetch" - "fever" - "few" - "fiber" - "fiction" - "field" - "figure" - "file" - "film" - "filter" - "final" - "find" - "fine" - "finger" - "finish" - "fire" - "firm" - "first" - "fiscal" - "fish" - "fit" - "fitness" - "fix" - "flag" - "flame" - "flash" - "flat" - "flavor" - "flee" - "flight" - "flip" - "float" - "flock" - "floor" - "flower" - "fluid" - "flush" - "fly" - "foam" - "focus" - "fog" - "foil" - "fold" - "follow" - "food" - "foot" - "force" - "forest" - "forget" - "fork" - "fortune" - "forum" - "forward" - "fossil" - "foster" - "found" - "fox" - "fragile" - "frame" - "frequent" - "fresh" - "friend" - "fringe" - "frog" - "front" - "frost" - "frown" - "frozen" - "fruit" - "fuel" - "fun" - "funny" - "furnace" - "fury" - "future" - "gadget" - "gain" - "galaxy" - "gallery" - "game" - "gap" - "garage" - "garbage" - "garden" - "garlic" - "garment" - "gas" - "gasp" - "gate" - "gather" - "gauge" - "gaze" - "general" - "genius" - "genre" - "gentle" - "genuine" - "gesture" - "ghost" - "giant" - "gift" - "giggle" - "ginger" - "giraffe" - "girl" - "give" - "glad" - "glance" - "glare" - "glass" - "glide" - "glimpse" - "globe" - "gloom" - "glory" - "glove" - "glow" - "glue" - "goat" - "goddess" - "gold" - "good" - "goose" - "gorilla" - "gospel" - "gossip" - "govern" - "gown" - "grab" - "grace" - "grain" - "grant" - "grape" - "grass" - "gravity" - "great" - "green" - "grid" - "grief" - "grit" - "grocery" - "group" - "grow" - "grunt" - "guard" - "guess" - "guide" - "guilt" - "guitar" - "gun" - "gym" - "habit" - "hair" - "half" - "hammer" - "hamster" - "hand" - "happy" - "harbor" - "hard" - "harsh" - "harvest" - "hat" - "have" - "hawk" - "hazard" - "head" - "health" - "heart" - "heavy" - "hedgehog" - "height" - "hello" - "helmet" - "help" - "hen" - "hero" - "hidden" - "high" - "hill" - "hint" - "hip" - "hire" - "history" - "hobby" - "hockey" - "hold" - "hole" - "holiday" - "hollow" - "home" - "honey" - "hood" - "hope" - "horn" - "horror" - "horse" - "hospital" - "host" - "hotel" - "hour" - "hover" - "hub" - "huge" - "human" - "humble" - "humor" - "hundred" - "hungry" - "hunt" - "hurdle" - "hurry" - "hurt" - "husband" - "hybrid" - "ice" - "icon" - "idea" - "identify" - "idle" - "ignore" - "ill" - "illegal" - "illness" - "image" - "imitate" - "immense" - "immune" - "impact" - "impose" - "improve" - "impulse" - "inch" - "include" - "income" - "increase" - "index" - "indicate" - "indoor" - "industry" - "infant" - "inflict" - "inform" - "inhale" - "inherit" - "initial" - "inject" - "injury" - "inmate" - "inner" - "innocent" - "input" - "inquiry" - "insane" - "insect" - "inside" - "inspire" - "install" - "intact" - "interest" - "into" - "invest" - "invite" - "involve" - "iron" - "island" - "isolate" - "issue" - "item" - "ivory" - "jacket" - "jaguar" - "jar" - "jazz" - "jealous" - "jeans" - "jelly" - "jewel" - "job" - "join" - "joke" - "journey" - "joy" - "judge" - "juice" - "jump" - "jungle" - "junior" - "junk" - "just" - "kangaroo" - "keen" - "keep" - "ketchup" - "key" - "kick" - "kid" - "kidney" - "kind" - "kingdom" - "kiss" - "kit" - "kitchen" - "kite" - "kitten" - "kiwi" - "knee" - "knife" - "knock" - "know" - "lab" - "label" - "labor" - "ladder" - "lady" - "lake" - "lamp" - "language" - "laptop" - "large" - "later" - "latin" - "laugh" - "laundry" - "lava" - "law" - "lawn" - "lawsuit" - "layer" - "lazy" - "leader" - "leaf" - "learn" - "leave" - "lecture" - "left" - "leg" - "legal" - "legend" - "leisure" - "lemon" - "lend" - "length" - "lens" - "leopard" - "lesson" - "letter" - "level" - "liar" - "liberty" - "library" - "license" - "life" - "lift" - "light" - "like" - "limb" - "limit" - "link" - "lion" - "liquid" - "list" - "little" - "live" - "lizard" - "load" - "loan" - "lobster" - "local" - "lock" - "logic" - "lonely" - "long" - "loop" - "lottery" - "loud" - "lounge" - "love" - "loyal" - "lucky" - "luggage" - "lumber" - "lunar" - "lunch" - "luxury" - "lyrics" - "machine" - "mad" - "magic" - "magnet" - "maid" - "mail" - "main" - "major" - "make" - "mammal" - "man" - "manage" - "mandate" - "mango" - "mansion" - "manual" - "maple" - "marble" - "march" - "margin" - "marine" - "market" - "marriage" - "mask" - "mass" - "master" - "match" - "material" - "math" - "matrix" - "matter" - "maximum" - "maze" - "meadow" - "mean" - "measure" - "meat" - "mechanic" - "medal" - "media" - "melody" - "melt" - "member" - "memory" - "mention" - "menu" - "mercy" - "merge" - "merit" - "merry" - "mesh" - "message" - "metal" - "method" - "middle" - "midnight" - "milk" - "million" - "mimic" - "mind" - "minimum" - "minor" - "minute" - "miracle" - "mirror" - "misery" - "miss" - "mistake" - "mix" - "mixed" - "mixture" - "mobile" - "model" - "modify" - "mom" - "moment" - "monitor" - "monkey" - "monster" - "month" - "moon" - "moral" - "more" - "morning" - "mosquito" - "mother" - "motion" - "motor" - "mountain" - "mouse" - "move" - "movie" - "much" - "muffin" - "mule" - "multiply" - "muscle" - "museum" - "mushroom" - "music" - "must" - "mutual" - "myself" - "mystery" - "myth" - "naive" - "name" - "napkin" - "narrow" - "nasty" - "nation" - "nature" - "near" - "neck" - "need" - "negative" - "neglect" - "neither" - "nephew" - "nerve" - "nest" - "net" - "network" - "neutral" - "never" - "news" - "next" - "nice" - "night" - "noble" - "noise" - "nominee" - "noodle" - "normal" - "north" - "nose" - "notable" - "note" - "nothing" - "notice" - "novel" - "now" - "nuclear" - "number" - "nurse" - "nut" - "oak" - "obey" - "object" - "oblige" - "obscure" - "observe" - "obtain" - "obvious" - "occur" - "ocean" - "october" - "odor" - "off" - "offer" - "office" - "often" - "oil" - "okay" - "old" - "olive" - "olympic" - "omit" - "once" - "one" - "onion" - "online" - "only" - "open" - "opera" - "opinion" - "oppose" - "option" - "orange" - "orbit" - "orchard" - "order" - "ordinary" - "organ" - "orient" - "original" - "orphan" - "ostrich" - "other" - "outdoor" - "outer" - "output" - "outside" - "oval" - "oven" - "over" - "own" - "owner" - "oxygen" - "oyster" - "ozone" - "pact" - "paddle" - "page" - "pair" - "palace" - "palm" - "panda" - "panel" - "panic" - "panther" - "paper" - "parade" - "parent" - "park" - "parrot" - "party" - "pass" - "patch" - "path" - "patient" - "patrol" - "pattern" - "pause" - "pave" - "payment" - "peace" - "peanut" - "pear" - "peasant" - "pelican" - "pen" - "penalty" - "pencil" - "people" - "pepper" - "perfect" - "permit" - "person" - "pet" - "phone" - "photo" - "phrase" - "physical" - "piano" - "picnic" - "picture" - "piece" - "pig" - "pigeon" - "pill" - "pilot" - "pink" - "pioneer" - "pipe" - "pistol" - "pitch" - "pizza" - "place" - "planet" - "plastic" - "plate" - "play" - "please" - "pledge" - "pluck" - "plug" - "plunge" - "poem" - "poet" - "point" - "polar" - "pole" - "police" - "pond" - "pony" - "pool" - "popular" - "portion" - "position" - "possible" - "post" - "potato" - "pottery" - "poverty" - "powder" - "power" - "practice" - "praise" - "predict" - "prefer" - "prepare" - "present" - "pretty" - "prevent" - "price" - "pride" - "primary" - "print" - "priority" - "prison" - "private" - "prize" - "problem" - "process" - "produce" - "profit" - "program" - "project" - "promote" - "proof" - "property" - "prosper" - "protect" - "proud" - "provide" - "public" - "pudding" - "pull" - "pulp" - "pulse" - "pumpkin" - "punch" - "pupil" - "puppy" - "purchase" - "purity" - "purpose" - "purse" - "push" - "put" - "puzzle" - "pyramid" - "quality" - "quantum" - "quarter" - "question" - "quick" - "quit" - "quiz" - "quote" - "rabbit" - "raccoon" - "race" - "rack" - "radar" - "radio" - "rail" - "rain" - "raise" - "rally" - "ramp" - "ranch" - "random" - "range" - "rapid" - "rare" - "rate" - "rather" - "raven" - "raw" - "razor" - "ready" - "real" - "reason" - "rebel" - "rebuild" - "recall" - "receive" - "recipe" - "record" - "recycle" - "reduce" - "reflect" - "reform" - "refuse" - "region" - "regret" - "regular" - "reject" - "relax" - "release" - "relief" - "rely" - "remain" - "remember" - "remind" - "remove" - "render" - "renew" - "rent" - "reopen" - "repair" - "repeat" - "replace" - "report" - "require" - "rescue" - "resemble" - "resist" - "resource" - "response" - "result" - "retire" - "retreat" - "return" - "reunion" - "reveal" - "review" - "reward" - "rhythm" - "rib" - "ribbon" - "rice" - "rich" - "ride" - "ridge" - "rifle" - "right" - "rigid" - "ring" - "riot" - "ripple" - "risk" - "ritual" - "rival" - "river" - "road" - "roast" - "robot" - "robust" - "rocket" - "romance" - "roof" - "rookie" - "room" - "rose" - "rotate" - "rough" - "round" - "route" - "royal" - "rubber" - "rude" - "rug" - "rule" - "run" - "runway" - "rural" - "sad" - "saddle" - "sadness" - "safe" - "sail" - "salad" - "salmon" - "salon" - "salt" - "salute" - "same" - "sample" - "sand" - "satisfy" - "satoshi" - "sauce" - "sausage" - "save" - "say" - "scale" - "scan" - "scare" - "scatter" - "scene" - "scheme" - "school" - "science" - "scissors" - "scorpion" - "scout" - "scrap" - "screen" - "script" - "scrub" - "sea" - "search" - "season" - "seat" - "second" - "secret" - "section" - "security" - "seed" - "seek" - "segment" - "select" - "sell" - "seminar" - "senior" - "sense" - "sentence" - "series" - "service" - "session" - "settle" - "setup" - "seven" - "shadow" - "shaft" - "shallow" - "share" - "shed" - "shell" - "sheriff" - "shield" - "shift" - "shine" - "ship" - "shiver" - "shock" - "shoe" - "shoot" - "shop" - "short" - "shoulder" - "shove" - "shrimp" - "shrug" - "shuffle" - "shy" - "sibling" - "sick" - "side" - "siege" - "sight" - "sign" - "silent" - "silk" - "silly" - "silver" - "similar" - "simple" - "since" - "sing" - "siren" - "sister" - "situate" - "six" - "size" - "skate" - "sketch" - "ski" - "skill" - "skin" - "skirt" - "skull" - "slab" - "slam" - "sleep" - "slender" - "slice" - "slide" - "slight" - "slim" - "slogan" - "slot" - "slow" - "slush" - "small" - "smart" - "smile" - "smoke" - "smooth" - "snack" - "snake" - "snap" - "sniff" - "snow" - "soap" - "soccer" - "social" - "sock" - "soda" - "soft" - "solar" - "soldier" - "solid" - "solution" - "solve" - "someone" - "song" - "soon" - "sorry" - "sort" - "soul" - "sound" - "soup" - "source" - "south" - "space" - "spare" - "spatial" - "spawn" - "speak" - "special" - "speed" - "spell" - "spend" - "sphere" - "spice" - "spider" - "spike" - "spin" - "spirit" - "split" - "spoil" - "sponsor" - "spoon" - "sport" - "spot" - "spray" - "spread" - "spring" - "spy" - "square" - "squeeze" - "squirrel" - "stable" - "stadium" - "staff" - "stage" - "stairs" - "stamp" - "stand" - "start" - "state" - "stay" - "steak" - "steel" - "stem" - "step" - "stereo" - "stick" - "still" - "sting" - "stock" - "stomach" - "stone" - "stool" - "story" - "stove" - "strategy" - "street" - "strike" - "strong" - "struggle" - "student" - "stuff" - "stumble" - "style" - "subject" - "submit" - "subway" - "success" - "such" - "sudden" - "suffer" - "sugar" - "suggest" - "suit" - "summer" - "sun" - "sunny" - "sunset" - "super" - "supply" - "supreme" - "sure" - "surface" - "surge" - "surprise" - "surround" - "survey" - "suspect" - "sustain" - "swallow" - "swamp" - "swap" - "swarm" - "swear" - "sweet" - "swift" - "swim" - "swing" - "switch" - "sword" - "symbol" - "symptom" - "syrup" - "system" - "table" - "tackle" - "tag" - "tail" - "talent" - "talk" - "tank" - "tape" - "target" - "task" - "taste" - "tattoo" - "taxi" - "teach" - "team" - "tell" - "ten" - "tenant" - "tennis" - "tent" - "term" - "test" - "text" - "thank" - "that" - "theme" - "then" - "theory" - "there" - "they" - "thing" - "this" - "thought" - "three" - "thrive" - "throw" - "thumb" - "thunder" - "ticket" - "tide" - "tiger" - "tilt" - "timber" - "time" - "tiny" - "tip" - "tired" - "tissue" - "title" - "toast" - "tobacco" - "today" - "toddler" - "toe" - "together" - "toilet" - "token" - "tomato" - "tomorrow" - "tone" - "tongue" - "tonight" - "tool" - "tooth" - "top" - "topic" - "topple" - "torch" - "tornado" - "tortoise" - "toss" - "total" - "tourist" - "toward" - "tower" - "town" - "toy" - "track" - "trade" - "traffic" - "tragic" - "train" - "transfer" - "trap" - "trash" - "travel" - "tray" - "treat" - "tree" - "trend" - "trial" - "tribe" - "trick" - "trigger" - "trim" - "trip" - "trophy" - "trouble" - "truck" - "true" - "truly" - "trumpet" - "trust" - "truth" - "try" - "tube" - "tuition" - "tumble" - "tuna" - "tunnel" - "turkey" - "turn" - "turtle" - "twelve" - "twenty" - "twice" - "twin" - "twist" - "two" - "type" - "typical" - "ugly" - "umbrella" - "unable" - "unaware" - "uncle" - "uncover" - "under" - "undo" - "unfair" - "unfold" - "unhappy" - "uniform" - "unique" - "unit" - "universe" - "unknown" - "unlock" - "until" - "unusual" - "unveil" - "update" - "upgrade" - "uphold" - "upon" - "upper" - "upset" - "urban" - "urge" - "usage" - "use" - "used" - "useful" - "useless" - "usual" - "utility" - "vacant" - "vacuum" - "vague" - "valid" - "valley" - "valve" - "van" - "vanish" - "vapor" - "various" - "vast" - "vault" - "vehicle" - "velvet" - "vendor" - "venture" - "venue" - "verb" - "verify" - "version" - "very" - "vessel" - "veteran" - "viable" - "vibrant" - "vicious" - "victory" - "video" - "view" - "village" - "vintage" - "violin" - "virtual" - "virus" - "visa" - "visit" - "visual" - "vital" - "vivid" - "vocal" - "voice" - "void" - "volcano" - "volume" - "vote" - "voyage" - "wage" - "wagon" - "wait" - "walk" - "wall" - "walnut" - "want" - "warfare" - "warm" - "warrior" - "wash" - "wasp" - "waste" - "water" - "wave" - "way" - "wealth" - "weapon" - "wear" - "weasel" - "weather" - "web" - "wedding" - "weekend" - "weird" - "welcome" - "west" - "wet" - "whale" - "what" - "wheat" - "wheel" - "when" - "where" - "whip" - "whisper" - "wide" - "width" - "wife" - "wild" - "will" - "win" - "window" - "wine" - "wing" - "wink" - "winner" - "winter" - "wire" - "wisdom" - "wise" - "wish" - "witness" - "wolf" - "woman" - "wonder" - "wood" - "wool" - "word" - "work" - "world" - "worry" - "worth" - "wrap" - "wreck" - "wrestle" - "wrist" - "write" - "wrong" - "yard" - "year" - "yellow" - "you" - "young" - "youth" - "zebra" - "zero" - "zone" - "zoo" -== diff --git a/pkg/arvo/lib/bip39/english.hoon b/pkg/arvo/lib/bip39/english.hoon new file mode 120000 index 000000000..f1ea0fe31 --- /dev/null +++ b/pkg/arvo/lib/bip39/english.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip39/english.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bitcoin-utils.hoon b/pkg/arvo/lib/bitcoin-utils.hoon deleted file mode 100644 index 69ba4738d..000000000 --- a/pkg/arvo/lib/bitcoin-utils.hoon +++ /dev/null @@ -1,166 +0,0 @@ -:: lib/bitcoin-utils.hoon -:: Utilities for working with BTC data types and transactions -:: -/- sur=bitcoin -=, sur -|% -:: -:: TODO: move this bit/byt stuff to zuse -:: bit/byte utilities -:: -:: -:: +blop: munge bit and byt sequences (cat, flip, take, drop) -:: -++ blop - |_ =bloq - +$ biyts [wid=@ud dat=@] - ++ cat - |= bs=(list biyts) - ^- biyts - :- (roll (turn bs |=(b=biyts -.b)) add) - (can bloq (flop bs)) - :: +flip: flip endianness while preserving lead/trail zeroes - :: - ++ flip - |= b=biyts - ^- biyts - [wid.b (rev bloq b)] - :: +take: take n bloqs from front - :: pads front with extra zeroes if n is longer than input - :: - ++ take - |= [n=@ b=biyts] - ^- biyts - ?: (gth n wid.b) - [n dat.b] - [n (rsh [bloq (sub wid.b n)] dat.b)] - :: +drop: drop n bloqs from front - :: returns 0^0 if n >= width - :: - ++ drop - |= [n=@ b=biyts] - ^- biyts - ?: (gte n wid.b) - 0^0x0 - =+ n-take=(sub wid.b n) - [n-take (end [bloq n-take] dat.b)] - -- -++ byt ~(. blop 3) -:: -++ bit - =/ bl ~(. blop 0) - |% - ++ cat cat:bl:bit - ++ flip flip:bl:bit - ++ take take:bl:bit - ++ drop drop:bl:bit - ++ from-atoms - |= [bitwidth=@ digits=(list @)] - ^- bits - %- cat:bit - %+ turn digits - |= a=@ - ?> (lte (met 0 a) bitwidth) - [bitwidth `@ub`a] - :: +to-atoms: convert bits to atoms of bitwidth - :: - ++ to-atoms - |= [bitwidth=@ bs=bits] - ^- (list @) - =| res=(list @) - ?> =(0 (mod wid.bs bitwidth)) - |- - ?: =(0 wid.bs) res - %= $ - res (snoc res dat:(take:bit bitwidth bs)) - bs (drop:bit bitwidth bs) - == - -- -:: big endian sha256: input and output are both MSB first (big endian) -:: -++ sha256 - |= =byts - ^- hexb - %- flip:byt - [32 (shay (flip:byt byts))] -:: -++ dsha256 - |= =byts - (sha256 (sha256 byts)) -:: -++ hash-160 - |= val=byts - ^- hexb - =, ripemd:crypto - :- 20 - %- ripemd-160 - (sha256 val) - -:: -:: hxb: hex parsing utilities -:: -++ hxb - |% - ++ from-cord - |= h=@t - ^- hexb - ?: =('' h) 1^0x0 - :: Add leading 00 - :: - =+ (lsh [3 2] h) - :: Group by 4-size block - :: - =+ (rsh [3 2] -) - :: Parse hex to atom - :: - :- (div (lent (trip h)) 2) - `@ux`(rash - hex) - :: - ++ to-cord - |= =hexb - ^- cord - (en:base16:mimes:html hexb) - -- -:: -:: +csiz: CompactSize integers (a Bitcoin-specific datatype) -:: https://btcinformation.org/en/developer-reference#compactsize-unsigned-integers -:: - encode: big endian to little endian -:: - decode: little endian to big endian -:: -++ csiz - |% - ++ en - |= a=@ - ^- hexb - =/ l=@ (met 3 a) - ?: =(l 1) 1^a - ?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)]) - ?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)]) - ?: (lte l 8) (cat:byt ~[1^0xff (flip:byt 8^a)]) - ~|("Cannot encode CompactSize longer than 8 bytes" !!) - :: - ++ de - |= h=hexb - ^- [n=hexb rest=hexb] - =/ s=@ux dat:(take:byt 1 h) - ?: (lth s 0xfd) [1^s (drop:byt 1 h)] - ~| "Invalid compact-size at start of {}" - =/ len=bloq - ?+ s !! - %0xfd 1 - %0xfe 2 - %0xff 3 - == - :_ (drop:byt (add 1 len) h) - %- flip:byt - (take:byt (bex len) (drop:byt 1 h)) - :: +dea: atom instead of hexb for parsed CompactSize - :: - ++ dea - |= h=hexb - ^- [a=@ rest=hexb] - => (de h) - [dat.n rest] - -- -:: --- diff --git a/pkg/arvo/lib/bitcoin-utils.hoon b/pkg/arvo/lib/bitcoin-utils.hoon new file mode 120000 index 000000000..7cc792906 --- /dev/null +++ b/pkg/arvo/lib/bitcoin-utils.hoon @@ -0,0 +1 @@ +../../base-dev/lib/bitcoin-utils.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/cram.hoon b/pkg/arvo/lib/cram.hoon deleted file mode 100644 index dbec8f7b4..000000000 --- a/pkg/arvo/lib/cram.hoon +++ /dev/null @@ -1,61 +0,0 @@ -|% -++ static :: freeze .mdh hoon subset - |= gen=hoon ^- [inf=(map term dime) elm=manx] - ?+ -.gen - =/ gen ~(open ap gen) - ?: =(gen ^gen) ~|([%cram-dynamic -.gen] !!) - $(gen gen) - :: - %xray [~ (single (shut gen))] - ^ [(malt (frontmatter p.gen)) (single (shut q.gen))] - == -:: -++ single :: unwrap one-elem marl - |= xml=marl ^- manx - ?: ?=([* ~] xml) i.xml - ~|(%many-elems !!) -:: -++ shut-mart :: xml attrs - |=([n=mane v=(list beer:hoot)] [n (turn v |=(a=beer:hoot ?^(a !! a)))]) -:: -++ shut :: as xml constant - |= gen=hoon ^- marl - ?+ -.gen ~|([%bad-xml -.gen] !!) - %dbug $(gen q.gen) - :: - %xray - [[n.g.p.gen (turn a.g.p.gen shut-mart)] $(gen [%mcts c.p.gen])]~ - :: - %mcts - ?~ p.gen ~ - =- (weld - $(p.gen t.p.gen)) - ?^ -.i.p.gen $(gen [%xray i.p.gen]) - ~| [%shut-tuna -.i.p.gen] - ?+ -.i.p.gen !! - %manx ?>(?=(%xray -.p.i.p.gen) $(gen p.i.p.gen)) - %marl ?>(?=(%mcts -.p.i.p.gen) $(gen p.i.p.gen)) - == - == -:: -:: -++ frontmatter :: parse ~[[%foo 1] [%bar ~s2]] - |= gen=hoon ^- (list [term dime]) - ?: ?=([%bust %null] gen) ~ - ?: ?=(%dbug -.gen) $(gen q.gen) - ?. ?=(%clsg -.gen) ~|([%bad-frontmatter -.gen] !!) - %+ turn p.gen - |= gen=hoon - ?. ?=(^ -.gen) - =/ gen ~(open ap gen) - ?: =(gen ^gen) ~|([%bad-frontmatter-elem -.gen] !!) - $(gen gen) - =/ hed (as-dime p.gen) - ?. =(%tas p.hed) ~|([%bad-frontmatter-key-type p.hed] !!) - [q.hed (as-dime q.gen)] -:: -++ as-dime :: %foo ~.foo 0vbar etc - |= gen=hoon ^- dime - ?: ?=(%dbug -.gen) $(gen q.gen) - ?. ?=([?(%rock %sand) @ @] gen) ~|([%bad-literal gen] !!) - +.gen --- diff --git a/pkg/arvo/lib/cram.hoon b/pkg/arvo/lib/cram.hoon new file mode 120000 index 000000000..4005e57ee --- /dev/null +++ b/pkg/arvo/lib/cram.hoon @@ -0,0 +1 @@ +../../base-dev/lib/cram.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/crunch.hoon b/pkg/arvo/lib/crunch.hoon new file mode 100644 index 000000000..58c0cbb7f --- /dev/null +++ b/pkg/arvo/lib/crunch.hoon @@ -0,0 +1,356 @@ +/- c=crunch, gs=graph-store, ms=metadata-store, p=post, r=resource +:: +=< + |_ [our=ship now=@da] + ++ walk-graph-associations + |= [=associations:ms content=? from=@da to=@da] + ^- wain + :: graph resources in `our`; used to avoid scrying, e.g., + :: a graph `our` has left and can no longer access + :: + =/ accessible-graphs=(set resource:r) (scry-graph-resources) + %- ~(rep by associations) + |= [[=md-resource:ms =association:ms] out=wain] + ^- wain + ?. ?=(%graph app-name.md-resource) + out + ?. ?=(%graph -.config.metadatum.association) + out + :: ensure graph, given by association, exists in `our` + :: + ?. (~(has in accessible-graphs) resource.md-resource) + out + :: scry the graph + :: + =/ graph=(unit graph:gs) (scry-graph resource.md-resource) + ?~ graph + out + :: prepare channel-info argument + :: + =/ channel-info=channel-info:c + :* group.association + resource.md-resource + module.config.metadatum.association + == + :: walk the graph + :: + ?+ module.config.metadatum.association + :: non-chat (e.g. links & notes) + :: + %+ weld out + %: walk-nested-graph-for-most-recent-entries + u.graph + content + channel-info + from + to + == + :: + %chat + %+ weld out + %: walk-chat-graph + u.graph + content + channel-info + from + to + == + == + :: + ++ scry-graph + |= graph-resource=resource:r + ^- (unit graph:gs) + =/ scry-response=update:gs + .^ update:gs + %gx + (scot %p our) + %graph-store + (scot %da now) + %graph + (scot %p entity.graph-resource) + name.graph-resource + /noun + == + ?. ?=(%add-graph -.q.scry-response) + ~ + ?~ graph.q.scry-response + ~ + [~ graph.q.scry-response] + :: + ++ scry-graph-resources + |= ~ + ^- (set resource:r) + =/ scry-response=update:gs + .^ update:gs + %gx + (scot %p our) + %graph-store + (scot %da now) + /keys/noun + == + ?. ?=(%keys -.q.scry-response) + ~ + resources.q.scry-response + :: helper arm for callers to get graph associations + :: to pass to `walk-graph-associations` + :: + ++ scry-graph-associations + |= ~ + ^- associations:ms + .^ associations:ms + %gx + (scot %p our) + %metadata-store + (scot %da now) + /app-name/graph/noun + == + -- +:: +|% +:: +:: parsing and formatting +:: +++ resource-to-cord + |= =resource:r + ^- @t + (rap 3 (scot %p entity.resource) '/' (scot %tas name.resource) ~) +:: +++ paths-to-resources + |= paxs=(list path) + ^- (set resource:r) + %- ~(gas in *(set resource:r)) + (turn paxs path-to-resource) +:: +++ path-to-resource + |= pax=path + ^- resource:r + =/ entity=@p (slav %p -.pax) + =/ name=@tas -.+.pax + [entity name] +:: +++ escape-characters-in-cord + |= =cord + ^- @t + %- crip + %- mesc + :: specific to CSVs: make sure content does not + :: contain commas (only allowed as delimiters) + :: + %- replace-tape-commas-with-semicolons + %- trip + cord +:: +++ replace-tape-commas-with-semicolons + |= string=tape + ^- tape + =/ comma-indices=(list @ud) (fand "," string) + |- + ^- tape + ?~ comma-indices + string + $(string (snap string i.comma-indices ';'), comma-indices t.comma-indices) +:: +++ contents-to-cord + |= contents=(list content:p) + ^- @t + ?~ contents + '' + %+ join-cords + ' ' + (turn contents content-to-cord) +:: +++ content-to-cord + |= =content:p + ^- @t + ?- -.content + %text (escape-characters-in-cord text.content) + %mention (scot %p ship.content) + %url url.content + %code expression.content :: TODO: also print output? + %reference (reference-content-to-cord reference.content) + == +:: +++ reference-content-to-cord + |= =reference:p + ^- @t + ?- -.reference + %group (resource-to-cord group.reference) + %graph (rap 3 (resource-to-cord group.reference) ': ' (resource-to-cord resource.uid.reference) ~) + == +:: +++ format-post-to-comma-separated-cord + |= [=post:gs =channel-info:c] + ^- @t + %+ join-cords + ',' + :~ (scot %da time-sent.post) + (scot %p author.post) + (resource-to-cord group.channel-info) + (resource-to-cord channel.channel-info) + (scot %tas channel-type.channel-info) + :: exclude content; optionally add later + :: + == +:: +++ join-cords + |= [delimiter=@t cords=(list @t)] + ^- @t + %+ roll cords + |= [cord=@t out=@t] + ^- @t + ?: =('' out) + :: don't put delimiter before first element + :: + cord + (rap 3 out delimiter cord ~) +:: +:: walking graphs +:: +++ walk-chat-graph + |= [=graph:gs content=? =channel-info:c from=@da to=@da] + ^- wain + %- flop + %+ roll + :: filter by time + :: + %+ only-nodes-older-than to + %+ only-nodes-newer-than from + ~(val by graph) + |= [=node:gs out=wain] + ^- wain + ?- -.post.node + %| + :: do not output deleted posts + :: + out + %& + ?~ contents.p.post.node + :: do not output structural nodes + :: + out + :_ out + =/ post-no-content=@t (format-post-to-comma-separated-cord p.post.node channel-info) + ?- content + %| post-no-content + %& + %+ join-cords ',' + ~[post-no-content (contents-to-cord contents.p.post.node)] + == + == +:: +++ walk-nested-graph-for-most-recent-entries + |= [=graph:gs content=? =channel-info:c from=@da to=@da] + ^- wain + =| out=wain + =| most-recent-post-content=@t + =/ nodes + :: filter by time + :: + %+ only-nodes-older-than to + %+ only-nodes-newer-than from + ~(val by graph) + %- flop + |- + ^- wain + ?~ nodes + ?: =('' most-recent-post-content) + :: don't return a cell: `['' ~]` + :: we want either an empty list `~` + :: or a list populated with actual entries + :: + out + [most-recent-post-content out] + :: + =? out ?=(%graph -.children.i.nodes) + %+ weld out + %: walk-nested-graph-for-most-recent-entries + p.children.i.nodes + content + channel-info + from + to + == + :: + ?- -.post.i.nodes + %| + :: do not keep deleted posts + :: + $(nodes t.nodes) + %& + ?~ contents.p.post.i.nodes + :: do not keep structural nodes + :: + $(nodes t.nodes) + =/ post-no-content=@t (format-post-to-comma-separated-cord p.post.i.nodes channel-info) + %= $ + nodes t.nodes + most-recent-post-content + ?- content + %| post-no-content + %& + %+ join-cords ',' + ~[post-no-content (contents-to-cord contents.p.post.i.nodes)] + == + == + == +:: +:: filters +:: +++ filter-associations-by-group-resources + |= [=associations:ms group-resources=(set resource:r)] + ^- associations:ms + %- ~(rep by associations) + |= [[=md-resource:ms =association:ms] out=associations:ms] + ^- associations:ms + ?. (~(has in group-resources) group.association) + out + (~(put by out) md-resource association) +:: wrappers for intuitive use of `filter-nodes-by-timestamp`: +:: pass `nodes` as given by the `graph-store` scry and no +:: need to worry about comparators +:: +++ only-nodes-older-than + |= [time=@da nodes=(list node:gs)] + (filter-nodes-by-timestamp nodes lte time) +:: +++ only-nodes-newer-than + |= [time=@da nodes=(list node:gs)] + %- flop + (filter-nodes-by-timestamp (flop nodes) gte time) +:: +++ filter-nodes-by-timestamp + |= [nodes=(list node:gs) comparator=$-([@ @] ?) time=@da] + =| out=(list node:gs) + :: return `out` in same time-order as `nodes` + :: + %- flop + |- + ^- (list node:gs) + ?~ nodes + out + ?- -.post.i.nodes + %| + :: skip deleted posts + :: + $(nodes t.nodes) + %& + ?. (comparator time-sent.p.post.i.nodes time) + :: assume: + :: * time is monotonic + :: * first `%.n` we hit indicates nodes further on are `%.n` + :: (i.e. `nodes` must be ordered st. they start `%.y`, + :: e.g. if want all `nodes` older than given time, + :: `nodes` must start with oldest and comparator is `lth`) + :: + out + $(nodes t.nodes, out [i.nodes out]) + == +:: +:: io +:: +++ note-write-csv-to-clay + |= [pax=path file-content=wain] + ?> =(%csv (snag (dec (lent pax)) pax)) + [%c [%info %base %& [pax %ins %csv !>(file-content)]~]] +:: +-- diff --git a/pkg/arvo/lib/dbug.hoon b/pkg/arvo/lib/dbug.hoon deleted file mode 100644 index ce98619e8..000000000 --- a/pkg/arvo/lib/dbug.hoon +++ /dev/null @@ -1,155 +0,0 @@ -:: dbug: agent wrapper for generic debugging tools -:: -:: usage: %-(agent:dbug your-agent) -:: -|% -+$ poke - $% [%bowl ~] - [%state grab=cord] - [%incoming =about] - [%outgoing =about] - == -:: -+$ about - $@ ~ - $% [%ship =ship] - [%path =path] - [%wire =wire] - [%term =term] - == -:: -++ agent - |= =agent:gall - ^- agent:gall - !. - |_ =bowl:gall - +* this . - ag ~(. agent bowl) - :: - ++ on-poke - |= [=mark =vase] - ^- (quip card:agent:gall agent:gall) - ?. ?=(%dbug mark) - =^ cards agent (on-poke:ag mark vase) - [cards this] - =/ dbug - !<(poke vase) - =; =tang - ((%*(. slog pri 1) tang) [~ this]) - ?- -.dbug - %bowl [(sell !>(bowl))]~ - :: - %state - =? grab.dbug =('' grab.dbug) '-' - =; product=^vase - [(sell product)]~ - =/ state=^vase - :: if the underlying app has implemented a /dbug/state scry endpoint, - :: use that vase in place of +on-save's. - :: - =/ result=(each ^vase tang) - (mule |.(q:(need (need (on-peek:ag /x/dbug/state))))) - ?:(?=(%& -.result) p.result on-save:ag) - %+ slap - (slop state !>([bowl=bowl ..zuse])) - (ream grab.dbug) - :: - %incoming - =; =tang - ?^ tang tang - [%leaf "no matching subscriptions"]~ - %+ murn - %+ sort ~(tap by sup.bowl) - |= [[* a=[=ship =path]] [* b=[=ship =path]]] - (aor [path ship]:a [path ship]:b) - |= [=duct [=ship =path]] - ^- (unit tank) - =; relevant=? - ?. relevant ~ - `>[path=path from=ship duct=duct]< - ?: ?=(~ about.dbug) & - ?- -.about.dbug - %ship =(ship ship.about.dbug) - %path ?=(^ (find path.about.dbug path)) - %wire %+ lien duct - |=(=wire ?=(^ (find wire.about.dbug wire))) - %term !! - == - :: - %outgoing - =; =tang - ?^ tang tang - [%leaf "no matching subscriptions"]~ - %+ murn - %+ sort ~(tap by wex.bowl) - |= [[[a=wire *] *] [[b=wire *] *]] - (aor a b) - |= [[=wire =ship =term] [acked=? =path]] - ^- (unit tank) - =; relevant=? - ?. relevant ~ - `>[wire=wire agnt=[ship term] path=path ackd=acked]< - ?: ?=(~ about.dbug) & - ?- -.about.dbug - %ship =(ship ship.about.dbug) - %path ?=(^ (find path.about.dbug path)) - %wire ?=(^ (find wire.about.dbug wire)) - %term =(term term.about.dbug) - == - == - :: - ++ on-peek - |= =path - ^- (unit (unit cage)) - ?. ?=([@ %dbug *] path) - (on-peek:ag path) - ?+ path [~ ~] - [%u %dbug ~] ``noun+!>(&) - [%x %dbug %state ~] ``noun+!>(on-save:ag) - [%x %dbug %subscriptions ~] ``noun+!>([wex sup]:bowl) - == - :: - ++ on-init - ^- (quip card:agent:gall agent:gall) - =^ cards agent on-init:ag - [cards this] - :: - ++ on-save on-save:ag - :: - ++ on-load - |= old-state=vase - ^- (quip card:agent:gall agent:gall) - =^ cards agent (on-load:ag old-state) - [cards this] - :: - ++ on-watch - |= =path - ^- (quip card:agent:gall agent:gall) - =^ cards agent (on-watch:ag path) - [cards this] - :: - ++ on-leave - |= =path - ^- (quip card:agent:gall agent:gall) - =^ cards agent (on-leave:ag path) - [cards this] - :: - ++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card:agent:gall agent:gall) - =^ cards agent (on-agent:ag wire sign) - [cards this] - :: - ++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card:agent:gall agent:gall) - =^ cards agent (on-arvo:ag wire sign-arvo) - [cards this] - :: - ++ on-fail - |= [=term =tang] - ^- (quip card:agent:gall agent:gall) - =^ cards agent (on-fail:ag term tang) - [cards this] - -- --- diff --git a/pkg/arvo/lib/dbug.hoon b/pkg/arvo/lib/dbug.hoon new file mode 120000 index 000000000..04f6855f7 --- /dev/null +++ b/pkg/arvo/lib/dbug.hoon @@ -0,0 +1 @@ +../../base-dev/lib/dbug.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/default-agent.hoon b/pkg/arvo/lib/default-agent.hoon deleted file mode 100644 index 319bf9524..000000000 --- a/pkg/arvo/lib/default-agent.hoon +++ /dev/null @@ -1,69 +0,0 @@ -/+ skeleton -|* [agent=* help=*] -?: ?=(%& help) - ~| %default-agent-helpfully-crashing - skeleton -|_ =bowl:gall -++ on-init - `agent -:: -++ on-save - !>(~) -:: -++ on-load - |= old-state=vase - `agent -:: -++ on-poke - |= =cage - ~| "unexpected poke to {} with mark {}" - !! -:: -++ on-watch - |= =path - ~| "unexpected subscription to {} on path {}" - !! -:: -++ on-leave - |= path - `agent -:: -++ on-peek - |= =path - ~| "unexpected scry into {} on path {}" - !! -:: -++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card:agent:gall _agent) - ?- -.sign - %poke-ack - ?~ p.sign - `agent - %- (slog leaf+"poke failed from {} on wire {}" u.p.sign) - `agent - :: - %watch-ack - ?~ p.sign - `agent - =/ =tank leaf+"subscribe failed from {} on wire {}" - %- (slog tank u.p.sign) - `agent - :: - %kick `agent - %fact - ~| "unexpected subscription update to {} on wire {}" - ~| "with mark {}" - !! - == -:: -++ on-arvo - |= [=wire =sign-arvo] - ~| "unexpected system response {<-.sign-arvo>} to {} on wire {}" - !! -:: -++ on-fail - |= [=term =tang] - %- (slog leaf+"error in {}" >term< tang) - `agent --- diff --git a/pkg/arvo/lib/default-agent.hoon b/pkg/arvo/lib/default-agent.hoon new file mode 120000 index 000000000..698f6802d --- /dev/null +++ b/pkg/arvo/lib/default-agent.hoon @@ -0,0 +1 @@ +../../base-dev/lib/default-agent.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/der.hoon b/pkg/arvo/lib/der.hoon deleted file mode 100644 index c46acc87f..000000000 --- a/pkg/arvo/lib/der.hoon +++ /dev/null @@ -1,210 +0,0 @@ -/- asn1 -:: |der: distinguished encoding rules for ASN.1 -:: -:: DER is a tag-length-value binary encoding for ASN.1, designed -:: so that there is only one (distinguished) valid encoding for an -:: instance of a type. -:: -|% -:: +en:der: encode +spec:asn1 to +octs (kindof) -:: -++ en - =< |= a=spec:asn1 - ^- [len=@ud dat=@ux] - =/ b ~(ren raw a) - [(lent b) (rep 3 b)] - |% - :: +raw:en:der: door for encoding +spec:asn1 to list of bytes - :: - ++ raw - |_ pec=spec:asn1 - :: +ren:raw:en:der: render +spec:asn1 to tag-length-value bytes - :: - ++ ren - ^- (list @D) - =/ a lem - [tag (weld (len a) a)] - :: +tag:raw:en:der: tag byte - :: - ++ tag - ^- @D - ?- pec - [%int *] 2 - [%bit *] 3 - [%oct *] 4 - [%nul *] 5 - [%obj *] 6 - [%seq *] 48 :: constructed: (con 0x20 16) - [%set *] 49 :: constructed: (con 0x20 17) - [%con *] ;: con - 0x80 :: context-specifc - ?:(imp.bes.pec 0 0x20) :: implicit? - (dis 0x1f tag.bes.pec) :: 5 bits of custom tag - == - == - :: +lem:raw:en:der: element bytes - :: - ++ lem - ^- (list @D) - ?- pec - :: unsigned only, interpreted as positive-signed and - :: rendered in big-endian byte order. negative-signed would - :: be two's complement - :: - [%int *] =/ a (flop (rip 3 int.pec)) - ?~ a [0 ~] - ?:((lte i.a 127) a [0 a]) - :: padded to byte-width, must be already byte-aligned - :: - [%bit *] =/ a (rip 3 bit.pec) - =/ b ~| %der-invalid-bit - ?. =(0 (mod len.pec 8)) - ~|(%der-invalid-bit-alignment !!) - (sub (div len.pec 8) (lent a)) - [0 (weld a (reap b 0))] - :: padded to byte-width - :: - [%oct *] =/ a (rip 3 oct.pec) - =/ b ~| %der-invalid-oct - (sub len.pec (lent a)) - (weld a (reap b 0)) - :: - [%nul *] ~ - [%obj *] (rip 3 obj.pec) - :: - [%seq *] %- zing - |- ^- (list (list @)) - ?~ seq.pec ~ - :- ren(pec i.seq.pec) - $(seq.pec t.seq.pec) - :: presumed to be already deduplicated and sorted - :: - [%set *] %- zing - |- ^- (list (list @)) - ?~ set.pec ~ - :- ren(pec i.set.pec) - $(set.pec t.set.pec) - :: already constructed - :: - [%con *] con.pec - == - :: +len:raw:en:der: length bytes - :: - ++ len - |= a=(list @D) - ^- (list @D) - =/ b (lent a) - ?: (lte b 127) - [b ~] :: note: big-endian - [(con 0x80 (met 3 b)) (flop (rip 3 b))] - -- - -- -:: +de:der: decode atom to +spec:asn1 -:: -++ de - |= [len=@ud dat=@ux] - ^- (unit spec:asn1) - :: XX refactor into +parse - =/ a (rip 3 dat) - =/ b ~| %der-invalid-len - (sub len (lent a)) - (rust `(list @D)`(weld a (reap b 0)) parse) -:: +parse:der: DER parser combinator -:: -++ parse - =< ^- $-(nail (like spec:asn1)) - ;~ pose - (stag %int (bass 256 (sear int ;~(pfix (tag 2) till)))) - (stag %bit (sear bit (boss 256 ;~(pfix (tag 3) till)))) - (stag %oct (boss 256 ;~(pfix (tag 4) till))) - (stag %nul (cold ~ ;~(plug (tag 5) (tag 0)))) - (stag %obj (^boss 256 ;~(pfix (tag 6) till))) - (stag %seq (sear recur ;~(pfix (tag 48) till))) - (stag %set (sear recur ;~(pfix (tag 49) till))) - (stag %con ;~(plug (sear context next) till)) - == - |% - :: +tag:parse:der: parse tag byte - :: - ++ tag - |=(a=@D (just a)) - :: +int:parse:der: sear unsigned big-endian bytes - :: - ++ int - |= a=(list @D) - ^- (unit (list @D)) - ?~ a ~ - ?: ?=([@ ~] a) `a - ?. =(0 i.a) `a - ?.((gth i.t.a 127) ~ `t.a) - :: +bit:parse:der: convert bytewidth to bitwidth - :: - ++ bit - |= [len=@ud dat=@ux] - ^- (unit [len=@ud dat=@ux]) - ?. =(0 (end 3 dat)) ~ - :+ ~ - (mul 8 (dec len)) - (rsh 3 dat) - :: +recur:parse:der: parse bytes for a list of +spec:asn1 - :: - ++ recur - |=(a=(list @) (rust a (star parse))) - :: +context:parse:der: decode context-specific tag byte - :: - ++ context - |= a=@D - ^- (unit bespoke:asn1) - ?. =(1 (cut 0 [7 1] a)) ~ - :+ ~ - =(1 (cut 0 [5 1] a)) - (dis 0x1f a) - :: +boss:parse:der: shadowed to count as well - :: - :: Use for parsing +octs more broadly? - :: - ++ boss - |* [wuc=@ tyd=rule] - %+ cook - |= waq=(list @) - :- (lent waq) - (reel waq |=([p=@ q=@] (add p (mul wuc q)))) - tyd - :: +till:parse:der: parser combinator for len-prefixed bytes - :: - :: advance until - :: - ++ till - |= tub=nail - ^- (like (list @D)) - ?~ q.tub - (fail tub) - :: fuz: first byte - length, or length of the length - :: - =* fuz i.q.tub - :: nex: offset of value bytes from fuz - :: len: length of value bytes - :: - =/ [nex=@ len=@] - :: faz: meaningful bits in fuz - :: - =/ faz (end [0 7] fuz) - ?: =(0 (cut 0 [7 1] fuz)) - [0 faz] - [faz (rep 3 (flop (scag faz t.q.tub)))] - ?: ?& !=(0 nex) - !=(nex (met 3 len)) - == - (fail tub) - :: zuf: value bytes - :: - =/ zuf (swag [nex len] t.q.tub) - ?. =(len (lent zuf)) - (fail tub) - :: zaf: product nail - :: - =/ zaf [p.p.tub (add +(nex) q.p.tub)] - [zaf `[zuf zaf (slag (add nex len) t.q.tub)]] - -- --- - diff --git a/pkg/arvo/lib/der.hoon b/pkg/arvo/lib/der.hoon new file mode 120000 index 000000000..8446f8e92 --- /dev/null +++ b/pkg/arvo/lib/der.hoon @@ -0,0 +1 @@ +../../base-dev/lib/der.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/desk-jam.hoon b/pkg/arvo/lib/desk-jam.hoon new file mode 100644 index 000000000..7e650c7c0 --- /dev/null +++ b/pkg/arvo/lib/desk-jam.hoon @@ -0,0 +1,32 @@ +=, clay +|% +++ jam-desk + |= [our=ship =desk now=@da] + ~> %slog.0^leaf/"jamming desk {}" + %- jam + %- ?:(=(%base desk) remove-misc-dirs same) + %- ankh-to-map + =< ank + .^(dome:clay %cv /(scot %p our)/[desk]/(scot %da now)) +:: +++ remove-misc-dirs + |= fiz=(map path page) + ^- (map path page) + %- ~(gas by *(map path page)) + %+ skip ~(tap by fiz) + |= [p=path *] + ?| ?=([%tmp *] p) + ?=([%tests *] p) + == +:: +++ ankh-to-map + =| res=(map path page) + =| pax=path + |= a=ankh + ^- (map path page) + =? res ?=(^ fil.a) (~(put by res) pax [p q.q]:q.u.fil.a) + =/ dir=(list [seg=@ta =ankh]) ~(tap by dir.a) + |- ^+ res + ?~ dir res + $(dir t.dir, res ^$(pax (snoc pax seg.i.dir), a ankh.i.dir)) +-- diff --git a/pkg/arvo/lib/dice.hoon b/pkg/arvo/lib/dice.hoon new file mode 100644 index 000000000..90c534242 --- /dev/null +++ b/pkg/arvo/lib/dice.hoon @@ -0,0 +1,120 @@ +:: dice: helper functions for L2 Rollers +:: +/- *dice +/+ naive, *naive-transactions +:: +|% +++ nonce-order + |= [a=[* =nonce:naive] b=[* =nonce:naive]] + (lte nonce.a nonce.b) +:: +++ apply-effects + |= [=effects:naive nas=^state:naive own=owners chain-t=@] + ^+ [nas=nas own=own] + %+ roll effects + |= [=diff:naive nas=_nas own=_own] + ^+ [nas own] + ?. ?=([%tx *] diff) [nas own] + =< [nas own] + (apply-raw-tx | raw-tx.diff nas own chain-t) +:: +++ apply-raw-tx + |= [force=? =raw-tx:naive nas=^state:naive own=owners chain-t=@] + ^- [? nas=_nas ups=(list update) own=_own] + =+ cache-nas=nas + =/ chain-t=@t (ud-to-ascii:naive chain-t) + ?. (verify-sig-and-nonce:naive verifier chain-t nas raw-tx) + ~& [%verify-sig-and-nonce %failed tx.raw-tx] + [force nas ~ own] + =^ * points.nas + (increment-nonce:naive nas from.tx.raw-tx) + ?~ nex=(receive-tx:naive nas tx.raw-tx) + ~& [%receive-tx %failed] + [force ?:(force nas cache-nas) ~ own] + =* new-nas +.u.nex + =* effects -.u.nex + :+ & + new-nas + (update-ownership effects cache-nas new-nas own) +:: +++ update-ownership + |= $: =effects:naive + cache-nas=^state:naive + nas=^state:naive + =owners + == + ^- (quip update own=_owners) + %+ roll effects + |= [=diff:naive ups=(list update) owners=_owners] + =, orm:naive + ?. ?=([%point *] diff) [ups owners] + =* ship ship.diff + =/ old=(unit point:naive) + (get points.cache-nas ship) + =/ new=point:naive + (need (get points.nas ship)) + =* event +>.diff + =; [to=(unit owner) from=(unit owner)] + =? owners &(?=(^ from) !=(address.u.from 0x0)) + (~(del ju owners) u.from ship) + ?: ?| =(~ to) + &(?=(^ to) =(address.u.to 0x0)) + == + [ups owners] + ?~ to [ups owners] + :_ (~(put ju owners) u.to ship) + (snoc ups [%point ship new u.to from]) + ?+ -.event [~ ~] + %owner + :- `[%own +.event] + ?~ old ~ + `[%own address.owner.own.u.old] + :: + %management-proxy + :- `[%manage +.event] + ?~ old ~ + `[%manage address.management-proxy.own.u.old] + :: + %spawn-proxy + :- `[%spawn +.event] + ?~ old ~ + `[%spawn address.spawn-proxy.own.u.old] + :: + %voting-proxy + :- `[%vote +.event] + ?~ old ~ + `[%vote address.voting-proxy.own.u.old] + :: + %transfer-proxy + :- `[%transfer +.event] + ?~ old ~ + `[%transfer address.transfer-proxy.own.u.old] + == +:: +++ get-owner + |= [=point:naive =proxy:naive] + ^- [nonce=@ _point] + =* own own.point + ?- proxy + %own + :- nonce.owner.own + point(nonce.owner.own +(nonce.owner.own)) + :: + %spawn + :- nonce.spawn-proxy.own + point(nonce.spawn-proxy.own +(nonce.spawn-proxy.own)) + :: + %manage + :- nonce.management-proxy.own + point(nonce.management-proxy.own +(nonce.management-proxy.own)) + :: + %vote + :- nonce.voting-proxy.own + point(nonce.voting-proxy.own +(nonce.voting-proxy.own)) + :: + %transfer + :- nonce.transfer-proxy.own + point(nonce.transfer-proxy.own +(nonce.transfer-proxy.own)) + == +:: +-- diff --git a/pkg/arvo/lib/ethereum.hoon b/pkg/arvo/lib/ethereum.hoon deleted file mode 100644 index bc8592270..000000000 --- a/pkg/arvo/lib/ethereum.hoon +++ /dev/null @@ -1,907 +0,0 @@ -:: ethereum: utilities -:: -=, ethereum-types -|% -:: deriving and using ethereum keys -:: -++ key - |% - ++ address-from-pub - =, keccak:crypto - |= pub=@ - %+ end [3 20] - %+ keccak-256 64 - (rev 3 64 pub) - :: - ++ address-from-prv - (cork pub-from-prv address-from-pub) - :: - ++ pub-from-prv - =, secp256k1:secp:crypto - |= prv=@ - %- serialize-point - (priv-to-pub prv) - :: - ++ sign-transaction - =, crypto - |= [tx=transaction:rpc pk=@] - ^- @ux - :: hash the raw transaction data - =/ hash=@ - =/ dat=@ - %- encode-atoms:rlp - :: with v=chain-id, r=0, s=0 - tx(chain-id [chain-id.tx 0 0 ~]) - =+ wid=(met 3 dat) - %- keccak-256:keccak - [wid (rev 3 wid dat)] - :: sign transaction hash with private key - =+ (ecdsa-raw-sign:secp256k1:secp hash pk) - :: complete transaction is raw data, with r and s - :: taken from the signature, and v as per eip-155 - %- encode-atoms:rlp - tx(chain-id [:(add (mul chain-id.tx 2) 35 v) r s ~]) - -- -:: -:: rlp en/decoding -::NOTE https://github.com/ethereum/wiki/wiki/RLP -:: -++ rlp - |% - ::NOTE rlp encoding doesn't really care about leading zeroes, - :: but because we need to disinguish between no-bytes zero - :: and one-byte zero (and also empty list) we end up with - :: this awful type... - +$ item - $% [%l l=(list item)] - [%b b=byts] - == - :: +encode-atoms: encode list of atoms as a %l of %b items - :: - ++ encode-atoms - |= l=(list @) - ^- @ - %+ encode %l - %+ turn l - |=(a=@ b+[(met 3 a) a]) - :: - ++ encode - |= in=item - |^ ^- @ - ?- -.in - %b - ?: &(=(1 wid.b.in) (lte dat.b.in 0x7f)) - dat.b.in - =- (can 3 ~[b.in [(met 3 -) -]]) - (encode-length wid.b.in 0x80) - :: - %l - =/ out=@ - %+ roll l.in - |= [ni=item en=@] - (cat 3 (encode ni) en) - %^ cat 3 out - (encode-length (met 3 out) 0xc0) - == - :: - ++ encode-length - |= [len=@ off=@] - ?: (lth len 56) (add len off) - =- (cat 3 len -) - :(add (met 3 len) off 55) - -- - :: +decode-atoms: decode expecting a %l of %b items, producing atoms within - :: - ++ decode-atoms - |= dat=@ - ^- (list @) - =/ i=item (decode dat) - ~| [%unexpected-data i] - ?> ?=(%l -.i) - %+ turn l.i - |= i=item - ~| [%unexpected-list i] - ?> ?=(%b -.i) - dat.b.i - :: - ++ decode - |= dat=@ - ^- item - =/ bytes=(list @) (flop (rip 3 dat)) - =? bytes ?=(~ bytes) ~[0] - |^ item:decode-head - :: - ++ decode-head - ^- [done=@ud =item] - ?~ bytes - ~| %rlp-unexpected-end - !! - =* byt i.bytes - :: byte in 0x00-0x79 range encodes itself - :: - ?: (lte byt 0x79) - :- 1 - [%b 1^byt] - :: byte in 0x80-0xb7 range encodes string length - :: - ?: (lte byt 0xb7) - =+ len=(sub byt 0x80) - :- +(len) - :- %b - len^(get-value 1 len) - :: byte in 0xb8-0xbf range encodes string length length - :: - ?: (lte byt 0xbf) - =+ led=(sub byt 0xb7) - =+ len=(get-value 1 led) - :- (add +(led) len) - :- %b - len^(get-value +(led) len) - :: byte in 0xc0-f7 range encodes list length - :: - ?: (lte byt 0xf7) - =+ len=(sub byt 0xc0) - :- +(len) - :- %l - %. len - decode-list(bytes (slag 1 `(list @)`bytes)) - :: byte in 0xf8-ff range encodes list length length - :: - ?: (lte byt 0xff) - =+ led=(sub byt 0xf7) - =+ len=(get-value 1 led) - :- (add +(led) len) - :- %l - %. len - decode-list(bytes (slag +(led) `(list @)`bytes)) - ~| [%rip-not-bloq-3 `@ux`byt] - !! - :: - ++ decode-list - |= rem=@ud - ^- (list item) - ?: =(0 rem) ~ - =+ ^- [don=@ud =item] ::TODO =/ - decode-head - :- item - %= $ - rem (sub rem don) - bytes (slag don bytes) - == - :: - ++ get-value - |= [at=@ud to=@ud] - ^- @ - (rep 3 (flop (swag [at to] bytes))) - -- - -- -:: -:: abi en/decoding -::NOTE https://solidity.readthedocs.io/en/develop/abi-spec.html -:: -++ abi - => |% - :: solidity types. integer bitsizes ignored - ++ etyp - $@ $? :: static - %address %bool - %int %uint - %real %ureal - :: dynamic - %bytes %string - == - $% :: static - [%bytes-n n=@ud] - :: dynamic - [%array-n t=etyp n=@ud] - [%array t=etyp] - == - :: - :: solidity-style typed data. integer bitsizes ignored - ++ data - $% [%address p=address] - [%string p=tape] - [%bool p=?] - [%int p=@sd] - [%uint p=@ud] - [%real p=@rs] - [%ureal p=@urs] - [%array-n p=(list data)] - [%array p=(list data)] - [%bytes-n p=octs] ::TODO just @, because context knows length? - [%bytes p=octs] - == - -- - =, mimes:html - |% - :: encoding - :: - ++ encode-args - :: encode list of arguments. - :: - |= das=(list data) - ^- tape - (encode-data [%array-n das]) - :: - ++ encode-data - :: encode typed data into ABI bytestring. - :: - |= dat=data - ^- tape - ?+ -.dat - ~| [%unsupported-type -.dat] - !! - :: - %array-n - :: enc(X) = head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[k-1]) - :: where head and tail are defined for X[i] being of a static type as - :: head(X[i]) = enc(X[i]) and tail(X[i]) = "" (the empty string), or as - :: head(X[i]) = enc(len( head(X[0])..head(X[k-1]) - :: tail(X[0])..tail(X[i-1]) )) - :: and tail(X[i]) = enc(X[i]) otherwise. - :: - :: so: if it's a static type, data goes in the head. if it's a dynamic - :: type, a reference goes into the head and data goes into the tail. - :: - :: in the head, we first put a placeholder where references need to go. - =+ hol=(reap 64 'x') - =/ hes=(list tape) - %+ turn p.dat - |= d=data - ?. (is-dynamic-type d) ^$(dat d) - hol - =/ tas=(list tape) - %+ turn p.dat - |= d=data - ?. (is-dynamic-type d) "" - ^$(dat d) - :: once we know the head and tail, we can fill in the references in head. - =- (weld nes `tape`(zing tas)) - ^- [@ud nes=tape] - =+ led=(lent (zing hes)) - %+ roll hes - |= [t=tape i=@ud nes=tape] - :- +(i) - :: if no reference needed, just put the data. - ?. =(t hol) (weld nes t) - :: calculate byte offset of data we need to reference. - =/ ofs=@ud - =- (div - 2) :: two hex digits per byte. - %+ add led :: count head, and - %- lent %- zing :: count all tail data - (scag i tas) :: preceding ours. - =+ ref=^$(dat [%uint ofs]) - :: shouldn't hit this unless we're sending over 2gb of data? - ~| [%weird-ref-lent (lent ref)] - ?> =((lent ref) (lent hol)) - (weld nes ref) - :: - %array :: where X has k elements (k is assumed to be of type uint256): - :: enc(X) = enc(k) enc([X[1], ..., X[k]]) - :: i.e. it is encoded as if it were an array of static size k, prefixed - :: with the number of elements. - %+ weld $(dat [%uint (lent p.dat)]) - $(dat [%array-n p.dat]) - :: - %bytes-n - :: enc(X) is the sequence of bytes in X padded with zero-bytes to a - :: length of 32. - :: Note that for any X, len(enc(X)) is a multiple of 32. - ~| [%bytes-n-too-long max=32 actual=p.p.dat] - ?> (lte p.p.dat 32) - (pad-to-multiple (render-hex-bytes p.dat) 64 %right) - :: - %bytes :: of length k (which is assumed to be of type uint256) - :: enc(X) = enc(k) pad_right(X), i.e. the number of bytes is encoded as a - :: uint256 followed by the actual value of X as a byte sequence, followed - :: by the minimum number of zero-bytes such that len(enc(X)) is a - :: multiple of 32. - %+ weld $(dat [%uint p.p.dat]) - (pad-to-multiple (render-hex-bytes p.dat) 64 %right) - :: - %string - :: enc(X) = enc(enc_utf8(X)), i.e. X is utf-8 encoded and this value is - :: interpreted as of bytes type and encoded further. Note that the length - :: used in this subsequent encoding is the number of bytes of the utf-8 - :: encoded string, not its number of characters. - $(dat [%bytes (lent p.dat) (swp 3 (crip p.dat))]) - :: - %uint - :: enc(X) is the big-endian encoding of X, padded on the higher-order - :: (left) side with zero-bytes such that the length is a multiple of 32 - :: bytes. - (pad-to-multiple (render-hex-bytes (as-octs p.dat)) 64 %left) - :: - %bool - :: as in the uint8 case, where 1 is used for true and 0 for false - $(dat [%uint ?:(p.dat 1 0)]) - :: - %address - :: as in the uint160 case - $(dat [%uint `@ud`p.dat]) - == - :: - ++ is-dynamic-type - |= a=data - ?. ?=(%array-n -.a) - ?=(?(%string %bytes %array) -.a) - &(!=((lent p.a) 0) (lien p.a is-dynamic-type)) - :: - :: decoding - :: - ++ decode-topics decode-arguments - :: - ++ decode-results - :: rex: string of hex bytes with leading 0x. - |* [rex=@t tys=(list etyp)] - =- (decode-arguments - tys) - %^ rut 9 - (rsh [3 2] rex) - (curr rash hex) - :: - ++ decode-arguments - |* [wos=(list @) tys=(list etyp)] - =/ wos=(list @) wos :: get rid of tmi - =| win=@ud - =< (decode-from 0 tys) - |% - ++ decode-from - |* [win=@ud tys=(list etyp)] - ?~ tys !! - =- ?~ t.tys dat - [dat $(win nin, tys t.tys)] - (decode-one win ~[i.tys]) - :: - ++ decode-one - ::NOTE we take (list etyp) even though we only operate on - :: a single etyp as a workaround for urbit/arvo#673 - |* [win=@ud tys=(list etyp)] - =- [nin dat]=- ::NOTE ^= regular form broken - ?~ tys !! - =* typ i.tys - =+ wor=(snag win wos) - ?+ typ - ~| [%unsupported-type typ] - !! - :: - ?(%address %bool %uint) :: %int %real %ureal - :- +(win) - ?- typ - %address `@ux`wor - %uint `@ud`wor - %bool =(1 wor) - == - :: - %string - =+ $(tys ~[%bytes]) - [nin (trip (swp 3 q.dat))] - :: - %bytes - :- +(win) - :: find the word index of the actual data. - =/ lic=@ud (div wor 32) - :: learn the bytelength of the data. - =/ len=@ud (snag lic wos) - (decode-bytes-n +(lic) len) - :: - [%bytes-n *] - :- (add win +((div (dec n.typ) 32))) - (decode-bytes-n win n.typ) - :: - [%array *] - :- +(win) - :: find the word index of the actual data. - =. win (div wor 32) - :: read the elements from their location. - %- tail - %^ decode-array-n ~[t.typ] +(win) - (snag win wos) - :: - [%array-n *] - (decode-array-n ~[t.typ] win n.typ) - == - :: - ++ decode-bytes-n - |= [fro=@ud bys=@ud] - ^- octs - :: parse {bys} bytes from {fro}. - :- bys - %+ rsh - :- 3 - =+ (mod bys 32) - ?:(=(0 -) - (sub 32 -)) - %+ rep 8 - %- flop - =- (swag [fro -] wos) - +((div (dec bys) 32)) - :: - ++ decode-array-n - ::NOTE we take (list etyp) even though we only operate on - :: a single etyp as a workaround for urbit/arvo#673 - ::NOTE careful! produces lists without type info - =| res=(list) - |* [tys=(list etyp) fro=@ud len=@ud] - ^- [@ud (list)] - ?~ tys !! - ?: =(len 0) [fro (flop `(list)`res)] - =+ (decode-one fro ~[i.tys]) :: [nin=@ud dat=*] - $(res ^+(res [dat res]), fro nin, len (dec len)) - -- - -- -:: -:: communicating with rpc nodes -::NOTE https://github.com/ethereum/wiki/wiki/JSON-RPC -:: -++ rpc - :: types - :: - => =, abi - =, format - |% - :: raw call data - ++ call-data - $: function=@t - arguments=(list data) - == - :: - :: raw transaction data - +$ transaction - $: nonce=@ud - gas-price=@ud - gas=@ud - to=address - value=@ud - data=@ux - chain-id=@ux - == - :: - :: ethereum json rpc api - :: - :: supported requests. - ++ request - $% [%eth-block-number ~] - [%eth-call cal=call deb=block] - $: %eth-new-filter - fro=(unit block) - tob=(unit block) - adr=(list address) - top=(list ?(@ux (list @ux))) - == - [%eth-get-block-by-number bon=@ud txs=?] - [%eth-get-filter-logs fid=@ud] - $: %eth-get-logs - fro=(unit block) - tob=(unit block) - adr=(list address) - top=(list ?(@ux (list @ux))) - == - $: %eth-get-logs-by-hash - has=@ - adr=(list address) - top=(list ?(@ux (list @ux))) - == - [%eth-get-filter-changes fid=@ud] - [%eth-get-transaction-by-hash txh=@ux] - [%eth-get-transaction-count adr=address =block] - [%eth-get-balance adr=address] - [%eth-get-transaction-receipt txh=@ux] - [%eth-send-raw-transaction dat=@ux] - == - :: - ::TODO clean up & actually use - ++ response - $% ::TODO - [%eth-new-filter fid=@ud] - [%eth-get-filter-logs los=(list event-log)] - [%eth-get-logs los=(list event-log)] - [%eth-get-logs-by-hash los=(list event-log)] - [%eth-got-filter-changes los=(list event-log)] - [%eth-transaction-hash haz=@ux] - == - :: - ++ transaction-result - $: block-hash=(unit @ux) - block-number=(unit @ud) - transaction-index=(unit @ud) - from=@ux - to=(unit @ux) - input=@t - == - :: - ++ event-log - $: :: null for pending logs - $= mined %- unit - $: input=(unit @ux) - log-index=@ud - transaction-index=@ud - transaction-hash=@ux - block-number=@ud - block-hash=@ux - removed=? - == - :: - address=@ux - data=@t - :: event data - :: - :: For standard events, the first topic is the event signature - :: hash. For anonymous events, the first topic is the first - :: indexed argument. - :: Note that this does not support the "anonymous event with - :: zero topics" case. This has dubious usability, and using - :: +lest instead of +list saves a lot of ?~ checks. - :: - topics=(lest @ux) - == - :: - :: data for eth_call. - ++ call - $: from=(unit address) - to=address - gas=(unit @ud) - gas-price=(unit @ud) - value=(unit @ud) - data=tape - == - :: - :: minimum data needed to construct a read call - ++ proto-read-request - $: id=(unit @t) - to=address - call-data - == - :: - :: block to operate on. - ++ block - $% [%number n=@ud] - [%label l=?(%earliest %latest %pending)] - == - -- - :: - :: logic - :: - |% - ++ encode-call - |= call-data - ^- tape - ::TODO should this check to see if the data matches the function signature? - =- :(weld "0x" - (encode-args arguments)) - %+ scag 8 - %+ render-hex-bytes 32 - %- keccak-256:keccak:crypto - (as-octs:mimes:html function) - :: - :: building requests - :: - ++ json-request - =, eyre - |= [url=purl jon=json] - ^- hiss - :^ url %post - %- ~(gas in *math) - ~['Content-Type'^['application/json']~] - (some (as-octt (en-json:html jon))) - :: +light-json-request: like json-request, but for %l - :: - :: TODO: Exorcising +purl from our system is a much longer term effort; - :: get the current output types for now. - :: - ++ light-json-request - |= [url=purl:eyre jon=json] - ^- request:http - :: - :* %'POST' - (crip (en-purl:html url)) - ~[['content-type' 'application/json']] - (some (as-octt (en-json:html jon))) - == - :: - ++ batch-read-request - |= req=(list proto-read-request) - ^- json - a+(turn req read-request) - :: - ++ read-request - |= proto-read-request - ^- json - %+ request-to-json id - :+ %eth-call - ^- call - [~ to ~ ~ ~ `tape`(encode-call function arguments)] - [%label %latest] - :: - ++ request-to-json - =, enjs:format - |= [riq=(unit @t) req=request] - ^- json - %- pairs - =; r=[met=@t pas=(list json)] - ::TODO should use request-to-json:rpc:jstd, - :: and probably (fall riq -.req) - :* jsonrpc+s+'2.0' - method+s+met.r - params+a+pas.r - ::TODO would just jamming the req noun for id be a bad idea? - ?~ riq ~ - [id+s+u.riq]~ - == - ?- -.req - %eth-block-number - ['eth_blockNumber' ~] - :: - %eth-call - :- 'eth_call' - :~ (eth-call-to-json cal.req) - (block-to-json deb.req) - == - :: - %eth-new-filter - :- 'eth_newFilter' - :_ ~ - :- %o %- ~(gas by *(map @t json)) - =- (murn - same) - ^- (list (unit (pair @t json))) - :~ ?~ fro.req ~ - `['fromBlock' (block-to-json u.fro.req)] - :: - ?~ tob.req ~ - `['toBlock' (block-to-json u.tob.req)] - :: - ::TODO fucking tmi - ?: =(0 (lent adr.req)) ~ - :+ ~ 'address' - ?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req))) - :- %a - (turn adr.req (cork address-to-hex tape)) - :: - ?~ top.req ~ - :+ ~ 'topics' - (topics-to-json top.req) - == - :: - %eth-get-block-by-number - :- 'eth_getBlockByNumber' - :~ (tape (num-to-hex bon.req)) - b+txs.req - == - :: - %eth-get-filter-logs - ['eth_getFilterLogs' (tape (num-to-hex fid.req)) ~] - :: - %eth-get-logs - :- 'eth_getLogs' - :_ ~ - :- %o %- ~(gas by *(map @t json)) - =- (murn - same) - ^- (list (unit (pair @t json))) - :~ ?~ fro.req ~ - `['fromBlock' (block-to-json u.fro.req)] - :: - ?~ tob.req ~ - `['toBlock' (block-to-json u.tob.req)] - :: - ?: =(0 (lent adr.req)) ~ - :+ ~ 'address' - ?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req))) - :- %a - (turn adr.req (cork address-to-hex tape)) - :: - ?~ top.req ~ - :+ ~ 'topics' - (topics-to-json top.req) - == - :: - %eth-get-logs-by-hash - :- 'eth_getLogs' - :_ ~ :- %o - %- ~(gas by *(map @t json)) - =- (murn - same) - ^- (list (unit (pair @t json))) - :~ `['blockHash' (tape (transaction-to-hex has.req))] - :: - ?: =(0 (lent adr.req)) ~ - :+ ~ 'address' - ?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req))) - :- %a - (turn adr.req (cork address-to-hex tape)) - :: - ?~ top.req ~ - :+ ~ 'topics' - (topics-to-json top.req) - == - :: - %eth-get-filter-changes - ['eth_getFilterChanges' (tape (num-to-hex fid.req)) ~] - :: - %eth-get-transaction-count - :- 'eth_getTransactionCount' - :~ (tape (address-to-hex adr.req)) - (block-to-json block.req) - == - :: - %eth-get-balance - ['eth_getBalance' (tape (address-to-hex adr.req)) ~] - :: - %eth-get-transaction-by-hash - ['eth_getTransactionByHash' (tape (transaction-to-hex txh.req)) ~] - :: - %eth-get-transaction-receipt - ['eth_getTransactionReceipt' (tape (transaction-to-hex txh.req)) ~] - :: - %eth-send-raw-transaction - ['eth_sendRawTransaction' (tape (num-to-hex dat.req)) ~] - == - :: - ++ eth-call-to-json - =, enjs:format - |= cal=call - ^- json - :- %o %- ~(gas by *(map @t json)) - =- (murn - same) - ^- (list (unit (pair @t json))) - :~ ?~ from.cal ~ - `['from' (tape (address-to-hex u.from.cal))] - :: - `['to' (tape (address-to-hex to.cal))] - :: - ?~ gas.cal ~ - `['gas' (tape (num-to-hex u.gas.cal))] - :: - ?~ gas-price.cal ~ - `['gasPrice' (tape (num-to-hex u.gas-price.cal))] - :: - ?~ value.cal ~ - `['value' (tape (num-to-hex u.value.cal))] - :: - ?~ data.cal ~ - `['data' (tape data.cal)] - == - :: - ++ block-to-json - |= dob=block - ^- json - ?- -.dob - %number s+(crip '0' 'x' ((x-co:co 1) n.dob)) - %label s+l.dob - == - :: - ++ topics-to-json - |= tos=(list ?(@ux (list @ux))) - ^- json - :- %a - =/ ttj - ;: cork - (cury render-hex-bytes 32) - prefix-hex - tape:enjs:format - == - %+ turn tos - |= t=?(@ (list @)) - ?@ t - ?: =(0 t) ~ - (ttj `@`t) - a+(turn t ttj) - :: - :: parsing responses - :: - ::TODO ++ parse-response |= json ^- response - :: - ++ parse-hex-result - |= j=json - ^- @ - ?> ?=(%s -.j) - (hex-to-num p.j) - :: - ++ parse-eth-new-filter-res parse-hex-result - :: - ++ parse-eth-block-number parse-hex-result - :: - ++ parse-transaction-hash parse-hex-result - :: - ++ parse-eth-get-transaction-count parse-hex-result - :: - ++ parse-eth-get-balance parse-hex-result - :: - ++ parse-event-logs - (ar:dejs:format parse-event-log) - :: - ++ parse-event-log - =, dejs:format - |= log=json - ^- event-log - =- ((ot -) log) - :~ =- ['logIndex'^(cu - (mu so))] - |= li=(unit @t) - ?~ li ~ - =- ``((ou -) log) ::TODO not sure if elegant or hacky. - :~ 'logIndex'^(un (cu hex-to-num so)) - 'transactionIndex'^(un (cu hex-to-num so)) - 'transactionHash'^(un (cu hex-to-num so)) - 'blockNumber'^(un (cu hex-to-num so)) - 'blockHash'^(un (cu hex-to-num so)) - 'removed'^(uf | bo) - == - :: - address+(cu hex-to-num so) - data+so - :: - =- topics+(cu - (ar so)) - |= r=(list @t) - ^- (lest @ux) - ?> ?=([@t *] r) - :- (hex-to-num i.r) - (turn t.r hex-to-num) - == - :: - ++ parse-transaction-result - =, dejs:format - |= jon=json - ~| jon=jon - ^- transaction-result - =- ((ot -) jon) - :~ 'blockHash'^_~ :: TODO: fails if maybe-num? - 'blockNumber'^maybe-num - 'transactionIndex'^maybe-num - from+(cu hex-to-num so) - to+maybe-num - input+so - == - :: - ++ maybe-num - =, dejs:format - =- (cu - (mu so)) - |= r=(unit @t) - ?~ r ~ - `(hex-to-num u.r) - -- -:: -:: utilities -::TODO give them better homes! -:: -++ num-to-hex - |= n=@ - ^- tape - %- prefix-hex - ?: =(0 n) - "0" - %- render-hex-bytes - (as-octs:mimes:html n) -:: -++ address-to-hex - |= a=address - ^- tape - %- prefix-hex - (render-hex-bytes 20 `@`a) -:: -++ transaction-to-hex - |= h=@ - ^- tape - %- prefix-hex - (render-hex-bytes 32 h) -:: -++ prefix-hex - |= a=tape - ^- tape - ['0' 'x' a] -:: -++ render-hex-bytes - :: atom to string of hex bytes without 0x prefix and dots. - |= a=octs - ^- tape - ((x-co:co (mul 2 p.a)) q.a) -:: -++ pad-to-multiple - |= [wat=tape mof=@ud wer=?(%left %right)] - ^- tape - =+ len=(lent wat) - ?: =(0 len) (reap mof '0') - =+ mad=(mod len mof) - ?: =(0 mad) wat - =+ tad=(reap (sub mof mad) '0') - %- weld - ?:(?=(%left wer) [tad wat] [wat tad]) -:: -++ hex-to-num - |= a=@t - (rash (rsh [3 2] a) hex) --- diff --git a/pkg/arvo/lib/ethereum.hoon b/pkg/arvo/lib/ethereum.hoon new file mode 120000 index 000000000..c0a2772eb --- /dev/null +++ b/pkg/arvo/lib/ethereum.hoon @@ -0,0 +1 @@ +../../base-dev/lib/ethereum.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/ethio.hoon b/pkg/arvo/lib/ethio.hoon deleted file mode 100644 index 46926ecd9..000000000 --- a/pkg/arvo/lib/ethio.hoon +++ /dev/null @@ -1,289 +0,0 @@ -:: ethio: Asynchronous Ethereum input/output functions. -:: -/- rpc=json-rpc -/+ ethereum, strandio -=, ethereum-types -=, jael -:: -=> |% - +$ topics (list ?(@ux (list @ux))) - -- -|% -:: +request-rpc: send rpc request, with retry -:: -++ request-rpc - |= [url=@ta id=(unit @t) req=request:rpc:ethereum] - =/ m (strand:strandio ,json) - ^- form:m - ;< res=(list [id=@t =json]) bind:m - (request-batch-rpc-strict url [id req]~) - ?: ?=([* ~] res) - (pure:m json.i.res) - %+ strand-fail:strandio - %unexpected-multiple-results - [>(lent res)< ~] -:: +request-batch-rpc-strict: send rpc requests, with retry -:: -:: sends a batch request. produces results for all requests in the batch, -:: but only if all of them are successful. -:: -++ request-batch-rpc-strict - |= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])] - |^ %+ (retry:strandio results) - `10 - attempt-request - :: - +$ results (list [id=@t =json]) - :: - ++ attempt-request - =/ m (strand:strandio ,(unit results)) - ^- form:m - ;< responses=(list response:rpc) bind:m - (request-batch-rpc-loose url reqs) - =- ?~ err - (pure:m `res) - (pure:m ~) - %+ roll responses - |= $: rpc=response:rpc - [res=results err=(list [id=@t code=@t message=@t])] - == - ?: ?=(%error -.rpc) - [res [+.rpc err]] - ?. ?=(%result -.rpc) - [res [['' 'ethio-rpc-fail' (crip )] err]] - [[+.rpc res] err] - -- -:: +request-batch-rpc-loose: send rpc requests, with retry -:: -:: sends a batch request. produces results for all requests in the batch, -:: including the ones that are unsuccessful. -:: -++ request-batch-rpc-loose - |= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])] - |^ %+ (retry:strandio results) - `10 - attempt-request - :: - +$ result response:rpc - +$ results (list response:rpc) - :: - ++ attempt-request - =/ m (strand:strandio ,(unit results)) - ^- form:m - =/ =request:http - :* method=%'POST' - url=url - header-list=['Content-Type'^'application/json' ~] - :: - ^= body - %- some %- as-octt:mimes:html - %- en-json:html - a+(turn reqs request-to-json:rpc:ethereum) - == - ;< ~ bind:m - (send-request:strandio request) - ;< rep=(unit client-response:iris) bind:m - take-maybe-response:strandio - ?~ rep - (pure:m ~) - (parse-responses u.rep) - :: - ++ parse-responses - |= =client-response:iris - =/ m (strand:strandio ,(unit results)) - ^- form:m - ?> ?=(%finished -.client-response) - ?~ full-file.client-response - (pure:m ~) - =/ body=@t q.data.u.full-file.client-response - =/ jon=(unit json) (de-json:html body) - ?~ jon - (pure:m ~) - =/ array=(unit (list response:rpc)) - ((ar:dejs-soft:format parse-one-response) u.jon) - ?~ array - (strand-fail:strandio %rpc-result-incomplete-batch >u.jon< ~) - (pure:m array) - :: - ++ parse-one-response - |= =json - ^- (unit response:rpc) - ?. &(?=([%o *] json) (~(has by p.json) 'error')) - =/ res=(unit [@t ^json]) - %. json - =, dejs-soft:format - (ot id+so result+some ~) - ?~ res ~ - `[%result u.res] - ~| parse-one-response=json - =/ error=(unit [id=@t ^json code=@ta mssg=@t]) - %. json - =, dejs-soft:format - :: A 'result' member is present in the error - :: response when using ganache, even though - :: that goes against the JSON-RPC spec - :: - (ot id+so result+some error+(ot code+no message+so ~) ~) - ?~ error ~ - =* err u.error - `[%error id.err code.err mssg.err] - -- -:: -:: +read-contract: calls a read function on a contract, produces result hex -:: -++ read-contract - |= [url=@t req=proto-read-request:rpc:ethereum] - =/ m (strand:strandio ,@t) - ;< res=(list [id=@t res=@t]) bind:m - (batch-read-contract-strict url [req]~) - ?: ?=([* ~] res) - (pure:m res.i.res) - %+ strand-fail:strandio - %unexpected-multiple-results - [>(lent res)< ~] -:: +batch-read-contract-strict: calls read functions on contracts -:: -:: sends a batch request. produces results for all requests in the batch, -:: but only if all of them are successful. -:: -++ batch-read-contract-strict - |= [url=@t reqs=(list proto-read-request:rpc:ethereum)] - |^ =/ m (strand:strandio ,results) - ^- form:m - ;< res=(list [id=@t =json]) bind:m - %+ request-batch-rpc-strict url - (turn reqs proto-to-rpc) - =+ ^- [=results =failures] - (roll res response-to-result) - ?~ failures (pure:m results) - (strand-fail:strandio %batch-read-failed-for >failures< ~) - :: - +$ results (list [id=@t res=@t]) - +$ failures (list [id=@t =json]) - :: - ++ proto-to-rpc - |= proto-read-request:rpc:ethereum - ^- [(unit @t) request:rpc:ethereum] - :- id - :+ %eth-call - ^- call:rpc:ethereum - [~ to ~ ~ ~ `tape`(encode-call:rpc:ethereum function arguments)] - [%label %latest] - :: - ++ response-to-result - |= [[id=@t =json] =results =failures] - ^+ [results failures] - ?: ?=(%s -.json) - [[id^p.json results] failures] - [results [id^json failures]] - -- -:: -:: -++ get-latest-block - |= url=@ta - =/ m (strand:strandio ,block) - ^- form:m - ;< =json bind:m - (request-rpc url `'block number' %eth-block-number ~) - (get-block-by-number url (parse-eth-block-number:rpc:ethereum json)) -:: -++ get-block-by-number - |= [url=@ta =number:block] - =/ m (strand:strandio ,block) - ^- form:m - |^ - %+ (retry:strandio ,block) `10 - =/ m (strand:strandio ,(unit block)) - ^- form:m - ;< =json bind:m - %+ request-rpc url - :- `'block by number' - [%eth-get-block-by-number number |] - (pure:m (parse-block json)) - :: - ++ parse-block - |= =json - ^- (unit block) - =< ?~(. ~ `[[&1 &2] |2]:u) - ^- (unit [@ @ @]) - ~| json - %. json - =, dejs-soft:format - %- ot - :~ hash+parse-hex - number+parse-hex - 'parentHash'^parse-hex - == - :: - ++ parse-hex |=(=json `(unit @)`(some (parse-hex-result:rpc:ethereum json))) - -- -:: -++ get-tx-by-hash - |= [url=@ta tx-hash=@ux] - =/ m (strand:strandio transaction-result:rpc:ethereum) - ^- form:m - ;< =json bind:m - %+ request-rpc url - :* `'tx by hash' - %eth-get-transaction-by-hash - tx-hash - == - %- pure:m - (parse-transaction-result:rpc:ethereum json) -:: -++ get-logs-by-hash - |= [url=@ta =hash:block contracts=(list address) =topics] - =/ m (strand:strandio (list event-log:rpc:ethereum)) - ^- form:m - ;< =json bind:m - %+ request-rpc url - :* `'logs by hash' - %eth-get-logs-by-hash - hash - contracts - topics - == - %- pure:m - (parse-event-logs:rpc:ethereum json) -:: -++ get-logs-by-range - |= $: url=@ta - contracts=(list address) - =topics - =from=number:block - =to=number:block - == - =/ m (strand:strandio (list event-log:rpc:ethereum)) - ^- form:m - ;< =json bind:m - %+ request-rpc url - :* `'logs by range' - %eth-get-logs - `number+from-number - `number+to-number - contracts - topics - == - %- pure:m - (parse-event-logs:rpc:ethereum json) -:: -++ get-next-nonce - |= [url=@ta =address] - =/ m (strand:strandio ,@ud) - ^- form:m - ;< =json bind:m - %^ request-rpc url `'nonce' - [%eth-get-transaction-count address [%label %latest]] - %- pure:m - (parse-eth-get-transaction-count:rpc:ethereum json) -:: -++ get-balance - |= [url=@ta =address] - =/ m (strand:strandio ,@ud) - ^- form:m - ;< =json bind:m - %^ request-rpc url `'balance' - [%eth-get-balance address] - %- pure:m - (parse-eth-get-balance:rpc:ethereum json) --- diff --git a/pkg/arvo/lib/ethio.hoon b/pkg/arvo/lib/ethio.hoon new file mode 120000 index 000000000..9c5b58148 --- /dev/null +++ b/pkg/arvo/lib/ethio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/ethio.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/fake-roller.hoon b/pkg/arvo/lib/fake-roller.hoon new file mode 100644 index 000000000..d9ee2778c --- /dev/null +++ b/pkg/arvo/lib/fake-roller.hoon @@ -0,0 +1,75 @@ +/- *dice +/+ naive, lib=naive-transactions +:: +:: Addresses derived from mnemonic: +:: +:: benefit crew supreme gesture quantum web +:: media hazard theory mercy wing kitten +:: +:: Available Accounts +:: ================== +:: (0) 0x6deffb0cafdb11d175f123f6891aa64f01c24f7d (100 eth) +:: (1) 0xd53208cf45fc9bd7938b200bff8814a26146688f (100 eth) +:: (2) 0x7b2a2d51e4d8fac602e20a5f6907ff9fbd88e1fd (100 eth) +:: (3) 0xf48062ae8bafd6ef19cd6cb89db93a0d0ca6ce26 (100 eth) +:: (4) 0xf84a77aeb351c49dfa87e805a659d2daddff7606 (100 eth) +:: (5) 0x167e357cf8b845370d0d408f9b389b66185b7b5b (100 eth) +:: (6) 0xcbecf3abc9878f07afc851aead2d8f1c436cc71d (100 eth) +:: (7) 0x0afc0c3f4eeea500871f464ca71eef5e54a9af36 (100 eth) +:: (8) 0x6d654ef2489674d21aed428e8a4ad8ca4820f125 (100 eth) +:: (9) 0x218f6f87683db546ad47a5dc8b480e5a9b694866 (100 eth) + +:: private keys +:: ================== +:: (0) 0xa44de2416ee6beb2f323fab48b432925c9785808d33a6ca6d7ba00b45e9370c3 +:: (1) 0x420b20f3538f7ddf4527770acbd33ed8aa858ba24eec5038bd22158f23a8a002 +:: (2) 0x655eae6e301ebe9da6384f717f774f6addb165606a6990ce13e86ead710fff8b +:: (3) 0x2480c5256d843c73cba67cc966a11a647c943a41db2fa138de4e4f16d0861a6b +:: (4) 0xd6abd8fbab1db8714f1e284c11b8621cf95d0e319b4f38c54de4247f2150f1ba +:: (5) 0x95f48754f44e6930473367a0802bdac7389e7749df2b3a6dd6e87bcbe0d0e0bc +:: (6) 0x92596e42f9ee7a47e0d8c48291c768945fede98874cc250202a1f19f12c97be3 +:: (7) 0xa0ae1d77d89854a55a4abdc1300e989b1981728e8e669cfb4b4179f0af1ac389 +:: (8) 0x7aec9f8027edaa2408ac5ca74b5ed929e271570a0eeed848f47bcee842902c16 +:: (9) 0x58d62eb79797502bc0f66cd3e7a49d00287bff53a2734b799ef09cb746340ed0 +:: +|% +++ prv-from-address + |= =address:naive + ^- @ + ?: =(address 0x6def.fb0c.afdb.11d1.75f1.23f6.891a.a64f.01c2.4f7d) + 0xa44d.e241.6ee6.beb2.f323.fab4.8b43.2925. + c978.5808.d33a.6ca6.d7ba.00b4.5e93.70c3 + ?: =(address 0xd532.08cf.45fc.9bd7.938b.200b.ff88.14a2.6146.688f) + 0x420b.20f3.538f.7ddf.4527.770a.cbd3.3ed8. + aa85.8ba2.4eec.5038.bd22.158f.23a8.a002 + ?: =(address 0x7b2a.2d51.e4d8.fac6.02e2.0a5f.6907.ff9f.bd88.e1fd) + 0x655e.ae6e.301e.be9d.a638.4f71.7f77.4f6a. + ddb1.6560.6a69.90ce.13e8.6ead.710f.ff8b + ?: =(address 0xf480.62ae.8baf.d6ef.19cd.6cb8.9db9.3a0d.0ca6.ce26) + 0x2480.c525.6d84.3c73.cba6.7cc9.66a1.1a64. + 7c94.3a41.db2f.a138.de4e.4f16.d086.1a6b + ?: =(address 0xf84a.77ae.b351.c49d.fa87.e805.a659.d2da.ddff.7606) + 0xd6ab.d8fb.ab1d.b871.4f1e.284c.11b8.621c. + f95d.0e31.9b4f.38c5.4de4.247f.2150.f1ba + ?: =(address 0x167e.357c.f8b8.4537.0d0d.408f.9b38.9b66.185b.7b5b) + 0x95f4.8754.f44e.6930.4733.67a0.802b.dac7. + 389e.7749.df2b.3a6d.d6e8.7bcb.e0d0.e0bc + ?: =(address 0xcbec.f3ab.c987.8f07.afc8.51ae.ad2d.8f1c.436c.c71d) + 0x9259.6e42.f9ee.7a47.e0d8.c482.91c7.6894. + 5fed.e988.74cc.2502.02a1.f19f.12c9.7be3 + ?: =(address 0xafc.0c3f.4eee.a500.871f.464c.a71e.ef5e.54a9.af36) + 0xa0ae.1d77.d898.54a5.5a4a.bdc1.300e.989b. + 1981.728e.8e66.9cfb.4b41.79f0.af1a.c389 + ?: =(address 0x6d65.4ef2.4896.74d2.1aed.428e.8a4a.d8ca.4820.f125) + 0x7aec.9f80.27ed.aa24.08ac.5ca7.4b5e.d929. + e271.570a.0eee.d848.f47b.cee8.4290.2c16 + ?. =(address 0x218f.6f87.683d.b546.ad47.a5dc.8b48.0e5a.9b69.4866) !! + 0x58d6.2eb7.9797.502b.c0f6.6cd3.e7a4.9d00.287b. + ff53.a273.4b79.9ef0.9cb7.4634.0ed0 +:: +++ fake-sig + |= [=tx:naive =address:naive =nonce:naive] + ^- octs + (gen-tx:lib nonce tx (prv-from-address address)) +:: +-- diff --git a/pkg/arvo/lib/hark/store.hoon b/pkg/arvo/lib/hark/store.hoon deleted file mode 100644 index 6c7181980..000000000 --- a/pkg/arvo/lib/hark/store.hoon +++ /dev/null @@ -1,560 +0,0 @@ -/- sur=hark-store, post -/+ resource, graph-store, group-store -^? -=< [. sur] -=, sur -|% -++ upgrade - |% - ++ to-three - =* two state-two - =* three state-three - |% - ++ index - |= =index:two - ^- (unit index:three) - `index - ++ contents - |= =contents:two - ^- (unit contents:three) - ?. ?=(%group -.contents) - `contents - =- ?: =(~ -) ~ - `[%group -] - %+ murn list.contents - |= =group-contents:two - ^- (unit group-contents:three) - ?: ?=(?(%add %remove) -.group-contents) - ~ - `group-contents - :: - ++ stats-index - |= =stats-index:two - ^- (unit stats-index:three) - `stats-index - :: - ++ notifications - upg-notifications:upg - :: - ++ upg - %. [index stats-index contents] - %: upgrade - index:two - stats-index:two - contents:two - index:three - stats-index:three - contents:three - == - -- - :: - ++ to-four - =* three state-three - =* four state-four - |% - ++ index - |= =index:three - ^- (unit index:four) - `index - ++ contents - |= =contents:three - ^- (unit contents:four) - ?. ?=(%graph -.contents) - `contents - `[%graph (turn list.contents post-to-one:upgrade:graph-store)] - :: - ++ unreads-each - upg-unreads-each:upg - :: - ++ notifications - upg-notifications:upg - :: - ++ stats-index - |= =stats-index:three - ^- (unit stats-index:four) - `stats-index - :: - ++ upg - %. [index stats-index contents] - %: upgrade - index:three - stats-index:three - contents:three - index:four - stats-index:four - contents:four - == - -- - :: - ++ to-five - =* four state-four - =* five sur - |% - ++ mark - |= module=@t - ^- (unit @t) - ?+ module ~ - %chat `%graph-validator-chat - %publish `%graph-validator-publish - %link `%graph-validator-link - == - ++ index - |= =index:four - ^- (unit index:five) - ?: ?=(%group -.index) - `index - =* i index - `[%graph graph.i (mark module.i) description.i index.i] - :: - ++ contents - |= =contents:four - ^- (unit contents:five) - `contents - :: - ++ unreads-each - upg-unreads-each:upg - :: - ++ stats-index - |= =stats-index:four - ^- (unit stats-index:five) - `stats-index - :: - ++ upg - %. [index stats-index contents] - %: upgrade - index:four - stats-index:four - contents:four - index:five - stats-index:five - contents:five - == - - ++ notifications - upg-notifications:upg - -- - :: - ++ upgrade - |* $: :: input molds - in-index=mold - in-stats-index=mold - in-contents=mold - :: output molds - out-index=mold - out-stats-index=mold - out-contents=mold - == - => . => - |% - :: - ++ in - |% - :: - +$ index in-index - +$ stats-index in-stats-index - +$ contents in-contents - +$ unreads-each (jug stats-index index) - +$ timebox (map index notification) - +$ notification - [date=@da read=? =contents] - ++ orm - ((ordered-map time timebox) gth) - +$ notifications - ((mop time timebox) gth) - -- - ++ out - |% - :: - :: - +$ index out-index - +$ stats-index out-stats-index - +$ contents out-contents - +$ timebox (map out-index notification) - +$ unreads-each (jug stats-index index) - +$ notification - [date=@da read=? contents=out-contents] - +$ notifications - ((mop time timebox) gth) - ++ orm - ((ordered-map time timebox) gth) - -- - -- - |= $: fun-index=$-(index:in (unit index:out)) - fun-stats-index=$-(stats-index:in (unit stats-index:out)) - fun-contents=$-(contents:in (unit contents:out)) - == - |% - :: - ++ upg-unreads-each - |= =unreads-each:in - ^- unreads-each:out - %- ~(gas by *unreads-each:out) - %+ murn ~(tap by unreads-each) - |= [=stats-index:in indices=(set index:in)] - ^- (unit [stats-index:out (set index:out)]) - =/ new-stats - (fun-stats-index stats-index) - ?~ new-stats ~ - =/ new-indices - (upg-indices indices) - ?: =(0 ~(wyt ^in new-indices)) ~ - `[u.new-stats new-indices] - :: - ++ upg-indices - |= indices=(set index:in) - ^- (set index:out) - %- ~(gas ^in *(set index:out)) - (murn ~(tap ^in indices) fun-index) - :: - ++ upg-notifications - |= =notifications:in - ^- notifications:out - %+ gas:orm:out *notifications:out - ^- (list [@da timebox:out]) - %+ murn (tap:orm:in notifications) - |= [time=@da =timebox:in] - ^- (unit [@da =timebox:out]) - =/ new-timebox=timebox:out - (upg-timebox timebox) - ?: =(0 ~(wyt by timebox)) - ~ - `[time new-timebox] - :: - ++ upg-timebox - |= =timebox:in - ^- timebox:out - %- ~(gas by *timebox:out) - %+ murn ~(tap by timebox) - |= [=index:in =notification:in] - ^- (unit [index:out notification:out]) - =/ new-index - (fun-index index) - ?~ new-index ~ - =/ new-notification - (upg-notification notification) - ?~ new-notification ~ - `[u.new-index u.new-notification] - :: - ++ upg-notification - |= n=notification:in - ^- (unit notification:out) - =/ new-contents - (fun-contents contents.n) - ?~ new-contents ~ - `[date.n read.n u.new-contents] - -- - -- - -++ dejs - =, dejs:format - |% - ++ index - %- of - :~ graph+graph-index - group+group-index - == - :: - ++ group-index - %- ot - :~ group+dejs-path:resource - description+so - == - :: - ++ graph-index - %- ot - :~ graph+dejs-path:resource - mark+(mu so) - description+so - index+(su ;~(pfix fas (more fas dem))) - == - :: - ++ stats-index - %- of - :~ graph+graph-stats-index - group+dejs-path:resource - == - ++ graph-stats-index - %- ot - :~ graph+dejs-path:resource - index+graph-store-index - == - :: parse date as @ud - :: TODO: move to zuse - ++ sd - |= jon=json - ^- @da - ?> ?=(%s -.jon) - `@da`(rash p.jon dem:ag) - :: - ++ notif-ref - ^- $-(json [(unit @da) ^index]) - %- ot - :~ time+(mu sd) - index+index - == - ++ graph-store-index - (su ;~(pfix fas (more fas dem))) - :: - ++ add - |= jon=json - [*^index *notification] - :: - ++ read-graph-index - %- ot - :~ index+stats-index - target+graph-store-index - == - :: - ++ action - ^- $-(json ^action) - %- of - :~ seen+ul - archive+notif-ref - read-note+index - add-note+add - set-dnd+bo - read-count+stats-index - read-each+read-graph-index - read-all+ul - == - -- -:: -++ enjs - =, enjs:format - |% - ++ update - |= upd=^update - ^- json - |^ - %+ frond -.upd - ?+ -.upd a+~ - %added (added +.upd) - %timebox (timebox +.upd) - %set-dnd b+dnd.upd - %count (numb count.upd) - %more (more +.upd) - %read-each (read-each +.upd) - %read-count (stats-index +.upd) - %unread-each (unread-each +.upd) - %unread-count (unread-count +.upd) - %remove-graph s+(enjs-path:resource +.upd) - %seen-index (seen-index +.upd) - %unreads (unreads +.upd) - %read-note (index +.upd) - %note-read (note-read +.upd) - :: - %archive - (notif-ref +.upd) - == - :: - ++ note-read - |= [tim=@da idx=^index] - %- pairs - :~ time+s+(scot %ud tim) - index+(index idx) - == - :: - ++ stats-index - |= s=^stats-index - %+ frond -.s - |^ - ?- -.s - %graph (graph-stats-index +.s) - %group s+(enjs-path:resource +.s) - == - :: - ++ graph-stats-index - |= [graph=resource =index:graph-store] - %- pairs - :~ graph+s+(enjs-path:resource graph) - index+(index:enjs:graph-store index) - == - -- - :: - ++ unreads - |= l=(list [^stats-index ^stats]) - ^- json - :- %a - ^- (list json) - %+ turn l - |= [idx=^stats-index s=^stats] - %- pairs - :~ stats+(stats s) - index+(stats-index idx) - == - :: - ++ unread - |= =^unreads - %+ frond - -.unreads - ?- -.unreads - %each a+(turn ~(tap by indices.unreads) index:enjs:graph-store) - :: - %count - (numb num.unreads) - == - :: - ++ stats - |= s=^stats - ^- json - %- pairs - :~ unreads+(unread unreads.s) - last+(time last-seen.s) - == - ++ added - |= [idx=^index not=^notification] - ^- json - %- pairs - :~ index+(index idx) - notification+(notification not) - == - :: - ++ notif-ref - |= [tim=(unit @da) idx=^index] - ^- json - %- pairs - :~ [%time ?~(tim ~ s+(scot %ud u.tim))] - index+(index idx) - == - ++ seen-index - |= [tim=@da idx=^stats-index] - ^- json - %- pairs - :~ time+(time tim) - index+(stats-index idx) - == - :: - ++ more - |= upds=(list ^update) - ^- json - a+(turn upds update) - :: - ++ index - |= =^index - %+ frond -.index - |^ - ?- -.index - %graph (graph-index +.index) - %group (group-index +.index) - == - :: - ++ graph-index - |= $: graph=resource - mark=(unit mark) - description=@t - idx=index:graph-store - == - ^- json - %- pairs - :~ graph+s+(enjs-path:resource graph) - mark+s+(fall mark '') - description+s+description - index+(index:enjs:graph-store idx) - == - :: - ++ group-index - |= [group=resource description=@t] - ^- json - %- pairs - :~ group+s+(enjs-path:resource group) - description+s+description - == - -- - :: - ++ notification - |= ^notification - ^- json - %- pairs - :~ time+(time date) - contents+(^contents contents) - == - :: - ++ contents - |= =^contents - ^- json - %+ frond -.contents - |^ - ?- -.contents - %graph (graph-contents +.contents) - %group (group-contents +.contents) - == - :: - ++ graph-contents - |= =(list post:post) - ^- json - :- %a - (turn list post:enjs:graph-store) - :: - ++ group-contents - |= =(list ^group-contents) - ^- json - :- %a - %+ turn list - |= =^group-contents - (update:enjs:group-store group-contents) - -- - :: - ++ indexed-notification - |= [=^index =^notification] - %- pairs - :~ index+(^index index) - notification+(^notification notification) - == - :: - ++ timebox - |= [tim=(unit @da) l=(list [^index ^notification])] - ^- json - %- pairs - :~ time+`json`?~(tim ~ s+(scot %ud u.tim)) - :- %notifications - ^- json - :- %a - %+ turn l - |= [=^index =^notification] - ^- json - (indexed-notification index notification) - == - :: - ++ read-each - |= [s=^stats-index target=index:graph-store] - %- pairs - :~ index+(stats-index s) - target+(index:enjs:graph-store target) - == - :: - ++ unread-each - |= [s=^stats-index target=index:graph-store tim=@da] - %- pairs - :~ index+(stats-index s) - target+(index:enjs:graph-store target) - last+(time tim) - == - :: - ++ unread-count - |= [s=^stats-index tim=@da] - %- pairs - :~ index+(stats-index s) - last+(time tim) - == - -- - -- -:: -++ to-stats-index - |= =index - ^- stats-index - ?- -.index - %graph [%graph graph.index index.index] - %group [%group group.index] - == -++ stats-index-is-index - |= [=stats-index =index] - ?- -.index - %graph - ?. ?=(%graph -.stats-index) %.n - =([graph index]:index [graph index]:stats-index) - :: - %group - ?. ?=(%group -.stats-index) %.n - =(group:index group:stats-index) - == --- diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 0023ed45e..bccebc46e 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -1,20 +1,36 @@ /- *sole /+ sole |% -+$ any-state $%(state) -+$ state [%2 pith-2] ++$ state state-4 ++$ any-state + $~ *state + $% state-4 + state-3 + state-2 + == ++$ state-4 [%4 pith-4] ++$ state-3 [%3 pith-3] ++$ state-2 [%2 pith-2] :: -++ pith-2 :: ++$ pith-4 $: eel=(set gill:gall) :: connect to - ray=(set well:gall) :: - fur=(map dude:gall (unit server)) :: servers + bin=(map bone source) :: terminals + == :: +:: +++ pith-3 :: + $: eel=(set gill:gall) :: connect to + ray=(map dude:gall desk) :: + fur=(map dude:gall (unit *)) :: servers bin=(map bone source) :: terminals == :: :: :: -++ server :: running server - $: syd=desk :: app identity - cas=case :: boot case +++ pith-2 :: + $: eel=(set gill:gall) :: connect to + ray=(set well:gall) :: + fur=(map dude:gall (unit *)) :: servers + bin=(map bone source) :: terminals == :: +:: :: ++ kill :: kill ring $: pos=@ud :: ring position num=@ud :: number of entries @@ -54,69 +70,6 @@ :::: :: :: :: :: :: |% -++ deft-apes :: default servers - |= [our=ship lit=?] - %- ~(gas in *(set well:gall)) - ^- (list well:gall) - :: boot all default apps off the home desk - :: - =- (turn - |=(a=term home+a)) - ^- (list term) - %+ welp - :~ %dojo - %spider - %eth-watcher - %azimuth - %ping - %goad - %lens - == - ?: lit - ~ - :~ %acme - %clock - %dojo - %launch - %publish - %weather - %group-store - %group-pull-hook - %group-push-hook - %invite-store - %invite-hook - %chat-store - %chat-hook - %chat-view - %chat-cli - %herm - %contact-store - %contact-push-hook - %contact-pull-hook - %metadata-store - %s3-store - %file-server - %glob - %graph-store - %graph-pull-hook - %graph-push-hook - %hark-store - %hark-graph-hook - %hark-group-hook - %hark-chat-hook - %observe-hook - %metadata-push-hook - %metadata-pull-hook - %group-view - %settings-store - %dm-hook - == -:: -++ deft-fish :: default connects - |= our=ship - %- ~(gas in *(set gill:gall)) - ^- (list gill:gall) - [[our %dojo] [our %chat-cli]~] -:: ++ en-gill :: gill to wire |= gyl=gill:gall ^- wire @@ -139,7 +92,7 @@ ++ this . +$ state ^state :: proxy +$ any-state ^any-state :: proxy -++ on-init se-abet:this(eel (deft-fish our.hid)) +++ on-init (poke-link our.hid %dojo) ++ diff-sole-effect-phat :: app event |= [way=wire fec=sole-effect] =< se-abet =< se-view @@ -150,21 +103,10 @@ ++ peer :: |= pax=path ~| [%drum-unauthorized our+our.hid src+src.hid] :: ourself - ?> (team:title our.hid src.hid) :: or our own moon + ?> (team:title our.hid src.hid) :: or our own moon =< se-abet =< se-view (se-text "[{}, driving {}]") :: -++ poke-set-boot-apps :: - |= lit=? - ^- (quip card:agent:gall ^state) - :: We do not run se-abet:se-view here because that starts the apps, - :: and some apps are not ready to start (eg Talk crashes because the - :: terminal has width 0). It appears the first message to drum must - :: be the peer. - :: - =. ray (deft-apes our.hid lit) - [~ sat] -:: ++ poke-dill-belt :: terminal event |= bet=dill-belt:dill =< se-abet =< se-view @@ -174,16 +116,6 @@ |= bit=dill-blit:dill se-abet:(se-blit-sys bit) :: -++ poke-start :: start app - |= wel=well:gall - =< se-abet =< se-view - (se-born & wel) -:: -++ poke-fade :: fade app - |= wel=well:gall - =< se-abet =< se-view - (se-fade wel) -:: ++ poke-link :: connect app |= gyl=gill:gall =< se-abet =< se-view @@ -210,58 +142,19 @@ %drum-exit =;(f (f !<(_+<.f vase)) poke-exit) %drum-link =;(f (f !<(_+<.f vase)) poke-link) %drum-put =;(f (f !<(_+<.f vase)) poke-put) - %drum-set-boot-apps =;(f (f !<(_+<.f vase)) poke-set-boot-apps) - %drum-start =;(f (f !<(_+<.f vase)) poke-start) - %drum-fade =;(f (f !<(_+<.f vase)) poke-fade) %drum-unlink =;(f (f !<(_+<.f vase)) poke-unlink) == :: ++ on-load |= [hood-version=@ud old=any-state] =< se-abet =< se-view + =? old ?=(%2 -.old) [%4 [eel bin]:old] + =? old ?=(%3 -.old) [%4 [eel bin]:old] + :: + ?> ?=(%4 -.old) =. sat old =. dev (~(gut by bin) ost *source) - =? ..on-load (lte hood-version %4) - ~> %slog.0^leaf+"drum: starting os1 agents" - => (se-born | %home %s3-store) - => (se-born | %home %contact-view) - => (se-born | %home %contact-hook) - => (se-born | %home %contact-store) - => (se-born | %home %metadata-hook) - => (se-born | %home %metadata-store) - => (se-born | %home %goad) - ~> %slog.0^leaf+"drum: resubscribing to %dojo and %chat-cli" - => (se-drop:(se-pull our.hid %dojo) | our.hid %dojo) - (se-drop:(se-pull our.hid %chat-cli) | our.hid %chat-cli) - =? ..on-load (lte hood-version %5) - (se-born | %home %file-server) - =? ..on-load (lte hood-version %7) - (se-born | %home %glob) - =? ..on-load (lte hood-version %8) - => (se-born | %home %group-push-hook) - (se-born | %home %group-pull-hook) - =? ..on-load (lte hood-version %9) - (se-born | %home %graph-store) - =? ..on-load (lte hood-version %10) - => (se-born | %home %graph-push-hook) - (se-born | %home %graph-pull-hook) - =? ..on-load (lte hood-version %11) - => (se-born | %home %hark-graph-hook) - => (se-born | %home %hark-group-hook) - => (se-born | %home %hark-chat-hook) - => (se-born | %home %hark-store) - => (se-born | %home %observe-hook) - => (se-born | %home %metadata-pull-hook) - => (se-born | %home %metadata-push-hook) - (se-born | %home %herm) - =? ..on-load (lte hood-version %12) - => (se-born | %home %contact-push-hook) - => (se-born | %home %contact-pull-hook) - => (se-born | %home %settings-store) - (se-born | %home %group-view) - =? ..on-load (lte hood-version %13) - (se-born | %home %dm-hook) - ..on-load + this :: ++ reap-phat :: ack connect |= [way=wire saw=(unit tang)] @@ -274,12 +167,6 @@ :: (se-drop & gyl) :: -++ take-arvo - |= [=wire =sign-arvo] - %+ take-onto wire - ?> ?=(%onto +<.sign-arvo) - +>.sign-arvo -:: ++ take-coup-phat :: ack poke |= [way=wire saw=(unit tang)] =< se-abet =< se-view @@ -290,29 +177,16 @@ :_ u.saw >[%drum-coup-fail src.hid gyl]< :: -++ take-onto :: ack start - |= [way=wire saw=(each suss:gall tang)] - =< se-abet =< se-view - ?> ?=([@ @ ~] way) - ?> (~(has by fur) i.t.way) - =/ wel=well:gall [i.way i.t.way] - ?- saw - [%| *] (se-dump p.saw) - [%& *] ?> =(q.wel p.p.saw) - :: =. +>.$ (se-text "live {}") - +>.$(fur (~(put by fur) q.wel `[p.wel %da r.p.saw])) - == -:: ++ take-agent |= [=wire =sign:agent:gall] - ?+ wire ~|([%drum-bad-take-agent wire -.sign] !!) - [%drum %phat *] + ?+ wire ~|([%drum-bad-take-agent wire -.sign] !!) + [%phat *] ?- -.sign - %poke-ack (take-coup-phat t.t.wire p.sign) - %watch-ack (reap-phat t.t.wire p.sign) - %kick (quit-phat t.t.wire) + %poke-ack (take-coup-phat t.wire p.sign) + %watch-ack (reap-phat t.wire p.sign) + %kick (quit-phat t.wire) %fact - %+ diff-sole-effect-phat t.t.wire + %+ diff-sole-effect-phat t.wire ?> ?=(%sole-effect p.cage.sign) !<(sole-effect q.cage.sign) == @@ -329,7 +203,7 @@ :: :: :: ++ se-abet :: resolve ^- (quip card:agent:gall state) - =. . se-subze:se-adze:se-subit:se-adit + =. . se-subze:se-adze :_ sat(bin (~(put by bin) ost dev)) ^- (list card:agent:gall) ?~ biz (flop moz) @@ -337,72 +211,6 @@ =/ =dill-blit:dill ?~(t.biz i.biz [%mor (flop biz)]) [%give %fact ~[/drum] %dill-blit !>(dill-blit)] :: -++ se-adit :: update servers - ^+ this - |^ - =/ servers=(list well:gall) - (sort ~(tap in ray) sort-by-priorities) - |- - ?~ servers - this - =/ wel=well:gall - i.servers - =/ =wire [%drum p.wel q.wel ~] - =/ hig=(unit (unit server)) - (~(get by fur) q.wel) - ?: &(?=(^ hig) |(?=(~ u.hig) =(p.wel syd.u.u.hig))) - $(servers t.servers) - =. fur - (~(put by fur) q.wel ~) - =. this - (se-text "activated app {(trip p.wel)}/{(trip q.wel)}") - =. this - %- se-emit - [%pass wire %arvo %g %conf q.wel] - $(servers t.servers) - :: - ++ priorities - ^- (list (set @)) - :~ - :: set up stores with priority: depended on, but never depending - %- sy - :~ %chat-store - %contact-store - %group-store - %invite-store - %metadata-store - == - :: ensure chat-cli can sub to invites - :: and file server can receive pokes - (sy ~[%chat-hook %file-server]) - == - ++ sort-by-priorities - =/ priorities priorities - |= [[desk a=term] [desk b=term]] - ^- ? - ?~ priorities - (aor a b) - =* priority i.priorities - ?: &((~(has in priority) a) (~(has in priority) b)) - (aor a b) - ?: (~(has in priority) a) - %.y - ?: (~(has in priority) b) - %.n - $(priorities t.priorities) - -- -:: -++ se-subit :: downdate servers - =/ ruf=(list term) ~(tap in ~(key by fur)) - |- ^+ this - ?~ ruf - this - ?: (~(has in ray) [%home i.ruf]) - $(ruf t.ruf) - =/ wire [%drum %fade i.ruf ~] - =. this (se-emit %pass wire %arvo %g %fade i.ruf %slay) - $(ruf t.ruf, fur (~(del by fur) i.ruf)) -:: ++ se-adze :: update connections ^+ . %+ roll @@ -487,26 +295,6 @@ (se-blit %bel ~) ta-abet:(ta-belt:(se-tame u.gul) bet) :: -++ se-born :: new server - |= [print-on-repeat=? wel=well:gall] - ^+ +> - ?: (~(has in ray) wel) - ?. print-on-repeat +> - (se-text "[already running {}/{}]") - %= +> - ray (~(put in ray) wel) - eel (~(put in eel) [our.hid q.wel]) - == -:: -++ se-fade :: delete server - |= wel=well:gall - ^+ +> - ?. (~(has in ray) wel) - (se-text "[fade not running {}/{}]") - %= +> - ray (~(del in ray) wel) - == -:: ++ se-drop :: disconnect |= [pej=? gyl=gill:gall] ^+ +> @@ -648,6 +436,7 @@ :: ++ se-peer :: send a peer |= gyl=gill:gall + ~> %slog.0^leaf/"drum: link {<[p q]:gyl>}" =/ =path /sole/(cat 3 'drum_' (scot %p our.hid)) %- se-emit(fug (~(put by fug) gyl ~)) [%pass (en-gill gyl) %agent gyl %watch path] @@ -747,7 +536,7 @@ %c ta-bel %d ?^ buf.say.inp ta-del - ?: (~(has in (deft-fish our.hid)) gyl) + ?: =([our.hid %dojo] gyl) +>(..ta (se-blit qit+~)) :: quit pier +>(..ta (se-klin gyl)) :: unlink app %e +>(pos.inp (lent buf.say.inp)) diff --git a/pkg/arvo/lib/hood/helm.hoon b/pkg/arvo/lib/hood/helm.hoon index 0f71669d6..9cee30851 100644 --- a/pkg/arvo/lib/hood/helm.hoon +++ b/pkg/arvo/lib/hood/helm.hoon @@ -1,8 +1,13 @@ /+ pill =* card card:agent:gall |% -+$ any-state $%(state state-0) -+$ state ++$ state state-1 ++$ any-state + $~ *state + $% state-1 + state-0 + == ++$ state-1 $: %1 mass-timer=[way=wire nex=@da tim=@dr] == @@ -222,8 +227,8 @@ ++ take-agent |= [=wire =sign:agent:gall] ?+ wire ~|([%helm-bad-take-agent wire -.sign] !!) - [%helm %hi *] ?> ?=(%poke-ack -.sign) - (coup-hi t.t.wire p.sign) + [%hi *] ?> ?=(%poke-ack -.sign) + (coup-hi t.wire p.sign) == :: ++ take-bound diff --git a/pkg/arvo/lib/hood/kiln.hoon b/pkg/arvo/lib/hood/kiln.hoon index 79b07a668..1c565423c 100644 --- a/pkg/arvo/lib/hood/kiln.hoon +++ b/pkg/arvo/lib/hood/kiln.hoon @@ -1,13 +1,167 @@ -/+ version +/- *hood =, clay =, space:userlib =, format +=* dude dude:gall |% -+$ state [%1 pith-1] ++$ state state-9 ++$ state-9 [%9 pith-9] ++$ state-8 [%8 pith-9] ++$ state-7 [%7 pith-7] ++$ state-6 [%6 pith-6] ++$ state-5 [%5 pith-5] ++$ state-4 [%4 pith-4] ++$ state-3 [%3 pith-3] ++$ state-2 [%2 pith-2] ++$ state-1 [%1 pith-1] ++$ state-0 [%0 pith-0] +$ any-state - $% state - [%0 pith-0] + $~ *state + $% state-9 + state-8 + state-7 + state-6 + state-5 + state-4 + state-3 + state-2 + state-1 + state-0 == +:: ++$ pith-9 + $: wef=(unit weft) + rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ark=(map desk arak) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == +:: ++$ pith-7 + $: wef=(unit weft) + rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ark=(map desk arak-7) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == :: ++$ arak-7 + $: rail=(unit rail-7) + =rein + == +:: ++$ rail-7 + $: paused=? + =ship + =desk + =aeon + next=(list rung) + == +:: ++$ pith-6 + $: wef=(unit weft) + rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ark=(map desk arak-6) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == :: +:: ++$ arak-6 [rail=rail-6 next=(list rung) =rein] ++$ rail-6 [paused=? =ship =desk =aeon] +:: ++$ pith-5 + $: rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ark=(map desk arak-6) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == :: +:: ++$ pith-4 :: + $: rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ark=(map desk arak-4) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == :: ++$ arak-4 + $: =ship + =desk + =aeon + next=(list rung) + =rein + == ++$ pith-3 :: + $: rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ark=(map desk arak-3) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + :: map desk to the currently ongoing fuse request + :: and the latest version numbers for beaks to + fus=(map desk per-fuse) + :: used for fuses - every time we get a fuse we + :: bump this. used when calculating hashes to + :: ensure they're unique even when the same + :: request is made multiple times. + hxs=(map desk @ud) + == ++$ arak-3 + $: =ship + =desk + =aeon + next=(list rung) + rein=rein-3 + == ++$ rein-3 + $: add=(set dude) + sub=(set dude) + == +:: ++$ pith-2 :: + $: rem=(map desk per-desk) :: + syn=(map kiln-sync let=@ud) :: + ota=(unit [=ship =desk =aeon]) :: + commit-timer=[way=wire nex=@da tim=@dr mon=term] :: + fus=(map desk per-fuse) + hxs=(map desk @ud) + == :: +$ pith-1 :: $: rem=(map desk per-desk) :: syn=(map kiln-sync let=@ud) :: @@ -31,6 +185,15 @@ sud=@tas :: from desk cas=case :: at case == ++$ per-fuse :: per fuse state + :: map [ship desk] to latest version number we + :: have for them. used for things we're %trak-ing + :: our invariant here is to store the latest version + :: number we've heard of. + $: mox=(map [ship desk] let=@ud) + :: relevant parts of originating request + kf=kiln-fuse-data + == +$ kiln-commit term :: +$ kiln-mount :: $: pax=path :: @@ -38,14 +201,14 @@ == +$ kiln-unmount $@(term [knot path]) :: +$ kiln-sync :: - $: syd=desk :: - her=ship :: - sud=desk :: + $: syd=desk :: local desk + her=ship :: foreign ship + sud=desk :: foreign desk == +$ kiln-unsync :: - $: syd=desk :: - her=ship :: - sud=desk :: + $: syd=desk :: local desk + her=ship :: foreign ship + sud=desk :: foreign desk == +$ kiln-merge :: $@ ~ @@ -55,18 +218,32 @@ cas=case :: gim=?(%auto germ) :: == ++$ fuse-source [who=ship des=desk ver=$@(%trak case)] +:: actual poke +$ kiln-fuse $@ ~ $: syd=desk - bas=beak - con=(list [beak germ]) + $@ ~ :: signifies clearing the fuse + $: overwrite=flag :: force overwrite previous fuse + bas=fuse-source + con=(list [fuse-source germ]) + == == +:: state tracked by kiln ++$ kiln-fuse-data + $: syd=desk + bas=fuse-source + con=(list [fuse-source germ]) + == +:: Request to list current fuses. ~ means "list all" +:: ++$ kiln-fuse-list (unit desk) -- |= [bowl:gall state] ?> =(src our) -|_ moz=(list card:agent:gall) -+$ state ^state :: proxy -+$ any-state ^any-state :: proxy +=| moz=(list card:agent:gall) +|% +++ kiln . ++ abet :: resolve [(flop moz) `state`+<+.$] :: @@ -78,61 +255,833 @@ |= (list card:agent:gall) ^+ +> ?~(+< +> $(+< t.+<, +> (emit i.+<))) +:: +fmt: format string for slogging +:: +++ fmt + |= mes=tape + [%0 %leaf (weld "kiln: " mes)] :: ++ render |= [mez=tape sud=desk who=ship syd=desk] :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) ~[leaf+"from {}" leaf+"on {}" leaf+"to {}"] :: -++ on-load - |= [hood-version=@ud old=any-state] +++ on-init =< abet - =? . ?=(%0 -.old) - =/ recognized-ota=(unit [syd=desk her=ship sud=desk]) - =/ syncs=(list [[syd=desk her=ship sud=desk] =aeon]) - ~(tap by syn.old) - |- ^- (unit [syd=desk her=ship sud=desk]) - ?~ syncs - ~ - ?: &(=(%base syd.i.syncs) !=(our her.i.syncs) =(%kids sud.i.syncs)) - `[syd her sud]:i.syncs - $(syncs t.syncs) - :: - =. +<+.$.abet - =- old(- %1, |3 [ota=~ commit-timer.old], syn -) - ?~ recognized-ota - syn - (~(del by syn) [syd her sud]:u.recognized-ota) - :: - =? ..abet ?=(^ recognized-ota) - (poke-internal:update `[her sud]:u.recognized-ota) - +(old +<+.$.abet) + ~> %slog.(fmt "boot") :: - ?> ?=(%1 -.old) - =. +<+.$.abet old - ..abet + =+ .^(desks=(set desk) %cd /(scot %p our)//(scot %da now)) + =. desks (~(del in desks) %base) + =. desks (~(del in desks) %kids) + :: + =/ sop=ship (sein:title our now our) + :: set up base desk + :: + =. ..on-init abet:(install-local:vats %base) + =? ..on-init ?=(?(%earl %duke %king) (clan:title our)) + abet:(install:vats %base sop %kids) + :: + :: watch for gall reloading + =. ..on-init abet:gall-lyv:vats + :: install other desks and make them public + :: + =/ dez=(list desk) ~(tap in desks) + |- ^+ ..on-init + ?~ dez ..on-init + =. ..on-init + abet:(install-local:vats i.dez) + =. ..on-init + %- emit + :^ %pass /kiln/permission %arvo + [%c %perm i.dez / %r `[%black ~]] + =/ src (get-publisher our i.dez now) + =? ..on-init &(?=(^ src) !=(our u.src)) + abet:(install:vats i.dez u.src i.dez) + $(dez t.dez) +:: +++ on-load + => |% + +$ ota [syd=desk her=ship sud=desk] + -- + =| old-ota=(unit ota) + |= [hood-version=@ud old=any-state] + =/ old-version -.old + =* state +<+.$.abet + :: + =? old-ota ?=(%0 -.old) + =/ syncs=(list [ota =aeon]) ~(tap by syn.old) + |- ^- (unit ota) + ?~ syncs + ~ + ?: &(=([%base %kids] [syd sud]:i.syncs) !=(our her.i.syncs)) + `[syd her sud]:i.syncs + $(syncs t.syncs) + :: + =? old ?=(%0 -.old) + =? syn.old ?=(^ old-ota) (~(del by syn.old) u.old-ota) + [%3 [rem syn ark=~ commit-timer fus=~ hxs=~]:old] + :: + =? old ?=(%1 -.old) + :* %2 + rem.old + syn.old + ota.old + commit-timer.old + fus=~ + hxs=~ + == + :: + =? old-ota ?=(%2 -.old) + ?~ ota.old ~ + `[%base ship desk]:u.ota.old + :: + =? old ?=(%2 -.old) + :* %3 + rem.old + syn.old + ark=~ + commit-timer.old + fus.old + hxs.old + == + :: + =? old ?=(%3 -.old) + :- %4 + +.old(ark (~(run by ark.old) |=(a=arak-3 a(rein [liv=& rein.a])))) + :: + =? old ?=(%4 -.old) + :- %5 + =- +.old(ark -) + %- ~(run by ark.old) + |= a=arak-4 + ^- arak-6 + [[paused=| ship desk aeon] next rein]:a + :: + =? old ?=(%5 -.old) + [%6 ~ +.old] + :: + =? old ?=(%6 -.old) + :- %7 + =- +.old(ark -) + %- ~(run by ark.old) + |= a=arak-6 + ^- arak-7 + :_ rein.a + ^- (unit rail-7) + `[paused.rail ship.rail desk.rail aeon.rail next]:a + :: + =? old ?=(%7 -.old) + :- %8 + =- +.old(ark -) + %- ~(gas by *(map desk arak)) + %+ turn ~(tap by ark.old) + |= [d=desk a=arak-7] + ^- [desk arak] + :- d + :_ rein.a + ?~ rail.a ~ + `[(get-publisher our d now) u.rail.a] + :: + =? old ?=(%8 -.old) + [%9 +.old] + :: + ?> ?=(%9 -.old) + =. state old + :: + =? kiln (lth old-version %7) + abet:(install:vats %base our %base) + =? kiln ?=(^ old-ota) + abet:(install:vats %base [her sud]:u.old-ota) + =? kiln (lth old-version %7) + abet:gall-lyv:vats + :: kiln %7 had a bug where it failed to properly emit a +listen + :: due to an unexpected crash. here we detect the cause of the crash + :: (not-yet-installed desks) and emit the +listen anew to make sure we + :: stay aware of commits to base. + :: + =? kiln + ?& =(%8 old-version) + :: + %+ lien ~(tap by ark.old) + |= [d=desk *] + =- =(0 rev) + .^([rev=@ud @da] %cw /(scot %p our)/[d]/(scot %da now)) + == + take-commit:(abed:vats %base) + =? kiln ?=(^ wef) + =/ except=(set desk) (sy %base %kids ~) + (bump:vats u.wef except force=%.n) + =. wef ~ + abet:kiln :: ++ on-peek |= =path ^- (unit (unit cage)) ?+ path [~ ~] - [%x %kiln %ota ~] ``noun+!>(ota) + [%x %kiln %lag ~] ``loob+!>(.^(? //(scot %p our)//(scot %da now)/zen/lag)) + :: + [%x %kiln %vat @ ~] + =* loc i.t.t.t.path + =/ ego (scot %p our) + =/ wen (scot %da now) + =/ rak=(unit arak) (~(get by ark) loc) + ?~ rak [~ ~] + =/ hog .^(@uv cz+~[ego loc wen]) + =/ cas .^(cass cw+~[ego loc wen]) + :^ ~ ~ %noun + !> ^- vat + [loc hog cas u.rak] + :: + [%x %kiln %vats ~] + :^ ~ ~ %kiln-vats + !> ^- (list vat) + =/ ego (scot %p our) + =/ wen (scot %da now) + %+ turn ~(tap by ark) + |= [loc=desk rak=arak] + =/ hog .^(@uv cz+~[ego loc wen]) + =/ cas .^(cass cw+~[ego loc wen]) + [loc hog cas rak] + :: + [%x %kiln %ark ~] ``noun+!>(ark) [%x %kiln %our ~] ``noun+!>(our) [%x %kiln %base-hash ~] - =/ ver (base-hash:version our now) + =/ ver (mergebase-hashes our %base now (~(got by ark) %base)) ``noun+!>(?~(ver 0v0 i.ver)) == :: -++ poke-commit - |= [mon=kiln-commit auto=?] - =< abet - =. +>.$ (emit %pass /commit %arvo %c [%dirk mon]) - ?. auto - +>.$ - =/ recur ~s1 - =. commit-timer - [/kiln/autocommit (add now recur) recur mon] - (emit %pass way.commit-timer %arvo %b [%wait nex.commit-timer]) +++ vats + |_ [loc=desk rak=arak] + ++ ral (need rail.rak) + ++ vats . + ++ abet + ~| [%uninitialized-desk loc] + ?< =(%$ loc) + kiln(ark (~(put by ark) loc rak)) + ++ abed + |= lac=desk + ~_ leaf/"kiln: {} not installed" + vats(loc lac, rak (~(got by ark) lac)) + :: + ++ here ?~ rail.rak "{} (local)" + "{} from {<[ship desk]:ral>}" + ++ make-wire |=(step=@tas /kiln/vats/[loc]/[step]) + ++ from-wire + |= =wire + ~| wire + ?> ?=([@ @ *] wire) + (abed i.wire) + :: + ++ emit |=(card:agent:gall vats(kiln (^emit +<))) + ++ emil |=((list card:agent:gall) vats(kiln (^emil +<))) + ++ give + |% + ++ snap [%give %fact ~[/kiln/vats] %kiln-vats-snap-0 !>(ark)] + ++ diff |=(d=^diff [%give %fact ~[/kiln/vats] %kiln-vats-diff-0 !>(d)]) + -- + ++ pass + |% + ++ pyre |=(=tang [%pass /kiln/vats %pyre tang]) + ++ find (warp %find [%sing %y ud+1 /]) + ++ sync-da (warp %sync [%sing %w da+now /]) + ++ sync-ud (warp %sync [%sing %w ud+aeon:ral /]) + ++ download (warp %download [%sing %v ud+aeon:ral /]) + ++ gall-lyv + =/ paths=(set [care:clay path]) + %- sy + :~ [%z /sys/hoon/hoon] + [%z /sys/arvo/hoon] + [%z /sys/lull/hoon] + [%z /sys/zuse/hoon] + [%z /sys/vane/gall/hoon] + == + %+ clay-card %gall-lyv + [%warp our %base ~ %mult da+now paths] + :: + ++ warp + |= [s=term r=rave] + (clay-card s %warp ship:ral desk:ral `r) + ++ merge-main + =/ germ (get-germ loc) + =/ =aeon (dec aeon:ral) + %+ clay-card %merge-main + [%merg loc ship:ral desk:ral ud+aeon germ] + ++ merge-kids + =/ germ (get-germ %kids) + =/ =aeon (dec aeon:ral) + %+ clay-card %merge-kids + [%merg %kids ship:ral desk:ral ud+aeon germ] + ++ listen + (clay-card %listen %warp our loc `[%next %z da+now /]) + ++ clay-card + |= [step=@tas =task:clay] + ^- card:agent:gall + [%pass (make-wire step) %arvo %c task] + ++ start-dude + |= =dude + ^- card:agent:gall + [%pass /kiln/vats/[loc]/jolt/[dude] %arvo %g %jolt loc dude] + ++ stop-dude + |= =dude + ^- card:agent:gall + [%pass /kiln/vats/[loc]/uninstall %arvo %g %idle dude] + -- + :: +uninstall: stop tracking apps on desk, and suspend apps + :: + ++ uninstall + |= lac=desk + ^+ kiln + ?: =(%base lac) + =- (^emit (pyre:pass leaf/- ~)) + "kiln: |uninstall: %base cannot be uninstalled" + ?. (~(has by ark) lac) + ~> %slog.(fmt "|uninstall: {} not installed, ignoring") + kiln + =. vats (abed lac) + ~> %slog.(fmt "uninstalling {here}") + =. vats stop-agents + kiln(ark (~(del by ark) lac)) + :: +install: set up desk sync to .lac to install all apps from [her rem] + :: + ++ install + |= [lac=desk her=ship rem=desk] + ^+ vats + =. loc lac + ?: =([her rem] [our lac]) + (install-local lac) + =/ got (~(get by ark) lac) + ?: =(`[her rem] got) + =. rak (need got) + ~> %slog.(fmt "already tracking {here:(abed lac)}, ignoring") + vats + =. rak [`[~ paused=| her rem *aeon next=~] rein:(fall got *arak)] + ~> %slog.(fmt "beginning install into {here}") + (emil find:pass listen:pass ~) + :: +install-local: install from a local desk, with no remote + :: + :: Also notify clients that the desk was installed. + :: + ++ install-local + |= lac=desk + ^+ vats + |^ ^+ vats + ?. (~(has by ark) lac) + go + =. vats (abed lac) + ?^ rail.rak + go + ~> %slog.(fmt "{} already installed locally, refreshing") + update-running-dudes + :: + ++ go + =. loc lac + =. rak *arak + ~> %slog.(fmt "installing {} locally") + =. vats update-running-dudes + (emil listen:pass (diff:give %commit lac rak) ~) + -- + :: +reset: resync after failure + :: + :: TODO: instead of jumping all the way back to find:pass, + :: which will end up skipping all the way until the latest + :: remote commit, increment the aeon so we skip only the problematic + :: commit and try the commit immediately after it. + :: + ++ reset + ^+ vats + ~> %slog.(fmt "resetting tracking for {here}") + =/ cad (diff:give %reset loc rak) + =/ rel ral + =. rail.rak `rel(aeon 0, next ~) + (emil find:pass cad ~) + :: +pause: stop syncing from upstream + :: + ++ pause + |= lac=desk + ^+ vats + =. vats (abed lac) + ?. is-tracking + ~> %slog.(fmt "{} already paused, ignoring") + vats + ~> %slog.(fmt "{} pausing updates") + =/ rel ral + =. rail.rak `rel(paused &, aeon 0) + vats + :: + :: +gall-lyv: watch gall source for reloading + ++ gall-lyv + =. vats (abed %base) + (emit gall-lyv:pass) + :: +remove-upstream: stop listening to an upstream for changes + :: + ++ remove-upstream + |= lac=desk + ^+ vats + =. vats (abed lac) + =. rail.rak ~ + vats + :: +resume: restart tracking from upstream + :: + :: TODO: check whether kelvin is legit + :: + ++ resume + |= lac=desk + ^+ vats + =. vats (abed lac) + ~> %slog. %- fmt + ?. paused:ral + "{} already tracking, ignoring" + "{} resuming updates" + =/ rel ral + =. rail.rak `rel(paused |) + reset + :: +suspend: shut down all agents, keep syncing + :: + ++ suspend + |= lac=desk + ^+ vats + =/ got (~(get by ark) lac) + ?: =(%base lac) + =- (emit (pyre:pass leaf/- ~)) + "kiln: suspend: %base cannot be suspended" + ?. (~(has by ark) lac) + ~> %slog.(fmt "suspend: {} not installed, ignoring") + vats + =. vats (abed lac) + =. liv.rein.rak | + =. vats stop-agents + (emit (diff:give %suspend loc rak)) + :: +revive: restart agents on a suspended desk + :: + ++ revive + |= lac=desk + ^+ vats + =. vats (abed lac) + =. liv.rein.rak & + =. vats update-running-dudes + (emit (diff:give %revive loc rak)) + :: +set-rein: adjust which agents are forced on or off + :: + ++ set-rein + |= [lac=desk new=rein] + ^+ vats + =. vats (abed lac) + =^ old rein.rak [rein.rak new] + ?+ [liv.old liv.new] !! + [%| %|] vats + [%| %&] (revive lac) + [%& %|] (suspend lac) + [%& %&] update-running-dudes + == + :: +bump: try to apply kernel kelvin upgrade + :: + :: Apply merges to revive faded agents on all desks. + :: If .force, suspends stale agents. Else, any stale desk + :: will cause a crash. + :: + ++ bump + |= [kel=weft except=(set desk) force=?] + ^+ kiln + =/ ded (find-blocked kel except) + ?: force + =. kiln (suspend-many ded) + (bump-many kel (all-desks-but (~(uni in except) ded))) + ?: =(~ ded) + (bump-many kel (all-desks-but except)) + =- (^emit (pyre:pass leaf/- ~)) + "kiln: desks blocked upgrade to {}: {}" + :: + ++ all-desks-but |=(not=(set desk) (~(dif in ~(key by ark)) not)) + :: + ++ find-blocked + |= [kel=weft except=(set desk)] + ^- (set desk) + (~(dif in (get-blockers kel)) (~(put in except) %base)) + :: + ++ suspend-many + |= dead=(set desk) + ^+ kiln + =/ ded ~(tap in dead) + |- ^+ kiln + ?~ ded kiln + $(ded t.ded, kiln abet:(suspend i.ded)) + :: + ++ bump-many + |= [kel=weft live=(set desk)] + ^+ kiln + :: ensure %base is always reloaded first + :: + =/ liv + %+ sort ~(tap in live) + |= [a=desk b=desk] + ^- ? + ?: =(%base a) & + ?: =(%base b) | + (lte `@`a `@`b) + :: + |- ^+ kiln + ?~ liv kiln + $(liv t.liv, kiln (bump-one kel i.liv)) + :: + ++ bump-one + |= [kel=weft =desk] + ^+ kiln + ~> %slog.(fmt "bump {} to {<[lal num]:kel>}") + =< abet ^+ vats + =. vats (abed desk) + =/ kul (read-kelvin-local our desk now) + ?~ kul + ~> %slog.(fmt "{here} not yet installed") + vats + ?: =(kel u.kul) + ~> %slog.(fmt "{here} already at {<[lal num]:kel>}") + update-running-dudes + =^ tem rail.rak (crank-next %| kel) + ?^ tem + (emit merge-main:pass) + =- (emit (pyre:pass leaf/- ~)) + "kiln: {here} killed upgrade to {<[lal num]:kel>}" + :: +stop-agents: internal helper to suspend agents on .loc + :: + :: Will not shut down %hood or %dojo. + :: + ++ stop-agents + ^+ vats + =/ ded (get-apps-live our loc now) + =. ded (skip ded |=(d=dude ?=(?(%hood %dojo) d))) + (stop-dudes ded) + :: + ++ take + |= [=wire syn=sign-arvo] + ^+ kiln + ?> ?=([@ @ *] wire) + ?: ?=(%jolt i.t.wire) + (take-onto wire syn) + ?: ?=(%listen i.t.wire) + (take-listen wire syn) + =< abet + =. vats (from-wire wire) + ?+ i.t.wire + ~> %slog.(fmt "vats-bad-take {}") + vats + %find (take-find syn) + %sync (take-sync syn) + %download (take-download syn) + %merge-main (take-merge-main syn) + %merge-kids (take-merge-kids syn) + %gall-lyv (take-gall-lyv syn) + == + :: + ++ take-find + |= syn=sign-arvo + ^+ vats + ?> ?=(%writ +<.syn) + ?. is-tracking + vats + ?~ p.syn + ~> %slog.(fmt "cancelled (1) install into {here}, aborting") + vats(ark (~(del by ark) loc)) + ~> %slog.(fmt "activated install into {here}") + (emit sync-da:pass) + :: + ++ take-sync + |= syn=sign-arvo + ^+ vats + ?> ?=(%writ +<.syn) + =* rit u.p.syn + ?. is-tracking + vats + ?~ p.syn + ~> %slog.(fmt "cancelled (1) install into {here}, retrying") + reset + =? rail.rak ?=(%w p.p.rit) `%*(. ral aeon ud:;;(cass:clay q.q.r.rit)) + ~> %slog.(fmt "downloading update for {here}") + (emit download:pass) + :: + ++ take-download + |= syn=sign-arvo + ^+ vats + ?> ?=(%writ +<.syn) + ?. is-tracking + vats + ?~ p.syn + ~> %slog.(fmt "cancelled (2) install into {here}, retrying") + reset + ~> %slog.(fmt "finished downloading update for {here}") + ?. (get-remote-diff our loc now [ship desk aeon]:ral) + ~> %slog.(fmt "remote is identical to {here}, skipping") + =. rail.rak `%*(. ral aeon +(aeon:ral)) + =. vats update-running-dudes + (emil sync-ud:pass (diff:give %commit loc rak) ~) + =/ old-weft `weft`[%zuse zuse] + =/ new-weft + ?: =(our ship:ral) + (need (read-kelvin-local our desk:ral now)) :: TODO error handling + (read-kelvin-foreign [ship desk aeon]:ral) + :: don't try to read from the local desk's bill file if + :: there are no commits to the local desk (aeon 0) + :: + =/ yon =<(ud .^(cass cw+/(scot %p our)/[loc]/(scot %da now))) + =? vats &(liv.rein.rak !=(0 yon)) + %- stop-dudes + =< idle + (adjust-dudes [our loc now] rein.rak) + =. rail.rak `%*(. ral aeon +(aeon:ral)) + |^ ^+ vats + ?: =(%base loc) + do-base + ?: (gth num.new-weft num.old-weft) + kelvin-retreat + ?: =(num.new-weft num.old-weft) + kelvin-same + kelvin-advance + :: + ++ kelvin-retreat + ^+ vats + ~> %slog.(fmt "cannot install {here}, old kelvin {}") + ~> %slog.(fmt "will retry at foreign kelvin {}") + =/ =diff [%block loc rak new-weft blockers=(sy %base ~)] + (emil sync-ud:pass (diff:give diff) ~) + :: + ++ kelvin-advance + ^+ vats + ~> %slog.(fmt "future version {}, enqueueing") + :: retry upgrade if not blocked anymore + =. rail.rak `%*(. ral next (snoc next:ral [(dec aeon:ral) new-weft])) + =. ark (~(put by ark) loc rak) + =/ =diff [%block loc rak new-weft blockers=(sy %base ~)] + =. vats (emil sync-ud:pass (diff:give diff) ~) + =/ base=arak (~(got by ark) %base) + ?~ rail.base + vats + =/ rel u.rail.base + ?. &(?=(^ next.rel) =(~ (get-blockers weft.i.next.rel))) + vats + ~> %slog.(fmt "unblocked system update, updating") + =. kiln (bump-one weft.i.next.rel %base) + vats + :: + ++ kelvin-same + ^+ vats + ~> %slog.(fmt "merging into {here}") + =. rail.rak +:(crank-next %& (dec aeon:ral)) + (emil ~[merge-main sync-ud]:pass) + :: + ++ do-base + ^+ vats + =/ blockers + ?: =(new-weft old-weft) + ~ + (get-blockers new-weft) + :: + ?. =(~ blockers) + ~> %slog.(fmt "OTA blocked on {}") + =. rail.rak + `%*(. ral next (snoc next:ral [(dec aeon:ral) new-weft])) + =/ =diff [%block loc rak new-weft blockers] + (emil sync-ud:pass (diff:give diff) ~) + ~> %slog.(fmt "applying OTA to {here}, kelvin: {}") + =. rail.rak +:(crank-next %& (dec aeon:ral)) + =. wef + ?: =(old-weft new-weft) ~ + `new-weft + (emil ~[merge-main sync-ud]:pass) + -- + :: + ++ take-listen + |= [=wire syn=sign-arvo] + ^+ kiln + ?> ?=([@ %writ ~ *] syn) + =/ lac=desk (head wire) + :: ignore spurious updates from clay on desks we've uninstalled + :: + ?. (~(has by ark) lac) + kiln + =. vats (from-wire wire) + take-commit + :: + ++ take-commit + ^+ kiln + =. kiln + =< abet + ~> %slog.(fmt "commit detected at {here}") + =. rail.rak + ?~ rail.rak ~ + `[(get-publisher our loc now) +.u.rail.rak] + =. vats (emil listen:pass (diff:give %commit loc rak) ~) + ?. liv.rein.rak + ~> %slog.(fmt "{} not running") + vats + update-running-dudes + ?. =(%base loc) + kiln + =/ kel=[@tas @ud] + ?~ rail.rak zuse/zuse + ?~ next.u.rail.rak zuse/zuse + weft.i.next.u.rail.rak + (bump-many kel (all-desks-but (sy %base ~))) + :: + ++ take-merge-main + |= syn=sign-arvo + ^+ vats + ?> ?=(%mere +<.syn) + ?: ?=([%| %ali-unavailable *] p.syn) + =+ "kiln: merge into {here} failed, maybe because sunk; restarting" + %- (slog leaf/- p.p.syn) + =. vats (emit (diff:give %merge-sunk loc rak p.p.syn)) + reset + ?: ?=(%| -.p.syn) + =+ "kiln: merge into {here} failed, waiting for next revision" + %- (slog leaf/- p.p.syn) + =. vats (emit (diff:give %merge-fail loc rak p.p.syn)) + vats + ~> %slog.(fmt "merge into {} succeeded") + ?. =(%base loc) + vats + ~> %slog.(fmt "merging %base into %kids") + (emit merge-kids:pass) + :: + ++ take-merge-kids + |= syn=sign-arvo + ^+ vats + ?> ?=(%mere +<.syn) + ?: ?=([%| %ali-unavailable *] p.syn) + ~> %slog.(fmt "OTA to %kids failed, maybe peer sunk; restarting") + =. vats (emit (diff:give %merge-sunk %kids rak p.p.syn)) + reset + ?- -.p.syn + %& ~> %slog.(fmt "OTA to %kids succeeded") + (emit (diff:give %commit %kids rak)) + %| ~> %slog.(fmt "OTA to %kids failed {}") + (emit (diff:give %merge-fail %kids rak p.p.syn)) + == + :: + ++ take-gall-lyv + |= syn=sign-arvo + ^+ vats + =. vats gall-lyv + =/ vets ~(tap in ~(key by ark)) + |- + ?~ vets vats + =. vats (abed i.vets) + =. vats update-running-dudes + $(vets t.vets) + :: + ++ take-onto + |= [=wire syn=sign-arvo] + ^+ kiln + =/ onto ?>(?=([%gall %onto *] syn) p.syn) + ?- -.onto + %& kiln + %| (mean p.onto) + == + :: + ++ update-running-dudes + ^+ vats + =/ local [our loc now] + =/ dif (adjust-dudes local rein.rak) + =. vats (start-dudes jolt.dif) + =. vats (stop-dudes idle.dif) + vats + :: + ++ start-dudes + |= daz=(list dude) + (emil (turn daz start-dude:pass)) + :: + ++ stop-dudes + |= daz=(list dude) + (emil (turn daz stop-dude:pass)) + :: +crank-next: pop stale items from .next until one matches + :: + ++ crank-next + |= new=(each aeon weft) + ^+ [match=*(unit rung) rail.rak] + ?~ rail.rak + ~| [%no-rail-for desk=loc] + !! + =/ rog next.u.rail.rak + =- [match `u.rail.rak(next next)] + |- ^- [match=(unit rung) next=(list rung)] + ?~ rog [~ next.u.rail.rak] + ?: ?- -.new + %& =(p.new aeon.i.rog) + %| =(p.new weft.i.rog) + == + [`i.rog t.rog] + $(rog t.rog) + :: + ++ is-tracking + ^- ? + ?~ rail.rak | + !paused.u.rail.rak + -- +:: +get-blockers: find desks that would block a kernel update +:: +++ get-blockers + |= kel=weft + ^- (set desk) + %- ~(gas in *(set desk)) + %+ murn ~(tap by ark) + |= [=desk =arak] + ?: =(%base desk) + ~ + ?. liv.rein.arak + ~ + ?: =(`kel (read-kelvin-local our desk now)) + ~ + ?~ rail.arak + `desk + ?: (lien next.u.rail.arak |=([* k=weft] =(k kel))) + ~ + `desk +:: +get-germ: select merge strategy into local desk +:: +:: If destination desk doesn't exist, need a %init merge. If this is +:: its first revision, it probably doesn't have a mergebase yet, so +:: use %take-that. +:: +++ get-germ + |= =desk + =+ .^(=cass:clay %cw /(scot %p our)/[desk]/(scot %da now)) + ?- ud.cass + %0 %init + * %take-that + ::%1 %take-that + ::* %mate + == +:: +++ poke + |= [=mark =vase] + ?+ mark ~|([%poke-kiln-bad-mark mark] !!) + %kiln-autocommit =;(f (f !<(_+<.f vase)) poke-autocommit) + %kiln-bump =;(f (f !<(_+<.f vase)) poke-bump) + %kiln-cancel =;(f (f !<(_+<.f vase)) poke-cancel) + %kiln-cancel-autocommit =;(f (f !<(_+<.f vase)) poke-cancel-autocommit) + %kiln-commit =;(f (f !<(_+<.f vase)) poke-commit) + %kiln-fuse =;(f (f !<(_+<.f vase)) poke-fuse) + %kiln-fuse-list =;(f (f !<(_+<.f vase)) poke-fuse-list) + %kiln-gall-sear =;(f (f !<(_+<.f vase)) poke-gall-sear) + %kiln-info =;(f (f !<(_+<.f vase)) poke-info) + %kiln-install =;(f (f !<(_+<.f vase)) poke-install) + %kiln-label =;(f (f !<(_+<.f vase)) poke-label) + %kiln-merge =;(f (f !<(_+<.f vase)) poke-merge) + %kiln-mount =;(f (f !<(_+<.f vase)) poke-mount) + %kiln-nuke =;(f (f !<(_+<.f vase)) poke-nuke) + %kiln-pause =;(f (f !<(_+<.f vase)) poke-pause) + %kiln-permission =;(f (f !<(_+<.f vase)) poke-permission) + %kiln-resume =;(f (f !<(_+<.f vase)) poke-resume) + %kiln-revive =;(f (f !<(_+<.f vase)) poke-revive) + %kiln-rein =;(f (f !<(_+<.f vase)) poke-rein) + %kiln-rm =;(f (f !<(_+<.f vase)) poke-rm) + %kiln-schedule =;(f (f !<(_+<.f vase)) poke-schedule) + %kiln-suspend =;(f (f !<(_+<.f vase)) poke-suspend) + %kiln-sync =;(f (f !<(_+<.f vase)) poke-sync) + %kiln-syncs =;(f (f !<(_+<.f vase)) poke-syncs) + %kiln-track =;(f (f !<(_+<.f vase)) poke-track) + %kiln-uninstall =;(f (f !<(_+<.f vase)) poke-uninstall) + %kiln-unmount =;(f (f !<(_+<.f vase)) poke-unmount) + %kiln-unsync =;(f (f !<(_+<.f vase)) poke-unsync) + == :: ++ poke-autocommit |= [mon=kiln-commit auto=?] @@ -145,10 +1094,123 @@ [/kiln/autocommit (add now recur) recur mon] (emit %pass way.commit-timer %arvo %b [%wait nex.commit-timer]) :: +++ poke-bump + |= [except=(set desk) force=?] + =/ =arak + (~(got by ark) %base) + =/ kel=weft + ?~ rail.arak zuse+zuse + ?~ next.u.rail.arak zuse+zuse + weft.i.next.u.rail.arak + abet:(bump:vats kel except force) +:: +++ poke-cancel + |= a=@tas + abet:(emit %pass /cancel %arvo %c [%drop a]) +:: ++ poke-cancel-autocommit |= ~ abet:(emit %pass way.commit-timer %arvo %b [%rest nex.commit-timer]) :: +++ poke-commit + |= [mon=kiln-commit auto=?] + =< abet + =. +>.$ (emit %pass /commit %arvo %c [%dirk mon]) + ?. auto + +>.$ + =/ recur ~s1 + =. commit-timer + [/kiln/autocommit (add now recur) recur mon] + (emit %pass way.commit-timer %arvo %b [%wait nex.commit-timer]) +:: +++ poke-fuse-list + => + |% + ++ format-fuse + |= [into=desk pf=per-fuse] + ^- tank + =/ sources=tape + %+ reel + con.kf.pf + |= [[fs=fuse-source g=germ] acc=tape] + ^- tape + :(weld " [" (format-fuse-source fs) " " "]" acc) + :- %leaf + ;: weld + "|fuse {} " + (format-fuse-source bas.kf.pf) + sources + == + :: +format-fuse-source: fuse source -> beak -> path + :: + ++ format-fuse-source + |= fs=fuse-source + ^- tape + =/ bec=beak [who.fs des.fs ?:(?=([%trak] ver.fs) [%tas %track] ver.fs)] + <(en-beam [bec /])> + -- + |= k=kiln-fuse-list + ^+ abet + %. abet + ?~ k + ?~ fus + (slog [leaf+"no ongoing fuses" ~]) + %- slog + %+ roll + ~(tap by `(map desk per-fuse)`fus) + |= [[syd=desk pf=per-fuse] acc=tang] + ^- tang + [(format-fuse syd pf) acc] + =/ pfu=(unit per-fuse) (~(get by fus) u.k) + ?~ pfu + (slog [leaf+"no ongoing fuse for {}" ~]) + (slog [(format-fuse u.k u.pfu) ~]) +:: +++ poke-fuse + |= k=kiln-fuse + ?~ k abet + =/ payload +.k + ?~ payload + :: cancelling an ongoing fuse + %- (slog [leaf+"cancelling fuse into {}" ~]) + =/ f (fuzz syd.k now) + ?~ f + abet + abet:abet:delete:u.f + ?: &(!overwrite.payload (~(has by fus) syd.k)) + ((slog [leaf+"existing fuse into {} - need =overwrite &" ~]) abet) + =. fus (~(put by fus) syd.k [~ [syd.k bas.payload con.payload]]) + =/ old-cnt=@ud (~(gut by hxs) syd.k 0) + =. hxs (~(put by hxs) syd.k +(old-cnt)) + =/ f (fuzz syd.k now) + ?~ f + abet + abet:abet:fuse:u.f +:: +++ poke-gall-sear + |= =ship + abet:(emit %pass /kiln %arvo %g %sear ship) +:: +++ poke-info + |= [mez=tape tor=(unit toro)] + ?~ tor + abet:(spam leaf+mez ~) + abet:(emit:(spam leaf+mez ~) %pass /kiln %arvo %c [%info u.tor]) +:: +++ poke-install + |= [loc=desk her=ship rem=desk] + abet:abet:(install:vats +<) +:: +++ poke-label + |= [syd=desk lab=@tas] + =+ pax=/(scot %p our)/[syd]/[lab] + (poke-info "labeled {(spud pax)}" `[syd %| lab]) +:: +++ poke-merge + |= kiln-merge + ?~ +< abet + abet:abet:(merge:(work syd) ali sud cas gim) +:: ++ poke-mount |= kiln-mount =+ bem=(de-beam pax) @@ -157,6 +1219,81 @@ abet:(spam leaf+- ~) abet:(emit %pass /mount %arvo %c [%mont pot u.bem]) :: +++ poke-nuke + |= [=term desk=?] + =< abet + ?. desk + (emit %pass /nuke %arvo %g [%nuke term]) + %- emil + %+ turn (get-apps-have our term now) + |=([=dude ?] [%pass /nuke %arvo %g [%nuke dude]]) +:: +++ poke-pause + |= =desk + abet:abet:(pause:vats desk) +:: +++ poke-permission + |= [syd=desk pax=path pub=?] + =< abet + %- emit + =/ =rite [%r ~ ?:(pub %black %white) ~] + [%pass /kiln/permission %arvo %c [%perm syd pax rite]] +:: +++ poke-rein + |= [=desk =rein] + abet:abet:(set-rein:vats +<) +:: +++ poke-resume + |= =desk + abet:abet:(resume:vats desk) +:: +++ poke-revive + |= =desk + abet:abet:(revive:vats desk) +:: +++ poke-rm + |= a=path + =+ b=.^(arch %cy a) + ?~ fil.b + =+ ~[leaf+"No such file:" leaf+"{}"] + abet:(spam -) + (poke-info "removed" `(fray a)) +:: +++ poke-schedule + |= [where=path tym=@da eve=@t] + =. where (welp where /sched) + %+ poke-info "scheduled" + =+ old=;;((map @da cord) (fall (file where) ~)) + `(foal where %sched !>((~(put by old) tym eve))) +:: +++ poke-suspend + |= =desk + abet:abet:(suspend:vats desk) +:: +++ poke-sync + |= hos=kiln-sync + ?: (~(has by syn) hos) + abet:(spam (render "already syncing" [sud her syd]:hos) ~) + abet:abet:start-sync:(auto hos) +:: +++ poke-syncs :: print sync config + |= ~ + =< abet %- spam + ?: =(0 ~(wyt by syn)) + [%leaf "no syncs configured"]~ + %+ turn ~(tap in ~(key by syn)) + |=(a=kiln-sync (render "sync configured" [sud her syd]:a)) +:: +++ poke-track + |= hos=kiln-sync + ?: (~(has by syn) hos) + abet:(spam (render "already tracking" [sud her syd]:hos) ~) + abet:abet:start-track:(auto hos) +:: +++ poke-uninstall + |= loc=desk + abet:(uninstall:vats +<) +:: ++ poke-unmount |= mon=kiln-unmount ?^ mon @@ -167,319 +1304,43 @@ abet:(emit %pass /unmount-beam %arvo %c [%ogre [[p q r] s]:u.bem]) abet:(emit %pass /unmount-point %arvo %c [%ogre mon]) :: -++ poke-track :: - |= hos=kiln-sync - ?: (~(has by syn) hos) - abet:(spam (render "already tracking" [sud her syd]:hos) ~) - abet:abet:start-track:(auto hos) -:: -++ update - |% - ++ make-wire - |= =path - ?> ?=(^ ota) - %- welp - :_ path - /kiln/ota/(scot %p ship.u.ota)/[desk.u.ota]/(scot %ud aeon.u.ota) - :: - ++ check-ota - |= =wire - ?~ ota - | - ?& ?=([@ @ @ *] wire) - =(i.wire (scot %p ship.u.ota)) - =(i.t.wire desk.u.ota) - =(i.t.t.wire (scot %ud aeon.u.ota)) - == - :: - ++ render - |= [mez=tape error=(unit (pair term tang))] - %+ spam - ?~ ota - leaf+mez - :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) - ~[leaf+"from {}" leaf+"on {}"] - ?~ error - ~ - [>p.u.error< q.u.error] - :: - ++ render-ket - |= [mez=tape error=(unit (pair term tang))] - ?> ?=(^ ota) - =< ?>(?=(^ ota) .) - %+ spam - :^ %palm [" " ~ ~ ~] leaf+(weld "kiln: " mez) - ~[leaf+"from {}" leaf+"on {}"] - ?~ error - ~ - [>p.u.error< q.u.error] - :: - :: If destination desk doesn't exist, need a %init merge. If this is - :: its first revision, it probably doesn't have a mergebase yet, so - :: use %take-that. - :: - ++ get-germ - |= =desk - =+ .^(=cass:clay %cw /(scot %p our)/[desk]/(scot %da now)) - ?- ud.cass - %0 %init - %1 %take-that - * %mate - == - :: - ++ poke - |= arg=(unit [=ship =desk]) - abet:(poke-internal arg) - :: - ++ poke-internal - |= arg=(unit [=ship =desk]) - ^+ ..abet - =? ..abet =(arg (bind ota |=([=ship =desk =aeon] [ship desk]))) - (render "restarting OTA sync" ~) - =? ..abet ?=(^ ota) - =. ..abet (render-ket "cancelling OTA sync" ~) - ..abet(ota ~) - ?~ arg - ..abet - =. ota `[ship.u.arg desk.u.arg *aeon] - =. ..abet (render "starting OTA sync" ~) - %: emit - %pass (make-wire /find) %arvo %c - %warp ship.u.arg desk.u.arg `[%sing %y ud+1 /] - == - :: - ++ take - |= [=wire =sign-arvo] - ^+ ..abet - ?> ?=(^ ota) - ?. (check-ota wire) - ..abet - ?. ?=([@ @ @ @ *] wire) - ..abet - ?+ i.t.t.t.wire ~&([%strange-ota-take t.t.t.wire] ..abet) - %find (take-find sign-arvo) - %sync (take-sync sign-arvo) - %download (take-download sign-arvo) - %merge-home (take-merge-home sign-arvo) - %merge-kids (take-merge-kids sign-arvo) - == - :: - ++ take-find - |= =sign-arvo - ?> ?=(%writ +<.sign-arvo) - ?> ?=(^ ota) - =. ..abet (render-ket "activated OTA" ~) - %: emit - %pass (make-wire /sync) %arvo %c - %warp ship.u.ota desk.u.ota `[%sing %w da+now /] - == - :: - ++ take-sync - |= =sign-arvo - ?> ?=(%writ +<.sign-arvo) - ?> ?=(^ ota) - ?~ p.sign-arvo - =. ..abet (render-ket "OTA cancelled (1), retrying" ~) - (poke-internal `[ship desk]:u.ota) - =. ..abet (render-ket "downloading OTA update" ~) - =? aeon.u.ota ?=(%w p.p.u.p.sign-arvo) - ud:;;(cass:clay q.q.r.u.p.sign-arvo) - %: emit - %pass (make-wire /download) %arvo %c - %warp ship.u.ota desk.u.ota `[%sing %v ud+aeon.u.ota /] - == - :: - ++ take-download - |= =sign-arvo - ^+ ..abet - ?> ?=(%writ +<.sign-arvo) - ?> ?=(^ ota) - ?~ p.sign-arvo - =. ..abet (render-ket "OTA cancelled (2), retrying" ~) - (poke-internal `[ship desk]:u.ota) - =. ..abet (render-ket "finished downloading OTA" ~) - =. aeon.u.ota +(aeon.u.ota) - =/ =germ (get-germ %home) - =. ..abet (render-ket "applying OTA to %home" ~) - %- emil - :~ :* %pass (make-wire /merge-home) %arvo %c - %merg %home ship.u.ota desk.u.ota ud+(dec aeon.u.ota) germ - == - :* %pass (make-wire /sync) %arvo %c - %warp ship.u.ota desk.u.ota `[%sing %z ud+aeon.u.ota /] - == - == - :: - ++ take-merge-home - |= =sign-arvo - ?> ?=(%mere +<.sign-arvo) - ?> ?=(^ ota) - ?: ?=([%| %ali-unavailable *] p.sign-arvo) - =. ..abet - =/ =tape "OTA to %home failed, maybe because sunk; restarting" - (render-ket tape `p.p.sign-arvo) - (poke-internal `[ship desk]:u.ota) - :: - ?: ?=(%| -.p.sign-arvo) - =/ =tape "OTA to %home failed, waiting for next revision" - (render-ket tape `p.p.sign-arvo) - =. ..abet (render-ket "OTA to %home succeeded" ~) - =. ..abet (render-ket "applying OTA to %kids" ~) - =/ =germ (get-germ %kids) - %: emit - %pass (make-wire /merge-kids) %arvo %c - %merg %kids ship.u.ota desk.u.ota ud+(dec aeon.u.ota) germ - == - :: - ++ take-merge-kids - |= =sign-arvo - ?> ?=(%mere +<.sign-arvo) - ?> ?=(^ ota) - ?: ?=([%| %ali-unavailable *] p.sign-arvo) - =. ..abet - =/ =tape "OTA to %kids failed, maybe because sunk; restarting" - (render-ket tape `p.p.sign-arvo) - (poke-internal `[ship desk]:u.ota) - :: - ?- -.p.sign-arvo - %& (render-ket "OTA to %kids succeeded" ~) - %| (render-ket "OTA to %kids failed" `p.p.sign-arvo) - == - -- -:: -++ poke-sync :: - |= hos=kiln-sync - ?: (~(has by syn) hos) - abet:(spam (render "already syncing" [sud her syd]:hos) ~) - abet:abet:start-sync:(auto hos) -:: -++ ota-info - ?~ ota - "OTAs disabled" - "OTAs enabled from {} on {}" -:: -++ poke-ota-info - |= * - =< abet %- spam - :~ [%leaf ota-info] - [%leaf "use |ota %disable or |ota ~sponsor %kids to reset it"] - == -:: -++ poke-syncs :: print sync config - |= ~ - =< abet %- spam - :- [%leaf ota-info] - ?: =(0 ~(wyt by syn)) - [%leaf "no other syncs configured"]~ - %+ turn ~(tap in ~(key by syn)) - |=(a=kiln-sync (render "sync configured" [sud her syd]:a)) -:: -++ poke-unsync :: +++ poke-unsync |= hus=kiln-unsync ?. (~(has by syn) hus) abet:(spam (render "not syncing" [sud her syd]:hus) ~) %* . abet:abet:stop:(auto hus) syn (~(del by syn) hus) == +:: +peer: handle %watch :: -++ poke-merge :: - |= kiln-merge - ?~ +< abet - abet:abet:(merge:(work syd) ali sud cas gim) -:: -++ poke-fuse - |= k=kiln-fuse - ?~ k abet - abet:(emit [%pass /kiln/fuse/[syd.k] %arvo %c [%fuse syd.k bas.k con.k]]) -:: -++ poke-cancel - |= a=@tas - abet:(emit %pass /cancel %arvo %c [%drop a]) -:: -++ poke-info - |= [mez=tape tor=(unit toro)] - ?~ tor - abet:(spam leaf+mez ~) - abet:(emit:(spam leaf+mez ~) %pass /kiln %arvo %c [%info u.tor]) -:: -++ poke-rm - |= a=path - =+ b=.^(arch %cy a) - ?~ fil.b - =+ ~[leaf+"No such file:" leaf+"{}"] - abet:(spam -) - (poke-info "removed" `(fray a)) -:: -++ poke-label - |= [syd=desk lab=@tas] - =+ pax=/(scot %p our)/[syd]/[lab] - (poke-info "labeled {(spud pax)}" `[syd %| lab]) -:: -++ poke-schedule - |= [where=path tym=@da eve=@t] - =. where (welp where /sched) - %+ poke-info "scheduled" - =+ old=;;((map @da cord) (fall (file where) ~)) - `(foal where %sched !>((~(put by old) tym eve))) -:: -++ poke-permission - |= [syd=desk pax=path pub=?] - =< abet - %- emit - =/ =rite [%r ~ ?:(pub %black %white) ~] - [%pass /kiln/permission %arvo %c [%perm syd pax rite]] -:: -++ poke - |= [=mark =vase] - ?+ mark ~|([%poke-kiln-bad-mark mark] !!) - %kiln-autocommit =;(f (f !<(_+<.f vase)) poke-autocommit) - %kiln-cancel =;(f (f !<(_+<.f vase)) poke-cancel) - %kiln-cancel-autocommit =;(f (f !<(_+<.f vase)) poke-cancel-autocommit) - %kiln-commit =;(f (f !<(_+<.f vase)) poke-commit) - %kiln-gall-sear =;(f (f !<(_+<.f vase)) poke-gall-sear) - %kiln-goad-gall =;(f (f !<(_+<.f vase)) poke-goad-gall) - %kiln-info =;(f (f !<(_+<.f vase)) poke-info) - %kiln-label =;(f (f !<(_+<.f vase)) poke-label) - %kiln-merge =;(f (f !<(_+<.f vase)) poke-merge) - %kiln-fuse =;(f (f !<(_+<.f vase)) poke-fuse) - %kiln-mount =;(f (f !<(_+<.f vase)) poke-mount) - %kiln-ota =;(f (f !<(_+<.f vase)) poke:update) - %kiln-ota-info =;(f (f !<(_+<.f vase)) poke-ota-info) - %kiln-permission =;(f (f !<(_+<.f vase)) poke-permission) - %kiln-rm =;(f (f !<(_+<.f vase)) poke-rm) - %kiln-schedule =;(f (f !<(_+<.f vase)) poke-schedule) - %kiln-sync =;(f (f !<(_+<.f vase)) poke-sync) - %kiln-syncs =;(f (f !<(_+<.f vase)) poke-syncs) - %kiln-track =;(f (f !<(_+<.f vase)) poke-track) - %kiln-unmount =;(f (f !<(_+<.f vase)) poke-unmount) - %kiln-unsync =;(f (f !<(_+<.f vase)) poke-unsync) +++ peer + |= =path + ?> (team:title our src) + ?+ path ~|(kiln-path/path !!) + [%vats ~] + abet(moz :_(moz [%give %fact ~ %kiln-vats-snap-0 !>(ark)])) == :: -++ poke-goad-gall - |= [force=? agent=(unit dude:gall)] - abet:(emit %pass /kiln %arvo %g %goad force agent) -:: -++ poke-gall-sear - |= =ship - abet:(emit %pass /kiln %arvo %g %sear ship) -:: -++ done - |= [way=wire saw=(unit error:ames)] - ~? ?=(^ saw) [%kiln-nack u.saw] - abet -:: ++ take-agent |= [=wire =sign:agent:gall] - ?+ wire ~|([%kiln-bad-take-agent wire -.sign] !!) - [%kiln %fancy *] ?> ?=(%poke-ack -.sign) - (take-coup-fancy t.t.wire p.sign) - [%kiln %spam *] ?> ?=(%poke-ack -.sign) - (take-coup-spam t.t.wire p.sign) + ?+ wire ~|([%kiln-bad-take-agent wire -.sign] !!) + [%fancy *] + ?> ?=(%poke-ack -.sign) + (take-coup-fancy t.wire p.sign) + :: + [%spam *] + ?> ?=(%poke-ack -.sign) + (take-coup-spam t.wire p.sign) + :: + [%link @ ~] + ?> ?=(%poke-ack -.sign) + ~> %slog.(fmt "linked {<`@tas`i.t.wire>} to console") + abet == :: ++ take-arvo |= [=wire =sign-arvo] - ?- wire + ?- wire [%sync %merg *] %+ take-mere-sync t.t.wire ?>(?=(%mere +<.sign-arvo) +>.sign-arvo) [%find-ship *] %+ take-writ-find-ship t.wire @@ -488,7 +1349,22 @@ ?>(?=(%writ +<.sign-arvo) +>.sign-arvo) [%autocommit *] %+ take-wake-autocommit t.wire ?>(?=(%wake +<.sign-arvo) +>.sign-arvo) - [%ota *] abet:(take:update t.wire sign-arvo) + [%vats *] abet:(take:vats t.wire sign-arvo) + [%fuse-request @tas *] + =/ f (fuzz i.t.wire now) + ?~ f + abet + abet:abet:(take:u.f t.t.wire sign-arvo) + [%fuse @tas *] ?> ?=(%mere +<.sign-arvo) + =/ syd=desk i.t.wire + ?. ?=([%| *] +>.sign-arvo) + ?~ p.p.sign-arvo + abet + =/ msg=tape "fuse merge conflict for {}" + %- (slog [leaf+msg >p.p.sign-arvo< ~]) + abet + %- (slog leaf+"failed fuse for {}" p.p.sign-arvo) + abet * ?+ +<.sign-arvo ((slog leaf+"kiln: strange card {<+<.sign-arvo wire>}" ~) abet) @@ -499,6 +1375,11 @@ == == ++ take |=(way=wire ?>(?=([@ ~] way) (work i.way))) :: general handler +++ done + |= [way=wire saw=(unit error:ames)] + ~? ?=(^ saw) [%kiln-nack u.saw] + abet +:: ++ take-mere :: |= [way=wire are=(each (set path) (pair term tang))] ?. ?=([@ ~] way) @@ -567,6 +1448,122 @@ ++ spam |= mes=(list tank) ((slog mes) ..spam) +:: state machine for fuses +:: +++ fuzz + |= [syd=desk now=@da] + =/ pfu=(unit per-fuse) (~(get by fus) syd) + ?~ pfu + ~ + =* kf kf.u.pfu + =* mox mox.u.pfu + =/ should-delete=flag | + %- some + |% + :: finalize + :: + ++ abet + ?: should-delete + ..fuzz(fus (~(del by fus) syd)) + ..fuzz(fus (~(put by fus) syd [mox kf])) + :: + ++ delete + ^+ ..delete + =. should-delete & + ..delete + :: queue moves + :: + ++ blab + |= new=(list card:agent:gall) + ^+ +> + +>.$(moz (welp new moz)) + :: +make-requests: send requests for each %trak source. + :: + ++ make-requests + ^+ ..abet + =/ movs=(list card:agent:gall) + %+ murn + [[bas.kf *germ] con.kf] + |= [fs=fuse-source germ] + ^- (unit card:agent:gall) + ?^ ver.fs + :: static source, don't need to track + ~ + =/ bec=beak (realize-fuse-source fs &) + ?> =(who.fs p.bec) + ?> =(des.fs q.bec) + =/ hax=@ud (mug [kf (~(got by hxs) syd)]) + =/ wir=wire + /kiln/fuse-request/[syd]/(scot %p p.bec)/[q.bec]/(scot %ud hax) + =/ rav=rave [%sing %w r.bec /] + =/ rif=riff [q.bec `rav] + `[%pass wir %arvo %c [%warp who.fs rif]] + :: No need to keep state if all the sources are static + ?~ movs + delete + (blab movs) + :: + ++ send-fuse + ^+ ..abet + =/ bas=beak (realize-fuse-source bas.kf |) + =/ con=(list [beak germ]) + %+ turn + con.kf + |= [fs=fuse-source g=germ] + [(realize-fuse-source fs |) g] + %- blab + [%pass /kiln/fuse/[syd] %arvo %c [%fuse syd bas con]]~ + :: + ++ fuse + ^+ ..abet + send-fuse:make-requests + :: + ++ take + |= [wir=wire =sign-arvo] + ^+ ..fuse + ?> =((lent wir) 3) + =/ who=ship (slav %p (snag 0 wir)) + =/ src=desk (snag 1 wir) + =/ hax=@ud (slav %ud (snag 2 wir)) + ?. =(hax (mug [kf (~(got by hxs) syd)])) + :: If the hash in the wire doesn't match the current request + :: this is a response for a previous fuse that we can ignore. + ..take + ?> ?=([?(%clay %behn) %writ *] sign-arvo) + =/ gif +.sign-arvo + ?~ p.gif + %- (slog leaf+"|fuse request failed for {} on - cancelling") + delete + =/ cas=cass:clay !<(cass:clay +.r.u.p.gif) + =. mox (~(put by mox) [who src] ud.cas) + fuse + :: + :: utility functions below + :: + :: +realize-fuse-source: convert a fuse-source to a + :: fully realized beak. + :: + ++ realize-fuse-source + |= [fs=fuse-source incr=flag] + ^- beak + :+ who.fs + des.fs + ?@ ver.fs + (realize-case [who.fs des.fs incr]) + `case`ver.fs + :: + ++ realize-case + |= [who=ship des=desk incr=flag] + ^- case + =/ let=(unit @ud) (~(get by mox) [who des]) + ^- case + ?~ let + da+now + :- %ud + ?: incr + +(u.let) + u.let + -- :: ++ auto |= kiln-sync diff --git a/pkg/arvo/lib/jose.hoon b/pkg/arvo/lib/jose.hoon deleted file mode 100644 index e2f77e8c5..000000000 --- a/pkg/arvo/lib/jose.hoon +++ /dev/null @@ -1,214 +0,0 @@ -/+ primitive-rsa, *pkcs -=* rsa primitive-rsa -|% -:: +en-base64url: url-safe base64 encoding, without padding -:: -++ en-base64url - ~(en base64:mimes:html | &) -:: +de-base64url: url-safe base64 decoding, without padding -:: -++ de-base64url - ~(de base64:mimes:html | &) -:: |octn: encode/decode unsigned atoms as big-endian octet stream -:: -++ octn - |% - ++ en |=(a=@u `octs`[(met 3 a) (swp 3 a)]) - ++ de |=(a=octs `@u`(rev 3 p.a q.a)) - -- -:: +eor: explicit sort order comparator -:: -:: Lookup :a and :b in :lit, and pass their indices to :com. -:: -++ eor - |= [com=$-([@ @] ?) lit=(list)] - |= [a=* b=*] - ^- ? - (fall (bind (both (find ~[a] lit) (find ~[b] lit)) com) |) -:: +en-json-sort: json encoding with sorted object keys -:: -:: XX move %zuse with sorting optional? -:: -++ en-json-sort :: XX rename - |^ |=([sor=$-(^ ?) val=json] (apex val sor "")) - :: :: ++apex:en-json:html - ++ apex - =, en-json:html - |= [val=json sor=$-(^ ?) rez=tape] - ^- tape - ?~ val (weld "null" rez) - ?- -.val - %a - :- '[' - =. rez [']' rez] - !. - ?~ p.val rez - |- - ?~ t.p.val ^$(val i.p.val) - ^$(val i.p.val, rez [',' $(p.val t.p.val)]) - :: - %b (weld ?:(p.val "true" "false") rez) - %n (weld (trip p.val) rez) - %s - :- '"' - =. rez ['"' rez] - =+ viz=(trip p.val) - !. - |- ^- tape - ?~ viz rez - =+ hed=(jesc i.viz) - ?: ?=([@ ~] hed) - [i.hed $(viz t.viz)] - (weld hed $(viz t.viz)) - :: - %o - :- '{' - =. rez ['}' rez] - =/ viz - %+ sort ~(tap by p.val) - |=((pair) (sor (head p) (head q))) - ?~ viz rez - !. - |- ^+ rez - ?~ t.viz ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)]) - =. rez [',' $(viz t.viz)] - ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)]) - == - -- -:: %/lib/jose -:: -:: |jwk: json representations of cryptographic keys (rfc7517) -:: -:: Url-safe base64 encoding of key parameters in big-endian byte order. -:: RSA-only for now -:: -++ jwk - |% - :: |en:jwk: encoding of json cryptographic keys - :: - ++ en - => |% - :: +numb:en:jwk: base64-url encode big-endian number - :: - ++ numb (corl en-base64url en:octn) - -- - |% - :: +pass:en:jwk: json encode public key - :: - ++ pass - |= k=key:rsa - ^- json - [%o (my kty+s+'RSA' n+s+(numb n.pub.k) e+s+(numb e.pub.k) ~)] - :: +ring:en:jwk: json encode private key - :: - ++ ring - |= k=key:rsa - ^- json - ~| %rsa-need-ring - ?> ?=(^ sek.k) - :- %o %- my :~ - kty+s+'RSA' - n+s+(numb n.pub.k) - e+s+(numb e.pub.k) - d+s+(numb d.u.sek.k) - p+s+(numb p.u.sek.k) - q+s+(numb q.u.sek.k) - == - -- - :: |de:jwk: decoding of json cryptographic keys - :: - ++ de - =, dejs-soft:format - => |% - :: +numb:de:jwk: parse base64-url big-endian number - :: - ++ numb (cu (cork de-base64url (lift de:octn)) so) - -- - |% - :: +pass:de:jwk: decode json public key - :: - ++ pass - %+ ci - =/ a (unit @ux) - |= [kty=@t n=a e=a] - ^- (unit key:rsa) - =/ pub (both n e) - ?~(pub ~ `[u.pub ~]) - (ot kty+(su (jest 'RSA')) n+numb e+numb ~) - :: +ring:de:jwk: decode json private key - :: - ++ ring - %+ ci - =/ a (unit @ux) - |= [kty=@t n=a e=a d=a p=a q=a] - ^- (unit key:rsa) - =/ pub (both n e) - =/ sek :(both d p q) - ?:(|(?=(~ pub) ?=(~ sek)) ~ `[u.pub sek]) - (ot kty+(su (jest 'RSA')) n+numb e+numb d+numb p+numb q+numb ~) - -- - :: |thumb:jwk: "thumbprint" json-encoded key (rfc7638) - :: - ++ thumb - |% - :: +pass:thumb:jwk: thumbprint json-encoded public key - :: - ++ pass - |= k=key:rsa - (en-base64url 32 (shax (crip (en-json-sort aor (pass:en k))))) - :: +ring:thumb:jwk: thumbprint json-encoded private key - :: - ++ ring !! - -- - -- -:: |jws: json web signatures (rfc7515) -:: -:: Note: flattened signature form only. -:: -++ jws - |% - :: +sign:jws: sign json value - :: - ++ sign - |= [k=key:rsa pro=json lod=json] - |^ ^- json - =. pro header - =/ protect=cord (encode pro) - =/ payload=cord (encode lod) - :- %o %- my :~ - protected+s+protect - payload+s+payload - signature+s+(sign protect payload) - == - :: +header:sign:jws: set signature algorithm in header - :: - ++ header - ?> ?=([%o *] pro) - ^- json - [%o (~(put by p.pro) %alg s+'RS256')] - :: +encode:sign:jws: encode json for signing - :: - :: Alphabetically sort object keys, url-safe base64 encode - :: the serialized json. - :: - ++ encode - |= jon=json - %- en-base64url - %- as-octt:mimes:html - (en-json-sort aor jon) - :: +sign:sign:jws: compute signature - :: - :: Url-safe base64 encode in big-endian byte order. - :: - ++ sign - |= [protect=cord payload=cord] - =/ msg=@t (rap 3 ~[protect '.' payload]) - =/ sig=@ud (~(sign rs256 k) (met 3 msg) msg) - =/ len=@ud (met 3 n.pub.k) - (en-base64url len (rev 3 len sig)) - -- - :: +verify:jws: verify signature - :: - ++ verify !! - -- --- diff --git a/pkg/arvo/lib/jose.hoon b/pkg/arvo/lib/jose.hoon new file mode 120000 index 000000000..6bff549ab --- /dev/null +++ b/pkg/arvo/lib/jose.hoon @@ -0,0 +1 @@ +../../base-dev/lib/jose.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/json/rpc.hoon b/pkg/arvo/lib/json/rpc.hoon index cd4b3c1a5..4a88e5a05 100644 --- a/pkg/arvo/lib/json/rpc.hoon +++ b/pkg/arvo/lib/json/rpc.hoon @@ -40,9 +40,7 @@ %batch a+(turn bas.response response-to-json) :: %result - :- %o - %- molt - ^- (list [@t json]) + %- pairs:enjs:format :: FIXME: return 'id' as string, number or NULL :: :~ ['jsonrpc' s+'2.0'] @@ -51,18 +49,20 @@ == :: %error - :- %o - %- molt - ^- (list [@t json]) + =, enjs:format + %- pairs :~ ['jsonrpc' s+'2.0'] ['id' ?~(id.response ~ s+id.response)] - ['code' n+code.response] - ['message' s+message.response] - == + :: + :- 'error' + %- pairs + :~ ['code' n+code.response] + ['message' s+message.response] + == == == :: ++ validate-request - |= [body=(unit octs) parse-method=$-(@t term)] + |= body=(unit octs) ^- (unit batch-request) ?~ body ~ ?~ jon=(de-json:html q.u.body) ~ @@ -76,7 +76,7 @@ :: ['id' so] ['jsonrpc' (su (jest '2.0'))] - ['method' (cu parse-method so)] + ['method' so] :: :- 'params' |= =json @@ -96,5 +96,6 @@ ++ params [%error id '-32602' 'Invalid params'] ++ internal [%error id '-32603' 'Internal error'] ++ not-found [%error id '-32000' 'Resource not found'] + ++ todo [%error id '-32001' 'Method not implemented'] -- -- diff --git a/pkg/arvo/lib/keygen.hoon b/pkg/arvo/lib/keygen.hoon deleted file mode 100644 index b4c0a6e20..000000000 --- a/pkg/arvo/lib/keygen.hoon +++ /dev/null @@ -1,112 +0,0 @@ -:: urbit-style key generation and derivation functions -:: -/- keygen -:: -/+ ethereum, bip32, bip39 -:: -=, keygen -:: -|% -++ argon2u - |= [who=ship tic=byts] - ^- @ - ~| [%who who (met 3 who)] - :: ?> (lte (met 3 who) 4) - %- (argon2-urbit:argon2:crypto 32) - :- tic - =- [(met 3 -) (swp 3 -)] - %- crip - (weld "urbitkeygen" (a-co:co who)) -:: -++ child-node-from-seed - |= [seed=@ typ=tape pass=(unit @t)] - ^- node - =+ sed=(seed:ds 32^seed typ) - =+ nom=(from-entropy:bip39 32^sed) - :+ typ nom - %- wallet:ds - %+ to-seed:bip39 nom - (trip (fall pass '')) -:: -++ derive-network-seed - |= [mngs=@ rev=@ud] - ^- @ux - =+ (seed:ds 64^mngs (weld "network" (a-co:co rev))) - ?: =(0 rev) - - :: hash again to prevent length extension attacks - (sha-256l:sha 32 -) -:: -++ ownership-wallet-from-ticket - |= [who=ship ticket=byts pass=(unit @t)] - ^- node - =+ master-seed=(argon2u who ticket) - (child-node-from-seed master-seed "ownership" pass) -:: -++ full-wallet-from-ticket - :: who: username - :: ticket: password - :: rev: network key revision - :: pass: optional passphrase - :: - |= [who=ship ticket=byts rev=@ud pass=(unit @t)] - ^- vault - =+ master-seed=(argon2u who ticket) - =/ cn :: child node - |= typ=nodetype - (child-node-from-seed master-seed typ pass) - :: - :- ^= ownership ^- node - (cn "ownership") - :: - :- ^= voting ^- node - (cn "voting") - :: - =/ management=node - (cn "management") - :- management=management - :: - :- ^= transfer ^- node - (cn "transfer") - :: - :- ^= spawn ^- node - (cn "spawn") - :: - ^= network ^- uode - =/ mad :: management seed - %+ to-seed:bip39 - seed:management - (trip (fall pass '')) - =+ sed=(derive-network-seed mad rev) - [rev sed (urbit:ds sed)] -:: -++ ds :: derive from raw seed - |% - ++ wallet - |= seed=@ - ^- ^wallet - =+ => (from-seed:bip32 64^seed) - (derive-path "m/44'/60'/0'/0/0") - :+ [public-key private-key] - (address-from-prv:key:ethereum private-key) - chain-code - :: - ++ urbit - |= seed=@ - ^- edkeys - =+ =< [pub=pub:ex sec=sec:ex] - (pit:nu:crub:crypto 256 seed) - :- ^= auth - :- (rsh 3 (end [3 33] pub)) - (rsh 3 (end [3 33] sec)) - ^= crypt - :- (rsh [3 33] pub) - (rsh [3 33] sec) - :: - ++ seed - |= [seed=byts salt=tape] - ^- @ux - %- sha-256l:sha - :- (add wid.seed (lent salt)) - (cat 3 (crip (flop salt)) dat.seed) - -- --- diff --git a/pkg/arvo/lib/keygen.hoon b/pkg/arvo/lib/keygen.hoon new file mode 120000 index 000000000..8557d0c52 --- /dev/null +++ b/pkg/arvo/lib/keygen.hoon @@ -0,0 +1 @@ +../../base-dev/lib/keygen.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/language-server/build.hoon b/pkg/arvo/lib/language-server/build.hoon deleted file mode 100644 index 015f37b88..000000000 --- a/pkg/arvo/lib/language-server/build.hoon +++ /dev/null @@ -1,61 +0,0 @@ -/- *language-server -:: -|% -++ parse-error - |= =tape - ^- (unit [=path =range]) - =/ parse-pair - %+ cook - |=([row=@ud col=@ud] [(dec row) col]) - (ifix [sel ser] ;~((glue ace) dem dem)) - =/ parse-path - %+ cook - |=(p=path (slag 3 p)) - (ifix [fas (jest '::')] (more fas urs:ab)) - =/ parse-full - ;~(plug parse-path ;~(sfix ;~((glue dot) parse-pair parse-pair) gar)) - (rust tape parse-full) -:: -++ get-errors-from-tang - |= [uri=@t =tang] - ^- (list range) - =/ =path - (uri-to-path uri) - %+ murn tang - |= =tank - ^- (unit range) - ?. ?=([%leaf *] tank) - ~ - =/ error - (parse-error p.tank) - ?~ error - ~ - ?: =(path path.u.error) - `range.u.error - ~ -:: -++ uri-to-path - |= uri=@t - ^- path - =/ pier-root=(set cord) - %- sy - ['app' 'gen' 'lib' 'mar' 'ren' 'sur' 'sys' 'test' ~] - =/ path=(list cord) - (parse-uri uri) - |- - ?< ?=(~ path) - ?: (~(has in pier-root) i.path) - `^path`path - $(path t.path) -:: -++ parse-uri - |= uri=@t - =- (fall - /fail) - %+ rush uri - %+ more - ;~(pose (plus fas) dot) - %+ cook - crip - (star ;~(pose col hep alf)) -:: --- diff --git a/pkg/arvo/lib/language-server/build.hoon b/pkg/arvo/lib/language-server/build.hoon new file mode 120000 index 000000000..749928056 --- /dev/null +++ b/pkg/arvo/lib/language-server/build.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/build.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/language-server/complete.hoon b/pkg/arvo/lib/language-server/complete.hoon deleted file mode 100644 index 56b3ca498..000000000 --- a/pkg/arvo/lib/language-server/complete.hoon +++ /dev/null @@ -1,386 +0,0 @@ -/+ language-server-parser -:: Autocomplete for hoon. -:: -=/ debug | -|% -+* option [item] - [term=cord detail=item] -:: -:: Like +rose except also produces line number -:: -++ lily - |* [los=tape sab=rule] - =+ vex=(sab [[1 1] los]) - ?~ q.vex - [%| p=p.vex(q (dec q.p.vex))] - ?. =(~ q.q.u.q.vex) - [%| p=p.vex(q (dec q.p.vex))] - [%& p=p.u.q.vex] -:: -:: Get all the identifiers accessible if this type is your subject. -:: -++ get-identifiers - |= ty=type - %- flop - |- ^- (list (option type)) - ?- ty - %noun ~ - %void ~ - [%atom *] ~ - [%cell *] - %+ weld - $(ty p.ty) - $(ty q.ty) - :: - [%core *] - %- weld - :_ ?. ?=(%gold r.p.q.ty) - ~ - $(ty p.ty) - ^- (list (option type)) - %- zing - %+ turn ~(tap by q.r.q.ty) - |= [term =tome] - %+ turn - ~(tap by q.tome) - |= [name=term =hoon] - ^- (pair term type) - ~| term=term - [name ~(play ~(et ut ty) ~[name] ~)] - :: - [%face *] - ?^ p.ty - ~ - [p.ty q.ty]~ - :: - [%fork *] - %= $ - ty - =/ tines ~(tap in p.ty) - ?~ tines - %void - |- ^- type - ?~ t.tines - i.tines - (~(fuse ut $(tines t.tines)) i.tines) - == - :: - [%hint *] $(ty q.ty) - [%hold *] $(ty ~(repo ut ty)) - == -:: -++ search-exact - |* [sid=term options=(list (option))] - =/ match - %+ skim options - |= [id=cord *] - =(sid id) - ?~ match - ~ - [~ i.match] -:: -:: Get all the identifiers that start with sid. -:: -++ search-prefix - |* [sid=cord ids=(list (option))] - ^+ ids - %+ skim ids - |= [id=cord *] - ^- ?(%.y %.n) - =(sid (end [3 (met 3 sid)] id)) -:: -:: Get the longest prefix of a list of identifiers. -:: -++ longest-match - |= matches=(list (option)) - ^- cord - ?~ matches - '' - =/ n 1 - =/ last (met 3 term.i.matches) - |- ^- term - ?: (gth n last) - term.i.matches - =/ prefix (end [3 n] term.i.matches) - ?: |- ^- ? - ?| ?=(~ t.matches) - ?& =(prefix (end [3 n] term.i.t.matches)) - $(t.matches t.t.matches) - == == - $(n +(n)) - (end [3 (dec n)] term.i.matches) -:: -:: Run +find-type safely, printing the first line of the stack trace on -:: error. -:: -++ find-type-mule - |= [sut=type gen=hoon] - ^- (unit [term type]) - =/ res (mule |.((find-type sut gen))) - ?- -.res - %& p.res - %| ((slog (flop (scag 10 p.res))) ~) - == -:: -:: Get the subject type of the wing where you've put the "magic-spoon". -:: -++ find-type - |= [sut=type gen=hoon] - =* loop $ - |^ - ^- (unit [term type]) - ?- gen - [%cnts [%magic-spoon ~] *] `['' sut] - [%cnts [%magic-spoon @ ~] *] `[i.t.p.gen sut] - [%cnts [%magic-spoon @ *] *] - %= $ - sut (~(play ut sut) wing+t.t.p.gen) - t.p.gen t.p.gen(t ~) - == - :: - [%cnts [%magic-fork @ ~] *] - `['' (~(play ut sut) wing+t.p.gen)] - :: - [^ *] (both p.gen q.gen) - [%brcn *] (grow q.gen) - [%brpt *] (grow q.gen) - [%cnts *] - |- ^- (unit [term type]) - =* inner-loop $ - ?~ q.gen - ~ - %+ replace - loop(gen q.i.q.gen) - |. inner-loop(q.gen t.q.gen) - :: - [%dtkt *] (spec-and-hoon p.gen q.gen) - [%dtls *] loop(gen p.gen) - [%rock *] ~ - [%sand *] ~ - [%tune *] ~ - [%dttr *] (both p.gen q.gen) - [%dtts *] (both p.gen q.gen) - [%dtwt *] loop(gen p.gen) - [%hand *] ~ - [%ktbr *] loop(gen p.gen) - [%ktls *] (both p.gen q.gen) - [%ktpm *] loop(gen p.gen) - [%ktsg *] loop(gen p.gen) - [%ktwt *] loop(gen p.gen) - [%note *] loop(gen q.gen) - [%sgzp *] (both p.gen q.gen) - [%sggr *] loop(gen q.gen) :: should check for hoon in p.gen - [%tsgr *] (change p.gen q.gen) - [%tscm *] - %+ replace - loop(gen p.gen) - |.(loop(gen q.gen, sut (~(busk ut sut) p.gen))) - :: - [%wtcl *] (bell p.gen q.gen r.gen) - [%fits *] (both p.gen wing+q.gen) - [%wthx *] loop(gen wing+q.gen) - [%dbug *] loop(gen q.gen) - [%zpcm *] (both p.gen q.gen) - [%lost *] loop(gen p.gen) - [%zpmc *] (both p.gen q.gen) - [%zpts *] loop(gen p.gen) - [%zppt *] (both q.gen r.gen) - [%zpgl *] (spec-and-hoon p.gen q.gen) - [%zpzp *] ~ - * - =+ doz=~(open ap gen) - ?: =(doz gen) - ~_ (show [%c 'hoon'] [%q gen]) - ~> %mean.'play-open' - !! - loop(gen doz) - == - :: - ++ replace - |= [a=(unit [term type]) b=(trap (unit [term type]))] - ^- (unit [term type]) - ?~(a $:b a) - :: - ++ both - |= [a=hoon b=hoon] - (replace loop(gen a) |.(loop(gen b))) - :: - ++ bell - |= [a=hoon b=hoon c=hoon] - %+ replace loop(gen a) - |. %+ replace loop(gen b, sut (~(gain ut sut) a)) - |. loop(gen c, sut (~(lose ut sut) a)) - :: - ++ spec-and-hoon - |= [a=spec b=hoon] - (replace (find-type-in-spec sut a) |.(loop(gen b))) - :: - ++ change - |= [a=hoon b=hoon] - (replace loop(gen a) |.(loop(gen b, sut (~(play ut sut) a)))) - :: - ++ grow - |= m=(map term tome) - =/ tomes ~(tap by m) - |- ^- (unit [term type]) - =* outer-loop $ - ?~ tomes - ~ - =/ arms ~(tap by q.q.i.tomes) - |- ^- (unit [term type]) - =* inner-loop $ - ?~ arms - outer-loop(tomes t.tomes) - %+ replace - loop(gen q.i.arms, sut (~(play ut sut) gen)) - |. inner-loop(arms t.arms) - -- -:: -:: Not implemented yet. I wonder whether we should modify types found -:: in spec mode such that if it's a mold that produces a type, it -:: should just display the type and not that it's technically a -:: function. -:: -++ find-type-in-spec - |= [sut=type pec=spec] - ^- (unit [term type]) - ~ -:: -++ get-id-sym - |= [pos=@ud =tape] - %^ get-id pos tape - ^- $-(nail (like (unit @t))) - ;~(sfix (punt sym) (star ;~(pose prn (just `@`10)))) -:: -++ get-id-cord - |= [pos=@ud =tape] - %^ get-id pos tape - ^- $-(nail (like (unit @t))) - ;~(sfix (punt (cook crip (star prn))) (star ;~(pose prn (just `@`10)))) -:: -++ get-id - |= [pos=@ud txt=tape seek=$-(nail (like (unit @t)))] - ^- [forward=(unit @t) backward=(unit @t) id=(unit @t)] - =/ forward=(unit @t) - (scan (slag pos txt) seek) - =/ backward=(unit @t) - %- (lift |=(t=@t (swp 3 t))) - (scan (flop (scag pos txt)) seek) - =/ id=(unit @t) - ?~ forward - ?~ backward - ~ - `u.backward - ?~ backward - `u.forward - `(cat 3 u.backward u.forward) - [forward backward id] -:: -:: Insert magic marker in hoon source at the given position. -:: -++ insert-magic - |= [pos=@ud txt=tape] - ^- [back-pos=@ud fore-pos=@ud txt=tape] - :: Find beg-pos by searching backward to where the current term - :: begins - =+ (get-id-sym pos txt) - =/ back-pos - ?~ backward - pos - (sub pos (met 3 u.backward)) - =/ fore-pos - ?~ forward - pos - (add pos (met 3 u.forward)) - :+ back-pos fore-pos - :: Insert "magic-spoon" marker so +find-type can identify where to - :: stop. - :: - ;: weld - (scag back-pos txt) - ?: &(?=(~ id) ?=([%'.' *] (slag pos txt))) - "magic-fork" - "magic-spoon" - ?~ id - "" - "." - (slag back-pos txt) - "\0a" - == -:: -:: Produce the longest possible advance without choosing between -:: matches. -:: -:: Takes a +hoon which has already has a magic-spoon marker. Useful if -:: you want to handle your own parsing. -:: -++ advance-hoon - |= [sut=type gen=hoon] - %+ bind (find-type-mule sut gen) - |= [id=term typ=type] - =/ matches=(list (option type)) - (search-prefix id (get-identifiers typ)) - (longest-match matches) -:: -:: Same as +advance-hoon, but takes a position and text directly. -:: -++ advance-tape - |= [sut=type pos=@ud code=tape] - (advance-hoon sut (scan txt:(insert-magic pos code) vest)) -:: -:: Produce a list of matches. -:: -:: Takes a +hoon which has already has a magic-spoon marker. Useful if -:: you want to handle your own parsing. -:: -++ tab-list-hoon - |= [sut=type gen=hoon] - ^- (unit (list (option type))) - %+ bind (find-type-mule sut gen) - |= [id=term typ=type] - (search-prefix id (get-identifiers typ)) -:: -:: Same as +advance-hoon, but takes a position and text directly. -:: -++ tab-list-tape - |= [sut=type pos=@ud code=tape] - ^- (each (unit (list (option type))) [row=@ col=@]) - ~? > debug %start-magick - =/ magicked txt:(insert-magic pos code) - ~? > debug %start-parsing - =/ res (lily magicked (language-server-parser *path)) - ?: ?=(%| -.res) - ~? > debug [%parsing-error p.res] - [%| p.res] - :- %& - ~? > debug %parsed-good - ((cury tab-list-hoon sut) hoon:`pile:clay`p.res) -:: -:: Generators -++ tab-generators - |= [pfix=path app=(unit term) gens=(list term)] - ^- (list (option tank)) - %+ turn gens - |= gen=term - ^- (option tank) - =/ pax=path - (weld pfix ~[gen %hoon]) - =/ file - .^(@t %cx pax) - :_ (render-help file) - ?~ app - (cat 3 '+' gen) - ?: =(%hood u.app) - (cat 3 '|' gen) - :((cury cat 3) ':' u.app '|' gen) -:: Stolen from +help -++ render-help - |= a=@t - ^- tank - :- %leaf - =/ c (to-wain:format a) - ?~ c "~" - ?. =(':: ' (end [3 4] i.c)) - "" - (trip i.c) --- diff --git a/pkg/arvo/lib/language-server/complete.hoon b/pkg/arvo/lib/language-server/complete.hoon new file mode 120000 index 000000000..219d824c7 --- /dev/null +++ b/pkg/arvo/lib/language-server/complete.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/complete.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/language-server/easy-print.hoon b/pkg/arvo/lib/language-server/easy-print.hoon deleted file mode 100644 index 12558c8a5..000000000 --- a/pkg/arvo/lib/language-server/easy-print.hoon +++ /dev/null @@ -1,484 +0,0 @@ -:: Fast type printing that's easy on the eyes or your money back -:: -=> |% - +$ cape [p=(map @ud wine) q=wine] - +$ wine - $@ $? %noun - %path - %type - %void - %wall - %wool - %yarn - == - $% [%mato p=term] - [%gate p=hoon q=type r=wine] - [%core p=(list @ta) q=wine] - [%face p=term q=wine] - [%list p=term q=wine] - [%pear p=term q=@] - [%bcwt p=(list wine)] - [%plot p=(list wine)] - [%stop p=@ud] - [%tree p=term q=wine] - [%unit p=term q=wine] - == - -- -|_ sut=type -++ dash - |= [mil=tape lim=char lam=tape] - ^- tape - =/ esc (~(gas in *(set @tD)) lam) - :- lim - |- ^- tape - ?~ mil [lim ~] - ?: ?| =(lim i.mil) - =('\\' i.mil) - (~(has in esc) i.mil) - == - ['\\' i.mil $(mil t.mil)] - ?: (lte ' ' i.mil) - [i.mil $(mil t.mil)] - ['\\' ~(x ne (rsh 2 i.mil)) ~(x ne (end 2 i.mil)) $(mil t.mil)] -:: -++ deal |=(lum=* (dish dole lum)) -++ dial - |= ham=cape - =+ gid=*(set @ud) - =| top-level=? :: don't need circumfix punctuation - =< `tank`-:$ - |% - ++ many - |= haz=(list wine) - ^- [(list tank) (set @ud)] - ?~ haz [~ gid] - =^ mor gid $(haz t.haz) - =^ dis gid ^$(q.ham i.haz) - [[dis mor] gid] - :: - ++ $ - ^- [tank (set @ud)] - ?- q.ham - %noun :_(gid [%leaf '*' ~]) - %path :_(gid [%leaf '/' ~]) - %type :_(gid [%leaf '#' 't' ~]) - %void :_(gid [%leaf '#' '!' ~]) - %wool :_(gid [%leaf '*' '"' '"' ~]) - %wall :_(gid [%leaf '*' '\'' '\'' ~]) - %yarn :_(gid [%leaf '"' '"' ~]) - [%mato *] :_(gid [%leaf '@' (trip p.q.ham)]) - [%gate *] - =^ sam gid - ?. ?=([%plot * * *] r.q.ham) - ?: ?=(%plot -.r.q.ham) - %- (slog -:$(q.ham r.q.ham) ~) - `gid - `gid - [`u=- +]:$(q.ham i.p.r.q.ham, top-level |) - :_ gid - :+ %rose - :- ?> ?=(%core -.q.q.ham) - ?: ?=(%dry q.p.q.q.q.ham) - " -> " - " ~> " - ?: top-level - ["" ""] - ["(" ")"] - :+ ?~(sam leaf+"_" u.sam) - =/ res (mule |.((~(play ut q.q.ham) p.q.ham))) - ?- -.res - %& duck(sut p.res) - %| leaf+"###" - == - ~ - :: - [%core *] - =^ sam gid - ?. ?=([%plot * * ~] q.q.ham) - `gid - [`u=- +]:$(q.ham i.p.q.q.ham) - :_ gid - ?~ sam - :+ %rose - [[' ' ~] ['<' ~] ['>' ~]] - |- ^- (list tank) - ?~ p.q.ham ~ - [[%leaf (rip 3 i.p.q.ham)] $(p.q.ham t.p.q.ham)] - :+ %rose - [" -> " "" ""] - :+ u.sam - :+ %rose - [[' ' ~] ['<' ~] ['>' ~]] - |- ^- (list tank) - ?~ p.q.ham ~ - [[%leaf (rip 3 i.p.q.ham)] $(p.q.ham t.p.q.ham)] - ~ - :: - [%face *] - =^ cox gid $(q.ham q.q.ham) - :_(gid [%palm [['=' ~] ~ ~ ~] [%leaf (trip p.q.ham)] cox ~]) - :: - [%list *] - =^ cox gid $(q.ham q.q.ham) - :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) - :: - [%bcwt *] - =^ coz gid (many p.q.ham) - :_(gid [%rose [[' ' ~] ['?' '(' ~] [')' ~]] coz]) - :: - [%plot *] - =^ coz gid (many p.q.ham) - :_(gid [%rose [[' ' ~] ['[' ~] [']' ~]] coz]) - :: - [%pear *] - :_(gid [%leaf '$' ~(rend co [%$ p.q.ham q.q.ham])]) - :: - [%stop *] - =+ num=~(rend co [%$ %ud p.q.ham]) - ?: (~(has in gid) p.q.ham) - :_(gid [%leaf '#' num]) - =^ cox gid - %= $ - gid (~(put in gid) p.q.ham) - q.ham (~(got by p.ham) p.q.ham) - == - :_(gid [%palm [['.' ~] ~ ~ ~] [%leaf ['^' '#' num]] cox ~]) - :: - [%tree *] - =^ cox gid $(q.ham q.q.ham) - :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) - :: - [%unit *] - =^ cox gid $(q.ham q.q.ham) - :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) - == - -- -:: -++ dish !: - |= [ham=cape lum=*] ^- tank - ~| [%dish-h ?@(q.ham q.ham -.q.ham)] - ~| [%lump lum] - ~| [%ham ham] - %- need - =| gil=(set [@ud *]) - |- ^- (unit tank) - ?- q.ham - %noun - %= $ - q.ham - ?: ?=(@ lum) - [%mato %$] - :- %plot - |- ^- (list wine) - [%noun ?:(?=(@ +.lum) [[%mato %$] ~] $(lum +.lum))] - == - :: - %path - :- ~ - :+ %rose - [['/' ~] ['/' ~] ~] - |- ^- (list tank) - ?~ lum ~ - ?@ lum !! - ?> ?=(@ -.lum) - [[%leaf (rip 3 -.lum)] $(lum +.lum)] - :: - %type - =+ tyr=|.((dial dole)) - =+ vol=tyr(sut lum) - =+ cis=;;(tank .*(vol [%9 2 %0 1])) - :^ ~ %palm - [~ ~ ~ ~] - [[%leaf '#' 't' '/' ~] cis ~] - :: - %wall - :- ~ - :+ %rose - [[' ' ~] ['<' '|' ~] ['|' '>' ~]] - |- ^- (list tank) - ?~ lum ~ - ?@ lum !! - [[%leaf (trip ;;(@ -.lum))] $(lum +.lum)] - :: - %wool - :- ~ - :+ %rose - [[' ' ~] ['<' '<' ~] ['>' '>' ~]] - |- ^- (list tank) - ?~ lum ~ - ?@ lum !! - [(need ^$(q.ham %yarn, lum -.lum)) $(lum +.lum)] - :: - %yarn - [~ %leaf (dash (tape lum) '"' "\{")] - :: - %void - ~ - :: - [%mato *] - ?. ?=(@ lum) - ~ - :+ ~ - %leaf - ?+ (rash p.q.ham ;~(sfix (cook crip (star low)) (star hig))) - ~(rend co [%$ p.q.ham lum]) - %$ ~(rend co [%$ %ud lum]) - %t (dash (rip 3 lum) '\'' ~) - %tas ['%' ?.(=(0 lum) (rip 3 lum) ['$' ~])] - == - :: - [%gate *] - !! - :: - [%core *] - :: XX needs rethinking for core metal - :: ?. ?=(^ lum) ~ - :: => .(lum `*`lum) - :: =- ?~(tok ~ [~ %rose [[' ' ~] ['<' ~] ['>' ~]] u.tok]) - :: ^= tok - :: |- ^- (unit (list tank)) - :: ?~ p.q.ham - :: =+ den=^$(q.ham q.q.ham) - :: ?~(den ~ [~ u.den ~]) - :: =+ mur=$(p.q.ham t.p.q.ham, lum +.lum) - :: ?~(mur ~ [~ [[%leaf (rip 3 i.p.q.ham)] u.mur]]) - [~ (dial ham)] - :: - [%face *] - =+ wal=$(q.ham q.q.ham) - ?~ wal - ~ - [~ %palm [['=' ~] ~ ~ ~] [%leaf (trip p.q.ham)] u.wal ~] - :: - [%list *] - ?: =(~ lum) - [~ %leaf '~' ~] - =- ?~ tok - ~ - [~ %rose [[' ' ~] ['~' '[' ~] [']' ~]] u.tok] - ^= tok - |- ^- (unit (list tank)) - ?: ?=(@ lum) - ?.(=(~ lum) ~ [~ ~]) - =+ [for=^$(q.ham q.q.ham, lum -.lum) aft=$(lum +.lum)] - ?. &(?=(^ for) ?=(^ aft)) - ~ - [~ u.for u.aft] - :: - [%bcwt *] - |- ^- (unit tank) - ?~ p.q.ham - ~ - =+ wal=^$(q.ham i.p.q.ham) - ?~ wal - $(p.q.ham t.p.q.ham) - wal - :: - [%plot *] - =- ?~ tok - ~ - [~ %rose [[' ' ~] ['[' ~] [']' ~]] u.tok] - ^= tok - |- ^- (unit (list tank)) - ?~ p.q.ham - ~ - ?: ?=([* ~] p.q.ham) - =+ wal=^$(q.ham i.p.q.ham) - ?~(wal ~ [~ [u.wal ~]]) - ?@ lum - ~ - =+ gim=^$(q.ham i.p.q.ham, lum -.lum) - ?~ gim - ~ - =+ myd=$(p.q.ham t.p.q.ham, lum +.lum) - ?~ myd - ~ - [~ u.gim u.myd] - :: - [%pear *] - ?. =(lum q.q.ham) - ~ - =. p.q.ham - (rash p.q.ham ;~(sfix (cook crip (star low)) (star hig))) - =+ fox=$(q.ham [%mato p.q.ham]) - ?> ?=([~ %leaf ^] fox) - ?: ?=(?(%n %tas) p.q.ham) - fox - [~ %leaf '%' p.u.fox] - :: - [%stop *] - ?: (~(has in gil) [p.q.ham lum]) ~ - =+ kep=(~(get by p.ham) p.q.ham) - ?~ kep - ~|([%stop-loss p.q.ham] !!) - $(gil (~(put in gil) [p.q.ham lum]), q.ham u.kep) - :: - [%tree *] - =- ?~ tok - ~ - [~ %rose [[' ' ~] ['{' ~] ['}' ~]] u.tok] - ^= tok - =+ tuk=*(list tank) - |- ^- (unit (list tank)) - ?: =(~ lum) - [~ tuk] - ?. ?=([n=* l=* r=*] lum) - ~ - =+ rol=$(lum r.lum) - ?~ rol - ~ - =+ tim=^$(q.ham q.q.ham, lum n.lum) - ?~ tim - ~ - $(lum l.lum, tuk [u.tim u.rol]) - :: - [%unit *] - ?@ lum - ?.(=(~ lum) ~ [~ %leaf '~' ~]) - ?. =(~ -.lum) - ~ - =+ wal=$(q.ham q.q.ham, lum +.lum) - ?~ wal - ~ - [~ %rose [[' ' ~] ['[' ~] [']' ~]] [%leaf '~' ~] u.wal ~] - == -:: -++ doge - |= ham=cape - =- ?+ woz woz - [%list * [%mato %'ta']] %path - [%list * [%mato %'t']] %wall - [%list * [%mato %'tD']] %yarn - [%list * %yarn] %wool - == - ^= woz - ^- wine - ?. ?=([%stop *] q.ham) - ?: ?& ?= [%bcwt [%pear %n %0] [%plot [%pear %n %0] [%face *] ~] ~] - q.ham - =(1 (met 3 p.i.t.p.i.t.p.q.ham)) - == - [%unit =<([p q] i.t.p.i.t.p.q.ham)] - q.ham - =+ may=(~(get by p.ham) p.q.ham) - ?~ may - q.ham - =+ nul=[%pear %n 0] - ?. ?& ?=([%bcwt *] u.may) - ?=([* * ~] p.u.may) - |(=(nul i.p.u.may) =(nul i.t.p.u.may)) - == - q.ham - =+ din=?:(=(nul i.p.u.may) i.t.p.u.may i.p.u.may) - ?: ?& ?=([%plot [%face *] [%face * %stop *] ~] din) - =(p.q.ham p.q.i.t.p.din) - =(1 (met 3 p.i.p.din)) - =(1 (met 3 p.i.t.p.din)) - == - :+ %list - (cat 3 p.i.p.din p.i.t.p.din) - q.i.p.din - ?: ?& ?= $: %plot - [%face *] - [%face * %stop *] - [[%face * %stop *] ~] - == - din - =(p.q.ham p.q.i.t.p.din) - =(p.q.ham p.q.i.t.t.p.din) - =(1 (met 3 p.i.p.din)) - =(1 (met 3 p.i.t.p.din)) - =(1 (met 3 p.i.t.t.p.din)) - == - :+ %tree - %^ cat - 3 - p.i.p.din - (cat 3 p.i.t.p.din p.i.t.t.p.din) - q.i.p.din - q.ham -:: -++ dole - ^- cape - =+ gil=*(set type) - =+ dex=[p=*(map type @) q=*(map @ wine)] - =< [q.p q] - |- ^- [p=[p=(map type @) q=(map @ wine)] q=wine] - =- [p.tez (doge q.p.tez q.tez)] - ^= tez - ^- [p=[p=(map type @) q=(map @ wine)] q=wine] - ?: (~(meet ut sut) -:!>(*type)) - [dex %type] - ?- sut - %noun [dex sut] - %void [dex sut] - [%atom *] [dex ?~(q.sut [%mato p.sut] [%pear p.sut u.q.sut])] - [%cell *] - =+ hin=$(sut p.sut) - =+ yon=$(dex p.hin, sut q.sut) - :- p.yon - :- %plot - ?:(?=([%plot *] q.yon) [q.hin p.q.yon] [q.hin q.yon ~]) - :: - [%core *] - ?: ?=([[%$ * [[%$ @ *] ~ ~]] ~ ~] q.r.q.sut) - =/ dad $(sut p.sut) - :- p.dad - ~! q.r.q.sut - [%gate q.n.q.q.n.q.r.q.sut sut(r.p.q %gold) q.dad] - =+ yad=$(sut p.sut) - :- p.yad - =+ ^= doy ^- [p=(list @ta) q=wine] - ?: ?=([%core *] q.yad) - [p.q.yad q.q.yad] - [~ q.yad] - :- %core - :_ q.doy - :_ p.doy - %^ cat 3 - %~ rent co - :+ %$ %ud - %- ~(rep by (~(run by q.r.q.sut) |=(tome ~(wyt by q.+<)))) - |=([[@ a=@u] b=@u] (add a b)) - %^ cat 3 - ?-(r.p.q.sut %gold '.', %iron '|', %lead '?', %zinc '&') - =+ gum=(mug q.r.q.sut) - %+ can 3 - :~ [1 (add 'a' (mod gum 26))] - [1 (add 'a' (mod (div gum 26) 26))] - [1 (add 'a' (mod (div gum 676) 26))] - == - :: - [%hint *] - $(sut q.sut) - :: - [%face *] - =+ yad=$(sut q.sut) - ?^(p.sut yad [p.yad [%face p.sut q.yad]]) - :: - [%fork *] - =+ yed=(sort ~(tap in p.sut) aor) - =- [p [%bcwt q]] - |- ^- [p=[p=(map type @) q=(map @ wine)] q=(list wine)] - ?~ yed - [dex ~] - =+ mor=$(yed t.yed) - =+ dis=^$(dex p.mor, sut i.yed) - [p.dis q.dis q.mor] - :: - [%hold *] - =+ hey=(~(get by p.dex) sut) - ?^ hey - [dex [%stop u.hey]] - ?: (~(has in gil) sut) - =+ dyr=+(~(wyt by p.dex)) - [[(~(put by p.dex) sut dyr) q.dex] [%stop dyr]] - =+ rom=$(gil (~(put in gil) sut), sut ~(repo ut sut)) - =+ rey=(~(get by p.p.rom) sut) - ?~ rey - rom - [[p.p.rom (~(put by q.p.rom) u.rey q.rom)] [%stop u.rey]] - == -:: -++ duck (dial dole) --- diff --git a/pkg/arvo/lib/language-server/easy-print.hoon b/pkg/arvo/lib/language-server/easy-print.hoon new file mode 120000 index 000000000..2160e2f5a --- /dev/null +++ b/pkg/arvo/lib/language-server/easy-print.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/easy-print.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/language-server/json.hoon b/pkg/arvo/lib/language-server/json.hoon deleted file mode 100644 index a817766df..000000000 --- a/pkg/arvo/lib/language-server/json.hoon +++ /dev/null @@ -1,301 +0,0 @@ -/- lsp=language-server -|% -:: -++ util - |% - ++ get-json-string - |= [jon=(map @t json) key=@t] - ^- (unit cord) - =/ cord-jon=(unit json) - (~(get by jon) key) - ?~ cord-jon - ~ - ?> ?=([%s *] u.cord-jon) - `p.u.cord-jon - -- -:: -:: -++ dejs - =, dejs:format - |% - ++ request - |= jon=json - ?> ?=([%o *] jon) - =/ method=cord - %- method - (trip (need (get-json-string:util p.jon 'method'))) - =/ id=cord - (need (get-json-string:util p.jon 'id')) - =/ params=json - (~(got by p.jon) 'params') - ^- all:request:lsp - |^ - ?+ method [%unknown jon] - %text-document--hover (text-document--hover params id) - %text-document--completion (text-document--completion params id) - == - :: - ++ text-document--hover - |= [params=json id=cord] - ^- text-document--hover:request:lsp - :+ %text-document--hover - id - %. params - %: ot - position+position - 'textDocument'^text-document-id - ~ - == - :: - ++ text-document--completion - |= [params=json id=cord] - :+ %text-document--completion id - %. params - %: ot - position+position - 'textDocument'^text-document-id - ~ - == - -- - :: - ++ notification - |= jon=json - ?> ?=([%o *] jon) - =/ method=cord - %- method - (trip (need (get-json-string:util p.jon 'method'))) - =/ params=json - (~(got by p.jon) 'params') - ^- all:notification:lsp - |^ - ?+ method [%unknown jon] - %text-document--did-change - (text-document--did-change params) - %text-document--did-open - (text-document--did-open params) - %text-document--did-save - (text-document--did-save params) - %text-document--did-close - (text-document--did-close params) - == - :: - ++ text-document--did-save - |= jon=json - ^- text-document--did-save:notification:lsp - ?> ?=([%o *] jon) - =/ doc-id - (~(got by p.jon) 'textDocument') - :- %text-document--did-save - (text-document-id doc-id) - :: - ++ text-document--did-close - |= jon=json - ^- text-document--did-close:notification:lsp - ?> ?=([%o *] jon) - =/ doc-id - (~(got by p.jon) 'textDocument') - :- %text-document--did-close - (text-document-id doc-id) - :: - ++ text-document--did-change - |= jon=json - ^- text-document--did-change:notification:lsp - :- %text-document--did-change - %. jon - %: ot - 'textDocument'^text-document-id - 'contentChanges'^text-document-changes - ~ - == - :: - ++ text-document--did-open - |= jon=json - ^- text-document--did-open:notification:lsp - ?> ?=([%o *] jon) - :- %text-document--did-open - (text-document-item (~(got by p.jon) 'textDocument')) - -- - :: Utilities - :: - ++ text-document-item - |= jon=json - ^- text-document-item:lsp - %. jon - %: ot - uri+so - version+(mu ni) - text+so - ~ - == - :: - ++ text-document-id - %: ou - uri+(un so) - version+(uf ~ (pe ~ ni)) - ~ - == - :: - ++ text-document-changes - %- ar - %: ou - range+(uf ~ (pe ~ range)) - 'rangeLength'^(uf ~ (pe ~ ni)) - text+(un so) - ~ - == - :: - ++ method - |= =tape - ^- cord - %- crip %- zing - %+ join "--" - ^- (list ^tape) - %+ turn - ^- (list (list ^tape)) - %+ scan - tape - %+ more - fas - ;~ plug - (star low) - (star ;~(plug (cook |=(a=@ (add a 32)) hig) (star low))) - == - |= words=(list ^tape) - ^- ^tape - (zing (join "-" words)) - :: - ++ range - %: ot - start+position - end+position - ~ - == - :: - ++ position - %: ot - line+ni - character+ni - ~ - == - -- -:: -++ enjs - =, enjs:format - |% - ++ text-document--publish-diagnostics - |= pub=text-document--publish-diagnostics:notification:lsp - ^- json - %: pairs - uri+s+uri.pub - diagnostics+a+(turn diagnostics.pub diagnostic) - ~ - == - ++ notification - |= notification=all:notification:lsp - ^- json - =/ params=json - ?+ -.notification !! - %text-document--publish-diagnostics - (text-document--publish-diagnostics notification) - == - ~! -.notification - =/ method=cord (crip (unparse-method -.notification)) - %: pairs - method+s+method - params+params - ~ - == - :: - ++ response - |= res=all:response:lsp - ^- json - |^ - ?- -.res - %text-document--hover (text-document--hover res) - %text-document--completion (text-document--completion res) - == - :: - ++ wrap-in-id - |= [id=cord res=json] - %: pairs - id+s+id - result+res - ~ - == - ++ text-document--hover - |= hov=text-document--hover:response:lsp - %+ wrap-in-id id.hov - %+ frond 'contents' - ?~ contents.hov - ~ - s+u.contents.hov - :: - ++ text-document--completion - |= com=text-document--completion:response:lsp - %+ wrap-in-id id.com - [%a (turn completion.com completion-item)] - -- - ++ unparse-method - |= =cord - ^- ^tape - %+ rash cord - %+ cook |=(l=(list ^tape) (zing (join "/" l))) - %+ more (jest '--') - %+ cook - |= tapes=(list ^tape) - ^- ^tape - ?~ tapes ~ - %- zing - :- i.tapes - %+ turn t.tapes - |= t=^tape - ^- ^tape - ?~ t ~ - [`@tD`(sub i.t 32) t.t] - %+ more - ;~(less (jest '--') hep) - (star alf) - :: - ++ completion-item - |= com=completion-item:lsp - ^- json - %: pairs - label+s+label.com - detail+s+detail.com - kind+(numb kind.com) - 'documentation'^s+doc.com - 'insertText'^s+insert-text.com - 'insertTextFormat'^(numb insert-text-format.com) - ~ - == - :: - ++ position - |= =position:lsp - ^- json - %: pairs - line+(numb row.position) - character+(numb col.position) - ~ - == - :: - ++ range - |= =range:lsp - ^- json - %: pairs - start+(position start.range) - end+(position end.range) - ~ - == - :: - ++ diagnostic - |= diag=diagnostic:lsp - ^- json - %: pairs - range+(range range.diag) - severity+(numb severity.diag) - message+s+message.diag - ~ - == - :: - -- --- diff --git a/pkg/arvo/lib/language-server/json.hoon b/pkg/arvo/lib/language-server/json.hoon new file mode 120000 index 000000000..96fe5b516 --- /dev/null +++ b/pkg/arvo/lib/language-server/json.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/json.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/language-server/parser.hoon b/pkg/arvo/lib/language-server/parser.hoon deleted file mode 100644 index cf5779092..000000000 --- a/pkg/arvo/lib/language-server/parser.hoon +++ /dev/null @@ -1,72 +0,0 @@ -:: lifted directly from ford, should probably be in zuse -=, clay -=< pile-rule -|% -++ pile-rule - |= pax=path - %- full - %+ ifix - :_ gay - :: parse optional /? and ignore - :: - ;~(plug gay (punt ;~(plug fas wut gap dem gap))) - |^ - ;~ plug - %+ cook (bake zing (list (list taut))) - %+ rune hep - (most ;~(plug com gaw) taut-rule) - :: - %+ cook (bake zing (list (list taut))) - %+ rune lus - (most ;~(plug com gaw) taut-rule) - :: - %+ rune tis - ;~(plug sym ;~(pfix gap stap)) - :: - %+ rune sig - ;~((glue gap) sym wyde:vast stap) - :: - %+ rune cen - ;~(plug sym ;~(pfix gap ;~(pfix cen sym))) - :: - %+ rune buc - ;~ (glue gap) - sym - ;~(pfix cen sym) - ;~(pfix cen sym) - == - :: - %+ rune tar - ;~ (glue gap) - sym - ;~(pfix cen sym) - stap - == - :: - %+ stag %tssg - (most gap tall:(vang & pax)) - == - :: - ++ pant - |* fel=^rule - ;~(pose fel (easy ~)) - :: - ++ mast - |* [bus=^rule fel=^rule] - ;~(sfix (more bus fel) bus) - :: - ++ rune - |* [bus=^rule fel=^rule] - %- pant - %+ mast gap - ;~(pfix fas bus gap fel) - -- -:: -++ taut-rule - %+ cook |=(taut +<) - ;~ pose - (stag ~ ;~(pfix tar sym)) - ;~(plug (stag ~ sym) ;~(pfix tis sym)) - (cook |=(a=term [`a a]) sym) - == --- diff --git a/pkg/arvo/lib/language-server/parser.hoon b/pkg/arvo/lib/language-server/parser.hoon new file mode 120000 index 000000000..327e1a5de --- /dev/null +++ b/pkg/arvo/lib/language-server/parser.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/parser.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/language-server/rune-snippet.hoon b/pkg/arvo/lib/language-server/rune-snippet.hoon deleted file mode 100644 index b25e306be..000000000 --- a/pkg/arvo/lib/language-server/rune-snippet.hoon +++ /dev/null @@ -1,532 +0,0 @@ -/- lsp-sur=language-server -/+ auto=language-server-complete -=> -|% -++ snippet - |= [rune=tape text=tape] - ^- json - =, enjs:format - %- pairs - :~ 'label'^(tape rune) - 'insertTextFormat'^(numb 2) - 'insertText'^(tape text) - == -:: -++ runes - ^- (list (option:auto tape)) - :~ :- '|$' - """ - $\{1:sample} - $\{2:body} - """ - :- '|_' - """ - $\{1:sample} - ++ $\{2:arm} - $\{3:body} - -- - """ - :- '|:' - """ - $\{1:sample} - $\{2:body} - """ - :- '|%' - """ - - ++ $\{1:arm} - $\{2:body} - -- - """ - :- '|.' - """ - $\{1:body} - """ - :- '|^' - """ - - $\{1:body} - :: - ++ $\{2:arm} - $\{3:body} - -- - """ - :- '|-' - """ - $\{1:body} - """ - :- '|~' - """ - $\{1:sample} - $\{2:body} - """ - :- '|*' - """ - $\{1:sample} - $\{2:body} - """ - :- '|=' - """ - $\{1:sample} - $\{2:body} - """ - :- '|@' - """ - ++ $\{1:arm} - $\{2:body} - -- - """ - :- '|?' - """ - $\{1:sample} - """ - :: - :- ':_' - """ - $\{1:tail} - $\{2:head} - """ - :- ':^' - """ - $\{1:car} - $\{2:cadr} - $\{3:caddr} - $\{4:cddr} - """ - :- ':-' - """ - $\{1:tail} - $\{2:head} - """ - :- ':+' - """ - $\{1:car} - $\{2:cadr} - $\{3:cddr} - """ - :- ':~' - """ - $\{1:item} - == - """ - :- ':*' - """ - $\{1:item} - == - """ - :: - :- '%_' - """ - $\{1:target} - $\{2:wing} $\{3:new-value} - == - """ - :- '%.' - """ - $\{1:arg} - $\{2:gate} - """ - :- '%-' - """ - $\{1:gate} - $\{2:arg} - """ - :- '%:' - """ - $\{1:gate} - $\{2:args} - == - """ - :- '%*' - """ - $\{1:target-wing} $\{2:from} - $\{3:wing} $\{4:new-value} - == - """ - :- '%^' - """ - $\{1:gate} - $\{2:arg1} - $\{3:arg2} - $\{4:arg3} - """ - :- '%+' - """ - $\{1:gate} - $\{2:arg1} - $\{3:arg2} - """ - :- '%~' - """ - $\{1:arm} - $\{2:core} - $\{3:arg} - """ - :- '%=' - """ - $\{1:target} - $\{2:wing} $\{3:new-value} - == - """ - :: - :- '.^' - """ - $\{1:mold} - $\{2:path} - """ - :- '.+' - """ - $\{1:atom} - """ - :- '.*' - """ - $\{1:subject} - $\{2:formula} - """ - :- '.=' - """ - $\{1:a} - $\{2:b} - """ - :- '.?' - """ - $\{1:noun} - """ - :: - :- '^|' - """ - $\{1:iron-core} - """ - :- '^.' - """ - $\{1:a} - $\{2:b} - """ - :- '^+' - """ - $\{1:like} - $\{2:body} - """ - :- '^-' - """ - $\{1:type} - $\{2:body} - """ - :- '^&' - """ - $\{1:zinc-core} - """ - :- '^~' - """ - $\{1:constant} - """ - :- '^=' - """ - $\{1:face} - $\{2:body} - """ - :- '^?' - """ - $\{1:lead-core} - """ - :- '^*' - """ - $\{1:type} - """ - :- '^:' - """ - $\{1:type} - """ - :: - :- '~|' - """ - $\{1:trace} - $\{2:body} - """ - :- '~_' - """ - $\{1:tank} - $\{2:body} - """ - :- '~%' - """ - $\{1:name} - $\{2:parent} - ~ - $\{3:body} - """ - :- '~/' - """ - $\{1:name} - $\{2:body} - """ - :- '~<' - """ - $\{1:hint} - $\{2:body} - """ - :- '~>' - """ - $\{1:hint} - $\{2:body} - """ - :- '~$' - """ - $\{1:name} - $\{2:body} - """ - :- '~+' - """ - - $\{1:body} - """ - :- '~&' - """ - $\{1:printf} - $\{2:body} - """ - :- '~=' - """ - $\{1:a} - $\{2:b} - """ - :- '~?' - """ - $\{1:condition} - $\{2:printf} - $\{3:body} - """ - :- '~!' - """ - $\{1:type} - $\{2:body} - """ - :: - :- ';=' - """ - $\{1:manx} - == - """ - :- ';:' - """ - $\{1:gate} - $\{2:args} - == - """ - :- ';/' - """ - $\{1:tape} - """ - :- ';<' - """ - $\{1:type} bind:m $\{2:body1} - $\{3:body2} - """ - :- ';~' - """ - $\{1:gate} - $\{2:args} - == - """ - :- ';;' - """ - $\{1:type} - $\{2:body} - """ - :: - :- '=|' - """ - $\{1:type} - $\{2:body} - """ - :- '=:' - """ - $\{1:wing} $\{2:value} - == - $\{3:body} - """ - :- '=/' - """ - $\{1:face} - $\{2:value} - $\{3:body} - """ - :- '=;' - """ - $\{1:face} - $\{2:body} - $\{3:value} - """ - :- '=.' - """ - $\{1:wing} - $\{2:value} - $\{3:body} - """ - :- '=?' - """ - $\{1:wing} $\{2:condition} - $\{3:value} - $\{4:body} - """ - :- '=<' - """ - $\{1:formula} - $\{2:subject} - """ - :- '=-' - """ - $\{1:body} - $\{2:value} - """ - :- '=>' - """ - $\{1:subject} - $\{2:formula} - """ - :- '=^' - """ - $\{1:face} $\{2:wing} - $\{3:computation} - $\{4:body} - """ - :- '=+' - """ - $\{1:value} - $\{2:body} - """ - :- '=~' - """ - - $\{1:body} - """ - :- '=*' - """ - $\{1:alias} $\{2:value} - $\{3:body} - """ - :- '=,' - """ - $\{1:alias} - $\{3:body} - """ - :: - :- '?|' - """ - $\{1:condition} - == - """ - :- '?-' - """ - $\{1:case} - $\{2:type} $\{3:value} - == - """ - :- '?:' - """ - $\{1:if} - $\{2:then} - $\{3:else} - """ - :- '?.' - """ - $\{1:if} - $\{2:else} - $\{3:then} - """ - :- '?^' - """ - $\{1:value} - $\{2:if-cell} - $\{3:if-atom} - """ - :- '?<' - """ - $\{1:assertion} - $\{2:body} - """ - :- '?>' - """ - $\{1:assertion} - $\{2:body} - """ - :- '?+' - """ - $\{1:case} $\{2:else} - $\{3:type} $\{4:value} - == - """ - :- '?&' - """ - $\{1:condition} - == - """ - :- '?@' - """ - $\{1:value} - $\{2:if-atom} - $\{3:if-cell} - """ - :- '?~' - """ - $\{1:value} - $\{2:if-null} - $\{3:if-nonnull} - """ - :- '?#' - """ - $\{1:skin} - $\{2:wing} - """ - :- '?=' - """ - $\{1:type} - $\{2:wing} - """ - :- '?!' - """ - $\{1:loobean} - """ - :: - :- '!,' - """ - *hoon - $\{1:ast} - """ - :- '!>' - """ - $\{1:value} - """ - :- '!;' - """ - $\{1:type} - $\{2:body} - """ - :- '!=' - """ - $\{1:body} - """ - :- '!@' - """ - $\{1:wing} - $\{2:if-exists} - $\{3:if-not-exists} - """ - :- '!?' - """ - $\{1:version} - $\{2:body} - """ - :- '!!' - "" - == --- -|= rune=tape -^- (list completion-item:lsp-sur) -=? rune =(' ' (snag 0 rune)) - (slag 1 rune) -~& rune -%+ turn (search-prefix:auto (crip rune) runes) -|= [name=cord snippet=tape] -^- completion-item:lsp-sur -[name 1 '' '' (crip snippet) 2] diff --git a/pkg/arvo/lib/language-server/rune-snippet.hoon b/pkg/arvo/lib/language-server/rune-snippet.hoon new file mode 120000 index 000000000..387505b59 --- /dev/null +++ b/pkg/arvo/lib/language-server/rune-snippet.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/rune-snippet.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/naive-transactions.hoon b/pkg/arvo/lib/naive-transactions.hoon index 524be1769..e85deb03e 100644 --- a/pkg/arvo/lib/naive-transactions.hoon +++ b/pkg/arvo/lib/naive-transactions.hoon @@ -19,24 +19,54 @@ =, secp256k1:secp:crypto %- address-from-pub:key:ethereum %- serialize-point - (ecdsa-raw-recover (keccak-256:keccak:crypto dat) v r s) + (ecdsa-raw-recover (hash-tx dat) v r s) ?- -.result %| ~ %& `p.result == +:: Verify signature and produce signer address +:: +++ verify-sig + |= [sig=@ txdata=octs] + ^- (unit address) + |^ + :: Reversed of the usual r-s-v order because Ethereum integers are + :: big-endian + :: + =^ v sig (take 3) + =^ s sig (take 3 32) + =^ r sig (take 3 32) + :: In Ethereum, v is generally 27 + recid, and verifier expects a + :: recid. Old versions of geth used 0 + recid, so most software + :: now supports either format. See: + :: + :: https://github.com/ethereum/go-ethereum/issues/2053 + :: + =? v (gte v 27) (sub v 27) + (verifier txdata v r s) + :: + ++ take + |= =bite + [(end bite sig) (rsh bite sig)] + -- +:: +++ unsigned-tx + |= [chain-id=@ud =nonce tx=octs] + ^- octs + =/ prepared-data (prepare-for-sig chain-id nonce tx) + =/ len (rsh [3 2] (scot %ui p.prepared-data)) + %: cad:naive 3 + 26^'\19Ethereum Signed Message:\0a' + (met 3 len)^len + prepared-data + ~ + == :: ++ sign-tx |= [pk=@ =nonce tx=octs] ^- octs - =/ prepared-data (prepare-for-sig 1.337 nonce tx) =/ sign-data - =/ len (rsh [3 2] (scot %ui p.prepared-data)) - %- keccak-256:keccak:crypto - %: cad:naive 3 - 26^'\19Ethereum Signed Message:\0a' - (met 3 len)^len - prepared-data - ~ - == + %- hash-tx + (unsigned-tx 1.337 nonce tx) =+ (ecdsa-raw-sign:secp256k1:secp:crypto sign-data pk) (cad:naive 3 1^v 32^s 32^r tx ~) :: @@ -53,8 +83,20 @@ ~ == :: +++ extract-address + |= [=raw-tx:naive nas=^state:naive chain-id=@] + ^- (unit @ux) + ?~ point=(get:orm:naive points.nas ship.from.tx.raw-tx) + ~ + =/ =nonce:naive + =< nonce + (proxy-from-point:naive proxy.from.tx.raw-tx u.point) + =/ message=octs + (unsigned-tx chain-id nonce raw.raw-tx) + (verify-sig sig.raw-tx message) +:: ++ gen-tx - |= [=nonce tx=tx:naive pk=@] + |= [=nonce tx=tx:naive pk=@] ^- octs :: takes in a nonce, tx:naive, and private key and returned a signed transactions as octs %^ sign-tx pk nonce (gen-tx-octs tx) :: @@ -161,4 +203,21 @@ :: -- :: +++ reverse-hash + |= keccak=@ux + ^+ keccak + (rev 3 (met 3 keccak) keccak) +:: +++ hash-tx keccak-256:keccak:crypto +:: +++ hash-raw-tx + |= raw-tx:naive + ^- @ux + %- hash-tx + %: cad:naive 3 + 65^sig + raw + ~ + == +:: -- diff --git a/pkg/arvo/lib/naive.hoon b/pkg/arvo/lib/naive.hoon index 446cf1a42..7f46eaf01 100644 --- a/pkg/arvo/lib/naive.hoon +++ b/pkg/arvo/lib/naive.hoon @@ -1,74 +1,6 @@ -:: L1 contract changes: -:: t Enforce that once spawn proxy is set to deposit address, it can't -:: switched back -:: t Enforce that once spawn proxy is set to deposit address, you can't -:: spawn children -:: + Possibly the same for approveForAll. No, because we're not going -:: to support approveForAll on L2 -:: + Enforce that only ownership key can set spawn proxy to rollup. -:: maybe not though. Yeah, a spawn proxy should be able to set spawn -:: proxy to the rollup -:: t Disallow depositing galaxy to L2 -:: + When depositing, clear proxies (maybe require reset). On L1 only, -:: not L2. If we don't do this, we need to make sure they can't keep -:: doing stuff using the proxies. Probably better to clear the -:: proxies explicitly instead of requiring _reset -:: t Maybe require that we're not depositing from a contract? But -:: what if they're depositing from something that's a contract, but the -:: owner is not a contract? Probably best for the only condition to -:: be that the owner is not a contract -:: + disallow spawning to deposit address? maybe, else we need to -:: default the ownership somehow. Or maybe this happens automatically -:: because it uses the safe transfer flow? Yes, _direct will never -:: be true unless we're depositing to ourself, so it'll go to the -:: owner address, which will never be the deposit address. So we're -:: safe. -:: t If either side is on L2, then all sponsorship happens on L2. If -:: both are on L1, sponsorship happens on L1 -:: - Maybe should special-case spawning directly to L2? Acceptable -:: right now but not ideal. -:: -:: TODO: can an L1 star adopt an L2 planet? It's not obvious how -- -:: maybe they need to adopt as an L2 transaction? That sounds right I -:: think. Can an L2 star adopt an L1 planet? I guess, but L1 wouldn't -:: know about it. Should L1 check whether the escape target is on L2 -:: for some reason? IMO if either side is on L2, then both sides -:: should operate on L2. -:: -:: I think the answer is that if either side is on L2, it's on L2; if -:: both are on L1, then it can be on either. L1 reading sponsorship -:: state cannot know the sponsorship info is correct; only L2 knows. -:: However, you can still use an on-chain multi-sig to control your -:: sponsorship as long as you don't create a proxy that could send -:: stuff on L2. -:: -:: TODO: is it possible to spawn directly to the deposit address? if -:: so, should we find its parent's owner to control it? -:: -:: TODO: need to find out what happens when you transfer with reset. -:: since the setOwner happens first, it might crash the rollup when the -:: other changes come -:: -:: TODO: secp needs to not crash the process when you give it a bad -:: v/recid. See #4797 -:: -:: TODO: check if spawning is gated on "link"ing -:: -:: TODO: make process-set-spawn-proxy work if you're on domain %spawn -:: -:: TODO: make sure you can spawn with the spawn proxy after on domain -:: %spawn -:: -:: TODO: planet shouldn't be able to set spawn proxy -:: -:: TODO: make sure that if we've already been deposited to L2, no -:: further L1 logs count except detach. -:: -:: TODO: change sponsorship to reject adoptions from L1 if they don't -:: accord with our local escape state? -:: -/+ std -=> => std +/+ tiny +!. +=> => tiny :: Laconic bit :: =| lac=? @@ -77,8 +9,6 @@ |% :: Transfers on L1 to this address count as depositing to L2 :: -:: 0x1234567890123456789012345678901234567890 -:: ++ deposit-address 0x1111.1111.1111.1111.1111.1111.1111.1111.1111.1111 ++ log-names |% @@ -218,7 +148,8 @@ == == == :: +$ state - $: =points + $: %0 + =points =operators dns=(list @t) == @@ -249,9 +180,10 @@ topics=(lest @ux) == +$ input + $: block=@ud $% [%bat batch=@] [%log =event-log] - == + == == :: ECDSA verifier. :: :: Must keccak `dat` and recover the ethereum address which signed. @@ -272,39 +204,34 @@ ++ parse-roll |= batch=@ =| =roll + =| pos=@ud + =/ las (met 0 batch) |- ^+ roll - ?~ batch + ?: (gte pos las) (flop roll) - =/ parse-result (parse-raw-tx batch) + =/ parse-result (parse-raw-tx pos batch) :: Parsing failed, abort batch :: ?~ parse-result (debug %parse-failed ~) - =^ =raw-tx batch u.parse-result + =^ =raw-tx pos u.parse-result $(roll [raw-tx roll]) :: -:: TODO: change batch to be a cursor to avoid allocating atoms -:: ++ parse-raw-tx - |= batch=@ - ^- (unit [raw-tx rest=@]) - =/ batch [len=0 rest=batch] + |= [pos=@ud batch=@] + ^- (unit [raw-tx pos=@ud]) |^ - =^ sig batch (take 3 65) - =. len.batch 0 - =/ orig-batch rest.batch - =/ res=(unit [=tx batch=_batch]) parse-tx - ?~ res - ~ - :- ~ :_ rest.batch.u.res - =/ len-bytes - ?> =(0 (mod len.batch.u.res 8)) - (div len.batch.u.res 8) - [sig [len-bytes (end [0 len.batch.u.res] orig-batch)] tx.u.res] + =^ sig pos (take 3 65) + =/ res=(unit [=tx pos=@ud]) parse-tx + ?~ res ~ + =/ dif (sub pos.u.res pos) + =/ len =>((dvr dif 8) ?>(=(0 q) p)) + :- ~ :_ pos.u.res + [sig [len (cut 0 [pos dif] batch)] tx.u.res] :: ++ parse-tx - ^- (unit [tx _batch]) - =^ from-proxy=@ batch (take 0 3) + ^- (unit [tx pos=@ud]) + =^ from-proxy=@ pos (take 0 3) ?. ?=(?(%0 %1 %2 %3 %4) from-proxy) (debug %bad-proxy ~) =/ =proxy ?- from-proxy @@ -314,68 +241,65 @@ %3 %vote %4 %transfer == - =^ pad batch (take 0 5) - =^ from-ship=ship batch (take 3 4) + =^ pad pos (take 0 5) + =^ from-ship=ship pos (take 3 4) =- ?~ res ~ - `[[[from-ship proxy] skim-tx.u.res] batch.u.res] - ^- res=(unit [=skim-tx =_batch]) - =^ op batch (take 0 7) - ?+ op ~>(%slog.[0 %strange-opcode] ~) + `[[[from-ship proxy] skim-tx.u.res] pos.u.res] + ^- res=(unit [=skim-tx pos=@ud]) + =^ op pos (take 0 7) + ?+ op (debug %strange-opcode ~) %0 - =^ reset=@ batch (take 0) - =^ =address batch (take 3 20) - `[[%transfer-point address =(0 reset)] batch] + =^ reset=@ pos (take 0) + =^ =address pos (take 3 20) + `[[%transfer-point address =(0 reset)] pos] :: %1 - =^ pad=@ batch (take 0) - =^ =ship batch (take 3 4) - =^ =address batch (take 3 20) - `[[%spawn ship address] batch] + =^ pad=@ pos (take 0) + =^ =ship pos (take 3 4) + =^ =address pos (take 3 20) + `[[%spawn ship address] pos] :: %2 - =^ breach=@ batch (take 0) - =^ encrypt=@ batch (take 3 32) - =^ auth=@ batch (take 3 32) - =^ crypto-suite=@ batch (take 3 4) - `[[%configure-keys encrypt auth crypto-suite =(0 breach)] batch] + =^ breach=@ pos (take 0) + =^ encrypt=@ pos (take 3 32) + =^ auth=@ pos (take 3 32) + =^ crypto-suite=@ pos (take 3 4) + `[[%configure-keys encrypt auth crypto-suite =(0 breach)] pos] :: - %3 =^(res batch take-escape `[[%escape res] batch]) - %4 =^(res batch take-escape `[[%cancel-escape res] batch]) - %5 =^(res batch take-escape `[[%adopt res] batch]) - %6 =^(res batch take-escape `[[%reject res] batch]) - %7 =^(res batch take-escape `[[%detach res] batch]) - %8 - =^(res batch take-ship-address `[[%set-management-proxy res] batch]) - :: - %9 =^(res batch take-ship-address `[[%set-spawn-proxy res] batch]) - %10 =^(res batch take-ship-address `[[%set-transfer-proxy res] batch]) + %3 =^(res pos take-ship `[[%escape res] pos]) + %4 =^(res pos take-ship `[[%cancel-escape res] pos]) + %5 =^(res pos take-ship `[[%adopt res] pos]) + %6 =^(res pos take-ship `[[%reject res] pos]) + %7 =^(res pos take-ship `[[%detach res] pos]) + %8 =^(res pos take-address `[[%set-management-proxy res] pos]) + %9 =^(res pos take-address `[[%set-spawn-proxy res] pos]) + %10 =^(res pos take-address `[[%set-transfer-proxy res] pos]) == :: :: Take a bite :: ++ take |= =bite - ^- [@ _batch] - :- (end bite +.batch) - :- %+ add -.batch - ?@ bite (bex bite) - (mul step.bite (bex bloq.bite)) - (rsh bite +.batch) + ^- [@ @ud] + =/ =step + ?@ bite (bex bite) + (mul step.bite (bex bloq.bite)) + [(cut 0 [pos step] batch) (add pos step)] :: Encode ship and address :: - ++ take-ship-address - ^- [address _batch] - =^ pad=@ batch (take 0) - =^ =address batch (take 3 20) - [address batch] + ++ take-address + ^- [address @ud] + =^ pad=@ pos (take 0) + =^ =address pos (take 3 20) + [address pos] :: Encode escape-related txs :: - ++ take-escape - ^- [ship _batch] - =^ pad=@ batch (take 0) - =^ other=ship batch (take 3 4) - [other batch] + ++ take-ship + ^- [ship @ud] + =^ pad=@ pos (take 0) + =^ other=ship pos (take 3 4) + [other pos] -- :: ++ proxy-from-point @@ -459,10 +383,12 @@ :: ++ ud-to-ascii |= n=@ud - ^- @t - ?~ n - *@t - (cat 3 $(n (div n 10)) (add '0' (mod n 10))) + ?~ n '0' + =| l=(list @) + |- ^- @t + ?~ n (rep 3 l) + =+ (dvr n 10) + $(n p, l [(add '0' q) l]) :: ++ ship-rank |= =ship @@ -495,7 +421,7 @@ `u.existing =| =point =. who.sponsor.net.point (sein ship) - ?+ (ship-rank ship) ~>(%slog.[0 %strange-point] ~) + ?+ (ship-rank ship) (debug %strange-point ~) %0 `point(dominion %l1) ?(%1 %2) =/ existing-parent $(ship (sein ship)) @@ -524,11 +450,13 @@ ?: =(log-name changed-dns:log-names) ?> ?=(~ t.topics.log) =/ words (rip 8 data.log) - ?> ?=([c=@ @ b=@ @ a=@ @ @ @ @ ~] words) :: TODO: not always true + :: This is only true if each domain is <= 32 bytes + :: + ?. ?=([c=@ @ b=@ @ a=@ @ @ @ @ ~] words) `state =* one &5.words =* two &3.words =* tri &1.words - =/ domains (turn ~[one two tri] |=(a=@ (swp 3 a))) + =/ domains ~[(swp 3 one) (swp 3 two) (swp 3 tri)] :- [%dns domains]~ state(dns domains) :: @@ -552,20 +480,26 @@ =/ the-point (get-point state ship) ?> ?=(^ the-point) =* point u.the-point - =- [effects state(points (put:orm points.state ship new-point))] - ^- [=effects new-point=^point] + :: + :: Important to fully no-op on failure so we don't insert an entry + :: into points.state + :: + =- ?~ res + `state + [effects.u.res state(points (put:orm points.state ship new-point.u.res))] + ^- res=(unit [=effects new-point=^point]) :: ?: =(log-name changed-spawn-proxy:log-names) - ?. ?=(%l1 -.point) `point + ?. ?=(%l1 -.point) ~ ?> ?=([@ ~] t.t.topics.log) =* to i.t.t.topics.log :: Depositing to L2 is represented by a spawn proxy change on L1, :: but it doesn't change the actual spawn proxy. :: ?: =(deposit-address to) - :- [%point ship %dominion %spawn]~ + :+ ~ [%point ship %dominion %spawn]~ point(dominion %spawn) - :- [%point ship %spawn-proxy to]~ + :+ ~ [%point ship %spawn-proxy to]~ point(address.spawn-proxy.own to) :: ?: =(log-name escape-accepted:log-names) @@ -573,8 +507,8 @@ =* parent=@ i.t.t.topics.log =/ parent-point (get-point state parent) ?> ?=(^ parent-point) - ?: |(?=(%l2 -.point) ?=(%l2 -.u.parent-point)) `point - :- [%point ship %sponsor `parent]~ + ?: ?=(%l2 -.u.parent-point) ~ + :+ ~ [%point ship %sponsor `parent]~ point(escape.net ~, sponsor.net [%& parent]) :: ?: =(log-name lost-sponsor:log-names) @@ -583,7 +517,7 @@ :: If the sponsor we lost was not our actual sponsor, we didn't :: actually lose anything. :: - ?. =(parent who.sponsor.net.point) `point + ?. =(parent who.sponsor.net.point) ~ :: =/ parent-point (get-point state parent) ?> ?=(^ parent-point) @@ -591,17 +525,21 @@ :: We can detach even if the child is on L2, as long as the parent :: is on L1. :: - ?: ?=(%l2 -.u.parent-point) `point - :- [%point ship %sponsor ~]~ + ?: ?=(%l2 -.u.parent-point) ~ + :+ ~ [%point ship %sponsor ~]~ point(has.sponsor.net %|) :: + :: The rest can be done by any ship on L1, even if their spawn proxy + :: is set to L2 + :: + ?: ?=(%l2 -.point) ~ + :: ?: =(log-name escape-requested:log-names) ?> ?=([@ ~] t.t.topics.log) =* parent=@ i.t.t.topics.log =/ parent-point (get-point state parent) ?> ?=(^ parent-point) - ?: |(?=(%l2 -.point) ?=(%l2 -.u.parent-point)) `point - :- [%point ship %escape `parent]~ + :+ ~ [%point ship %escape `parent]~ point(escape.net `parent) :: ?: =(log-name escape-canceled:log-names) @@ -609,19 +547,13 @@ =* parent=@ i.t.t.topics.log =/ parent-point (get-point state parent) ?> ?=(^ parent-point) - ?: |(?=(%l2 -.point) ?=(%l2 -.u.parent-point)) `point - :- [%point ship %escape ~]~ + :+ ~ [%point ship %escape ~]~ point(escape.net ~) :: - :: The rest can be done by any ship on L1, even if their spawn proxy - :: is set to L2 - :: - ?: ?=(%l2 -.point) `point - :: ?: =(log-name broke-continuity:log-names) ?> ?=(~ t.t.topics.log) =* rift=@ data.log - :- [%point ship %rift rift]~ + :+ ~ [%point ship %rift rift]~ point(rift.net rift) :: ?: =(log-name changed-keys:log-names) @@ -632,7 +564,7 @@ auth=(cut 8 [2 1] data.log) crypt=(cut 8 [3 1] data.log) == - :- [%point ship %keys keys]~ + :+ ~ [%point ship %keys keys]~ point(keys.net keys) :: ?: =(log-name owner-changed:log-names) @@ -642,31 +574,30 @@ :: but it doesn't change who actually owns the ship. :: ?: =(deposit-address to) - :- [%point ship %dominion %l2]~ + :+ ~ [%point ship %dominion %l2]~ point(dominion %l2) - :- [%point ship %owner to]~ + :+ ~ [%point ship %owner to]~ point(address.owner.own to) :: ?: =(log-name changed-transfer-proxy:log-names) ?> ?=([@ ~] t.t.topics.log) =* to i.t.t.topics.log - :- [%point ship %transfer-proxy to]~ + :+ ~ [%point ship %transfer-proxy to]~ point(address.transfer-proxy.own to) :: ?: =(log-name changed-management-proxy:log-names) ?> ?=([@ ~] t.t.topics.log) =* to i.t.t.topics.log - :- [%point ship %management-proxy to]~ + :+ ~ [%point ship %management-proxy to]~ point(address.management-proxy.own to) :: ?: =(log-name changed-voting-proxy:log-names) ?> ?=([@ ~] t.t.topics.log) =* to i.t.t.topics.log - :- [%point ship %voting-proxy to]~ + :+ ~ [%point ship %voting-proxy to]~ point(address.voting-proxy.own to) :: - ~> %slog.[0 %unknown-log] - `point + (debug %unknown-log ~) :: :: Receive batch of L2 transactions :: @@ -744,7 +675,9 @@ %adopt (w-point-esc process-adopt ship.tx +>.tx) %reject (w-point-esc process-reject ship.tx +>.tx) %detach (w-point-esc process-detach ship.tx +>.tx) - %set-spawn-proxy (w-point process-set-spawn-proxy ship.from.tx +>.tx) + %set-spawn-proxy + (w-point-spawn process-set-spawn-proxy ship.from.tx +>.tx) + :: %set-transfer-proxy (w-point process-set-transfer-proxy ship.from.tx +>.tx) :: @@ -757,10 +690,14 @@ ^- (unit [effects ^state]) =/ point (get-point state ship) ?~ point (debug %strange-ship ~) + ?. ?=(%l2 -.u.point) (debug %ship-not-on-l2 ~) + :: Important to fully no-op on failure so we don't insert an entry + :: into points.state + :: =/ res=(unit [=effects new-point=^point]) (fun u.point rest) ?~ res ~ - `[effects.u.res state(points (~(put by points.state) ship new-point.u.res))] + `[effects.u.res state(points (put:orm points.state ship new-point.u.res))] :: ++ w-point-esc |* [fun=$-([ship point *] (unit [effects point])) =ship rest=*] @@ -772,6 +709,17 @@ ~ `[effects.u.res state(points (put:orm points.state ship new-point.u.res))] :: + ++ w-point-spawn + |* [fun=$-([ship point *] (unit [effects point])) =ship rest=*] + ^- (unit [effects ^state]) + =/ point (get-point state ship) + ?~ point (debug %strange-ship ~) + ?: ?=(%l1 -.u.point) (debug %ship-on-l2 ~) + =/ res=(unit [=effects new-point=^point]) (fun u.point rest) + ?~ res + ~ + `[effects.u.res state(points (put:orm points.state ship new-point.u.res))] + :: ++ process-transfer-point |= [=point to=address reset=?] =* ship ship.from.tx @@ -832,13 +780,10 @@ (debug %bad-permission ~) :: Assert child not already spawned :: - :: TODO: verify this means the ship exists on neither L1 nor L2 - :: ?^ (get:orm points.state ship) (debug %spawn-exists ~) :: Assert one-level-down :: ?. =(+((ship-rank parent)) (ship-rank ship)) (debug %bad-rank ~) - :: TODO check spawnlimit :: =/ [=effects new-point=point] =/ point=(unit point) (get-point state ship) @@ -852,8 +797,6 @@ =(to address.spawn-proxy.own.u.parent-point) == == - :: TODO: use get-point or duplicate sponsor logic - :: :- ~[[%point ship %dominion %l2] [%point ship %owner to]] u.point(address.owner.own to) :: Else spawn to parent and set transfer proxy @@ -899,7 +842,7 @@ (debug %bad-rank ~) :: :+ ~ [%point ship %escape `parent]~ - point(escape.net `parent) :: TODO: omitting a lot of source material? + point(escape.net `parent) :: ++ process-cancel-escape |= [=point parent=ship] @@ -913,8 +856,6 @@ ++ process-adopt |= [=point =ship] =* parent ship.from.tx - :: TODO: assert child/parent on L2? - :: ?. |(=(%own proxy.from.tx) =(%manage proxy.from.tx)) (debug %bad-permission ~) :: @@ -975,7 +916,7 @@ :: |= [=verifier chain-id=@ud =state =input] ^- [effects ^state] -?: ?=(%log -.input) +?: ?=(%log +<.input) :: Received log from L1 transaction :: (receive-log state event-log.input) diff --git a/pkg/arvo/lib/ph/io.hoon b/pkg/arvo/lib/ph/io.hoon deleted file mode 100644 index e41bb9f48..000000000 --- a/pkg/arvo/lib/ph/io.hoon +++ /dev/null @@ -1,360 +0,0 @@ -/- *aquarium, spider -/+ libstrand=strand, *strandio, util=ph-util -=, strand=strand:libstrand -|% -++ send-events - |= events=(list aqua-event) - =/ m (strand ,~) - ^- form:m - (poke-our %aqua %aqua-events !>(events)) -:: -++ send-azimuth-action - |= =azimuth-action - =/ m (strand ,~) - ^- form:m - (poke-our %aqua %azimuth-action !>(azimuth-action)) -:: -++ take-unix-effect - =/ m (strand ,[ship unix-effect]) - ^- form:m - ;< [=path =cage] bind:m (take-fact-prefix /effect) - ?> ?=(%aqua-effect p.cage) - (pure:m !<([aqua-effect] q.cage)) -:: -++ start-simple - (start-test %aqua-ames %aqua-behn %aqua-dill %aqua-eyre ~) -++ end-simple - (end-test %aqua-ames %aqua-behn %aqua-dill %aqua-eyre ~) -:: -++ start-azimuth - =/ m (strand ,tid:spider) - ^- form:m - ;< ~ bind:m (start-test %aqua-ames %aqua-behn %aqua-dill ~) - (start-thread %aqua-eyre-azimuth) -:: -++ end-azimuth - (end-test %aqua-ames %aqua-behn %aqua-dill %aqua-eyre-azimuth ~) -:: -++ start-test - |= vane-threads=(list term) - =/ m (strand ,~) - ^- form:m - ~& > "starting" - ;< tids=(map term tid:spider) bind:m (start-threads vane-threads) - ;< ~ bind:m (watch-our /effect %aqua /effect) - :: Get our very own event with no mistakes in it... yet. - :: - :: We want to wait for the vane threads to actually start and get - :: their subscriptions started. Other ways to do this are delaying - :: the ack from spider until the build is finished (does that - :: guarantee the subscriptions have started?) or subscribe to the - :: threads themselves for a notification when they're done. This is - :: probably the best option because the thread can delay until it - :: gets a positive ack on the subscription. - :: - :: Threads might not get built until a %writ is dripped back to - :: spider. Drips are at +(now), so we sleep until two clicks in the - :: future. - :: - ;< ~ bind:m (sleep `@dr`2) - (pure:m ~) -:: -++ end-test - |= vane-threads=(list term) - =/ m (strand ,~) - ^- form:m - ~& > "done" - ;< ~ bind:m (stop-threads vane-threads) - ;< ~ bind:m (leave-our /effect %aqua) - (pure:m ~) -:: -++ start-threads - |= threads=(list term) - =/ m (strand ,(map term tid:spider)) - ^- form:m - ;< =bowl:spider bind:m get-bowl - =| tids=(map term tid:spider) - |- ^- form:m - =* loop $ - ?~ threads - (pure:m tids) - =/ tid - %+ scot %ta - (cat 3 (cat 3 'strand_' i.threads) (scot %uv (sham i.threads eny.bowl))) - =/ poke-vase !>([`tid.bowl ~ i.threads *vase]) - ;< ~ bind:m (poke-our %spider %spider-start poke-vase) - loop(threads t.threads, tids (~(put by tids) i.threads tid)) -:: -++ stop-threads - |= threads=(list term) - =/ m (strand ,~) - ^- form:m - (pure:m ~) -:: -:: XX +spawn-aqua and +breach-aqua mean do these actions using aqua's internal -:: azimuth management system, eventually these should just replace +spawn -:: +breach -:: -++ init-azimuth - =/ m (strand ,~) - ^- form:m - (send-azimuth-action %init-azimuth ~) -:: -++ spawn-aqua - |= =ship - ~& > "spawning {}" - =/ m (strand ,~) - ^- form:m - (send-azimuth-action %spawn ship) -:: -++ breach-aqua - |= =ship - ~& > "breaching {}" - =/ m (strand ,~) - ^- form:m - (send-azimuth-action %breach ship) -:: -++ spawn - |= [=tid:spider =ship] - ~& > "spawning {}" - =/ m (strand ,~) - =/ =vase !>(`input:spider`[tid %azimuth-command !>([%spawn ship])]) - (poke-our %spider %spider-input vase) -:: -++ breach - |= [=tid:spider who=ship] - =/ m (strand ,~) - ~& > "breaching {}" - =/ =vase - !>([tid %azimuth-command !>([%breach who])]) - (poke-our %spider %spider-input vase) -:: -:: who: breachee -:: her: wait until hears about breach -:: -++ breach-and-hear - |= [=tid:spider who=ship her=ship] - =/ m (strand ,~) - ~& > "breaching {} for {}" - ;< =bowl:spider bind:m get-bowl - =/ aqua-pax - :- %i - /(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun - =/ old-rut ;;((unit @) (scry-aqua:util noun our.bowl now.bowl aqua-pax)) - =/ new-rut - ?~ old-rut - 1 - +(+.old-rut) - =/ =vase - !>([tid %azimuth-command !>([%breach who])]) - ;< ~ bind:m (poke-our %spider %spider-input vase) - |- ^- form:m - =* loop $ - ;< [him=ship =unix-effect] bind:m take-unix-effect - ;< =bowl:spider bind:m get-bowl - =/ aqua-pax - :- %i - /(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun - =/ rut (scry-aqua:util noun our.bowl now.bowl aqua-pax) - ?: =([~ new-rut] rut) - (pure:m ~) - loop -:: -++ breach-and-hear-aqua - |= [who=ship her=ship] - =/ m (strand ,~) - ;< =bowl:spider bind:m get-bowl - =/ aqua-pax - :- %i - /(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun - =/ old-rut ;;((unit @) (scry-aqua:util noun our.bowl now.bowl aqua-pax)) - =/ new-rut - ?~ old-rut - 1 - +(+.old-rut) - ;< ~ bind:m (send-azimuth-action %breach who) - |- ^- form:m - =* loop $ - ;< ~ bind:m (sleep ~s1) - ;< =bowl:spider bind:m get-bowl - =/ aqua-pax - :- %i - /(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun - =/ rut (scry-aqua:util noun our.bowl now.bowl aqua-pax) - ?: =([~ new-rut] rut) - (pure:m ~) - loop -:: -++ init-ship - |= =ship - =/ m (strand ,~) - ^- form:m - ~& > "starting {}" - ;< ~ bind:m (send-events (init:util ship `*dawn-event:jael)) - (check-ship-booted ship) -:: -++ real-ship - |= [=tid:spider =ship] - ~& > "booting real {}" - =/ m (strand ,~) - =/ =vase !>([tid %azimuth-command !>([%create-ship ship])]) - ;< ~ bind:m (poke-our %spider %spider-input vase) - (check-ship-booted ship) -:: -++ raw-ship - |= [=ship keys=(unit dawn-event:jael)] - =/ m (strand ,~) - ^- form:m - ~& > "starting {}" - ;< ~ bind:m (send-events (init:util ship keys)) - (check-ship-booted ship) -:: -++ check-ship-booted - |= =ship - =/ m (strand ,~) - ^- form:m - =* loop $ - ;< [her=^ship =unix-effect] bind:m take-unix-effect - =/ f |=(=tape (is-dojo-output:util ship her unix-effect tape)) - :: This is a pretty bad heuristic, but in general galaxies will - :: hit the first of these cases, and other ships will hit the - :: second. - :: - ?: ?| (f ":dojo>") - (f "is your neighbor") - == - (pure:m ~) - loop -:: -++ dojo - |= [=ship =tape] - =/ m (strand ,~) - ^- form:m - ~& > "dojo: {tape}" - (send-events (dojo:util ship tape)) -:: -++ wait-for-output - |= [=ship =tape] - =/ m (strand ,~) - ^- form:m - ~& > "waiting for output: {tape}" - |- ^- form:m - =* loop $ - ;< [her=^ship =unix-effect] bind:m take-unix-effect - ?: (is-dojo-output:util ship her unix-effect tape) - (pure:m ~) - loop -:: -:: Send "|hi" from one ship to another -:: -++ send-hi - |= [from=@p to=@p] - =/ m (strand ,~) - ^- form:m - ;< ~ bind:m (dojo from "|hi {(scow %p to)}") - (wait-for-output from "hi {(scow %p to)} successful") -:: -:: Send "|hi" and wait for "not responding" message -:: -++ send-hi-not-responding - |= [from=@p to=@p] - =/ m (strand ,~) - ;< ~ bind:m (dojo from "|hi {(scow %p to)}") - (wait-for-output from "{(scow %p to)} not responding still trying") -:: -:: Mount a desk. -:: -++ mount - |= [=ship =desk] - =/ m (strand ,~) - ^- form:m - ;< ~ bind:m (dojo ship "|mount /={(trip desk)}=") - |- ^- form:m - =* loop $ - ;< [her=^ship =unix-effect] bind:m take-unix-effect - ?: (is-ergo:util ship her unix-effect) - (pure:m ~) - loop -:: -:: Modify /sur/aquarium/hoon on the given ship -:: -++ touch-file - |= [her=ship =desk extra=@t] - =/ m (strand ,@t) - ^- form:m - (touch her desk /sur/aquarium/hoon extra) -:: -:: Modify path on the given ship -:: -++ touch - |= [her=ship =desk pax=path extra=@t] - =/ m (strand ,@t) - ^- form:m - ~& > "touching file on {}/{}" - ;< ~ bind:m (mount her desk) - ;< our=@p bind:m get-our - ;< now=@da bind:m get-time - =/ aqua-pax - ;: weld - /i/(scot %p her)/cx/(scot %p her)/[desk]/(scot %da now) - pax - /noun - == - =/ warped - %^ cat 3 '=> . ' - %^ cat 3 extra - (need (scry-aqua:util (unit @) our now aqua-pax)) - ;< ~ bind:m (send-events (insert-files:util her desk [pax warped] ~)) - (pure:m warped) -:: -:: Check /sur/aquarium/hoon on the given has the given contents. -:: -++ check-file-touched - |= [=ship =desk warped=@t] - =/ m (strand ,~) - (check-touched ship desk /sur/aquarium/hoon warped) -:: -:: Check path on the given desk has the given contents. -:: -++ check-touched - |= [=ship =desk pax=path warped=@t] - =/ m (strand ,~) - ~& > "checking file touched on {}/{}" - ;< ~ bind:m (mount ship desk) - ^- form:m - |- ^- form:m - =* loop $ - ;< [her=^ship =unix-effect] bind:m take-unix-effect - ;< our=@p bind:m get-our - ;< now=@da bind:m get-time - :: %ergo is no longer sufficient because .^ is pinned to beginning of - :: the event. So we hope somebody sets a timer for something. - :: - ?. &(=(ship her) ?=(?(%init %ergo %doze) -.q.unix-effect)) - loop - =/ aqua-pax - ;: weld - /i/(scot %p ship)/cx/(scot %p ship)/[desk]/(scot %da now) - pax - /noun - == - ?: =(warped (need (scry-aqua:util (unit @) our now aqua-pax))) - (pure:m ~) - loop -:: -:: Turns poke into a dojo command -:: -++ poke-app - |= [=ship app=term =mark data=*] - =/ m (strand ,~) - ^- form:m - =/ command=tape ":{(trip app)} &{(trip mark)} {}" - (send-events (dojo:util ship command)) -:: -++ dojo-thread - |= [=ship ted=term =mark data=*] - =/ m (strand ,~) - ^- form:m - =/ command=tape "-{(trip ted)} &{(trip mark)} {}" - (send-events (dojo:util ship command)) --- diff --git a/pkg/arvo/lib/ph/io.hoon b/pkg/arvo/lib/ph/io.hoon new file mode 120000 index 000000000..9b660df8f --- /dev/null +++ b/pkg/arvo/lib/ph/io.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/ph/io.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/ph/util.hoon b/pkg/arvo/lib/ph/util.hoon deleted file mode 100644 index 09e7ff623..000000000 --- a/pkg/arvo/lib/ph/util.hoon +++ /dev/null @@ -1,112 +0,0 @@ -:: Utility functions for constructing tests -:: -/- aquarium -=, aquarium -|% -:: -:: Turn [ship (list unix-event)] into (list ph-event) -:: -++ send-events-to - |= [who=ship what=(list unix-event)] - ^- (list aqua-event) - %+ turn what - |= ue=unix-event - [%event who ue] -:: -:: Start a ship (low-level; prefer +raw-ship) -:: -++ init - |= [who=ship keys=(unit dawn-event:jael)] - ^- (list aqua-event) - [%init-ship who keys]~ -:: -:: Send dojo command -:: -++ dojo - |= [who=ship what=tape] - ^- (list aqua-event) - %+ send-events-to who - ^- (list unix-event) - :~ - [//term/1 %belt %ctl `@c`%e] - [//term/1 %belt %ctl `@c`%u] - [//term/1 %belt %txt ((list @c) what)] - [//term/1 %belt %ret ~] - == -:: -:: Control character -:: -++ ctrl - |= [who=ship what=term] - ^- (list ph-event) - %+ send-events-to who - :~ [//term/1 %belt %ctl (,@c what)] - == -:: -:: Inject a file into a ship -:: -++ insert-files - |= [who=ship des=desk files=(list [=path txt=@t])] - ^- (list aqua-event) - =/ input - %+ turn files - |= [=path txt=@t] - [path ~ /text/plain (as-octs:mimes:html txt)] - %+ send-events-to who - :~ - [//sync/0v1n.2m9vh %into des | input] - == -:: -:: Checks whether the given event is a dojo output blit containing the -:: given tape -:: -++ is-dojo-output - |= [who=ship her=ship uf=unix-effect what=tape] - ?& =(who her) - ?=(%blit -.q.uf) - :: - %+ lien p.q.uf - |= =blit:dill - ?. ?=(%lin -.blit) - | - !=(~ (find what p.blit)) - == -:: -:: Test is successful if +is-dojo-output -:: -++ expect-dojo-output - |= [who=ship her=ship uf=unix-effect what=tape] - ^- (list ph-event) - ?. (is-dojo-output who her uf what) - ~ - [%test-done &]~ -:: -:: Check whether the given event is an ergo -:: -++ is-ergo - |= [who=ship her=ship uf=unix-effect] - ?& =(who her) - ?=(%ergo -.q.uf) - == -:: -:: Check if given effect is an http request; extract -:: -++ extract-request - |= [uf=unix-effect dest=@t] - ^- (unit [num=@ud =request:http]) - ?. ?=(%request -.q.uf) ~ - ?. =(dest url.request.q.uf) ~ - `[id.q.uf request.q.uf] -:: -:: Scry into a running aqua ship -:: -++ scry-aqua - |* [a=mold our=@p now=@da pax=path] - .^ a - %gx - (scot %p our) - %aqua - (scot %da now) - pax - == --- diff --git a/pkg/arvo/lib/ph/util.hoon b/pkg/arvo/lib/ph/util.hoon new file mode 120000 index 000000000..ec423efc0 --- /dev/null +++ b/pkg/arvo/lib/ph/util.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/ph/util.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/pill.hoon b/pkg/arvo/lib/pill.hoon deleted file mode 100644 index fcde0e598..000000000 --- a/pkg/arvo/lib/pill.hoon +++ /dev/null @@ -1,152 +0,0 @@ -:: |pill: helper functions for making pills -:: -^? -|% -:: -+$ pill - $% [%ivory p=(list)] - $: %pill - nam=term - boot-ova=(list) - kernel-ova=(list unix-event) - userspace-ova=(list unix-event) - == == -:: -+$ unix-event - %+ pair wire - $% [%wack p=@] - [%what p=(list (pair path (cask)))] - [%whom p=ship] - [%boot ? $%($>(%fake task:jael) $>(%dawn task:jael))] - unix-task - == -:: +boot-ovum: boostrap kernel filesystem load -:: -++ boot-ovum - |= [hoon=cord arvo=cord] - :~ //arvo - %what - [/sys/hoon hoon/hoon] - [/sys/arvo hoon/arvo] - == -:: +file-ovum: userspace filesystem load -:: -:: bas: full path to / directory -:: -++ file-ovum - =/ directories=(list path) - :~ /app :: %gall applications - /gen :: :dojo generators - /lib :: libraries - /mar :: mark definitions - /sur :: structures - /sys :: system files - /ted :: :spider strands - /tests :: unit tests - /web :: %eyre web content - == - |= bas=path - ^- unix-event - %. directories - |= :: sal: all spurs to load from - :: - sal=(list spur) - ^- unix-event - :: - :: hav: all user files - :: - =; hav ~& user-files+(lent hav) - [/c/sync [%into %$ & hav]] - =| hav=mode:clay - |- ^+ hav - ?~ sal ~ - =. hav $(sal t.sal) - :: - :: tyl: spur - :: - =/ tyl i.sal - |- ^+ hav - :: - :: pax: full path at `tyl` - :: lon: directory at `tyl` - :: - =/ pax (weld bas (flop tyl)) - =/ lon .^(arch %cy pax) - :: XX this serialization should use marks - :: - =? hav ?=(^ fil.lon) - :: XX this whitelist needs to be reviewed - :: - ?. ?= ?(%css %hoon %html %js %json %md %png %txt %udon %umd) - -.tyl - :: - :: install only files with whitelisted marks - :: - ~& ignoring+pax - hav - :: - :: cot: file as plain-text octet-stream - :: - =; cot [[(flop `path`tyl) `[/text/plain cot]] hav] - ^- octs - ?- tyl - [%json *] - =/ dat .^(json %cx pax) - (as-octt:mimes:html (en-json:html dat)) - :: - [?(%md %txt) *] - =/ dat .^(wain %cx pax) - (as-octs:mimes:html (of-wain:format dat)) - :: - * - =/ dat .^(@t %cx pax) - [(met 3 dat) dat] - == - =/ all ~(tap by dir.lon) - |- ^- mode:clay - ?~ all hav - $(all t.all, hav ^$(tyl [p.i.all tyl])) -:: -:: +file-ovum2: electric boogaloo -:: -++ file-ovum2 |=(p=path `unix-event`[//arvo what/(user-files p)]) -:: -:: +user-files: all userspace hoon files -:: -++ user-files - |= bas=path - %. directories:file-ovum - |= sal=(list spur) - ^- (list (pair path (cask))) - :: - :: hav: all user files - :: - =| hav=(list (pair path (cask))) - |- ^+ hav - ?~ sal ~ - =. hav $(sal t.sal) - :: - :: tyl: spur - :: - =/ tyl i.sal - |- ^+ hav - :: - :: pax: full path at `tyl` - :: lon: directory at `tyl` - :: - =/ pax (weld bas (flop tyl)) - =/ lon .^(arch %cy pax) - =? hav ?=(^ fil.lon) - :: - :: install only hoon files for now - :: - ?. ?=([%hoon *] tyl) - hav - :_ hav - [(flop `path`t.tyl) hoon/.^(@t %cx pax)] - :: - =/ all ~(tap by dir.lon) - |- ^+ hav - ?~ all hav - $(all t.all, hav ^$(tyl [p.i.all tyl])) --- diff --git a/pkg/arvo/lib/pill.hoon b/pkg/arvo/lib/pill.hoon new file mode 120000 index 000000000..41e912cf1 --- /dev/null +++ b/pkg/arvo/lib/pill.hoon @@ -0,0 +1 @@ +../../base-dev/lib/pill.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/pkcs.hoon b/pkg/arvo/lib/pkcs.hoon deleted file mode 100644 index d94356174..000000000 --- a/pkg/arvo/lib/pkcs.hoon +++ /dev/null @@ -1,378 +0,0 @@ -/- asn1 -/+ primitive-rsa, der -=* rsa primitive-rsa -:::: %/lib/pkcs -|% -:: +rs256: RSA signatures over a sha-256 digest -:: -++ rs256 - |_ k=key:rsa - :: +emsa:rs256: message digest - :: - :: Padded, DER encoded sha-256 hash (EMSA-PKCS1-v1_5). - :: - ++ emsa - |= m=byts - =/ emlen (met 3 n.pub.k) - =/ pec=spec:asn1 - :~ %seq - [%seq [%obj sha-256:obj:asn1] [%nul ~] ~] - [%oct 32 (shay wid.m dat.m)] - == - :: note: this asn.1 digest is rendered raw here, as we require - :: big-endian bytes, and the product of +en:der is little-endian - :: - =/ t=(list @D) ~(ren raw:en:der pec) - =/ tlen=@ud (lent t) - ?: (lth emlen (add 11 tlen)) - ~|(%emsa-too-short !!) - =/ ps=(list @D) - (reap (sub emlen (add 3 tlen)) 0xff) - (rep 3 (flop (weld [0x0 0x1 ps] [0x0 t]))) - :: +sign:rs256: sign message - :: - :: An RSA signature is the primitive decryption of the message hash. - :: - ++ sign - |=(m=byts (de:rsa (emsa m) k)) - :: +verify:rs256: verify signature - :: - :: RSA signature verification confirms that the primitive encryption - :: of the signature matches the message hash. - :: - ++ verify - |= [s=@ m=byts] - =((emsa m) (en:rsa s k)) - -- -:: |pem: generic PEM implementation (rfc7468) -:: -:: PEM is the base64 encoding of DER encoded data, with BEGIN and -:: END labels indicating some type. -:: -++ pem - |% - :: +en:pem: PEM encode - :: - ++ en - |= [lab=@t len=@ud der=@ux] - ^- wain - :: XX validate label? - :- (rap 3 ['-----BEGIN ' lab '-----' ~]) - =/ a (en:base64:mimes:html len `@`der) - |- ^- wain - ?~ a - [(rap 3 ['-----END ' lab '-----' ~]) ~] - [(end [3 64] a) $(a (rsh [3 64] a))] - :: +de:pem: PEM decode - :: - ++ de - |= [lab=@t mep=wain] - ^- (unit [len=@ud der=@ux]) - =/ a (sub (lent mep) 2) - ?~ mep ~ - :: XX validate label? - ?. =((rap 3 ['-----BEGIN ' lab '-----' ~]) i.mep) ~ - ?. =((rap 3 ['-----END ' lab '-----' ~]) (snag a t.mep)) ~ - ^- (unit [@ @]) - (de:base64:mimes:html (rap 3 (scag a t.mep))) - -- -:: |pkcs1: RSA asymmetric cryptography (rfc3447) -:: -++ pkcs1 - |% - :: |spec:pkcs1: ASN.1 specs for RSA keys - :: - ++ spec - |% - :: |en:spec:pkcs1: ASN.1 encoding for RSA keys - :: - ++ en - |% - :: +pass:en:spec:pkcs1: encode public key to ASN.1 - :: - ++ pass - |= k=key:rsa - ^- spec:asn1 - [%seq [%int n.pub.k] [%int e.pub.k] ~] - :: +ring:en:spec:pkcs1: encode private key to ASN.1 - :: - ++ ring - |= k=key:rsa - ^- spec:asn1 - ~| %rsa-need-ring - ?> ?=(^ sek.k) - :~ %seq - [%int 0] - [%int n.pub.k] - [%int e.pub.k] - [%int d.u.sek.k] - [%int p.u.sek.k] - [%int q.u.sek.k] - [%int (mod d.u.sek.k (dec p.u.sek.k))] - [%int (mod d.u.sek.k (dec q.u.sek.k))] - [%int (~(inv fo p.u.sek.k) q.u.sek.k)] - == - -- - :: |de:spec:pkcs1: ASN.1 decoding for RSA keys - :: - ++ de - |% - :: +pass:de:spec:pkcs1: decode ASN.1 public key - :: - ++ pass - |= a=spec:asn1 - ^- (unit key:rsa) - ?. ?=([%seq [%int *] [%int *] ~] a) - ~ - =* n int.i.seq.a - =* e int.i.t.seq.a - `[[n e] ~] - :: +ring:de:spec:pkcs1: decode ASN.1 private key - :: - ++ ring - |= a=spec:asn1 - ^- (unit key:rsa) - ?. ?=([%seq *] a) ~ - ?. ?= $: [%int %0] - [%int *] - [%int *] - [%int *] - [%int *] - [%int *] - * - == - seq.a - ~ - =* n int.i.t.seq.a - =* e int.i.t.t.seq.a - =* d int.i.t.t.t.seq.a - =* p int.i.t.t.t.t.seq.a - =* q int.i.t.t.t.t.t.seq.a - `[[n e] `[d p q]] - -- - -- - :: |der:pkcs1: DER encoding for RSA keys - :: - :: En(coding) and de(coding) for public (pass) and private (ring) keys. - :: - ++ der - |% - ++ en - |% - ++ pass |=(k=key:rsa (en:^der (pass:en:spec k))) - ++ ring |=(k=key:rsa (en:^der (ring:en:spec k))) - -- - ++ de - |% - ++ pass |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) pass:de:spec)) - ++ ring |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) ring:de:spec)) - -- - -- - :: |pem:pkcs1: PEM encoding for RSA keys - :: - :: En(coding) and de(coding) for public (pass) and private (ring) keys. - :: - ++ pem - |% - ++ en - |% - ++ pass |=(k=key:rsa (en:^pem 'RSA PUBLIC KEY' (pass:en:der k))) - ++ ring |=(k=key:rsa (en:^pem 'RSA PRIVATE KEY' (ring:en:der k))) - -- - ++ de - |% - ++ pass |=(mep=wain (biff (de:^pem 'RSA PUBLIC KEY' mep) pass:de:der)) - ++ ring |=(mep=wain (biff (de:^pem 'RSA PRIVATE KEY' mep) ring:de:der)) - -- - -- - -- -:: |pkcs8: asymmetric cryptography (rfc5208, rfc5958) -:: -:: RSA-only for now. -:: -++ pkcs8 - |% - :: |spec:pkcs8: ASN.1 specs for asymmetric keys - :: - ++ spec - |% - ++ en - |% - :: +pass:spec:pkcs8: public key ASN.1 - :: - :: Technically not part of pkcs8, but standardized later in - :: the superseding RFC. Included here for symmetry. - :: - ++ pass - |= k=key:rsa - ^- spec:asn1 - :~ %seq - [%seq [[%obj rsa:obj:asn1] [%nul ~] ~]] - =/ a=[len=@ud dat=@ux] - (pass:en:der:pkcs1 k) - [%bit (mul 8 len.a) dat.a] - == - :: +ring:spec:pkcs8: private key ASN.1 - :: - ++ ring - |= k=key:rsa - ^- spec:asn1 - :~ %seq - [%int 0] - [%seq [[%obj rsa:obj:asn1] [%nul ~] ~]] - [%oct (ring:en:der:pkcs1 k)] - == - -- - :: |de:spec:pkcs8: ASN.1 decoding for asymmetric keys - :: - ++ de - |% - :: +pass:de:spec:pkcs8: decode public key ASN.1 - :: - ++ pass - |= a=spec:asn1 - ^- (unit key:rsa) - ?. ?=([%seq [%seq *] [%bit *] ~] a) - ~ - ?. ?& ?=([[%obj *] [%nul ~] ~] seq.i.seq.a) - =(rsa:obj:asn1 obj.i.seq.i.seq.a) - == - ~ - (pass:de:der:pkcs1 (div len.i.t.seq.a 8) bit.i.t.seq.a) - :: +ring:de:spec:pkcs8: decode private key ASN.1 - :: - ++ ring - |= a=spec:asn1 - ^- (unit key:rsa) - ?. ?=([%seq [%int %0] [%seq *] [%oct *] ~] a) - ~ - ?. ?& ?=([[%obj *] [%nul ~] ~] seq.i.t.seq.a) - =(rsa:obj:asn1 obj.i.seq.i.t.seq.a) - == - ~ - (ring:de:der:pkcs1 [len oct]:i.t.t.seq.a) - -- - -- - :: |der:pkcs8: DER encoding for asymmetric keys - :: - :: En(coding) and de(coding) for public (pass) and private (ring) keys. - :: RSA-only for now. - :: - ++ der - |% - ++ en - |% - ++ pass |=(k=key:rsa `[len=@ud dat=@ux]`(en:^der (pass:en:spec k))) - ++ ring |=(k=key:rsa `[len=@ud dat=@ux]`(en:^der (ring:en:spec k))) - -- - ++ de - |% - ++ pass |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) pass:de:spec)) - ++ ring |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) ring:de:spec)) - -- - -- - :: |pem:pkcs8: PEM encoding for asymmetric keys - :: - :: En(coding) and de(coding) for public (pass) and private (ring) keys. - :: RSA-only for now. - :: - ++ pem - |% - ++ en - |% - ++ pass |=(k=key:rsa (en:^pem 'PUBLIC KEY' (pass:en:der k))) - ++ ring |=(k=key:rsa (en:^pem 'PRIVATE KEY' (ring:en:der k))) - -- - ++ de - |% - ++ pass |=(mep=wain (biff (de:^pem 'PUBLIC KEY' mep) pass:de:der)) - ++ ring |=(mep=wain (biff (de:^pem 'PRIVATE KEY' mep) ring:de:der)) - -- - -- - -- -:: |pkcs10: certificate signing requests (rfc2986) -:: -:: Only implemented for RSA keys with subject-alternate names. -:: -++ pkcs10 - => |% - :: +csr:pkcs10: certificate request - :: - +$ csr [key=key:rsa hot=(list turf)] - -- - |% - :: |spec:pkcs10: ASN.1 specs for certificate signing requests - :: - ++ spec - |% - :: +en:spec:pkcs10: ASN.1 encoding for certificate signing requests - :: - ++ en - |= csr - ^- spec:asn1 - |^ =/ dat=spec:asn1 (info key hot) - :~ %seq - dat - [%seq [[%obj rsa-sha-256:obj:asn1] [%nul ~] ~]] - :: big-endian signature bits - :: - :: the signature bitwidth is definitionally the key length - :: - :+ %bit - (met 0 n.pub.key) - (swp 3 (~(sign rs256 key) (en:^der dat))) - == - :: +info:en:spec:pkcs10: certificate request info - :: - ++ info - |= csr - ^- spec:asn1 - :~ %seq - [%int 0] - [%seq ~] - (pass:en:spec:pkcs8 key) - :: explicit, context-specific tag #0 (extensions) - :: - :+ %con - `bespoke:asn1`[| 0] - %~ ren - raw:en:^der - :~ %seq - [%obj csr-ext:obj:asn1] - :~ %set - :~ %seq - :~ %seq - [%obj sub-alt:obj:asn1] - [%oct (en:^der (san hot))] - == == == == == - :: +san:en:spec:pkcs10: subject-alternate-names - :: - ++ san - |= hot=(list turf) - ^- spec:asn1 - :- %seq - %+ turn hot - :: implicit, context-specific tag #2 (IA5String) - :: XX sanitize string? - |=(=turf [%con `bespoke:asn1`[& 2] (trip (en-turf:html turf))]) - -- - :: |de:spec:pkcs10: ASN.1 decoding for certificate signing requests - ++ de !! - -- - :: |der:pkcs10: DER encoding for certificate signing requests - :: - ++ der - |% - ++ en |=(a=csr `[len=@ud der=@ux]`(en:^der (en:spec a))) - ++ de !! ::|=(a=@ `(unit csr)`(biff (de:^der a) de:spec)) - -- - :: |pem:pkcs10: PEM encoding for certificate signing requests - :: - ++ pem - |% - ++ en |=(a=csr (en:^pem 'CERTIFICATE REQUEST' (en:der a))) - ++ de !! ::|=(mep=wain (biff (de:^pem 'CERTIFICATE REQUEST' mep) de:der)) - -- - -- --- - diff --git a/pkg/arvo/lib/pkcs.hoon b/pkg/arvo/lib/pkcs.hoon new file mode 120000 index 000000000..d7a2ab46f --- /dev/null +++ b/pkg/arvo/lib/pkcs.hoon @@ -0,0 +1 @@ +../../base-dev/lib/pkcs.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/primitive-rsa.hoon b/pkg/arvo/lib/primitive-rsa.hoon deleted file mode 100644 index b843e2545..000000000 --- a/pkg/arvo/lib/primitive-rsa.hoon +++ /dev/null @@ -1,84 +0,0 @@ -:: |rsa: primitive, textbook RSA -:: -:: Unpadded, unsafe, unsuitable for encryption! -:: -|% -:: +key:rsa: rsa public or private key -:: -+$ key - $: :: pub: public parameters (n=modulus, e=pub-exponent) - :: - pub=[n=@ux e=@ux] - :: sek: secret parameters (d=private-exponent, p/q=primes) - :: - sek=(unit [d=@ux p=@ux q=@ux]) - == -:: +ramp: make rabin-miller probabilistic prime -:: -:: XX replace +ramp:number? -:: a: bitwidth -:: b: snags (XX small primes to check divisibility?) -:: c: entropy -:: -++ ramp - |= [a=@ b=(list @) c=@] - =. c (shas %ramp c) - :: XX what is this value? - :: - =| d=@ - |- ^- @ux - :: XX what is this condition? - :: - ?: =((mul 100 a) d) - ~|(%ar-ramp !!) - :: e: prime candidate - :: - :: Sets low bit, as prime must be odd. - :: Sets high bit, as +raw:og only gives up to :a bits. - :: - =/ e :(con 1 (lsh [0 (dec a)] 1) (~(raw og c) a)) - :: XX what algorithm is this modular remainder check? - :: - ?: ?& (levy b |=(f=@ !=(1 (mod e f)))) - (pram:number e) - == - e - $(c +(c), d (shax d)) -:: +elcm:rsa: carmichael totient -:: -++ elcm - |= [a=@ b=@] - (div (mul a b) d:(egcd a b)) -:: +new-key:rsa: write somethingXXX -:: -++ new-key - =/ e `@ux`65.537 - |= [wid=@ eny=@] - ^- key - =/ diw (rsh 0 wid) - =/ p=@ux (ramp diw [3 5 ~] eny) - =/ q=@ux (ramp diw [3 5 ~] +(eny)) - =/ n=@ux (mul p q) - =/ d=@ux (~(inv fo (elcm (dec p) (dec q))) e) - [[n e] `[d p q]] -:: +en:rsa: primitive RSA encryption -:: -:: ciphertext = message^e (mod n) -:: -++ en - |= [m=@ k=key] - ~| %rsa-len - ?> (lte (met 0 m) (met 0 n.pub.k)) - (~(exp fo n.pub.k) e.pub.k m) -:: +de:rsa: primitive RSA decryption -:: -:: message = ciphertext^d (mod e) -:: -++ de - |= [m=@ k=key] - :: XX assert rsa-len here too? - ~| %rsa-need-ring - ?> ?=(^ sek.k) - =/ fu (fu:number p.u.sek.k q.u.sek.k) - (out.fu (exp.fu d.u.sek.k (sit.fu m))) --- diff --git a/pkg/arvo/lib/primitive-rsa.hoon b/pkg/arvo/lib/primitive-rsa.hoon new file mode 120000 index 000000000..f9dde2d95 --- /dev/null +++ b/pkg/arvo/lib/primitive-rsa.hoon @@ -0,0 +1 @@ +../../base-dev/lib/primitive-rsa.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/ring.hoon b/pkg/arvo/lib/ring.hoon deleted file mode 100644 index a7be742b7..000000000 --- a/pkg/arvo/lib/ring.hoon +++ /dev/null @@ -1,477 +0,0 @@ -/- *ring -:: ring signatures over the edwards curve -:: -|% -:: +raw is the raw internal ring signature implementation. +raw does not deal -:: with urbit ship identities or urbit nouns and is low level. It only deals -:: with ed25519 keys and message digests. -:: -:: This raw interface is vaguely modeled on the haskell aos-signature package, -:: but is written in terms of ed25519 primitives instead of general ECC and -:: changes how linkage tags are computed so that how linkage occurs is a -:: client decision instead of hard coding the set of public keys as the -:: linkage scope. -:: -++ raw - |% - :: +generate-public-linkage: generate public linkage information - :: - ++ generate-public-linkage - |= link-scope=@ - ^- [data=@ h=@udpoint] - :: - =/ data=@ (mod link-scope l:ed:crypto) - =/ h=@udpoint (scalarmult-base:ed:crypto data) - [data h] - :: +generate-linkage: linkage information from scope and private key - :: - :: data: deterministically picked data point based off scope - :: h: h = [data] * g - :: y: y = [x] * h - ++ generate-linkage - |= [link-scope=(unit @) my-private-key=@] - ^- (unit [data=@ h=@udpoint y=@udpoint]) - :: - ?~ link-scope - ~ - :: - =+ [data=@ h=@udpoint]=(generate-public-linkage u.link-scope) - =/ y=@udpoint (scalarmult:ed:crypto my-private-key h) - [~ data h y] - :: +generate-challenge: generate challenge from a given message - :: - :: When :link-scope is ~ (ie, we're not building a linked ring signature), - :: calculates just the hash of `[message g]`. Otherwise, weaves the - :: linkage state into the challenge. - :: - ++ generate-challenge - |= $: :: common to both linked and unlinked - message=@ - g=@udpoint - :: high level universal state - :: - link-state=(unit [data=@ h=@udpoint y=@udpoint]) - :: point to include in challenge when link-state isn't ~ - :: - h=(unit @udpoint) - == - ^- @ - :: concatenate and reduce our message down to a 512-bit hash - =/ concatenated - ?~ link-state - (shal 96 (can 3 ~[[64 message] [32 g]])) - :: - %+ shal 192 - %+ can 3 - :~ [64 message] - [32 g] - [32 data.u.link-state] - [32 y.u.link-state] - [32 (need h)] - == - :: - (mod concatenated l:ed:crypto) - :: +generate-challenges: generates the full list of challenges - :: - ++ generate-challenges - |= $: link-state=(unit [data=@ h=@udpoint y=@udpoint]) - message=@ - public-keys=(list @udpoint) - ss=(list @) - :: - prev-k=@u - prev-s=@ - prev-ch=@ - challenges=(list @) - == - ^- (list @) - :: - =/ gs=@udpoint - %- add-scalarmult-scalarmult-base:ed:crypto :* - prev-ch - (snag prev-k public-keys) - prev-s - == - :: - =/ hs=(unit @udpoint) - ?~ link-state - ~ - :: - :- ~ - %- add-double-scalarmult:ed:crypto :* - prev-s - h.u.link-state - prev-ch - y.u.link-state - == - :: - =/ ch=@ - (generate-challenge message gs link-state hs) - :: - ?~ ss - [ch challenges] - :: - %_ $ - prev-k (mod (add prev-k 1) (lent public-keys)) - prev-s i.ss - prev-ch ch - ss t.ss - challenges [ch challenges] - == - :: +scalarmult-h: maybe multiply u by h in linkage - :: - :: Since linkage tags are optional, we need to be able to just do the math - :: in case :linkage is set and fall through otherwise. +scalarmult-h is - :: used to generate the (unit point) consumed by +generate-challenge. - :: - ++ scalarmult-h - |= [u=@ linkage=(unit [data=@ h=@udpoint y=@udpoint])] - ^- (unit @udpoint) - ?~ linkage - ~ - [~ (scalarmult:ed:crypto u h.u.linkage)] - :: +reorder: reorders a list so the ith element is first - :: - ++ reorder - |* [i=@ l=(list)] - %+ weld - (slag i l) - (scag i l) - :: +sign: creates a ring signature on an ed25519 curve - :: - ++ sign - |= $: message=@ - link-scope=(unit @) - :: - anonymity-set=(set @udpoint) - my-public-key=@udpoint - my-private-key=@udscalar - :: - eny=@uvJ - == - ^- raw-ring-signature - |^ :: k: our public-key's position in :anonymity-list - :: - =/ k=@u - ~| [%couldnt-find my-public-key in=anonymity-list] - (need (find [my-public-key ~] anonymity-list)) - :: Generate linkage information if given - :: - =/ linkage=(unit [data=@ h=@udpoint y=@udpoint]) - (generate-linkage link-scope my-private-key) - :: initialize our random number generator from entropy - :: - =+ rand=~(. og eny) - :: generate the random s values used in the ring - :: - =^ random-s-values=(list @) rand - =| count=@ - =| random-s-values=(list @) - |- - ?: =(count (sub participants 1)) - [random-s-values rand] - :: - =^ v=@ rand (rads:rand l:ed:crypto) - $(count (add 1 count), random-s-values [v random-s-values]) - :: - ?> ?=(^ random-s-values) - =/ sk1=@ i.random-s-values - =/ sk2-to-prev-sk=(list @) t.random-s-values - :: Pick a random :u - :: - =^ u=@ rand - (rads:rand l:ed:crypto) - :: Compute challenge at k + 1 - :: - =/ chk1=@ - %- generate-challenge :* - message - (scalarmult-base:ed:crypto u) - linkage - (scalarmult-h u linkage) - == - :: Generate challenges for [ck, ..., c1, c0, ... ck + 2, ck + 1] - :: - =/ reversed-chk-to-chk1=(list @) - %- generate-challenges :* - linkage - message - anonymity-list - sk2-to-prev-sk - :: - (mod (add k 1) participants) - sk1 - chk1 - [chk1 ~] - == - =/ chk=@ (head reversed-chk-to-chk1) - :: Compute s = u - x * c mod n - :: - =/ sk=@ (~(dif fo l:ed:crypto) u (mul my-private-key chk)) - :: - =/ ordered-challenges=(list @) - (order-challenges k (flop reversed-chk-to-chk1)) - :: - =/ ordered-ss=(list @) (order-ss k [sk sk1 sk2-to-prev-sk]) - =/ ch0 (head ordered-challenges) - :: - [ch0 ordered-ss ?~(linkage ~ `y.u.linkage)] - :: - ++ anonymity-list - ~(tap in anonymity-set) - :: - ++ participants - (lent anonymity-list) - :: - ++ order-challenges - |= [k=@ ch=(list @)] - (reorder (sub participants (add k 1)) ch) - :: - ++ order-ss - |= [k=@ sk-to-prev-sk=(list @)] - (reorder (sub participants k) sk-to-prev-sk) - -- - :: +verify: verify signature - :: - ++ verify - |= $: message=@ - link-scope=(unit @) - :: - anonymity-set=(set @udpoint) - signature=raw-ring-signature - == - ^- ? - :: if there's a linkage scope but no tag, fail - :: - ?: &(?=(^ link-scope) ?=(~ y.signature)) - %.n - :: if there's no linkage scope but a tag, fail - :: - ?: &(?=(~ link-scope) ?=(^ y.signature)) - %.n - :: vice versa. - :: - :: decompose the signature into [s0 s1 s2....] - :: - ?> ?=([@ @ *] s.signature) - =/ s0=@ i.s.signature - =/ s1=@ i.t.s.signature - =/ s2-to-end=(list @) t.t.s.signature - :: anonymity-list: set of public keys listified in ring order - :: - =/ anonymity-list=(list @udpoint) - ~(tap in anonymity-set) - :: participants: length of :anonymity-list - :: - =/ participants=@u - (lent anonymity-list) - :: - =/ z0p=@udpoint - %- add-scalarmult-scalarmult-base:ed:crypto :* - ch0.signature - (head anonymity-list) - s0 - == - :: generate the linkage using public data, and the y point from the - :: signature - :: - =/ linkage=(unit [data=@ h=@udpoint y=@udpoint]) - ?~ link-scope - ~ - =+ [data=@ h=@udpoint]=(generate-public-linkage u.link-scope) - :- ~ - [data h (need y.signature)] - :: - =/ z0pp=(unit @udpoint) - ?~ linkage - ~ - :- ~ - %- add-double-scalarmult:ed:crypto :* - s0 - h.u.linkage - ch0.signature - y.u.linkage - == - :: initial challenge - :: - =/ ch1=@ - (generate-challenge message z0p linkage z0pp) - :: - =/ challenges - %- generate-challenges :* - linkage - message - anonymity-list - s2-to-end - :: - (mod 1 participants) - s1 - ch1 - [ch1 ~] - == - :: - =(ch0.signature (head challenges)) - -- -:: +detail: details about getting keys from Azimuth -:: -++ detail - |% - :: +seed-to-private-key-scalar: keyfile form to scalar we can multiply with - :: - ++ seed-to-private-key-scalar - |= sk=@I ^- @udscalar - ?: (gth (met 3 sk) 32) !! - =+ h=(shal (rsh [0 3] b:ed:crypto) sk) - %+ add - (bex (sub b:ed:crypto 2)) - (lsh [0 3] (cut 0 [3 (sub b:ed:crypto 5)] h)) - :: +get-public-key-from-pass: decode the raw @ public key structure - :: - ++ get-public-key-from-pass - |= a=pass - ^- [@ @] - =+ [mag=(end 3 a) bod=(rsh 3 a)] - ~| %not-crub-pubkey ?> =('b' mag) - [cry=(rsh 8 bod) sgn=(end 8 bod)] - :: - :: - ++ get-private-key-from-ring - |= a=ring - ^- [@ @] - =+ [mag=(end 3 a) bod=(rsh 3 a)] - ~| %not-crub-seckey ?> =('B' mag) - =+ [c=(rsh 8 bod) s=(end 8 bod)] - :: todo: do we puck here? - [c s] - :: +ship-life-to-pubid: fetches public key information from jael - :: - ++ ship-life-to-pubid - |= [our=@p now=@da ship=@p =life] - ^- @udpoint - :: - =/ d=[=^life =pass] - =/ scry-path=path - :~ %k - (scot %p our) - (scot %da now) - (scot %p ship) - (scot %ud life) - == - .^([^life pass] scry-path) - :: we have the deed which has pass, which is several numbers +cat-ed - :: together; pull out the keys - :: - =/ x=[crypt=@ auth=@] (get-public-key-from-pass pass.d) - :: - `@udpoint`auth.x - :: - ++ build-signing-participants - |= [our=@p now=@da invited=(list @p)] - ^- [(set [@p life]) (set @udpoint)] - :: - =| participants=(set [@p life]) - =| keys=(set @udpoint) - :: - |- - ?~ invited - [participants keys] - :: - =/ =life - .^(life k+/(scot %p our)/life/(scot %da now)/(scot %p i.invited)) - :: - ?: =(life 0) - $(invited t.invited) - :: - =/ pubkey=@udpoint (ship-life-to-pubid our now i.invited life) - :: - =. participants (~(put in participants) [i.invited life]) - =. keys (~(put in keys) pubkey) - :: - $(invited t.invited) - :: - :: - ++ build-verifying-participants - |= [our=@p now=@da invited=(list [ship=@p =life])] - ^- (set @udpoint) - :: - =| keys=(set @udpoint) - :: - |- - ?~ invited - keys - :: - =/ pubkey=@udpoint - (ship-life-to-pubid our now ship.i.invited life.i.invited) - =. keys - (~(put in keys) pubkey) - :: - $(invited t.invited) - -- --- -:: public interface -:: -|% -:: +sign: ring-signs a message using the current ship -:: -++ sign - |= $: our=@p - now=@da - eny=@uvJ - :: - message=* - link-scope=(unit *) - anonymity-set=(set @p) - == - ^- ring-signature - :: if our is not in @p, we must be in @p. - :: - =. anonymity-set (~(put in anonymity-set) our) - :: - =/ msg-hash=@ (shaz (jam message)) - =/ link-hash=(unit @) (bind link-scope |=(a=* (shaz (jam a)))) - :: get everyone's public keys - :: - =/ p=[participants=(set [ship=@p =life]) keys=(set @udpoint)] - (build-signing-participants:detail our now ~(tap in anonymity-set)) - :: get our ships' current life - :: - =/ our-life=life - .^(life %k /(scot %p our)/life/(scot %da now)/(scot %p our)) - :: get our ships' secret keyfile ring - :: - =/ secret-ring=ring - .^(ring %k /(scot %p our)/vein/(scot %da now)/(scot %ud our-life)) - :: fetch the encoded auth seed from the ring - :: - =/ secret-auth-seed=@ - +:(get-private-key-from-ring:detail secret-ring) - :: get our ships' public key - :: - =/ public-key=@udpoint - (ship-life-to-pubid:detail our now our our-life) - :: - :- participants.p - :- link-scope - %- sign:raw :* - msg-hash - link-hash - keys.p - public-key - (seed-to-private-key-scalar:detail secret-auth-seed) - eny - == -:: +verify: verifies a message against a ring signature -:: -++ verify - |= [our=@p now=@da message=* =ring-signature] - ^- ? - :: - =/ keys=(set @udpoint) - %^ build-verifying-participants:detail our now - ~(tap in participants.ring-signature) - :: - =/ msg-hash=@ (shaz (jam message)) - =/ link-hash=(unit @) (bind link-scope.ring-signature |=(a=* (shaz (jam a)))) - :: - (verify:raw msg-hash link-hash keys raw.ring-signature) --- diff --git a/pkg/arvo/lib/ring.hoon b/pkg/arvo/lib/ring.hoon new file mode 120000 index 000000000..e5e819947 --- /dev/null +++ b/pkg/arvo/lib/ring.hoon @@ -0,0 +1 @@ +../../base-dev/lib/ring.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/server.hoon b/pkg/arvo/lib/server.hoon deleted file mode 100644 index 431b5db8a..000000000 --- a/pkg/arvo/lib/server.hoon +++ /dev/null @@ -1,159 +0,0 @@ -=, eyre -|% -+$ request-line - $: [ext=(unit @ta) site=(list @t)] - args=(list [key=@t value=@t]) - == -:: +parse-request-line: take a cord and parse out a url -:: -++ parse-request-line - |= url=@t - ^- request-line - (fall (rush url ;~(plug apat:de-purl:html yque:de-purl:html)) [[~ ~] ~]) -:: -++ manx-to-octs - |= man=manx - ^- octs - (as-octt:mimes:html (en-xml:html man)) -:: -++ json-to-octs - |= jon=json - ^- octs - (as-octt:mimes:html (en-json:html jon)) -:: -++ app - |% - :: - :: +require-authorization: - :: redirect to the login page when unauthenticated - :: otherwise call handler on inbound request - :: - ++ require-authorization - |= $: =inbound-request:eyre - handler=$-(inbound-request:eyre simple-payload:http) - == - ^- simple-payload:http - :: - ?: authenticated.inbound-request - ~! this - ~! +:*handler - (handler inbound-request) - :: - =- [[307 ['location' -]~] ~] - %^ cat 3 - '/~/login?redirect=' - url.request.inbound-request - :: - :: +require-authorization-simple: - :: redirect to the login page when unauthenticated - :: otherwise pass through simple-paylod - :: - ++ require-authorization-simple - |= [=inbound-request:eyre =simple-payload:http] - ^- simple-payload:http - :: - ?: authenticated.inbound-request - ~! this - simple-payload - :: - =- [[307 ['location' -]~] ~] - %^ cat 3 - '/~/login?redirect=' - url.request.inbound-request - :: - ++ give-simple-payload - |= [eyre-id=@ta =simple-payload:http] - ^- (list card:agent:gall) - =/ header-cage - [%http-response-header !>(response-header.simple-payload)] - =/ data-cage - [%http-response-data !>(data.simple-payload)] - :~ [%give %fact ~[/http-response/[eyre-id]] header-cage] - [%give %fact ~[/http-response/[eyre-id]] data-cage] - [%give %kick ~[/http-response/[eyre-id]] ~] - == - -- -++ gen - |% - :: - ++ max-1-da ['cache-control' 'max-age=86400'] - ++ max-1-wk ['cache-control' 'max-age=604800'] - :: - ++ html-response - =| cache=? - |= =octs - ^- simple-payload:http - :_ `octs - [200 [['content-type' 'text/html'] ?:(cache [max-1-wk ~] ~)]] - :: - ++ css-response - =| cache=? - |= =octs - ^- simple-payload:http - :_ `octs - [200 [['content-type' 'text/css'] ?:(cache [max-1-wk ~] ~)]] - :: - ++ js-response - =| cache=? - |= =octs - ^- simple-payload:http - :_ `octs - [200 [['content-type' 'text/javascript'] ?:(cache [max-1-wk ~] ~)]] - :: - ++ png-response - =| cache=? - |= =octs - ^- simple-payload:http - :_ `octs - [200 [['content-type' 'image/png'] ?:(cache [max-1-wk ~] ~)]] - :: - ++ svg-response - =| cache=? - |= =octs - ^- simple-payload:http - :_ `octs - [200 [['content-type' 'image/svg+xml'] ?:(cache [max-1-wk ~] ~)]] - :: - ++ ico-response - |= =octs - ^- simple-payload:http - [[200 [['content-type' 'image/x-icon'] max-1-wk ~]] `octs] - :: - ++ woff2-response - =| cache=? - |= =octs - ^- simple-payload:http - [[200 [['content-type' 'font/woff2'] max-1-wk ~]] `octs] - :: - ++ json-response - =| cache=_| - |= =json - ^- simple-payload:http - :_ `(json-to-octs json) - [200 [['content-type' 'application/json'] ?:(cache [max-1-da ~] ~)]] - :: - ++ manx-response - =| cache=_| - |= man=manx - ^- simple-payload:http - :_ `(manx-to-octs man) - [200 [['content-type' 'text/html'] ?:(cache [max-1-da ~] ~)]] - :: - ++ not-found - ^- simple-payload:http - [[404 ~] ~] - :: - ++ login-redirect - |= =request:http - ^- simple-payload:http - =- [[307 ['location' -]~] ~] - %^ cat 3 - '/~/login?redirect=' - url.request - :: - ++ redirect - |= redirect=cord - ^- simple-payload:http - [[307 ['location' redirect]~] ~] - -- --- diff --git a/pkg/arvo/lib/server.hoon b/pkg/arvo/lib/server.hoon new file mode 120000 index 000000000..6176cfc00 --- /dev/null +++ b/pkg/arvo/lib/server.hoon @@ -0,0 +1 @@ +../../base-dev/lib/server.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/shoe.hoon b/pkg/arvo/lib/shoe.hoon deleted file mode 100644 index 0348e10e5..000000000 --- a/pkg/arvo/lib/shoe.hoon +++ /dev/null @@ -1,532 +0,0 @@ -:: shoe: console application library -:: -:: /lib/sole: draw some characters -:: /lib/shoe: draw the rest of the fscking app -:: -:: call +agent with a type, then call the resulting function with a core -:: of the shape described in +shoe. -:: you may produce classic gall cards and "shoe-effects", shorthands for -:: sending cli events to connected clients. -:: default implementations for the shoe-specific arms are in +default. -:: for a simple usage example, see /app/shoe. -:: -/- *sole -/+ sole, auto=language-server-complete -|% -+$ state-0 - $: %0 - soles=(map @ta sole-share) - == -:: $card: standard gall cards plus shoe effects -:: -+$ card - $% card:agent:gall - [%shoe sole-ids=(list @ta) effect=shoe-effect] :: ~ sends to all soles - == -:: $shoe-effect: easier sole-effects -:: -+$ shoe-effect - $% :: %sole: raw sole-effect - :: - [%sole effect=sole-effect] - :: %table: sortable, filterable data, with suggested column char widths - :: - [%table head=(list dime) wide=(list @ud) rows=(list (list dime))] - :: %row: line sections with suggested char widths - :: - [%row wide=(list @ud) cols=(list dime)] - == -:: +shoe: gall agent core with extra arms -:: -++ shoe - |* command-type=mold - $_ ^| - |_ bowl:gall - :: +command-parser: input parser for a specific session - :: - :: if the head of the result is true, instantly run the command - :: - ++ command-parser - |~ sole-id=@ta - |~(nail *(like [? command-type])) - :: +tab-list: autocomplete options for the session (to match +command-parser) - :: - ++ tab-list - |~ sole-id=@ta - :: (list [@t tank]) - *(list (option:auto tank)) - :: +on-command: called when a valid command is run - :: - ++ on-command - |~ [sole-id=@ta command=command-type] - *(quip card _^|(..on-init)) - :: - ++ can-connect - |~ sole-id=@ta - *? - :: - ++ on-connect - |~ sole-id=@ta - *(quip card _^|(..on-init)) - :: - ++ on-disconnect - |~ sole-id=@ta - *(quip card _^|(..on-init)) - :: - ::NOTE standard gall agent arms below, though they may produce %shoe cards - :: - ++ on-init - *(quip card _^|(..on-init)) - :: - ++ on-save - *vase - :: - ++ on-load - |~ vase - *(quip card _^|(..on-init)) - :: - ++ on-poke - |~ [mark vase] - *(quip card _^|(..on-init)) - :: - ++ on-watch - |~ path - *(quip card _^|(..on-init)) - :: - ++ on-leave - |~ path - *(quip card _^|(..on-init)) - :: - ++ on-peek - |~ path - *(unit (unit cage)) - :: - ++ on-agent - |~ [wire sign:agent:gall] - *(quip card _^|(..on-init)) - :: - ++ on-arvo - |~ [wire sign-arvo] - *(quip card _^|(..on-init)) - :: - ++ on-fail - |~ [term tang] - *(quip card _^|(..on-init)) - -- -:: +default: bare-minimum implementations of shoe arms -:: -++ default - |* [shoe=* command-type=mold] - |_ =bowl:gall - ++ command-parser - |= sole-id=@ta - (easy *[? command-type]) - :: - ++ tab-list - |= sole-id=@ta - ~ - :: - ++ on-command - |= [sole-id=@ta command=command-type] - [~ shoe] - :: - ++ can-connect - |= sole-id=@ta - (team:title [our src]:bowl) - :: - ++ on-connect - |= sole-id=@ta - [~ shoe] - :: - ++ on-disconnect - |= sole-id=@ta - [~ shoe] - -- -:: +agent: creates wrapper core that handles sole events and calls shoe arms -:: -++ agent - |* command-type=mold - |= =(shoe command-type) - =| state-0 - =* state - - ^- agent:gall - => - |% - ++ deal - |= cards=(list card) - %+ turn cards - |= =card - ^- card:agent:gall - ?. ?=(%shoe -.card) card - ?- -.effect.card - %sole - =- [%give %fact - %sole-effect !>(effect.effect.card)] - %+ turn - ?^ sole-ids.card sole-ids.card - ~(tap in ~(key by soles)) - |= sole-id=@ta - /sole/[sole-id] - :: - %table - =; fez=(list sole-effect) - $(effect.card [%sole %mor fez]) - =, +.effect.card - :- (row:draw & wide head) - %+ turn rows - (cury (cury row:draw |) wide) - :: - %row - $(effect.card [%sole (row:draw | +.effect.card)]) - == - -- - :: - |_ =bowl:gall - +* this . - og ~(. shoe bowl) - :: - ++ on-init - ^- (quip card:agent:gall agent:gall) - =^ cards shoe on-init:og - [(deal cards) this] - :: - ++ on-save !>([%shoe-app on-save:og state]) - :: - ++ on-load - |= old-state=vase - ^- (quip card:agent:gall agent:gall) - :: we could be upgrading from a shoe-less app, in which case the vase - :: contains inner application state instead of our +on-save. - :: to distinguish between the two, we check for the presence of our own - :: +on-save tag in the vase. - :: - ?. ?=([%shoe-app ^] q.old-state) - =^ cards shoe (on-load:og old-state) - [(deal cards) this] - =^ old-inner state +:!<([%shoe-app vase state-0] old-state) - =^ cards shoe (on-load:og old-inner) - [(deal cards) this] - :: - ++ on-poke - |= [=mark =vase] - ^- (quip card:agent:gall agent:gall) - ?. ?=(%sole-action mark) - =^ cards shoe (on-poke:og mark vase) - [(deal cards) this] - :: - =/ act !<(sole-action vase) - =* sole-id id.act - =/ cli-state=sole-share - (~(gut by soles) sole-id *sole-share) - |^ =^ [cards=(list card) =_cli-state] shoe - ?- -.dat.act - %det (apply-edit +.dat.act) - %clr [[~ cli-state] shoe] - %ret try-command - %tab [(tab +.dat.act) shoe] - == - :- (deal cards) - this(soles (~(put by soles) sole-id cli-state)) - :: - ++ effect - |= =sole-effect - ^- card - [%shoe [sole-id]~ %sole sole-effect] - :: - ++ apply-edit - |= =sole-change - ^+ [[*(list card) cli-state] shoe] - =^ inverse cli-state - (~(transceive sole cli-state) sole-change) - :: res: & for fully parsed, | for parsing failure at location - :: - =/ res=(each (unit [run=? cmd=command-type]) @ud) - %+ rose (tufa buf.cli-state) - (command-parser:og sole-id) - ?: ?=(%& -.res) - :: only auto-run eligible commands if they were typed out - :: (that is, not retrieved from command history) - :: - ?. &(?=(^ p.res) run.u.p.res !?=(%set -.ted.sole-change)) - [[~ cli-state] shoe] - (run-command cmd.u.p.res) - :_ shoe - :: parsing failed - :: - ?. &(?=(%del -.inverse) =(+(p.inverse) (lent buf.cli-state))) - :: if edit was somewhere in the middle, let it happen anyway - :: - [~ cli-state] - :: if edit was insertion at buffer tail, revert it - :: - =^ undo cli-state - (~(transmit sole cli-state) inverse) - :_ cli-state - :_ ~ - %+ effect %mor - :~ [%det undo] :: undo edit - [%err p.res] :: cursor to error location - == - :: - ++ try-command - ^+ [[*(list card) cli-state] shoe] - =/ res=(unit [? cmd=command-type]) - %+ rust (tufa buf.cli-state) - (command-parser:og sole-id) - ?^ res (run-command cmd.u.res) - [[[(effect %bel ~)]~ cli-state] shoe] - :: - ++ run-command - |= cmd=command-type - ^+ [[*(list card) cli-state] shoe] - =^ cards shoe (on-command:og sole-id cmd) - :: clear buffer - :: - =^ clear cli-state (~(transmit sole cli-state) [%set ~]) - =- [[[- cards] cli-state] shoe] - %+ effect %mor - :~ [%nex ~] - [%det clear] - == - :: - ++ tab - |= pos=@ud - ^- (quip card _cli-state) - =+ (get-id-cord:auto pos (tufa buf.cli-state)) - =/ needle=term - (fall id %$) - :: autocomplete empty command iff user at start of command - :: - =/ options=(list (option:auto tank)) - (search-prefix:auto needle (tab-list:og sole-id)) - =/ advance=term - (longest-match:auto options) - =/ to-send=tape - %- trip - (rsh [3 (met 3 needle)] advance) - =/ send-pos=@ud - %+ add pos - (met 3 (fall forward '')) - =| cards=(list card) - :: only render the option list if we couldn't complete anything - :: - =? cards &(?=(~ to-send) ?=(^ options)) - [(effect %tab options) cards] - |- ^- (quip card _cli-state) - ?~ to-send - [(flop cards) cli-state] - =^ char cli-state - (~(transmit sole cli-state) [%ins send-pos `@c`i.to-send]) - %_ $ - cards [(effect %det char) cards] - send-pos +(send-pos) - to-send t.to-send - == - -- - :: - ++ on-watch - |= =path - ^- (quip card:agent:gall agent:gall) - ?. ?=([%sole @ ~] path) - =^ cards shoe - (on-watch:og path) - [(deal cards) this] - =* sole-id i.t.path - ?> (can-connect:og sole-id) - =. soles (~(put by soles) sole-id *sole-share) - =^ cards shoe - (on-connect:og sole-id) - :_ this - %- deal - :_ cards - [%shoe [sole-id]~ %sole %pro & dap.bowl "> "] - :: - ++ on-leave - |= =path - ^- (quip card:agent:gall agent:gall) - =^ cards shoe (on-leave:og path) - [(deal cards) this] - :: - ++ on-peek - |= =path - ^- (unit (unit cage)) - ?. =(/x/dbug/state path) ~ - ``noun+(slop on-save:og !>(shoe=state)) - :: - ++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card:agent:gall agent:gall) - =^ cards shoe (on-agent:og wire sign) - [(deal cards) this] - :: - ++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card:agent:gall agent:gall) - =^ cards shoe (on-arvo:og wire sign-arvo) - [(deal cards) this] - :: - ++ on-fail - |= [=term =tang] - ^- (quip card:agent:gall agent:gall) - =^ cards shoe (on-fail:og term tang) - [(deal cards) this] - -- -:: -++ draw - |% - ++ row - |= [bold=? wide=(list @ud) cols=(list dime)] - ^- sole-effect - :- %mor - ^- (list sole-effect) - =/ cows=(list [wid=@ud col=dime]) - %- head - %^ spin cols wide - |= [col=dime wiz=(list @ud)] - ~| [%too-few-wide col] - ?> ?=(^ wiz) - [[i.wiz col] t.wiz] - =/ cobs=(list [wid=@ud (list tape)]) - (turn cows col-as-lines) - =+ [lin=0 any=|] - =| fez=(list sole-effect) - |- ^+ fez - =; out=tape - :: done when we're past the end of all columns - :: - ?: (levy out (cury test ' ')) - (flop fez) - =; fec=sole-effect - $(lin +(lin), fez [fec fez]) - ?. bold txt+out - klr+[[`%br ~ ~]^[(crip out)]~]~ - %+ roll cobs - |= [[wid=@ud lines=(list tape)] out=tape] - %+ weld out - %+ weld ?~(out "" " ") - =+ l=(swag [lin 1] lines) - ?^(l i.l (reap wid ' ')) - :: - ++ col-as-lines - |= [wid=@ud col=dime] - ^- [@ud (list tape)] - :- wid - %+ turn - (break wid (col-as-text col) (break-sets -.col)) - (cury (cury pad wid) (alignment -.col)) - :: - ++ col-as-text - |= col=dime - ^- tape - ?+ p.col (scow col) - %t (trip q.col) - %tas ['%' (scow col)] - == - :: - ++ alignment - |= wut=@ta - ^- ?(%left %right) - ?: ?=(?(%t %ta %tas %da) wut) - %left - %right - :: - ++ break-sets - |= wut=@ta - :: for: may break directly before these characters - :: aft: may break directly after these characters - :: new: always break on these characters, consuming them - :: - ^- [for=(set @t) aft=(set @t) new=(set @t)] - ?+ wut [(sy " ") (sy ".:-/") (sy "\0a")] - ?(%p %q) [(sy "-") (sy "-") ~] - %ux [(sy ".") ~ ~] - == - :: - ++ break - |= [wid=@ud cot=tape brs=_*break-sets] - ^- (list tape) - ~| [wid cot] - ?: =("" cot) ~ - =; [lin=tape rem=tape] - [lin $(cot rem)] - :: take snip of max width+1, search for breakpoint on that. - :: we grab one char extra, to look-ahead for for.brs. - :: later on, we always transfer _at least_ the extra char. - :: - =^ lin=tape cot - [(scag +(wid) cot) (slag +(wid) cot)] - =+ len=(lent lin) - :: find the first newline character - :: - =/ new=(unit @ud) - =+ new=~(tap in new.brs) - =| las=(unit @ud) - |- - ?~ new las - $(new t.new, las (hunt lth las (find [i.new]~ lin))) - :: if we found a newline, break on it - :: - ?^ new - :- (scag u.new lin) - (weld (slag +(u.new) lin) cot) - :: if it fits, we're done - :: - ?: (lte len wid) - [lin cot] - =+ nil=(flop lin) - :: search for latest aft match - :: - =/ aft=(unit @ud) - :: exclude the look-ahead character from search - :: - =. len (dec len) - =. nil (slag 1 nil) - =- ?~(- ~ `+(u.-)) - ^- (unit @ud) - =+ aft=~(tap in aft.brs) - =| las=(unit @ud) - |- - ?~ aft (bind las (cury sub (dec len))) - $(aft t.aft, las (hunt lth las (find [i.aft]~ nil))) - :: search for latest for match - :: - =/ for=(unit @ud) - =+ for=~(tap in for.brs) - =| las=(unit @ud) - |- - ?~ for (bind las (cury sub (dec len))) - =- $(for t.for, las (hunt lth las -)) - =+ (find [i.for]~ nil) - :: don't break before the first character - :: - ?:(=(`(dec len) -) ~ -) - :: if any result, break as late as possible - :: - =+ brk=(hunt gth aft for) - ?~ brk - :: lin can't break, produce it in its entirety - :: (after moving the look-ahead character back) - :: - :- (scag wid lin) - (weld (slag wid lin) cot) - :- (scag u.brk lin) - =. cot (weld (slag u.brk lin) cot) - :: eat any leading whitespace the next line might have, "clean break" - :: - |- ^+ cot - ?~ cot ~ - ?. ?=(?(%' ' %'\09') i.cot) - cot - $(cot t.cot) - :: - ++ pad - |= [wid=@ud lyn=?(%left %right) lin=tape] - ^+ lin - =+ l=(lent lin) - ?: (gte l wid) lin - =+ p=(reap (sub wid l) ' ') - ?- lyn - %left (weld lin p) - %right (weld p lin) - == - -- --- diff --git a/pkg/arvo/lib/shoe.hoon b/pkg/arvo/lib/shoe.hoon new file mode 120000 index 000000000..a4aab1dd7 --- /dev/null +++ b/pkg/arvo/lib/shoe.hoon @@ -0,0 +1 @@ +../../base-dev/lib/shoe.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/skeleton.hoon b/pkg/arvo/lib/skeleton.hoon deleted file mode 100644 index 982c371b8..000000000 --- a/pkg/arvo/lib/skeleton.hoon +++ /dev/null @@ -1,51 +0,0 @@ -:: Similar to default-agent except crashes everywhere -^- agent:gall -|_ bowl:gall -++ on-init - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-save - ^- vase - !! -:: -++ on-load - |~ old-state=vase - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-poke - |~ in-poke-data=cage - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-watch - |~ path - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-leave - |~ path - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-peek - |~ path - ^- (unit (unit cage)) - !! -:: -++ on-agent - |~ [wire sign:agent:gall] - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-arvo - |~ [wire =sign-arvo] - ^- (quip card:agent:gall agent:gall) - !! -:: -++ on-fail - |~ [term tang] - ^- (quip card:agent:gall agent:gall) - !! --- diff --git a/pkg/arvo/lib/skeleton.hoon b/pkg/arvo/lib/skeleton.hoon new file mode 120000 index 000000000..77626a327 --- /dev/null +++ b/pkg/arvo/lib/skeleton.hoon @@ -0,0 +1 @@ +../../base-dev/lib/skeleton.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/sole.hoon b/pkg/arvo/lib/sole.hoon deleted file mode 100644 index 66684668a..000000000 --- a/pkg/arvo/lib/sole.hoon +++ /dev/null @@ -1,139 +0,0 @@ -:: -:::: /hoon/sole/lib - :: -/? 310 -/- *sole -:::: - :: -|_ sole-share :: shared-state engine -++ abet +< -++ apply - |= ted=sole-edit - ^+ +> - ?- -.ted - %del +>.$(buf (weld (scag p.ted buf) (slag +(p.ted) buf))) - %ins +>.$(buf (weld (scag p.ted buf) `_buf`[q.ted (slag p.ted buf)])) - %mor |- ^+ +>.^$ - ?~ p.ted - +>.^$ - $(p.ted t.p.ted, +>.^$ ^$(ted i.p.ted)) - %nop +>.$ - %set +>.$(buf p.ted) - == -:: -:::: -:: ++transmute: symmetric operational transformation. -:: -:: for any sole state +>, obeys -:: -:: =+ [x=(transmute a b) y=(transmute b a)] -:: .= (apply:(apply a) x) -:: (apply:(apply b) y) -:: -++ transmute :: dex as after sin - |= [sin=sole-edit dex=sole-edit] - ~| [%transmute sin dex] - ^- sole-edit - ?: ?=(%mor -.sin) - |- ^- sole-edit - ?~ p.sin dex - $(p.sin t.p.sin, dex ^$(sin i.p.sin)) - :: - ?: ?=(%mor -.dex) - :- %mor - |- ^- (list sole-edit) - ?~ p.dex ~ - [^$(dex i.p.dex) $(p.dex t.p.dex)] - :: - ?: |(?=(%nop -.sin) ?=(%nop -.dex)) dex - ?: ?=(%set -.sin) [%nop ~] - ?: ?=(%set -.dex) dex - :: - ?- -.sin - %del - ?- -.dex - %del ?: =(p.sin p.dex) [%nop ~] - ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex) - %ins ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex) - == - :: - %ins - ?- -.dex - %del ?:((lte p.sin p.dex) dex(p +(p.dex)) dex) - %ins ?: =(p.sin p.dex) - ?:((lth q.sin q.dex) dex dex(p +(p.dex))) - ?:((lte p.sin p.dex) dex(p +(p.dex)) dex) - == - == -:: -++ commit :: local change - |= ted=sole-edit - ^- sole-share - abet:(apply(own.ven +(own.ven), leg [ted leg]) ted) -:: -:::: -:: ++inverse: inverse of change in context. -:: -:: for any sole state +>, obeys -:: -:: =(+> (apply:(apply a) (inverse a))) -:: -++ inverse :: relative inverse - |= ted=sole-edit - ^- sole-edit - =. ted ?.(?=([%mor * ~] ted) ted i.p.ted) - ?- -.ted - %del [%ins p.ted (snag p.ted buf)] - %ins [%del p.ted] - %mor :- %mor - %- flop - |- ^- (list sole-edit) - ?~ p.ted ~ - :- ^$(ted i.p.ted) - $(p.ted t.p.ted, +>.^$ (apply i.p.ted)) - %nop [%nop ~] - %set [%set buf] - == -:: -++ receive :: naturalize event - |= sole-change - ^- [sole-edit sole-share] - ?. &(=(his.ler his.ven) (lte own.ler own.ven)) - ~| [%receive-sync his+[his.ler his.ven] own+[own.ler own.ven]] - !! - ?> &(=(his.ler his.ven) (lte own.ler own.ven)) - ?> |(!=(own.ler own.ven) =(`@`0 haw) =(haw (sham buf))) - =. leg (scag (sub own.ven own.ler) leg) - :: ~? !=(own.ler own.ven) [%miss-leg leg] - =+ dat=(transmute [%mor leg] ted) - :: ~? !=(~ leg) [%transmute from+ted to+dat ~] - [dat abet:(apply(his.ven +(his.ven)) dat)] -:: -++ remit :: conditional accept - |= [cal=sole-change ask=$-((list @c) ?)] - ^- [(unit sole-change) sole-share] - =+ old=buf - =^ dat +>+<.$ (receive cal) - ?: (ask buf) - [~ +>+<.$] - =^ lic +>+<.$ (transmit (inverse(buf old) dat)) - [`lic +>+<.$] -:: -++ transmit :: outgoing change - |= ted=sole-edit - ^- [sole-change sole-share] - [[[his.ven own.ven] (sham buf) ted] (commit ted)] -:: -++ transceive :: receive and invert - |= sole-change - ^- [sole-edit sole-share] - =+ old=buf - =^ dat +>+<.$ (receive +<.$) - [(inverse(buf old) dat) +>+<.$] -:: -++ transpose :: adjust position - |= pos=@ud - =+ dat=(transmute [%mor leg] [%ins pos `@c`0]) - ?> ?=(%ins -.dat) - p.dat --- diff --git a/pkg/arvo/lib/sole.hoon b/pkg/arvo/lib/sole.hoon new file mode 120000 index 000000000..f776890f2 --- /dev/null +++ b/pkg/arvo/lib/sole.hoon @@ -0,0 +1 @@ +../../base-dev/lib/sole.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/strand.hoon b/pkg/arvo/lib/strand.hoon deleted file mode 100644 index b618f2d4e..000000000 --- a/pkg/arvo/lib/strand.hoon +++ /dev/null @@ -1,167 +0,0 @@ -|% -+$ card card:agent:gall -+$ input - $% [%poke =cage] - [%sign =wire =sign-arvo] - [%agent =wire =sign:agent:gall] - [%watch =path] - == -+$ strand-input [=bowl in=(unit input)] -+$ tid @tatid -+$ bowl - $: our=ship - src=ship - tid=tid - mom=(unit tid) - wex=boat:gall - sup=bitt:gall - eny=@uvJ - now=@da - byk=beak - == -:: -:: cards: cards to send immediately. These will go out even if a -:: later stage of the computation fails, so they shouldn't have -:: any semantic effect on the rest of the system. -:: Alternately, they may record an entry in contracts with -:: enough information to undo the effect if the computation -:: fails. -:: wait: don't move on, stay here. The next sign should come back -:: to this same callback. -:: skip: didn't expect this input; drop it down to be handled -:: elsewhere -:: cont: continue computation with new callback. -:: fail: abort computation; don't send effects -:: done: finish computation; send effects -:: -++ strand-output-raw - |* a=mold - $~ [~ %done *a] - $: cards=(list card) - $= next - $% [%wait ~] - [%skip ~] - [%cont self=(strand-form-raw a)] - [%fail err=(pair term tang)] - [%done value=a] - == - == -:: -++ strand-form-raw - |* a=mold - $-(strand-input (strand-output-raw a)) -:: -:: Abort strand computation with error message -:: -++ strand-fail - |= err=(pair term tang) - |= strand-input - [~ %fail err] -:: -:: Asynchronous transcaction monad. -:: -:: Combo of four monads: -:: - Reader on input -:: - Writer on card -:: - Continuation -:: - Exception -:: -++ strand - |* a=mold - |% - ++ output (strand-output-raw a) - :: - :: Type of an strand computation. - :: - ++ form (strand-form-raw a) - :: - :: Monadic pure. Identity computation for bind. - :: - ++ pure - |= arg=a - ^- form - |= strand-input - [~ %done arg] - :: - :: Monadic bind. Combines two computations, associatively. - :: - ++ bind - |* b=mold - |= [m-b=(strand-form-raw b) fun=$-(b form)] - ^- form - |= input=strand-input - =/ b-res=(strand-output-raw b) - (m-b input) - ^- output - :- cards.b-res - ?- -.next.b-res - %wait [%wait ~] - %skip [%skip ~] - %cont [%cont ..$(m-b self.next.b-res)] - %fail [%fail err.next.b-res] - %done [%cont (fun value.next.b-res)] - == - :: - :: The strand monad must be evaluted in a particular way to maintain - :: its monadic character. +take:eval implements this. - :: - ++ eval - |% - :: Indelible state of a strand - :: - +$ eval-form - $: =form - == - :: - :: Convert initial form to eval-form - :: - ++ from-form - |= =form - ^- eval-form - form - :: - :: The cases of results of +take - :: - +$ eval-result - $% [%next ~] - [%fail err=(pair term tang)] - [%done value=a] - == - :: - :: Take a new sign and run the strand against it - :: - ++ take - :: cards: accumulate throughout recursion the cards to be - :: produced now - =| cards=(list card) - |= [=eval-form =strand-input] - ^- [[(list card) =eval-result] _eval-form] - =* take-loop $ - :: run the strand callback - :: - =/ =output (form.eval-form strand-input) - :: add cards to cards - :: - =. cards - %+ welp - cards - :: XX add tag to wires? - cards.output - :: case-wise handle next steps - :: - ?- -.next.output - %wait [[cards %next ~] eval-form] - %skip [[cards %next ~] eval-form] - %fail [[cards %fail err.next.output] eval-form] - %done [[cards %done value.next.output] eval-form] - %cont - :: recurse to run continuation with initialization input - :: - %_ take-loop - form.eval-form self.next.output - strand-input [bowl.strand-input ~] - == - == - -- - -- --- diff --git a/pkg/arvo/lib/strand.hoon b/pkg/arvo/lib/strand.hoon new file mode 120000 index 000000000..d95df7948 --- /dev/null +++ b/pkg/arvo/lib/strand.hoon @@ -0,0 +1 @@ +../../base-dev/lib/strand.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/strandio.hoon b/pkg/arvo/lib/strandio.hoon deleted file mode 100644 index d0574fc73..000000000 --- a/pkg/arvo/lib/strandio.hoon +++ /dev/null @@ -1,740 +0,0 @@ -/- spider -/+ libstrand=strand -=, strand=strand:libstrand -=, strand-fail=strand-fail:libstrand -|% -++ send-raw-cards - |= cards=(list =card:agent:gall) - =/ m (strand ,~) - ^- form:m - |= strand-input:strand - [cards %done ~] -:: -++ send-raw-card - |= =card:agent:gall - =/ m (strand ,~) - ^- form:m - (send-raw-cards card ~) -:: -++ ignore - |= tin=strand-input:strand - `[%fail %ignore ~] -:: -++ get-bowl - =/ m (strand ,bowl:strand) - ^- form:m - |= tin=strand-input:strand - `[%done bowl.tin] -:: -++ get-beak - =/ m (strand ,beak) - ^- form:m - |= tin=strand-input:strand - `[%done [our q.byk da+now]:bowl.tin] -:: -++ get-time - =/ m (strand ,@da) - ^- form:m - |= tin=strand-input:strand - `[%done now.bowl.tin] -:: -++ get-our - =/ m (strand ,ship) - ^- form:m - |= tin=strand-input:strand - `[%done our.bowl.tin] -:: -++ get-entropy - =/ m (strand ,@uvJ) - ^- form:m - |= tin=strand-input:strand - `[%done eny.bowl.tin] -:: -:: Convert skips to %ignore failures. -:: -:: This tells the main loop to try the next handler. -:: -++ handle - |* a=mold - =/ m (strand ,a) - |= =form:m - ^- form:m - |= tin=strand-input:strand - =/ res (form tin) - =? next.res ?=(%skip -.next.res) - [%fail %ignore ~] - res -:: -:: Wait for a poke with a particular mark -:: -++ take-poke - |= =mark - =/ m (strand ,vase) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %poke @ *] - ?. =(mark p.cage.u.in.tin) - `[%skip ~] - `[%done q.cage.u.in.tin] - == -:: -:: -:: -++ take-sign-arvo - =/ m (strand ,[wire sign-arvo]) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %sign *] - `[%done [wire sign-arvo]:u.in.tin] - == -:: -:: Wait for a subscription update on a wire -:: -++ take-fact-prefix - |= =wire - =/ m (strand ,[path cage]) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %agent * %fact *] - ?. =(watch+wire (scag +((lent wire)) wire.u.in.tin)) - `[%skip ~] - `[%done (slag (lent wire) wire.u.in.tin) cage.sign.u.in.tin] - == -:: -:: Wait for a subscription update on a wire -:: -++ take-fact - |= =wire - =/ m (strand ,cage) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %agent * %fact *] - ?. =(watch+wire wire.u.in.tin) - `[%skip ~] - `[%done cage.sign.u.in.tin] - == -:: -:: Wait for a subscription close -:: -++ take-kick - |= =wire - =/ m (strand ,~) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %agent * %kick *] - ?. =(watch+wire wire.u.in.tin) - `[%skip ~] - `[%done ~] - == -:: -++ echo - =/ m (strand ,~) - ^- form:m - %- (main-loop ,~) - :~ |= ~ - ^- form:m - ;< =vase bind:m ((handle ,vase) (take-poke %echo)) - =/ message=tape !<(tape vase) - %- (slog leaf+"{message}..." ~) - ;< ~ bind:m (sleep ~s2) - %- (slog leaf+"{message}.." ~) - (pure:m ~) - :: - |= ~ - ^- form:m - ;< =vase bind:m ((handle ,vase) (take-poke %over)) - %- (slog leaf+"over..." ~) - (pure:m ~) - == -:: -++ take-watch - =/ m (strand ,path) - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %watch *] - `[%done path.u.in.tin] - == -:: -++ take-wake - |= until=(unit @da) - =/ m (strand ,~) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %sign [%wait @ ~] %behn %wake *] - ?. |(?=(~ until) =(`u.until (slaw %da i.t.wire.u.in.tin))) - `[%skip ~] - ?~ error.sign-arvo.u.in.tin - `[%done ~] - `[%fail %timer-error u.error.sign-arvo.u.in.tin] - == -:: -++ take-poke-ack - |= =wire - =/ m (strand ,~) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %agent * %poke-ack *] - ?. =(wire wire.u.in.tin) - `[%skip ~] - ?~ p.sign.u.in.tin - `[%done ~] - `[%fail %poke-fail u.p.sign.u.in.tin] - == -:: -++ take-watch-ack - |= =wire - =/ m (strand ,~) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %agent * %watch-ack *] - ?. =(watch+wire wire.u.in.tin) - `[%skip ~] - ?~ p.sign.u.in.tin - `[%done ~] - `[%fail %watch-ack-fail u.p.sign.u.in.tin] - == -:: -++ poke - |= [=dock =cage] - =/ m (strand ,~) - ^- form:m - =/ =card:agent:gall [%pass /poke %agent dock %poke cage] - ;< ~ bind:m (send-raw-card card) - (take-poke-ack /poke) -:: -++ raw-poke - |= [=dock =cage] - =/ m (strand ,~) - ^- form:m - =/ =card:agent:gall [%pass /poke %agent dock %poke cage] - ;< ~ bind:m (send-raw-card card) - =/ m (strand ,~) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ - `[%wait ~] - :: - [~ %agent * %poke-ack *] - ?. =(/poke wire.u.in.tin) - `[%skip ~] - `[%done ~] - == -:: -++ raw-poke-our - |= [app=term =cage] - =/ m (strand ,~) - ^- form:m - ;< =bowl:spider bind:m get-bowl - (raw-poke [our.bowl app] cage) -:: -++ poke-our - |= [=term =cage] - =/ m (strand ,~) - ^- form:m - ;< our=@p bind:m get-our - (poke [our term] cage) -:: -++ watch - |= [=wire =dock =path] - =/ m (strand ,~) - ^- form:m - =/ =card:agent:gall [%pass watch+wire %agent dock %watch path] - ;< ~ bind:m (send-raw-card card) - (take-watch-ack wire) -:: -++ watch-our - |= [=wire =term =path] - =/ m (strand ,~) - ^- form:m - ;< our=@p bind:m get-our - (watch wire [our term] path) -:: -++ scry - |* [=mold =path] - =/ m (strand ,mold) - ^- form:m - ?> ?=(^ path) - ?> ?=(^ t.path) - ;< =bowl:spider bind:m get-bowl - %- pure:m - .^(mold i.path (scot %p our.bowl) i.t.path (scot %da now.bowl) t.t.path) -:: -++ leave - |= [=wire =dock] - =/ m (strand ,~) - ^- form:m - =/ =card:agent:gall [%pass watch+wire %agent dock %leave ~] - (send-raw-card card) -:: -++ leave-our - |= [=wire =term] - =/ m (strand ,~) - ^- form:m - ;< our=@p bind:m get-our - (leave wire [our term]) -:: -++ rewatch - |= [=wire =dock =path] - =/ m (strand ,~) - ;< ~ bind:m ((handle ,~) (take-kick wire)) - ;< ~ bind:m (flog-text "rewatching {} {}") - ;< ~ bind:m (watch wire dock path) - (pure:m ~) -:: -++ wait - |= until=@da - =/ m (strand ,~) - ^- form:m - ;< ~ bind:m (send-wait until) - (take-wake `until) -:: -++ sleep - |= for=@dr - =/ m (strand ,~) - ^- form:m - ;< now=@da bind:m get-time - (wait (add now for)) -:: -++ send-wait - |= until=@da - =/ m (strand ,~) - ^- form:m - =/ =card:agent:gall - [%pass /wait/(scot %da until) %arvo %b %wait until] - (send-raw-card card) -:: -++ map-err - |* computation-result=mold - =/ m (strand ,computation-result) - |= [f=$-([term tang] [term tang]) computation=form:m] - ^- form:m - |= tin=strand-input:strand - =* loop $ - =/ c-res (computation tin) - ?: ?=(%cont -.next.c-res) - c-res(self.next ..loop(computation self.next.c-res)) - ?. ?=(%fail -.next.c-res) - c-res - c-res(err.next (f err.next.c-res)) -:: -++ set-timeout - |* computation-result=mold - =/ m (strand ,computation-result) - |= [time=@dr computation=form:m] - ^- form:m - ;< now=@da bind:m get-time - =/ when (add now time) - =/ =card:agent:gall - [%pass /timeout/(scot %da when) %arvo %b %wait when] - ;< ~ bind:m (send-raw-card card) - |= tin=strand-input:strand - =* loop $ - ?: ?& ?=([~ %sign [%timeout @ ~] %behn %wake *] in.tin) - =((scot %da when) i.t.wire.u.in.tin) - == - `[%fail %timeout ~] - =/ c-res (computation tin) - ?: ?=(%cont -.next.c-res) - c-res(self.next ..loop(computation self.next.c-res)) - ?: ?=(%done -.next.c-res) - =/ =card:agent:gall - [%pass /timeout/(scot %da when) %arvo %b %rest when] - c-res(cards [card cards.c-res]) - c-res -:: -++ send-request - |= =request:http - =/ m (strand ,~) - ^- form:m - (send-raw-card %pass /request %arvo %i %request request *outbound-config:iris) -:: -++ send-cancel-request - =/ m (strand ,~) - ^- form:m - (send-raw-card %pass /request %arvo %i %cancel-request ~) -:: -++ take-client-response - =/ m (strand ,client-response:iris) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %sign [%request ~] %iris %http-response %finished *] - `[%done client-response.sign-arvo.u.in.tin] - == -:: -:: Wait until we get an HTTP response or cancelation and unset contract -:: -++ take-maybe-sigh - =/ m (strand ,(unit httr:eyre)) - ^- form:m - ;< rep=(unit client-response:iris) bind:m - take-maybe-response - ?~ rep - (pure:m ~) - :: XX s/b impossible - :: - ?. ?=(%finished -.u.rep) - (pure:m ~) - (pure:m (some (to-httr:iris +.u.rep))) -:: -++ take-maybe-response - =/ m (strand ,(unit client-response:iris)) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %sign [%request ~] %iris %http-response %cancel *] - `[%done ~] - [~ %sign [%request ~] %iris %http-response %finished *] - `[%done `client-response.sign-arvo.u.in.tin] - == -:: -++ extract-body - |= =client-response:iris - =/ m (strand ,cord) - ^- form:m - ?> ?=(%finished -.client-response) - ?> ?=(^ full-file.client-response) - (pure:m q.data.u.full-file.client-response) -:: -++ fetch-cord - |= url=tape - =/ m (strand ,cord) - ^- form:m - =/ =request:http [%'GET' (crip url) ~ ~] - ;< ~ bind:m (send-request request) - ;< =client-response:iris bind:m take-client-response - (extract-body client-response) -:: -++ fetch-json - |= url=tape - =/ m (strand ,json) - ^- form:m - ;< =cord bind:m (fetch-cord url) - =/ json=(unit json) (de-json:html cord) - ?~ json - (strand-fail %json-parse-error ~) - (pure:m u.json) -:: -++ hiss-request - |= =hiss:eyre - =/ m (strand ,(unit httr:eyre)) - ^- form:m - ;< ~ bind:m (send-request (hiss-to-request:html hiss)) - take-maybe-sigh -:: -:: +build-file: build the source file at the specified $beam -:: -++ build-file - |= [[=ship =desk =case] =spur] - =* arg +< - =/ m (strand ,(unit vase)) - ^- form:m - ;< =riot:clay bind:m - (warp ship desk ~ %sing %a case spur) - ?~ riot - (pure:m ~) - ?> =(%vase p.r.u.riot) - (pure:m (some !<(vase q.r.u.riot))) -:: +build-mark: build a mark definition to a $dais -:: -++ build-mark - |= [[=ship =desk =case] mak=mark] - =* arg +< - =/ m (strand ,dais:clay) - ^- form:m - ;< =riot:clay bind:m - (warp ship desk ~ %sing %b case /[mak]) - ?~ riot - (strand-fail %build-mark >arg< ~) - ?> =(%dais p.r.u.riot) - (pure:m !<(dais:clay q.r.u.riot)) -:: +build-tube: build a mark conversion gate ($tube) -:: -++ build-tube - |= [[=ship =desk =case] =mars:clay] - =* arg +< - =/ m (strand ,tube:clay) - ^- form:m - ;< =riot:clay bind:m - (warp ship desk ~ %sing %c case /[a.mars]/[b.mars]) - ?~ riot - (strand-fail %build-tube >arg< ~) - ?> =(%tube p.r.u.riot) - (pure:m !<(tube:clay q.r.u.riot)) -:: -:: +build-nave: build a mark definition to a $nave -:: -++ build-nave - |= [[=ship =desk =case] mak=mark] - =* arg +< - =/ m (strand ,vase) - ^- form:m - ;< =riot:clay bind:m - (warp ship desk ~ %sing %e case /[mak]) - ?~ riot - (strand-fail %build-nave >arg< ~) - ?> =(%nave p.r.u.riot) - (pure:m q.r.u.riot) -:: +build-cast: build a mark conversion gate (static) -:: -++ build-cast - |= [[=ship =desk =case] =mars:clay] - =* arg +< - =/ m (strand ,vase) - ^- form:m - ;< =riot:clay bind:m - (warp ship desk ~ %sing %f case /[a.mars]/[b.mars]) - ?~ riot - (strand-fail %build-cast >arg< ~) - ?> =(%cast p.r.u.riot) - (pure:m q.r.u.riot) -:: -:: Read from Clay -:: -++ warp - |= [=ship =riff:clay] - =/ m (strand ,riot:clay) - ;< ~ bind:m (send-raw-card %pass /warp %arvo %c %warp ship riff) - (take-writ /warp) -:: -++ read-file - |= [[=ship =desk =case:clay] =spur] - =* arg +< - =/ m (strand ,cage) - ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur) - ?~ riot - (strand-fail %read-file >arg< ~) - (pure:m r.u.riot) -:: -++ check-for-file - |= [[=ship =desk =case:clay] =spur] - =/ m (strand ,?) - ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur) - (pure:m ?=(^ riot)) -:: -++ list-tree - |= [[=ship =desk =case:clay] =spur] - =* arg +< - =/ m (strand ,(list path)) - ;< =riot:clay bind:m (warp ship desk ~ %sing %t case spur) - ?~ riot - (strand-fail %list-tree >arg< ~) - (pure:m !<((list path) q.r.u.riot)) -:: -:: Take Clay read result -:: -++ take-writ - |= =wire - =/ m (strand ,riot:clay) - ^- form:m - |= tin=strand-input:strand - ?+ in.tin `[%skip ~] - ~ `[%wait ~] - [~ %sign * ?(%behn %clay) %writ *] - ?. =(wire wire.u.in.tin) - `[%skip ~] - `[%done +>.sign-arvo.u.in.tin] - == -:: +check-online: require that peer respond before timeout -:: -++ check-online - |= [who=ship lag=@dr] - =/ m (strand ,~) - ^- form:m - %+ (map-err ,~) |=(* [%offline *tang]) - %+ (set-timeout ,~) lag - ;< ~ bind:m - (poke [who %hood] %helm-hi !>(~)) - (pure:m ~) -:: -:: Queue on skip, try next on fail %ignore -:: -++ main-loop - |* a=mold - =/ m (strand ,~) - =/ m-a (strand ,a) - =| queue=(qeu (unit input:strand)) - =| active=(unit [in=(unit input:strand) =form:m-a forms=(list $-(a form:m-a))]) - =| state=a - |= forms=(lest $-(a form:m-a)) - ^- form:m - |= tin=strand-input:strand - =* top `form:m`..$ - =. queue (~(put to queue) in.tin) - |^ (continue bowl.tin) - :: - ++ continue - |= =bowl:strand - ^- output:m - ?> =(~ active) - ?: =(~ queue) - `[%cont top] - =^ in=(unit input:strand) queue ~(get to queue) - ^- output:m - =. active `[in (i.forms state) t.forms] - ^- output:m - (run bowl in) - :: - ++ run - ^- form:m - |= tin=strand-input:strand - ^- output:m - ?> ?=(^ active) - =/ res (form.u.active tin) - =/ =output:m - ?- -.next.res - %wait `[%wait ~] - %skip `[%cont ..$(queue (~(put to queue) in.tin))] - %cont `[%cont ..$(active `[in.u.active self.next.res forms.u.active])] - %done (continue(active ~, state value.next.res) bowl.tin) - %fail - ?: &(?=(^ forms.u.active) ?=(%ignore p.err.next.res)) - %= $ - active `[in.u.active (i.forms.u.active state) t.forms.u.active] - in.tin in.u.active - == - `[%fail err.next.res] - == - [(weld cards.res cards.output) next.output] - -- -:: -++ retry - |* result=mold - |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))] - =/ m (strand ,result) - =| try=@ud - |- ^- form:m - =* loop $ - ?: =(crash-after `try) - (strand-fail %retry-too-many ~) - ;< ~ bind:m (backoff try ~m1) - ;< res=(unit result) bind:m computation - ?^ res - (pure:m u.res) - loop(try +(try)) -:: -++ backoff - |= [try=@ud limit=@dr] - =/ m (strand ,~) - ^- form:m - ;< eny=@uvJ bind:m get-entropy - %- sleep - %+ min limit - ?: =(0 try) ~s0 - %+ add - (mul ~s1 (bex (dec try))) - (mul ~s0..0001 (~(rad og eny) 1.000)) -:: -:: ---- -:: -:: Output -:: -++ flog - |= =flog:dill - =/ m (strand ,~) - ^- form:m - (send-raw-card %pass / %arvo %d %flog flog) -:: -++ flog-text - |= =tape - =/ m (strand ,~) - ^- form:m - (flog %text tape) -:: -++ flog-tang - |= =tang - =/ m (strand ,~) - ^- form:m - =/ =wall - (zing (turn (flop tang) (cury wash [0 80]))) - |- ^- form:m - =* loop $ - ?~ wall - (pure:m ~) - ;< ~ bind:m (flog-text i.wall) - loop(wall t.wall) -:: -++ trace - |= =tang - =/ m (strand ,~) - ^- form:m - (pure:m ((slog tang) ~)) -:: -++ app-message - |= [app=term =cord =tang] - =/ m (strand ,~) - ^- form:m - =/ msg=tape :(weld (trip app) ": " (trip cord)) - ;< ~ bind:m (flog-text msg) - (flog-tang tang) -:: -:: ---- -:: -:: Handle domains -:: -++ install-domain - |= =turf - =/ m (strand ,~) - ^- form:m - (send-raw-card %pass / %arvo %e %rule %turf %put turf) -:: -:: ---- -:: -:: Threads -:: -++ start-thread - |= file=term - (start-thread-with-args file *vase) -:: -++ start-thread-with-args - |= [file=term args=vase] - =/ m (strand ,tid:spider) - ^- form:m - ;< =bowl:spider bind:m get-bowl - =/ tid - (scot %ta (cat 3 (cat 3 'strand_' file) (scot %uv (sham file eny.bowl)))) - =/ poke-vase !>([`tid.bowl `tid file args]) - ;< ~ bind:m (poke-our %spider %spider-start poke-vase) - ;< ~ bind:m (sleep ~s0) :: wait for thread to start - (pure:m tid) -:: -+$ thread-result - (each vase [term tang]) -:: -++ await-thread - |= [file=term args=vase] - =/ m (strand ,thread-result) - ^- form:m - ;< =bowl:spider bind:m get-bowl - =/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl)))) - =/ poke-vase !>([`tid.bowl `tid file args]) - ;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid]) - ;< ~ bind:m (poke-our %spider %spider-start poke-vase) - ;< ~ bind:m (sleep ~s0) :: wait for thread to start - ;< =cage bind:m (take-fact /awaiting/[tid]) - ;< ~ bind:m (take-kick /awaiting/[tid]) - ?+ p.cage ~|([%strange-thread-result p.cage file tid] !!) - %thread-done (pure:m %& q.cage) - %thread-fail (pure:m %| !<([term tang] q.cage)) - == --- diff --git a/pkg/arvo/lib/strandio.hoon b/pkg/arvo/lib/strandio.hoon new file mode 120000 index 000000000..0caebfac1 --- /dev/null +++ b/pkg/arvo/lib/strandio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/strandio.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/test.hoon b/pkg/arvo/lib/test.hoon deleted file mode 100644 index 7e4eca44a..000000000 --- a/pkg/arvo/lib/test.hoon +++ /dev/null @@ -1,50 +0,0 @@ -:: testing utilities meant to be directly used from files in %/tests -:: -|% -:: +expect-eq: compares :expected and :actual and pretty-prints the result -:: -++ expect-eq - |= [expected=vase actual=vase] - ^- tang - :: - =| result=tang - :: - =? result !=(q.expected q.actual) - %+ weld result - ^- tang - :~ [%palm [": " ~ ~ ~] [leaf+"expected" (sell expected) ~]] - [%palm [": " ~ ~ ~] [leaf+"actual" (sell actual) ~]] - == - :: - =? result !(~(nest ut p.actual) | p.expected) - %+ weld result - ^- tang - :~ :+ %palm [": " ~ ~ ~] - :~ [%leaf "failed to nest"] - (~(dunk ut p.actual) %actual) - (~(dunk ut p.expected) %expected) - == == - result -:: +expect: compares :actual to %.y and pretty-prints anything else -:: -++ expect - |= actual=vase - (expect-eq !>(%.y) actual) -:: +expect-fail: kicks a trap, expecting crash. pretty-prints if succeeds -:: -++ expect-fail - |= a=(trap) - ^- tang - =/ b (mule a) - ?- -.b - %| ~ - %& [leaf+"expected failure - succeeded" ~] - == -:: +category: prepends a name to an error result; passes successes unchanged -:: -++ category - |= [a=tape b=tang] ^- tang - ?: =(~ b) ~ :: test OK - :- leaf+"in: '{a}'" - (turn b |=(c=tank rose+[~ " " ~]^~[c])) --- diff --git a/pkg/arvo/lib/test.hoon b/pkg/arvo/lib/test.hoon new file mode 120000 index 000000000..cc50ce7cf --- /dev/null +++ b/pkg/arvo/lib/test.hoon @@ -0,0 +1 @@ +../../base-dev/lib/test.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/std.hoon b/pkg/arvo/lib/tiny.hoon similarity index 87% rename from pkg/arvo/lib/std.hoon rename to pkg/arvo/lib/tiny.hoon index 852868ce6..f4cbf064f 100644 --- a/pkg/arvo/lib/std.hoon +++ b/pkg/arvo/lib/tiny.hoon @@ -30,10 +30,6 @@ :: ++ jug |$ [key value] (map key (set value)) :: -:: Biblical -:: -++ ruth |=([a=* b=*] ?>(?=(@ b) b)) -:: :: Bits :: ++ dec :: decrement @@ -82,6 +78,12 @@ ?: (lth a b) c $(a (sub a b), c +(c)) :: +++ dvr :: divide w/remainder + ~/ %dvr + |: [a=`@`1 b=`@`1] + ^- [p=@ q=@] + [(div a b) (mod a b)] +:: ++ mod :: modulus ~/ %mod |: [a=`@`1 b=`@`1] @@ -210,15 +212,10 @@ (add (lsh [a (met a b)] c) b) :: ++ cut :: slice - ~/ %cut :: TODO: jet + ~/ %cut |= [a=bloq [b=step c=step] d=@] (end [a c] (rsh [a b] d)) :: -++ dad :: concatenate fixed - ~/ %dad - |= [=bite a=@ b=@] - (add a (lsh bite b)) -:: ++ can :: assemble ~/ %can |= [a=bloq b=(list [p=step q=@])] @@ -310,23 +307,6 @@ +<-(+ $(+<- +<->)) -- :: -++ turn :: transform - ~/ %turn - |* [a=(list) b=$-(* *)] - => .(a (homo a)) - ^- (list _?>(?=(^ a) (b i.a))) - |- - ?~ a ~ - [i=(b i.a) t=$(a t.a)] -:: -++ levy :: all of - ~/ %levy - |* [a=(list) b=$-(* ?)] - |- ^- ? - ?~ a & - ?. (b i.a) | - $(a t.a) -:: ++ reap :: replicate ~/ %reap |* [a=@ b=*] @@ -492,11 +472,6 @@ $(a l.a) $(a r.a) :: - ++ has - ~/ %has - |* b=* - !=(~ (get b)) - :: ++ put ~/ %put |* [b=* c=*] @@ -575,13 +550,6 @@ ?~(r.a %.y &((mor key.n.a key.n.r.a) $(a r.a, r `key.n.a))) == :: - ++ gas - ~/ %gas - |= [a=(tree item) b=(list item)] - ^- (tree item) - ?~ b a - $(b t.b, a (put a i.b)) - :: ++ get ~/ %get |= [a=(tree item) b=key] @@ -599,58 +567,6 @@ ^- ? !=(~ (get a b)) :: - ++ lot - ~/ %lot - |= $: tre=(tree item) - start=(unit key) - end=(unit key) - == - ^- (tree item) - |^ - ?: ?&(?=(~ start) ?=(~ end)) - tre - ?~ start - (del-span tre %end end) - ?~ end - (del-span tre %start start) - ?> (compare u.start u.end) - =. tre (del-span tre %start start) - (del-span tre %end end) - :: - ++ del-span - |= [a=(tree item) b=?(%start %end) c=(unit key)] - ^- (tree item) - ?~ a a - ?~ c a - ?- b - %start - ?: =(key.n.a u.c) - (nip a(l ~)) - ?: (compare key.n.a u.c) - $(a (nip a(l ~))) - a(l $(a l.a)) - :: - %end - ?: =(u.c key.n.a) - (nip a(r ~)) - ?: (compare key.n.a u.c) - a(r $(a r.a)) - $(a (nip a(r ~))) - == - -- - :: - ++ nip - ~/ %nip - |= a=(tree item) - ^- (tree item) - ?> ?=(^ a) - |- ^- (tree item) - ?~ l.a r.a - ?~ r.a l.a - ?: (mor key.n.l.a key.n.r.a) - l.a(r $(l.a r.l.a)) - r.a(l $(r.a l.r.a)) - :: ++ put ~/ %put |= [a=(tree item) =key =val] @@ -668,15 +584,6 @@ ?: (mor key.n.a key.n.r) a(r r) r(l a(r l.r)) - :: - ++ tap - ~/ %tap - |= a=(tree item) - ^- (list item) - =| b=(list item) - |- ^+ b - ?~ a b - $(a l.a, b [n.a $(a r.a)]) -- :: :: Sets diff --git a/pkg/arvo/lib/tree.hoon b/pkg/arvo/lib/tree.hoon deleted file mode 100644 index 2d0d1174f..000000000 --- a/pkg/arvo/lib/tree.hoon +++ /dev/null @@ -1,34 +0,0 @@ -:: -:::: /hoon/tree/lib - :: -/? 314 -:: -|% -++ getall :: search in manx - |= tag=(list mane) - |= ele=manx ^- marl - ?: (lien tag |=(a=mane =(a n.g.ele))) - ~[ele] - (zing (turn c.ele ..$)) -:: -:: a.b_c.d => [[%a %b] [%c %d]] -:: a.b_c, a_b__c => [[%a %b] %c] -:: a_b_c, a__b_c => [%a [%b %c]] -++ read-schem :: decode gapped noun - =< (cook to-noun (cook build-grove apex)) - |% - ++ noun $@(term [noun noun]) :: shadow - :: improper list of possible entry points - ++ grove $@(term [gap=@ sealed=noun pending=grove]) - ++ apex ;~(plug sym (star ;~(plug delim sym))) - ++ delim ;~(pose (cold 0 dot) (cook lent (plus cab))) - ++ to-noun |=(a=grove ?@(a a [sealed.a $(a pending.a)])) - ++ build-grove - |= [a=grove b=(list [p=@u q=term])] ^- grove - %+ roll b =< .(acc a) - |= [[gap=@u v=term] acc=grove] ^- grove - ?@ acc [gap acc v] - ?: (gth gap gap.acc) [gap (to-noun acc) v] - acc(pending $(acc pending.acc)) - -- --- diff --git a/pkg/arvo/lib/urb-split.hoon b/pkg/arvo/lib/urb-split.hoon deleted file mode 100644 index 139357710..000000000 --- a/pkg/arvo/lib/urb-split.hoon +++ /dev/null @@ -1,10 +0,0 @@ -:: -:::: /hoon/urb-split/lib - :: -/? 310 -|= [dep=@uvH urb=manx] ^- [hed=[@uvh marl] bod=[@uvH marl]] -~| [%malformed-urb urb] :: XX types -?> ?=([[%html ~] [[%head ~] *] [[%body ~] *] ~] urb) -=+ `[[%html ~] [[%head ~] hed=marl] [[%body ~] bod=marl] ~]`urb -:- [dep hed] :: Assume all dependencies are hard -[0v0 bod] diff --git a/pkg/arvo/lib/verb.hoon b/pkg/arvo/lib/verb.hoon deleted file mode 100644 index 2737addfc..000000000 --- a/pkg/arvo/lib/verb.hoon +++ /dev/null @@ -1,105 +0,0 @@ -:: Print what your agent is doing. -:: -/- verb -:: -|= [loud=? =agent:gall] -=| bowl-print=_| -^- agent:gall -|^ !. -|_ =bowl:gall -+* this . - ag ~(. agent bowl) -:: -++ on-init - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-init")) - =^ cards agent on-init:ag - [[(emit-event %on-init ~) cards] this] -:: -++ on-save - ^- vase - %- (print bowl |.("{}: on-save")) - on-save:ag -:: -++ on-load - |= old-state=vase - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-load")) - =^ cards agent (on-load:ag old-state) - [[(emit-event %on-load ~) cards] this] -:: -++ on-poke - |= [=mark =vase] - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-poke with mark {}")) - ?: ?=(%verb mark) - ?- !<(?(%loud %bowl) vase) - %loud `this(loud !loud) - %bowl `this(bowl-print !bowl-print) - == - =^ cards agent (on-poke:ag mark vase) - [[(emit-event %on-poke mark) cards] this] -:: -++ on-watch - |= =path - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-watch on path {}")) - =^ cards agent - ?: ?=([%verb %events ~] path) - [~ agent] - (on-watch:ag path) - [[(emit-event %on-watch path) cards] this] -:: -++ on-leave - |= =path - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-leave on path {}")) - ?: ?=([%verb %event ~] path) - [~ this] - =^ cards agent (on-leave:ag path) - [[(emit-event %on-leave path) cards] this] -:: -++ on-peek - |= =path - ^- (unit (unit cage)) - %- (print bowl |.("{}: on-peek on path {}")) - (on-peek:ag path) -:: -++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-agent on wire {}, {<-.sign>}")) - =^ cards agent (on-agent:ag wire sign) - [[(emit-event %on-agent wire -.sign) cards] this] -:: -++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card:agent:gall agent:gall) - %- %+ print bowl |. - "{}: on-arvo on wire {}, {<[- +<]:sign-arvo>}" - =^ cards agent (on-arvo:ag wire sign-arvo) - [[(emit-event %on-arvo wire [- +<]:sign-arvo) cards] this] -:: -++ on-fail - |= [=term =tang] - ^- (quip card:agent:gall agent:gall) - %- (print bowl |.("{}: on-fail with term {}")) - =^ cards agent (on-fail:ag term tang) - [[(emit-event %on-fail term) cards] this] --- -:: -++ print - |= [=bowl:gall render=(trap tape)] - ^+ same - =? . bowl-print - %- (slog >bowl< ~) - . - ?. loud same - %- (slog [%leaf $:render] ~) - same -:: -++ emit-event - |= =event:verb - ^- card:agent:gall - [%give %fact ~[/verb/events] %verb-event !>(event)] --- diff --git a/pkg/arvo/lib/verb.hoon b/pkg/arvo/lib/verb.hoon new file mode 120000 index 000000000..939072347 --- /dev/null +++ b/pkg/arvo/lib/verb.hoon @@ -0,0 +1 @@ +../../base-dev/lib/verb.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/version.hoon b/pkg/arvo/lib/version.hoon deleted file mode 100644 index edf1872e9..000000000 --- a/pkg/arvo/lib/version.hoon +++ /dev/null @@ -1,18 +0,0 @@ -|% -++ base-hash - |= [our=@p now=@da] - ^- (list @uv) - =+ .^ ota=(unit [=ship =desk =aeon:clay]) - %gx /(scot %p our)/hood/(scot %da now)/kiln/ota/noun - == - ?~ ota - ~ - =/ parent (scot %p ship.u.ota) - =/ takos - .^ (list tako:clay) %cs - /(scot %p our)/home/(scot %da now)/base/[parent]/[desk.u.ota] - == - %+ turn takos - |= =tako:clay - .^(@uv %cs /(scot %p our)/home/(scot %da now)/hash/(scot %uv tako)) --- diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon deleted file mode 100644 index 1c5a6e1ea..000000000 --- a/pkg/arvo/mar/belt.hoon +++ /dev/null @@ -1,29 +0,0 @@ -:: belt: runtime belt structure -:: -|_ =belt:dill -++ grad %noun -:: +grab: convert from -:: -++ grab - |% - ++ noun belt:dill - ++ json - ^- $-(^json belt:dill) - =, dejs:format - %- of - :~ aro+(su (perk %d %l %r %u ~)) - bac+ul - ctl+(cu taft so) - del+ul - met+(cu taft so) - ret+ul - txt+(ar (cu taft so)) - == - -- -:: +grow: convert to -:: -++ grow - |% - ++ noun belt - -- --- diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon new file mode 120000 index 000000000..0c8999932 --- /dev/null +++ b/pkg/arvo/mar/belt.hoon @@ -0,0 +1 @@ +../../base-dev/mar/belt.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/bill.hoon b/pkg/arvo/mar/bill.hoon new file mode 120000 index 000000000..801d99730 --- /dev/null +++ b/pkg/arvo/mar/bill.hoon @@ -0,0 +1 @@ +../../base-dev/mar/bill.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon deleted file mode 100644 index 4c23c5705..000000000 --- a/pkg/arvo/mar/blit.hoon +++ /dev/null @@ -1,61 +0,0 @@ -:: blit: runtime blit structure -:: -|_ =blit:dill -++ grad %noun -:: +grab: convert from -:: -++ grab - |% - ++ noun blit:dill - -- -:: +grow: convert to -:: -++ grow - |% - ++ noun blit - ++ json - ^- ^json - =, enjs:format - %+ frond -.blit - ?- -.blit - %bel b+& - %clr b+& - %hop (numb p.blit) - %lin a+(turn p.blit |=(c=@c s+(tuft c))) - %mor b+& - %url s+p.blit - :: - %sag - %- pairs - :~ 'path'^(path p.blit) - 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit))) - == - :: - %sav - %- pairs - :~ 'path'^(path p.blit) - 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit)) - == - :: - %klr - :- %a - %+ turn p.blit - |= [=stye text=(list @c)] - %- pairs - :~ 'text'^a+(turn text |=(c=@c s+(tuft c))) - :: - :- 'stye' - %- pairs - |^ :~ 'back'^(color p.q.stye) - 'fore'^(color q.q.stye) - 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d))) - == - ++ color - |= =tint - ?@ tint ?~(tint ~ s+tint) - s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint))) - -- - == - == - -- --- diff --git a/pkg/arvo/mar/blit.hoon b/pkg/arvo/mar/blit.hoon new file mode 120000 index 000000000..3ea8dc943 --- /dev/null +++ b/pkg/arvo/mar/blit.hoon @@ -0,0 +1 @@ +../../base-dev/mar/blit.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/csv.hoon b/pkg/arvo/mar/csv.hoon new file mode 100644 index 000000000..15445aad9 --- /dev/null +++ b/pkg/arvo/mar/csv.hoon @@ -0,0 +1,15 @@ +=, format +=, mimes:html +|_ csv=wain +:: +++ grab :: convert from + |% + ++ mime |=((pair mite octs) (to-wain q.q)) + ++ noun wain :: clam from %noun + -- +++ grow + |% + ++ mime [/text/csv (as-octs (of-wain csv))] + -- +++ grad %mime +-- diff --git a/pkg/arvo/mar/hoon.hoon b/pkg/arvo/mar/hoon.hoon deleted file mode 100644 index b6f590649..000000000 --- a/pkg/arvo/mar/hoon.hoon +++ /dev/null @@ -1,49 +0,0 @@ -:::: /hoon/hoon/mar - :: -/? 310 -:: -=, eyre -|_ own=@t -:: -++ grow :: convert to - |% - ++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime - ++ elem :: convert to %html - ;div:pre(urb_codemirror "", mode "hoon"):"{(trip own)}" - :: =+ gen-id="src-{<`@ui`(mug own)>}" - :: ;div - :: ;textarea(id "{gen-id}"):"{(trip own)}" - :: ;script:""" - :: CodeMirror.fromTextArea( - :: window[{}], - :: \{lineNumbers:true, readOnly:true} - :: ) - :: """ - :: == - ++ hymn - :: ;html:(head:title:"Source" "+{elem}") - ;html - ;head - ;title:"Source" - ;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js"; - ;script@"/lib/syntax/hoon.js"; - ;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/". - "codemirror/4.3.0/codemirror.min.css"); - ;link/"/lib/syntax/codemirror.css"(rel "stylesheet"); - == - ;body - ;textarea#src:"{(trip own)}" - ;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})' - == - == - ++ txt - (to-wain:format own) - -- -++ grab - |% :: convert from - ++ mime |=([p=mite q=octs] q.q) - ++ noun @t :: clam from %noun - ++ txt of-wain:format - -- -++ grad %txt --- diff --git a/pkg/arvo/mar/hoon.hoon b/pkg/arvo/mar/hoon.hoon new file mode 120000 index 000000000..95f8f67f9 --- /dev/null +++ b/pkg/arvo/mar/hoon.hoon @@ -0,0 +1 @@ +../../base-dev/mar/hoon.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/htm.hoon b/pkg/arvo/mar/htm.hoon deleted file mode 100644 index a40a432dd..000000000 --- a/pkg/arvo/mar/htm.hoon +++ /dev/null @@ -1,15 +0,0 @@ -:: -:::: /hoon/htm/mar - :: -/? 310 -|_ own=manx -:: -++ grad %noun -++ grow :: convert to - |% - ++ noun own - ++ hymn own - -- -++ grab |% :: convert from - ++ noun manx :: clam from %noun --- -- diff --git a/pkg/arvo/mar/htm.hoon b/pkg/arvo/mar/htm.hoon new file mode 120000 index 000000000..d29e24bac --- /dev/null +++ b/pkg/arvo/mar/htm.hoon @@ -0,0 +1 @@ +../../base-dev/mar/htm.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/html.hoon b/pkg/arvo/mar/html.hoon deleted file mode 100644 index 203d75f61..000000000 --- a/pkg/arvo/mar/html.hoon +++ /dev/null @@ -1,22 +0,0 @@ -:: -:::: /hoon/html/mar - :: -/? 310 - :: -:::: compute - :: -=, html -|_ htm=@t -++ grow :: convert to - ^? - |% :: - ++ mime [/text/html (met 3 htm) htm] :: to %mime - ++ hymn (need (de-xml htm)) :: to %hymn - -- :: -++ grab ^? - |% :: convert from - ++ noun @t :: clam from %noun - ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime - -- -++ grad %mime --- diff --git a/pkg/arvo/mar/html.hoon b/pkg/arvo/mar/html.hoon new file mode 120000 index 000000000..14a5f8f7b --- /dev/null +++ b/pkg/arvo/mar/html.hoon @@ -0,0 +1 @@ +../../base-dev/mar/html.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/httr.hoon b/pkg/arvo/mar/httr.hoon deleted file mode 100644 index bbac8f990..000000000 --- a/pkg/arvo/mar/httr.hoon +++ /dev/null @@ -1,25 +0,0 @@ -:: -:::: /hoon/httr/mar - :: -/? 310 -:: -=, eyre -=, format -=, html -|_ hit=httr -++ grad %noun -++ grow |% ++ wall (turn wain trip) - ++ wain (to-wain cord) - ++ json (need (de-json cord)) - ++ cord q:octs - ++ noun hit - ++ octs - ~| hit - ?> =(2 (div p.hit 100)) - (need r.hit) - -- -++ grab :: convert from - |% - ++ noun httr :: clam from %noun - -- --- diff --git a/pkg/arvo/mar/httr.hoon b/pkg/arvo/mar/httr.hoon new file mode 120000 index 000000000..572665778 --- /dev/null +++ b/pkg/arvo/mar/httr.hoon @@ -0,0 +1 @@ +../../base-dev/mar/httr.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/hymn.hoon b/pkg/arvo/mar/hymn.hoon deleted file mode 100644 index cf01508ea..000000000 --- a/pkg/arvo/mar/hymn.hoon +++ /dev/null @@ -1,17 +0,0 @@ -:: -:::: /hoon/hymn/mar - :: -/? 310 -=, mimes:html -=, html -|_ own=manx -:: -++ grad %noun -++ grow :: convert to - |% - ++ html (crip (en-xml own)) :: convert to %html - ++ mime [/text/html (as-octs html)] :: convert to %mime - -- -++ grab |% :: convert from - ++ noun manx :: clam from %noun --- -- diff --git a/pkg/arvo/mar/hymn.hoon b/pkg/arvo/mar/hymn.hoon new file mode 120000 index 000000000..905156749 --- /dev/null +++ b/pkg/arvo/mar/hymn.hoon @@ -0,0 +1 @@ +../../base-dev/mar/hymn.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/js.hoon b/pkg/arvo/mar/js.hoon deleted file mode 100644 index e8fbe7701..000000000 --- a/pkg/arvo/mar/js.hoon +++ /dev/null @@ -1,22 +0,0 @@ -:: -:::: /hoon/js/mar - :: -/? 310 -:: -=, eyre -|_ mud=@ -++ grow - |% - ++ mime [/application/javascript (as-octs:mimes:html (@t mud))] - ++ elem ;script - ;- (trip (@t mud)) - == - ++ hymn ;html:(head:"+{elem}" body) - -- -++ grab - |% :: convert from - ++ mime |=([p=mite q=octs] (@t q.q)) - ++ noun cord :: clam from %noun - -- -++ grad %mime --- diff --git a/pkg/arvo/mar/js.hoon b/pkg/arvo/mar/js.hoon new file mode 120000 index 000000000..00189f4c6 --- /dev/null +++ b/pkg/arvo/mar/js.hoon @@ -0,0 +1 @@ +../../base-dev/mar/js.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/json.hoon b/pkg/arvo/mar/json.hoon deleted file mode 100644 index 506b70835..000000000 --- a/pkg/arvo/mar/json.hoon +++ /dev/null @@ -1,26 +0,0 @@ -:: -:::: /hoon/json/mar - :: -/? 310 - :: -:::: compute - :: -=, eyre -=, format -=, html -|_ jon=json -:: -++ grow :: convert to - |% - ++ mime [/application/json (as-octs:mimes -:txt)] :: convert to %mime - ++ txt [(crip (en-json jon))]~ - -- -++ grab - |% :: convert from - ++ mime |=([p=mite q=octs] (fall (rush (@t q.q) apex:de-json) *json)) - ++ noun json :: clam from %noun - ++ numb numb:enjs - ++ time time:enjs - -- -++ grad %mime --- diff --git a/pkg/arvo/mar/json.hoon b/pkg/arvo/mar/json.hoon new file mode 120000 index 000000000..e77f85d05 --- /dev/null +++ b/pkg/arvo/mar/json.hoon @@ -0,0 +1 @@ +../../base-dev/mar/json.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/json/rpc/response.hoon b/pkg/arvo/mar/json/rpc/response.hoon deleted file mode 100644 index 91ea2f670..000000000 --- a/pkg/arvo/mar/json/rpc/response.hoon +++ /dev/null @@ -1,43 +0,0 @@ -:: -/- *json-rpc -:: -|_ res=response -:: -++ grad %noun -++ grow - |% - ++ noun res - -- -++ grab :: convert from - |% - ++ noun response :: from noun - ++ httr :: from httr - |= hit=httr:eyre - ^- response - ~| hit - ?: ?=(%2 (div p.hit 100)) - =, html - %- json - ?~ r.hit - a+~ - (need (de-json q:u.r.hit)) - fail+hit - ++ json :: from json - =, dejs-soft:format - |= a=json - ^- response - =; dere - =+ res=((ar dere) a) - ?~ res (need (dere a)) - [%batch u.res] - |= a=json - ^- (unit response) - =/ res=(unit [@t json]) - ::TODO breaks when no id present - ((ot id+so result+some ~) a) - ?^ res `[%result u.res] - ~| a - :+ ~ %error %- need - ((ot id+so error+(ot code+no message+so ~) ~) a) - -- --- diff --git a/pkg/arvo/mar/json/rpc/response.hoon b/pkg/arvo/mar/json/rpc/response.hoon new file mode 120000 index 000000000..52c97c864 --- /dev/null +++ b/pkg/arvo/mar/json/rpc/response.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/json/rpc/response.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/kelvin.hoon b/pkg/arvo/mar/kelvin.hoon new file mode 120000 index 000000000..195ebe0dc --- /dev/null +++ b/pkg/arvo/mar/kelvin.hoon @@ -0,0 +1 @@ +../../base-dev/mar/kelvin.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/kiln/bump.hoon b/pkg/arvo/mar/kiln/bump.hoon new file mode 100644 index 000000000..35896403b --- /dev/null +++ b/pkg/arvo/mar/kiln/bump.hoon @@ -0,0 +1,24 @@ +|% ++$ bump [%kiln-bump except=(set desk) force=_|] +-- +|_ b=bump +++ grad %noun +++ grab + |% + ++ noun bump + ++ json + ^- $-(^json bump) + =, dejs:format + %+ pe %kiln-bump + %- ot + :~ except+(as so) + force+bo + == + -- +++ grow + |% + ++ noun b + -- +-- + + diff --git a/pkg/arvo/mar/kiln/install.hoon b/pkg/arvo/mar/kiln/install.hoon new file mode 100644 index 000000000..ca0600bff --- /dev/null +++ b/pkg/arvo/mar/kiln/install.hoon @@ -0,0 +1,29 @@ +|% ++$ install + [local=term =ship =desk] +-- +|_ inst=install +++ grad %noun +++ grow + |% + ++ noun inst + ++ json + %- pairs:enjs:format + :~ local+s+local.inst + desk+s+desk.inst + ship+s+(scot %p ship.inst) + == + -- +++ grab + |% + ++ noun install + ++ json + ^- $-(^json install) + =, dejs:format + %- ot + :~ local+so + ship+(su ;~(pfix sig fed:ag)) + desk+so + == + -- +-- diff --git a/pkg/arvo/mar/kiln/pause.hoon b/pkg/arvo/mar/kiln/pause.hoon new file mode 100644 index 000000000..335cd9580 --- /dev/null +++ b/pkg/arvo/mar/kiln/pause.hoon @@ -0,0 +1,13 @@ +|_ =desk +++ grad %noun +++ grow + |% + ++ noun desk + ++ json s+desk + -- +++ grab + |% + ++ noun ^desk + ++ json so:dejs:format + -- +-- diff --git a/pkg/arvo/mar/kiln/resume.hoon b/pkg/arvo/mar/kiln/resume.hoon new file mode 100644 index 000000000..335cd9580 --- /dev/null +++ b/pkg/arvo/mar/kiln/resume.hoon @@ -0,0 +1,13 @@ +|_ =desk +++ grad %noun +++ grow + |% + ++ noun desk + ++ json s+desk + -- +++ grab + |% + ++ noun ^desk + ++ json so:dejs:format + -- +-- diff --git a/pkg/arvo/mar/kiln/revive.hoon b/pkg/arvo/mar/kiln/revive.hoon new file mode 100644 index 000000000..335cd9580 --- /dev/null +++ b/pkg/arvo/mar/kiln/revive.hoon @@ -0,0 +1,13 @@ +|_ =desk +++ grad %noun +++ grow + |% + ++ noun desk + ++ json s+desk + -- +++ grab + |% + ++ noun ^desk + ++ json so:dejs:format + -- +-- diff --git a/pkg/arvo/mar/kiln/suspend.hoon b/pkg/arvo/mar/kiln/suspend.hoon new file mode 100644 index 000000000..335cd9580 --- /dev/null +++ b/pkg/arvo/mar/kiln/suspend.hoon @@ -0,0 +1,13 @@ +|_ =desk +++ grad %noun +++ grow + |% + ++ noun desk + ++ json s+desk + -- +++ grab + |% + ++ noun ^desk + ++ json so:dejs:format + -- +-- diff --git a/pkg/arvo/mar/kiln/uninstall.hoon b/pkg/arvo/mar/kiln/uninstall.hoon new file mode 100644 index 000000000..335cd9580 --- /dev/null +++ b/pkg/arvo/mar/kiln/uninstall.hoon @@ -0,0 +1,13 @@ +|_ =desk +++ grad %noun +++ grow + |% + ++ noun desk + ++ json s+desk + -- +++ grab + |% + ++ noun ^desk + ++ json so:dejs:format + -- +-- diff --git a/pkg/arvo/mar/kiln/vats-diff-0.hoon b/pkg/arvo/mar/kiln/vats-diff-0.hoon new file mode 100644 index 000000000..cc98e8656 --- /dev/null +++ b/pkg/arvo/mar/kiln/vats-diff-0.hoon @@ -0,0 +1,54 @@ +/- hood +|_ =diff:hood +++ grad %noun +++ grow + |% + ++ noun diff + ++ json + =, enjs:format + |^ + %+ frond -.diff + ?- -.diff + %block (block +.diff) + ?(%merge-sunk %merge-fail) (desk-arak-err +.diff) + ?(%reset %commit %suspend %revive) (desk-arak +.diff) + == + :: + ++ block + |= [=desk =arak:hood =weft:hood blockers=(set desk)] + %+ merge (desk-arak desk arak) + %- pairs + :~ weft+(weft:enjs:hood weft) + blockers+a+(turn ~(tap in blockers) (lead %s)) + == + :: + ++ desk-arak + |= [=desk =arak:hood] + %- pairs + :~ desk+s+desk + arak+(arak:enjs:hood arak) + == + :: + ++ desk-arak-err + |= [=desk =arak:hood =tang] + %+ merge (desk-arak desk arak) + %+ frond %tang + a+(turn tang tank) + :: + ++ merge + |= [a=^json b=^json] + ^- ^json + ?> &(?=(%o -.a) ?=(%o -.b)) + o+(~(uni by p.a) p.b) + -- + -- +++ grab + |% + ++ noun diff:hood + -- +-- + + + + + diff --git a/pkg/arvo/mar/kiln/vats-snap-0.hoon b/pkg/arvo/mar/kiln/vats-snap-0.hoon new file mode 100644 index 000000000..955229e1a --- /dev/null +++ b/pkg/arvo/mar/kiln/vats-snap-0.hoon @@ -0,0 +1,20 @@ +/- hood +!: +|_ ark=(map desk arak:hood) +++ grad %noun +++ grow + |% + ++ noun ark + ++ json + =, enjs:format + %- pairs + %+ turn ~(tap by ark) + |= [=desk =arak:hood] + [desk (arak:enjs:hood arak)] + -- +:: +++ grab + |% + ++ noun (map desk arak:hood) + -- +-- diff --git a/pkg/arvo/mar/kiln/vats.hoon b/pkg/arvo/mar/kiln/vats.hoon new file mode 100644 index 000000000..2a2ec8660 --- /dev/null +++ b/pkg/arvo/mar/kiln/vats.hoon @@ -0,0 +1,21 @@ +/- *hood +|_ vats=(list vat) +++ grad %noun +++ grow + |% + ++ noun vats + ++ json (vats:enjs vats) + -- +++ grab + |% + ++ noun (list vat) + -- +-- + + + + + + + + diff --git a/pkg/arvo/mar/language-server/rpc/notification.hoon b/pkg/arvo/mar/language-server/rpc/notification.hoon deleted file mode 100644 index d464da489..000000000 --- a/pkg/arvo/mar/language-server/rpc/notification.hoon +++ /dev/null @@ -1,18 +0,0 @@ -/- *language-server -/+ lsp-json=language-server-json -|_ not=all:notification -++ grad %noun -++ grab - |% - ++ noun all:notification - ++ json - |= jon=^json - (notification:dejs:lsp-json jon) - -- -++ grow - |% - ++ noun not - ++ json - (notification:enjs:lsp-json not) - -- --- diff --git a/pkg/arvo/mar/language-server/rpc/notification.hoon b/pkg/arvo/mar/language-server/rpc/notification.hoon new file mode 120000 index 000000000..b95e54c35 --- /dev/null +++ b/pkg/arvo/mar/language-server/rpc/notification.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/language-server/rpc/notification.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/language-server/rpc/request.hoon b/pkg/arvo/mar/language-server/rpc/request.hoon deleted file mode 100644 index 989a6f41c..000000000 --- a/pkg/arvo/mar/language-server/rpc/request.hoon +++ /dev/null @@ -1,16 +0,0 @@ -/- *language-server -/+ lsp-json=language-server-json -|_ req=all:request -++ grad %noun -++ grow - |% - ++ noun req - -- -++ grab - |% - ++ noun all:request - ++ json - |= jon=^json - (request:dejs:lsp-json jon) - -- --- diff --git a/pkg/arvo/mar/language-server/rpc/request.hoon b/pkg/arvo/mar/language-server/rpc/request.hoon new file mode 120000 index 000000000..26203cf5b --- /dev/null +++ b/pkg/arvo/mar/language-server/rpc/request.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/language-server/rpc/request.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/language-server/rpc/response.hoon b/pkg/arvo/mar/language-server/rpc/response.hoon deleted file mode 100644 index f82408b87..000000000 --- a/pkg/arvo/mar/language-server/rpc/response.hoon +++ /dev/null @@ -1,17 +0,0 @@ -/- *language-server -/+ lsp=language-server-json -|_ res=all:response -:: -++ grad %noun -++ grow - |% - ++ noun res - ++ json (response:enjs:lsp res) - -- -:: -++ grab - |% - ++ noun all:response - -- -:: --- diff --git a/pkg/arvo/mar/language-server/rpc/response.hoon b/pkg/arvo/mar/language-server/rpc/response.hoon new file mode 120000 index 000000000..9dddb2cef --- /dev/null +++ b/pkg/arvo/mar/language-server/rpc/response.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/language-server/rpc/response.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/loob.hoon b/pkg/arvo/mar/loob.hoon new file mode 100644 index 000000000..7b124f99c --- /dev/null +++ b/pkg/arvo/mar/loob.hoon @@ -0,0 +1,12 @@ +|_ loob=? +++ grad %noun +++ grow + |% + ++ noun loob + ++ json b+loob + -- +++ grab + |% + ++ noun ? + -- +-- diff --git a/pkg/arvo/mar/mime.hoon b/pkg/arvo/mar/mime.hoon deleted file mode 100644 index 83b4daeb5..000000000 --- a/pkg/arvo/mar/mime.hoon +++ /dev/null @@ -1,32 +0,0 @@ -:: -:::: /hoon/mime/mar - :: -/? 310 -:: -|_ own=mime -++ grow - ^? - |% - ++ jam `@`q.q.own - -- -:: -++ grab :: convert from - ^? - |% - ++ noun mime :: clam from %noun - ++ tape - |=(a=_"" [/application/x-urb-unknown (as-octt:mimes:html a)]) - -- -++ grad - ^? - |% - ++ form %mime - ++ diff |=(mime +<) - ++ pact |=(mime +<) - ++ join |=([mime mime] `(unit mime)`~) - ++ mash - |= [[ship desk mime] [ship desk mime]] - ^- mime - ~|(%mime-mash !!) - -- --- diff --git a/pkg/arvo/mar/mime.hoon b/pkg/arvo/mar/mime.hoon new file mode 120000 index 000000000..0d85898f3 --- /dev/null +++ b/pkg/arvo/mar/mime.hoon @@ -0,0 +1 @@ +../../base-dev/mar/mime.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/noun.hoon b/pkg/arvo/mar/noun.hoon deleted file mode 100644 index 5c798d3c2..000000000 --- a/pkg/arvo/mar/noun.hoon +++ /dev/null @@ -1,19 +0,0 @@ -:: -:::: /hoon/noun/mar - :: -/? 310 -!: -:::: A minimal noun mark -|_ non=* -++ grab |% - ++ noun * - -- -++ grad - |% - ++ form %noun - ++ diff |=(* +<) - ++ pact |=(* +<) - ++ join |=([* *] *(unit *)) - ++ mash |=([[ship desk *] [ship desk *]] `*`~|(%noun-mash !!)) - -- --- diff --git a/pkg/arvo/mar/noun.hoon b/pkg/arvo/mar/noun.hoon new file mode 120000 index 000000000..97cc30876 --- /dev/null +++ b/pkg/arvo/mar/noun.hoon @@ -0,0 +1 @@ +../../base-dev/mar/noun.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/path.hoon b/pkg/arvo/mar/path.hoon deleted file mode 100644 index 2196ba95a..000000000 --- a/pkg/arvo/mar/path.hoon +++ /dev/null @@ -1,11 +0,0 @@ -|_ pax=path -++ grad %noun -++ grow - |% - ++ noun pax - -- -++ grab - |% - ++ noun path - -- --- diff --git a/pkg/arvo/mar/path.hoon b/pkg/arvo/mar/path.hoon new file mode 120000 index 000000000..c07b00064 --- /dev/null +++ b/pkg/arvo/mar/path.hoon @@ -0,0 +1 @@ +../../base-dev/mar/path.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/png.hoon b/pkg/arvo/mar/png.hoon deleted file mode 100644 index 6a60a6a27..000000000 --- a/pkg/arvo/mar/png.hoon +++ /dev/null @@ -1,12 +0,0 @@ -|_ dat=@ -++ grow - |% - ++ mime [/image/png (as-octs:mimes:html dat)] - -- -++ grab - |% - ++ mime |=([p=mite q=octs] q.q) - ++ noun @ - -- -++ grad %mime --- diff --git a/pkg/arvo/mar/png.hoon b/pkg/arvo/mar/png.hoon new file mode 120000 index 000000000..c2d8cf9fa --- /dev/null +++ b/pkg/arvo/mar/png.hoon @@ -0,0 +1 @@ +../../base-dev/mar/png.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/purl.hoon b/pkg/arvo/mar/purl.hoon deleted file mode 100644 index 3fb39fa69..000000000 --- a/pkg/arvo/mar/purl.hoon +++ /dev/null @@ -1,18 +0,0 @@ -:: -:::: /hoon/purl/mar - :: -/? 310 -=, eyre -|_ url=purl -++ grad %noun -:: -++ grow - |% - ++ noun url - ++ hiss [url %get ~ ~] - -- -++ grab :: convert from - |% - ++ noun purl :: clam from %noun - -- --- diff --git a/pkg/arvo/mar/purl.hoon b/pkg/arvo/mar/purl.hoon new file mode 120000 index 000000000..d0d2cc0de --- /dev/null +++ b/pkg/arvo/mar/purl.hoon @@ -0,0 +1 @@ +../../base-dev/mar/purl.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/ship.hoon b/pkg/arvo/mar/ship.hoon new file mode 120000 index 000000000..72de2c03c --- /dev/null +++ b/pkg/arvo/mar/ship.hoon @@ -0,0 +1 @@ +../../base-dev/mar/ship.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/sole/action.hoon b/pkg/arvo/mar/sole/action.hoon deleted file mode 100644 index 149ef5ef1..000000000 --- a/pkg/arvo/mar/sole/action.hoon +++ /dev/null @@ -1,50 +0,0 @@ -:: -:::: /hoon/action/sole/mar - :: -/? 310 -/- sole -:: -:::: - :: -=, sole -|_ sole-action -:: -++ grad %noun -++ grow - |% - ++ noun +<.grad - -- -++ grab :: convert from - |% - ++ json - |= jon=^json ^- sole-action - %- need %. jon - => [dejs-soft:format ..sole-action] - |^ (ot id+so dat+(fo %ret (of det+change tab+ni ~)) ~) - ++ fo - |* [a=term b=fist] - |=(c=json ?.(=([%s a] c) (b c) (some [a ~]))) - :: - ++ ra - |* [a=[term fist] b=fist] - |= c=json %. c - ?.(=(%a -.c) b (pe -.a (ar +.a))) - :: - ++ ke :: callbacks - |* [gar=* sef=(trap fist)] - |= jon=json ^- (unit _gar) - =- ~! gar ~! (need -) - - ((sef) jon) - :: - ++ change (ot ler+(at ni ni ~) ted+(pe 0v0 edit) ~) - ++ char (cu taft so) - ++ edit - %+ ke *sole-edit |. ~+ - %+ fo %nop - %+ ra mor+edit - (of del+ni set+(cu tuba sa) ins+(ot at+ni cha+char ~) ~) - -- - :: - ++ noun sole-action :: clam from %noun - -- --- diff --git a/pkg/arvo/mar/sole/action.hoon b/pkg/arvo/mar/sole/action.hoon new file mode 120000 index 000000000..b349bd771 --- /dev/null +++ b/pkg/arvo/mar/sole/action.hoon @@ -0,0 +1 @@ +../../../base-dev/mar/sole/action.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/sole/effect.hoon b/pkg/arvo/mar/sole/effect.hoon deleted file mode 100644 index 7b1f7477b..000000000 --- a/pkg/arvo/mar/sole/effect.hoon +++ /dev/null @@ -1,82 +0,0 @@ -:: -:::: /hoon/effect/sole/mar - :: -/? 310 -/- sole -!: -:: -:::: - :: -=, sole -=, format -|% -++ mar-sole-change :: XX dependency - |_ cha=sole-change - ++ grow - |% ++ json - ^- ^json - =, enjs - =; edi - =,(cha (pairs ted+(edi ted) ler+a+~[(numb own.ler) (numb his.ler)] ~)) - |= det=sole-edit - ?- -.det - %nop [%s 'nop'] - %mor [%a (turn p.det ..$)] - %del (frond %del (numb p.det)) - %set (frond %set (tape (tufa p.det))) - %ins (frond %ins (pairs at+(numb p.det) cha+s+(tuft q.det) ~)) - == - -- - -- -++ wush - |= [wid=@u tan=tang] - ^- tape - (of-wall (turn (flop tan) |=(a=tank (of-wall (wash 0^wid a))))) -:: -++ purge :: discard ++styx style - |= a=styx ^- tape - %- zing %+ turn a - |= a=_?>(?=(^ a) i.a) - ?@(a (trip a) ^$(a q.a)) --- -:: -|_ sef=sole-effect -:: -++ grad %noun -++ grab :: convert from - |% - ++ noun sole-effect :: clam from %noun - -- -++ grow - =, enjs - |% - ++ noun sef - ++ json - ^- ^json - ?+ -.sef - ~|(unsupported-effect+-.sef !!) - %mor [%a (turn p.sef |=(a=sole-effect json(sef a)))] - %err (frond %hop (numb p.sef)) - %txt (frond %txt (tape p.sef)) - %tan (frond %tan (tape (wush 160 p.sef))) - %det (frond %det json:~(grow mar-sole-change +.sef)) - :: - %pro - %+ frond %pro - (pairs vis+b+vis.sef tag+s+tag.sef cad+(tape (purge cad.sef)) ~) - :: - %tab - :- %a - %+ turn p.sef - |= [=cord =^tank] - %+ frond %tab - %- pairs - :~ match+s+cord - info+(tape ~(ram re tank)) - == - :: - ?(%bel %clr %nex %bye) - (frond %act %s -.sef) - == - -- --- diff --git a/pkg/arvo/mar/sole/effect.hoon b/pkg/arvo/mar/sole/effect.hoon new file mode 120000 index 000000000..bc11205c0 --- /dev/null +++ b/pkg/arvo/mar/sole/effect.hoon @@ -0,0 +1 @@ +../../../base-dev/mar/sole/effect.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/svg.hoon b/pkg/arvo/mar/svg.hoon deleted file mode 100644 index 2911e4900..000000000 --- a/pkg/arvo/mar/svg.hoon +++ /dev/null @@ -1,12 +0,0 @@ -|_ dat=@ -++ grow - |% - ++ mime [/image/'svg+xml' (as-octs:mimes:html dat)] - -- -++ grab - |% - ++ mime |=([p=mite q=octs] q.q) - ++ noun @ - -- -++ grad %mime --- diff --git a/pkg/arvo/mar/svg.hoon b/pkg/arvo/mar/svg.hoon new file mode 120000 index 000000000..2b406c2ac --- /dev/null +++ b/pkg/arvo/mar/svg.hoon @@ -0,0 +1 @@ +../../base-dev/mar/svg.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/tang.hoon b/pkg/arvo/mar/tang.hoon deleted file mode 100644 index 681e939fb..000000000 --- a/pkg/arvo/mar/tang.hoon +++ /dev/null @@ -1,30 +0,0 @@ -:: -:::: /hoon/tang/mar - :: -/? 310 -:: -=, format -|_ tan=(list tank) -++ grad %noun -++ grow - |% - ++ noun tan - ++ json - =/ result=(each (list ^json) tang) - (mule |.((turn tan tank:enjs:format))) - ?- -.result - %& a+p.result - %| a+[a+[%s '[[output rendering error]]']~]~ - == - :: - ++ elem - =- ;pre:code:"{(of-wall -)}" - ^- wall %- zing ^- (list wall) - (turn (flop tan) |=(a=tank (wash 0^160 a))) - -- -++ grab :: convert from - |% - ++ noun (list ^tank) :: clam from %noun - ++ tank |=(a=^tank [a]~) - -- --- diff --git a/pkg/arvo/mar/tang.hoon b/pkg/arvo/mar/tang.hoon new file mode 120000 index 000000000..9206e52b2 --- /dev/null +++ b/pkg/arvo/mar/tang.hoon @@ -0,0 +1 @@ +../../base-dev/mar/tang.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/tape.hoon b/pkg/arvo/mar/tape.hoon deleted file mode 100644 index a30176421..000000000 --- a/pkg/arvo/mar/tape.hoon +++ /dev/null @@ -1,12 +0,0 @@ -|_ tap=tape -++ grad %noun -++ grow - |% - ++ noun tap - ++ json s+(crip tap) - -- -++ grab - |% - ++ noun tape - -- --- diff --git a/pkg/arvo/mar/tape.hoon b/pkg/arvo/mar/tape.hoon new file mode 120000 index 000000000..be51fcb2d --- /dev/null +++ b/pkg/arvo/mar/tape.hoon @@ -0,0 +1 @@ +../../base-dev/mar/tape.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/txt-diff.hoon b/pkg/arvo/mar/txt-diff.hoon deleted file mode 100644 index 2c9a500dc..000000000 --- a/pkg/arvo/mar/txt-diff.hoon +++ /dev/null @@ -1,16 +0,0 @@ -:: -:::: /hoon/txt-diff/mar - :: -/? 310 -|_ txt-diff=(urge:clay cord) -:: -++ grad %noun -++ grow - |% - ++ noun txt-diff - -- -++ grab :: convert from - |% - ++ noun (urge:clay cord) :: make from %noun - -- --- diff --git a/pkg/arvo/mar/txt-diff.hoon b/pkg/arvo/mar/txt-diff.hoon new file mode 120000 index 000000000..1f7c04285 --- /dev/null +++ b/pkg/arvo/mar/txt-diff.hoon @@ -0,0 +1 @@ +../../base-dev/mar/txt-diff.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/txt.hoon b/pkg/arvo/mar/txt.hoon deleted file mode 100644 index 1c349b182..000000000 --- a/pkg/arvo/mar/txt.hoon +++ /dev/null @@ -1,275 +0,0 @@ -:: -:::: /hoon/txt/mar - :: -/? 310 -:: -=, clay -=, differ -=, format -=, mimes:html -|_ txt=wain -:: -++ grab :: convert from - |% - ++ mime |=((pair mite octs) (to-wain q.q)) - ++ noun wain :: clam from %noun - -- -++ grow - => v=. - |% - ++ mime => v [/text/plain (as-octs (of-wain txt))] - ++ elem => v ;pre: {(trip (of-wain txt))} - -- -++ grad - |% - ++ form %txt-diff - ++ diff - |= tyt=wain - ^- (urge cord) - (lusk txt tyt (loss txt tyt)) - :: - ++ pact - |= dif=(urge cord) - ~| [%pacting dif] - ^- wain - (lurk txt dif) - :: - ++ join - |= [ali=(urge cord) bob=(urge cord)] - ^- (unit (urge cord)) - |^ - =. ali (clean ali) - =. bob (clean bob) - |- ^- (unit (urge cord)) - ?~ ali `bob - ?~ bob `ali - ?- -.i.ali - %& - ?- -.i.bob - %& - ?: =(p.i.ali p.i.bob) - %+ bind $(ali t.ali, bob t.bob) - |=(cud=(urge cord) [i.ali cud]) - ?: (gth p.i.ali p.i.bob) - %+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob) - |=(cud=(urge cord) [i.bob cud]) - %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali)) - |=(cud=(urge cord) [i.ali cud]) - :: - %| - ?: =(p.i.ali (lent p.i.bob)) - %+ bind $(ali t.ali, bob t.bob) - |=(cud=(urge cord) [i.bob cud]) - ?: (gth p.i.ali (lent p.i.bob)) - %+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob) - |=(cud=(urge cord) [i.bob cud]) - ~ - == - :: - %| - ?- -.i.bob - %| - ?. =(i.ali i.bob) - ~ - %+ bind $(ali t.ali, bob t.bob) - |=(cud=(urge cord) [i.ali cud]) - :: - %& - ?: =(p.i.bob (lent p.i.ali)) - %+ bind $(ali t.ali, bob t.bob) - |=(cud=(urge cord) [i.ali cud]) - ?: (gth p.i.bob (lent p.i.ali)) - %+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali))) - |=(cud=(urge cord) [i.ali cud]) - ~ - == - == - ++ clean :: clean - |= wig=(urge cord) - ^- (urge cord) - ?~ wig ~ - ?~ t.wig wig - ?: ?=(%& -.i.wig) - ?: ?=(%& -.i.t.wig) - $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) - [i.wig $(wig t.wig)] - ?: ?=(%| -.i.t.wig) - $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) - [i.wig $(wig t.wig)] - -- - :: - ++ mash - |= $: [als=ship ald=desk ali=(urge cord)] - [bos=ship bod=desk bob=(urge cord)] - == - ^- (urge cord) - |^ - =. ali (clean ali) - =. bob (clean bob) - |- ^- (urge cord) - ?~ ali bob - ?~ bob ali - ?- -.i.ali - %& - ?- -.i.bob - %& - ?: =(p.i.ali p.i.bob) - [i.ali $(ali t.ali, bob t.bob)] - ?: (gth p.i.ali p.i.bob) - [i.bob $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)] - [i.ali $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))] - :: - %| - ?: =(p.i.ali (lent p.i.bob)) - [i.bob $(ali t.ali, bob t.bob)] - ?: (gth p.i.ali (lent p.i.bob)) - [i.bob $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)] - =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] - (resolve ali bob) - [fic $(ali ali, bob bob)] - :: ~ :: here, alice is good for a while, but not for the whole - == :: length of bob's changes - :: - %| - ?- -.i.bob - %| - =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] - (resolve ali bob) - [fic $(ali ali, bob bob)] - :: - %& - ?: =(p.i.bob (lent p.i.ali)) - [i.ali $(ali t.ali, bob t.bob)] - ?: (gth p.i.bob (lent p.i.ali)) - [i.ali $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))] - =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] - (resolve ali bob) - [fic $(ali ali, bob bob)] - == - == - :: - ++ annotate :: annotate conflict - |= $: ali=(list @t) - bob=(list @t) - bas=(list @t) - == - ^- (list @t) - %- zing - ^- (list (list @t)) - %- flop - ^- (list (list @t)) - :- :_ ~ - %^ cat 3 '<<<<<<<<<<<<' - %^ cat 3 ' ' - %^ cat 3 `@t`(scot %p bos) - %^ cat 3 '/' - bod - - :- bob - :- ~['------------'] - :- bas - :- ~['++++++++++++'] - :- ali - :- :_ ~ - %^ cat 3 '>>>>>>>>>>>>' - %^ cat 3 ' ' - %^ cat 3 `@t`(scot %p als) - %^ cat 3 '/' - ald - ~ - :: - ++ clean :: clean - |= wig=(urge cord) - ^- (urge cord) - ?~ wig ~ - ?~ t.wig wig - ?: ?=(%& -.i.wig) - ?: ?=(%& -.i.t.wig) - $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) - [i.wig $(wig t.wig)] - ?: ?=(%| -.i.t.wig) - $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) - [i.wig $(wig t.wig)] - :: - ++ resolve - |= [ali=(urge cord) bob=(urge cord)] - ^- [fic=[%| p=(list cord) q=(list cord)] ali=(urge cord) bob=(urge cord)] - =- [[%| bac (annotate alc boc bac)] ali bob] - |- ^- $: $: bac=(list cord) - alc=(list cord) - boc=(list cord) - == - ali=(urge cord) - bob=(urge cord) - == - ?~ ali [[~ ~ ~] ali bob] - ?~ bob [[~ ~ ~] ali bob] - ?- -.i.ali - %& - ?- -.i.bob - %& [[~ ~ ~] ali bob] :: no conflict - %| - =+ lob=(lent p.i.bob) - ?: =(lob p.i.ali) - [[p.i.bob p.i.bob q.i.bob] t.ali t.bob] - ?: (lth lob p.i.ali) - [[p.i.bob p.i.bob q.i.bob] [[%& (sub p.i.ali lob)] t.ali] t.bob] - =+ wat=(scag (sub lob p.i.ali) p.i.bob) - =+ ^= res - %= $ - ali t.ali - bob [[%| (scag (sub lob p.i.ali) p.i.bob) ~] t.bob] - == - :* :* (welp bac.res wat) - (welp alc.res wat) - (welp boc.res q.i.bob) - == - ali.res - bob.res - == - == - :: - %| - ?- -.i.bob - %& - =+ loa=(lent p.i.ali) - ?: =(loa p.i.bob) - [[p.i.ali q.i.ali p.i.ali] t.ali t.bob] - ?: (lth loa p.i.bob) - [[p.i.ali q.i.ali p.i.ali] t.ali [[%& (sub p.i.bob loa)] t.bob]] - =+ wat=(slag (sub loa p.i.bob) p.i.ali) - =+ ^= res - %= $ - ali [[%| (scag (sub loa p.i.bob) p.i.ali) ~] t.ali] - bob t.bob - == - :* :* (welp bac.res wat) - (welp alc.res q.i.ali) - (welp boc.res wat) - == - ali.res - bob.res - == - :: - %| - =+ loa=(lent p.i.ali) - =+ lob=(lent p.i.bob) - ?: =(loa lob) - [[p.i.ali q.i.ali q.i.bob] t.ali t.bob] - =+ ^= res - ?: (gth loa lob) - $(ali [[%| (scag (sub loa lob) p.i.ali) ~] t.ali], bob t.bob) - ~& [%scagging loa=loa pibob=p.i.bob slag=(scag loa p.i.bob)] - $(ali t.ali, bob [[%| (scag (sub lob loa) p.i.bob) ~] t.bob]) - :* :* (welp bac.res ?:((gth loa lob) p.i.bob p.i.ali)) - (welp alc.res q.i.ali) - (welp boc.res q.i.bob) - == - ali.res - bob.res - == - == - == - -- - -- --- diff --git a/pkg/arvo/mar/txt.hoon b/pkg/arvo/mar/txt.hoon new file mode 120000 index 000000000..432541575 --- /dev/null +++ b/pkg/arvo/mar/txt.hoon @@ -0,0 +1 @@ +../../base-dev/mar/txt.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/udon.hoon b/pkg/arvo/mar/udon.hoon deleted file mode 100644 index 72c9e6f5c..000000000 --- a/pkg/arvo/mar/udon.hoon +++ /dev/null @@ -1,32 +0,0 @@ -:: -:::: /hoon/udon/mar - :: -/+ cram -:: -|_ mud=@t -++ grow - |% - ++ mime [/text/x-unmark (as-octs:mimes:html mud)] - ++ txt - (to-wain:format mud) - ++ elem - ^- manx - =, cram - elm:(static (ream mud)) - ++ front :: XX performance, types - ^- (map term knot) - %- ~(run by inf:(static:cram (ream mud))) - |= a=dime ^- cord - ?+ (end 3 p.a) (scot a) - %t q.a - == - -- -++ grab - |% - ++ mime |=((pair mite octs) q.q) - ++ noun @t - ++ txt of-wain:format - -- -++ grad %txt -++ garb /down --- diff --git a/pkg/arvo/mar/udon.hoon b/pkg/arvo/mar/udon.hoon new file mode 120000 index 000000000..215e0ada9 --- /dev/null +++ b/pkg/arvo/mar/udon.hoon @@ -0,0 +1 @@ +../../base-dev/mar/udon.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/umd.hoon b/pkg/arvo/mar/umd.hoon deleted file mode 100644 index d249bcff8..000000000 --- a/pkg/arvo/mar/umd.hoon +++ /dev/null @@ -1,32 +0,0 @@ -:: -:::: /hoon/umd/mar - :: -/+ cram -:: -|_ mud=@t -++ grow - |% - ++ mime [/text/x-unmark (as-octs:mimes:html mud)] - ++ txt - (to-wain:format mud) - ++ elem - ^- manx - =, cram - elm:(static (ream mud)) - ++ front :: XX performance, types - ^- (map term knot) - %- ~(run by inf:(static:cram (ream mud))) - |= a=dime ^- cord - ?+ (end 3 p.a) (scot a) - %t q.a - == - -- -++ grab - |% - ++ mime |=((pair mite octs) q.q) - ++ noun @t - ++ txt of-wain:format - -- -++ grad %txt -++ garb /down --- diff --git a/pkg/arvo/mar/umd.hoon b/pkg/arvo/mar/umd.hoon new file mode 120000 index 000000000..9b827a24d --- /dev/null +++ b/pkg/arvo/mar/umd.hoon @@ -0,0 +1 @@ +../../base-dev/mar/umd.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/urb.hoon b/pkg/arvo/mar/urb.hoon deleted file mode 100644 index 49545e73f..000000000 --- a/pkg/arvo/mar/urb.hoon +++ /dev/null @@ -1,18 +0,0 @@ -:: -:::: /hoon/elem/urb/mar - :: -/? 310 -=, mimes:html -=, html -|_ own=manx -:: -++ grad %noun -++ grow :: convert to - |% - ++ hymn ;html:(head body:"+{own}") :: convert to %hymn - ++ html (crip (en-xml hymn)) :: convert to %html - ++ mime [/text/html (as-octs html)] :: convert to %mime - -- -++ grab |% :: convert from - ++ noun manx :: clam from %noun --- -- diff --git a/pkg/arvo/mar/urb.hoon b/pkg/arvo/mar/urb.hoon new file mode 120000 index 000000000..2d8112d1d --- /dev/null +++ b/pkg/arvo/mar/urb.hoon @@ -0,0 +1 @@ +../../base-dev/mar/urb.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/urbit.hoon b/pkg/arvo/mar/urbit.hoon deleted file mode 100644 index 8d2c3c658..000000000 --- a/pkg/arvo/mar/urbit.hoon +++ /dev/null @@ -1,17 +0,0 @@ -:: -:::: /hoon/urbit/mar - :: -/? 310 -:::: A minimal urbit mark -:: -|_ her=@p -++ grab - |% - ++ noun @p - -- -++ grow - |% - ++ noun her - -- -++ grad %noun --- diff --git a/pkg/arvo/mar/urbit.hoon b/pkg/arvo/mar/urbit.hoon new file mode 120000 index 000000000..70a62a723 --- /dev/null +++ b/pkg/arvo/mar/urbit.hoon @@ -0,0 +1 @@ +../../base-dev/mar/urbit.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/woff2.hoon b/pkg/arvo/mar/woff2.hoon deleted file mode 100644 index 7e7242908..000000000 --- a/pkg/arvo/mar/woff2.hoon +++ /dev/null @@ -1,12 +0,0 @@ -|_ dat=octs -++ grow - |% - ++ mime [/font/woff2 dat] - -- -++ grab - |% - ++ mime |=([=mite =octs] octs) - ++ noun octs - -- -++ grad %mime --- diff --git a/pkg/arvo/mar/woff2.hoon b/pkg/arvo/mar/woff2.hoon new file mode 120000 index 000000000..beaf4875c --- /dev/null +++ b/pkg/arvo/mar/woff2.hoon @@ -0,0 +1 @@ +../../base-dev/mar/woff2.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/xml.hoon b/pkg/arvo/mar/xml.hoon deleted file mode 100644 index 6d52d8024..000000000 --- a/pkg/arvo/mar/xml.hoon +++ /dev/null @@ -1,21 +0,0 @@ -:: -:::: /hoon/xml/mar - :: -/? 310 - :: -:::: compute - :: -=, mimes:html -=, html -|_ xml=@t -:: -++ grad %mime -++ grow :: convert to - |% :: - ++ mime [/application/xml (as-octs xml)] :: to %mime - ++ hymn (need (de-xml xml)) :: to %hymn - -- :: -++ grab |% :: convert from - ++ noun @t :: clam from %noun - ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime --- -- diff --git a/pkg/arvo/mar/xml.hoon b/pkg/arvo/mar/xml.hoon new file mode 120000 index 000000000..e6323e215 --- /dev/null +++ b/pkg/arvo/mar/xml.hoon @@ -0,0 +1 @@ +../../base-dev/mar/xml.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/aggregator.hoon b/pkg/arvo/sur/aggregator.hoon deleted file mode 100644 index 1f3b6be50..000000000 --- a/pkg/arvo/sur/aggregator.hoon +++ /dev/null @@ -1,60 +0,0 @@ -/+ naive, ethereum -:: -|% -+$ roller-config - $: next-batch=time - frequency=@dr - refresh-time=@dr - contract=@ux - chain-id=@ - == -:: -+$ keccak @ux -:: -+$ tx-status - $: status=?(%unknown %pending %sending %confirmed %failed) - pointer=(unit l1-tx-pointer) - == -:: -+$ l1-tx-pointer - $: =address:ethereum - nonce=@ud - == -:: -+$ l2-tx - $? %transfer-point - %spawn - %configure-keys - %escape - %cancel-escape - %adopt - %reject - %detach - %set-management-proxy - %set-spawn-proxy - %set-transfer-proxy - == -:: -:: TODO: add submission time? -:: -+$ roller-tx [status=tx-status hash=keccak type=l2-tx] -:: -+$ pend-tx [force=? =address:naive =raw-tx:naive] -:: -+$ part-tx - $% [%raw raw=octs] - [%don =tx:naive] - [%ful raw=octs =tx:naive] ::TODO redundant? - == -:: -+$ rpc-send-roll - $: endpoint=@t - contract=address:ethereum - chain-id=@ - pk=@ - :: - nonce=@ud - next-gas-price=@ud - txs=(list raw-tx:naive) - == --- \ No newline at end of file diff --git a/pkg/arvo/sur/aquarium.hoon b/pkg/arvo/sur/aquarium.hoon deleted file mode 100644 index fbf0f5b97..000000000 --- a/pkg/arvo/sur/aquarium.hoon +++ /dev/null @@ -1,76 +0,0 @@ -:: Traditionally, ovo refers to an ovum -- (pair wire card) -- and ova -:: refers to a list of them. We have several versions of each of these -:: depending on context, so we do away with that naming scheme and use -:: the following naming scheme. -:: -:: Every card is either an `event` or an `effect`. Prepended to this -:: is `unix` if it has no ship associated with it, or `aqua` if it -:: does. `timed` is added if it includes the time of the event. -:: -:: Short names are simply the first letter of each word plus `s` if -:: it's a list. -:: -/+ pill -=, pill-lib=pill -|% -+$ az-log [topics=(lest @) data=@t] -+$ az-state - $: logs=(list az-log) - lives=(map ship [lyfe=life rut=rift]) - tym=@da - == -++ ph-event - $% [%test-done p=?] - aqua-event - == -:: -+$ unix-event unix-event:pill-lib -+$ pill pill:pill-lib -:: -+$ aqua-event - $% [%init-ship who=ship keys=(unit dawn-event:jael)] - [%pause-events who=ship] - [%snap-ships lab=term hers=(list ship)] - [%restore-snap lab=term] - [%event who=ship ue=unix-event] - == -:: -+$ azimuth-action - $% [%init-azimuth ~] - [%spawn who=ship] - [%breach who=ship] - == -:: -+$ aqua-effects - [who=ship ufs=(list unix-effect)] -:: -+$ aqua-effect - [who=ship ufs=unix-effect] -:: -+$ aqua-events - [who=ship utes=(list unix-timed-event)] -:: -+$ aqua-boths - [who=ship ub=(list unix-both)] -:: -+$ unix-both - $% [%event unix-timed-event] - [%effect unix-effect] - == -:: -+$ unix-timed-event [tym=@da ue=unix-event] -:: -+$ unix-effect - %+ pair wire - $% [%blit p=(list blit:dill)] - [%send p=lane:ames q=@] - [%doze p=(unit @da)] - [%thus p=@ud q=(unit hiss:eyre)] - [%ergo p=@tas q=mode:clay] - [%sleep ~] - [%restore ~] - [%kill ~] - [%init ~] - [%request id=@ud request=request:http] - == --- diff --git a/pkg/arvo/sur/aquarium.hoon b/pkg/arvo/sur/aquarium.hoon new file mode 120000 index 000000000..1195b2c62 --- /dev/null +++ b/pkg/arvo/sur/aquarium.hoon @@ -0,0 +1 @@ +../../base-dev/sur/aquarium.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/asn1.hoon b/pkg/arvo/sur/asn1.hoon deleted file mode 100644 index 348c07ebe..000000000 --- a/pkg/arvo/sur/asn1.hoon +++ /dev/null @@ -1,80 +0,0 @@ -:: |asn1: small selection of types and constants for ASN.1 -:: -:: A minimal representation of some basic ASN.1 types, -:: created to support PKCS keys, digests, and cert requests. -:: -^? -|% -:: +bespoke:asn1: context-specific, generic ASN.1 tag type -:: -:: Note that *explicit* implies *constructed* (ie, bit 5 is set in DER). -:: -+$ bespoke - :: imp: & is implicit, | is explicit - :: tag: 5 bits for the custom tag number - :: - [imp=? tag=@ud] -:: +spec:asn1: minimal representations of basic ASN.1 types -:: -+$ spec - $% :: %int: arbitrary-sized, unsigned integers - :: - :: Unsigned integers, represented as having a positive sign. - :: Negative integers would be two's complement in DER, - :: but we don't need them. - :: - [%int int=@u] - :: %bit: very minimal support for bit strings - :: - :: Specifically, values must already be padded and byte-aligned. - :: len: bitwidth - :: bit: data - :: - [%bit len=@ud bit=@ux] - :: %oct: octets in little-endian byte order - :: - :: len: bytewidth - :: bit: data - :: - [%oct len=@ud oct=@ux] - :: %nul: fully supported! - :: - [%nul ~] - :: %obj: object identifiers, pre-packed - :: - :: Object identifiers are technically a sequence of integers, - :: represented here in their already-encoded form. - :: - [%obj obj=@ux] - :: %seq: a list of specs - :: - [%seq seq=(list spec)] - :: %set: a logical set of specs - :: - :: Implemented here as a list for the sake of simplicity. - :: must be already deduplicated and sorted! - :: - [%set set=(list spec)] - :: %con: context-specific - :: - :: General support for context-specific tags. - :: bes: custom tag number, implicit or explicit - :: con: already-encoded bytes - :: - [%con bes=bespoke con=(list @D)] - == -:: |obj:asn1: constant object ids, pre-encoded -:: -++ obj - ^? - |% :: rfc4055 - ++ sha-256 0x1.0204.0365.0148.8660 :: 2.16.840.1.101.3.4.2.1 - ++ rsa 0x1.0101.0df7.8648.862a :: 1.2.840.113549.1.1.1 - ++ rsa-sha-256 0xb.0101.0df7.8648.862a :: 1.2.840.113549.1.1.11 - :: rfc2985 - ++ csr-ext 0xe.0901.0df7.8648.862a :: 1.2.840.113549.1.9.14 - :: rfc3280 - ++ sub-alt 0x11.1d55 :: 2.5.29.17 - -- --- - diff --git a/pkg/arvo/sur/asn1.hoon b/pkg/arvo/sur/asn1.hoon new file mode 120000 index 000000000..7888cada0 --- /dev/null +++ b/pkg/arvo/sur/asn1.hoon @@ -0,0 +1 @@ +../../base-dev/sur/asn1.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/bitcoin.hoon b/pkg/arvo/sur/bitcoin.hoon deleted file mode 100644 index 06aee8178..000000000 --- a/pkg/arvo/sur/bitcoin.hoon +++ /dev/null @@ -1,84 +0,0 @@ -:: sur/btc.hoon -:: Utilities for working with BTC data types and transactions -:: -:: chyg: whether account is (non-)change. 0 or 1 -:: bytc: "btc-byts" with dat cast to @ux -|% -+$ network ?(%main %testnet) -+$ hexb [wid=@ dat=@ux] :: hex byts -+$ bits [wid=@ dat=@ub] -+$ xpub @ta -+$ address - $% [%base58 @uc] - [%bech32 cord] - == -+$ fprint hexb -+$ bipt $?(%44 %49 %84) -+$ chyg $?(%0 %1) -+$ idx @ud -+$ hdkey [=fprint pubkey=hexb =network =bipt =chyg =idx] -+$ sats @ud -+$ vbytes @ud -+$ txid hexb -+$ utxo [pos=@ =txid height=@ value=sats recvd=(unit @da)] -++ address-info - $: =address - confirmed-value=sats - unconfirmed-value=sats - utxos=(set utxo) - == -++ tx - |% - +$ data - $: is=(list input) - os=(list output) - locktime=@ud - nversion=@ud - segwit=(unit @ud) - == - +$ val - $: =txid - pos=@ud - =address - value=sats - == - :: included: whether tx is in the mempool or blockchain - :: - +$ info - $: included=? - =txid - confs=@ud - recvd=(unit @da) - inputs=(list val) - outputs=(list val) - == - +$ input - $: =txid - pos=@ud - sequence=hexb - script-sig=(unit hexb) - pubkey=(unit hexb) - value=sats - == - +$ output - $: script-pubkey=hexb - value=sats - == - -- -++ psbt - |% - +$ base64 cord - +$ in [=utxo rawtx=hexb =hdkey] - +$ out [=address hk=(unit hdkey)] - +$ target $?(%input %output) - +$ keyval [key=hexb val=hexb] - +$ map (list keyval) - -- -++ ops - |% - ++ op-dup 118 - ++ op-equalverify 136 - ++ op-hash160 169 - ++ op-checksig 172 - -- --- diff --git a/pkg/arvo/sur/bitcoin.hoon b/pkg/arvo/sur/bitcoin.hoon new file mode 120000 index 000000000..d72c2c830 --- /dev/null +++ b/pkg/arvo/sur/bitcoin.hoon @@ -0,0 +1 @@ +../../base-dev/sur/bitcoin.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/crunch.hoon b/pkg/arvo/sur/crunch.hoon new file mode 100644 index 000000000..e2d5a5a73 --- /dev/null +++ b/pkg/arvo/sur/crunch.hoon @@ -0,0 +1,9 @@ +/- resource +:: +|% ++$ channel-info + $: group=resource:resource + channel=resource:resource + channel-type=term + == +-- diff --git a/pkg/arvo/sur/dice.hoon b/pkg/arvo/sur/dice.hoon new file mode 100644 index 000000000..8b6bd09b2 --- /dev/null +++ b/pkg/arvo/sur/dice.hoon @@ -0,0 +1,89 @@ +:: dice: structures for L2 rollers +:: +/+ naive, ethereum +:: +|% ++$ owner [=proxy:naive =address:naive] ++$ owners (jug owner ship) ++$ net ?(%mainnet %ropsten %local) +:: ++$ config + $% [%frequency frequency=@dr] + [%setkey pk=@] + [%endpoint endpoint=@t =net] + [%resend-time time=@dr] + [%update-rate rate=@dr] + [%slice slice=@dr] + [%quota quota=@ud] + == +:: ++$ azimuth-config + $: refresh-rate=@dr + == +:: ++$ roller-config + $: next-batch=time + frequency=@dr + resend-time=@dr + update-rate=@dr + contract=@ux + chain-id=@ + slice=@dr + quota=@ud + == +:: ++$ keccak @ux +:: ++$ status + ?(%unknown %pending %sending %confirmed %failed %cancelled) +:: ++$ tx-status + $: =status + pointer=(unit l1-tx-pointer) + == +:: ++$ l1-tx-pointer + $: =address:ethereum + nonce=@ud + == +:: ++$ l2-tx + $? %transfer-point + %spawn + %configure-keys + %escape + %cancel-escape + %adopt + %reject + %detach + %set-management-proxy + %set-spawn-proxy + %set-transfer-proxy + == +:: ++$ update + $% [%point =ship =point:naive new=owner old=(unit owner)] + [%tx =address:ethereum =roll-tx] + == +:: ++$ hist-tx [p=time q=roll-tx] ++$ roll-tx [=ship =status hash=keccak type=l2-tx] ++$ pend-tx [force=? =address:naive =time =raw-tx:naive] ++$ send-tx [next-gas-price=@ud sent=? txs=(list raw-tx:naive)] ++$ part-tx + $% [%raw raw=octs] + [%don =tx:naive] + [%ful raw=octs =tx:naive] ::TODO redundant? + == +:: ++$ rpc-send-roll + $: endpoint=@t + contract=address:ethereum + chain-id=@ + pk=@ + :: + nonce=@ud + next-gas-price=@ud + txs=(list raw-tx:naive) + == +-- diff --git a/pkg/arvo/sur/hood.hoon b/pkg/arvo/sur/hood.hoon new file mode 120000 index 000000000..b212f501e --- /dev/null +++ b/pkg/arvo/sur/hood.hoon @@ -0,0 +1 @@ +../../base-dev/sur/hood.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/json/rpc.hoon b/pkg/arvo/sur/json/rpc.hoon deleted file mode 100644 index 1c99b0f0a..000000000 --- a/pkg/arvo/sur/json/rpc.hoon +++ /dev/null @@ -1,28 +0,0 @@ -:: json-rpc: protocol types -:: -|% -+$ batch-request - $% [%a p=(list request)] - [%o p=request] - == -:: -+$ request - $: id=@t - jsonrpc=@t - method=@t - params=request-params - == -:: -+$ request-params - $% [%list (list json)] - [%map (map @t json)] - [%object (list (pair @t json))] - == -+$ response - $~ [%fail *httr:eyre] - $% [%result id=@t res=json] - [%error id=@t code=@t message=@t] ::TODO data? - [%fail hit=httr:eyre] - [%batch bas=(list response)] - == --- diff --git a/pkg/arvo/sur/json/rpc.hoon b/pkg/arvo/sur/json/rpc.hoon new file mode 120000 index 000000000..e499542f6 --- /dev/null +++ b/pkg/arvo/sur/json/rpc.hoon @@ -0,0 +1 @@ +../../../base-dev/sur/json/rpc.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/keygen.hoon b/pkg/arvo/sur/keygen.hoon deleted file mode 100644 index f897eee4a..000000000 --- a/pkg/arvo/sur/keygen.hoon +++ /dev/null @@ -1,23 +0,0 @@ -|% -+$ revision @ud -+$ nodetype tape -+$ mnemonic tape -:: -+$ vault - $: ownership=node - voting=node - management=node - transfer=node - spawn=node - network=uode - == -:: -+$ node [type=nodetype seed=mnemonic keys=wallet] -+$ uode [revi=revision seed=@ux keys=edkeys] -:: -+$ wallet [keys=[public=@ux private=@ux] addr=@ux chain=@ux] -:: -+$ edkeys [auth=keypair crypt=keypair] -:: -+$ keypair [public=@ux secret=@ux] --- diff --git a/pkg/arvo/sur/keygen.hoon b/pkg/arvo/sur/keygen.hoon new file mode 120000 index 000000000..99bcd5fc8 --- /dev/null +++ b/pkg/arvo/sur/keygen.hoon @@ -0,0 +1 @@ +../../base-dev/sur/keygen.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/language-server.hoon b/pkg/arvo/sur/language-server.hoon deleted file mode 100644 index f781588c3..000000000 --- a/pkg/arvo/sur/language-server.hoon +++ /dev/null @@ -1,114 +0,0 @@ -|% -:: -+$ versioned-doc-id - [uri=@t version=(unit @)] -:: -++ request - |% - +$ all - $% - text-document--hover - text-document--completion - unknown - == - +$ text-document--hover - [%text-document--hover id=cord position versioned-doc-id] - +$ text-document--completion - [%text-document--completion id=cord position versioned-doc-id] - +$ unknown - [%unknown json] - -- -++ response - |% - +$ all - $% - text-document--hover - text-document--completion - == - +$ text-document--hover - [%text-document--hover id=cord contents=(unit @t)] - +$ text-document--completion - [%text-document--completion id=cord completion=(list completion-item)] - -- -:: -+$ completion-item - $: - label=cord - kind=@ud - detail=cord - doc=cord - insert-text=cord - insert-text-format=@ud - == - - - -:: -+$ diagnostic - [=range severity=@ud message=@t] -:: -+$ position - [row=@ud col=@ud] -:: -+$ text-document-item - [uri=@t version=(unit @) text=@t] -:: -++ notification - |% - :: - +$ in - $% - text-document--did-change - text-document--did-open - text-document--did-save - text-document--did-close - exit - unknown - == - :: - +$ out - $% - text-document--publish-diagnostics - == - :: - +$ all - $% - out - in - == - :: - +$ text-document--did-change - [%text-document--did-change versioned-doc-id changes=(list change)] - :: - +$ text-document--did-open - [%text-document--did-open text-document-item] - :: - +$ text-document--did-save - [%text-document--did-save versioned-doc-id] - :: - +$ text-document--did-close - [%text-document--did-close versioned-doc-id] - :: - +$ exit - [%exit ~] - :: - +$ unknown - [%unknown =json] - :: - +$ text-document--publish-diagnostics - [%text-document--publish-diagnostics uri=@t diagnostics=(list diagnostic)] - :: - -- -:: -+$ change - $: range=(unit range) - range-length=(unit @ud) - text=@t - == -:: -+$ range - $: start=position - end=position - == -:: --- diff --git a/pkg/arvo/sur/language-server.hoon b/pkg/arvo/sur/language-server.hoon new file mode 120000 index 000000000..a1c726780 --- /dev/null +++ b/pkg/arvo/sur/language-server.hoon @@ -0,0 +1 @@ +../../base-dev/sur/language-server.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/ring.hoon b/pkg/arvo/sur/ring.hoon deleted file mode 100644 index f25cec06b..000000000 --- a/pkg/arvo/sur/ring.hoon +++ /dev/null @@ -1,47 +0,0 @@ -|% -:: +raw-ring-signature: low level ring signature type -:: -:: The :s field of a ring signature grows O(n) with the number of -:: participants in the ring. -:: -++ raw-ring-signature - $: ch0=@ - :: - s=(list @) - :: linked ring signature tag - :: - :: Two linked ring signatures with the same link scope can be shown to - :: have been made by the same private key, leading to Sybil - :: resistance...but if your private keys are compromised, your - :: adversary can determine which signatures you made. - :: - y=(unit @udpoint) - == -:: +ring-signature: higher level ring signature type -:: -:: This contains all the identifying information to verify a ring signature -:: in an urbit context. -:: -++ ring-signature - $: :: a ring signature is computed over a set of public keys. the - :: participants set is not those keys, but static references to them. - :: - participants=(set [ship=@p =life]) - :: the linkage scope this signature was made on - :: - link-scope=(unit *) - :: the rest of the low level ring signature is appended - :: - raw=raw-ring-signature - == -:: -+$ ring-group - $: :: a ring signature is computed over a set of public keys. the - :: participants set is not those keys, but static references to them. - :: - participants=(set [ship=@p =life]) - :: the linkage scope this signature was made on - :: - link-scope=(unit *) - == --- diff --git a/pkg/arvo/sur/ring.hoon b/pkg/arvo/sur/ring.hoon new file mode 120000 index 000000000..633c96332 --- /dev/null +++ b/pkg/arvo/sur/ring.hoon @@ -0,0 +1 @@ +../../base-dev/sur/ring.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/settings.hoon b/pkg/arvo/sur/settings.hoon deleted file mode 100644 index 67a071f7d..000000000 --- a/pkg/arvo/sur/settings.hoon +++ /dev/null @@ -1,31 +0,0 @@ -|% -+$ settings-0 (map key bucket-0) -+$ bucket-0 (map key val-0) -+$ val-0 - $% [%s p=@t] - [%b p=?] - [%n p=@] - == -:: -+$ settings (map key bucket) -+$ bucket (map key val) -+$ key term -+$ val - $~ [%n 0] - $% [%s p=@t] - [%b p=?] - [%n p=@] - [%a p=(list val)] - == -+$ event - $% [%put-bucket =key =bucket] - [%del-bucket =key] - [%put-entry buc=key =key =val] - [%del-entry buc=key =key] - == -+$ data - $% [%all =settings] - [%bucket =bucket] - [%entry =val] - == --- diff --git a/pkg/arvo/sur/sole.hoon b/pkg/arvo/sur/sole.hoon deleted file mode 100644 index e942bccb8..000000000 --- a/pkg/arvo/sur/sole.hoon +++ /dev/null @@ -1,87 +0,0 @@ -:: -:::: /hoon/sole/sur - :: -^? -|% -+$ sole-action :: sole to app - $: id=@ta :: duct id - $= dat - $% :: [%abo ~] :: reset interaction - [%det sole-change] :: command line edit - [%ret ~] :: submit and clear - [%clr ~] :: exit context - [%tab pos=@ud] :: tab complete - == :: - == -+$ sole-buffer (list @c) :: command state -+$ sole-change :: network change - $: ler=sole-clock :: destination clock - haw=@uvH :: source hash - ted=sole-edit :: state change - == :: -+$ sole-clock [own=@ud his=@ud] :: vector clock -+$ sole-edit :: shared state change - $% [%del p=@ud] :: delete one at - [%ins p=@ud q=@c] :: insert at - [%mor p=(list sole-edit)] :: combination - [%nop ~] :: no-op - [%set p=sole-buffer] :: discontinuity - == :: -+$ sole-effect :: app to sole - $% [%bel ~] :: beep - [%blk p=@ud q=@c] :: blink+match char at - [%bye ~] :: close session - [%clr ~] :: clear screen - [%det sole-change] :: edit command - [%err p=@ud] :: error point - [%klr p=styx] :: styled text line - [%mor p=(list sole-effect)] :: multiple effects - [%nex ~] :: save clear command - [%pro sole-prompt] :: set prompt - [%sag p=path q=*] :: save to jamfile - [%sav p=path q=@] :: save to file - [%tab p=(list [=cord =tank])] :: tab-complete list - [%tan p=(list tank)] :: classic tank - :: [%taq p=tanq] :: modern tank - [%txt p=tape] :: text line - [%url p=@t] :: activate url - == :: -+$ sole-command :: command state - $: pos=@ud :: cursor position - say=sole-share :: cursor - == :: -+$ sole-prompt :: prompt definition - $: vis=? :: command visible - tag=term :: history mode - cad=styx :: caption - == :: -+$ sole-share :: symmetric state - $: ven=sole-clock :: our vector clock - leg=(list sole-edit) :: unmerged edits - buf=sole-buffer :: sole state - == :: -:: :: -:: :: -++ sole-dialog :: standard dialog - |* out=$-(* *) :: output structure - $-(sole-input (sole-result out)) :: output function -:: :: -+$ sole-input tape :: prompt input -++ sole-result :: conditional result - |* out=$-(* *) :: output structure - $@(@ud (sole-product out)) :: error position -:: :: -++ sole-product :: success result - |* out=$-(* *) :: - %+ pair (list tank) :: - %+ each (unit out) :: ~ is abort - (pair sole-prompt (sole-dialog out)) :: ask and continue -:: :: -+$ sole-gen :: XX virtual type - $% [%say $-((sole-args) (cask))] :: direct noun - [%ask $-((sole-args) (sole-product (cask)))] :: dialog - == :: -++ sole-args :: generator arguments - |* _[* *] :: - ,[[now=@da eny=@uvJ bek=beak] [,+<- ,+<+]] :: --- diff --git a/pkg/arvo/sur/sole.hoon b/pkg/arvo/sur/sole.hoon new file mode 120000 index 000000000..8cac11891 --- /dev/null +++ b/pkg/arvo/sur/sole.hoon @@ -0,0 +1 @@ +../../base-dev/sur/sole.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/spider.hoon b/pkg/arvo/sur/spider.hoon deleted file mode 100644 index 5fe7a7626..000000000 --- a/pkg/arvo/sur/spider.hoon +++ /dev/null @@ -1,14 +0,0 @@ -/+ libstrand=strand -=, strand=strand:libstrand -|% -+$ thread $-(vase _*form:(strand ,vase)) -+$ input [=tid =cage] -+$ tid tid:strand -+$ bowl bowl:strand -+$ http-error - $? %bad-request :: 400 - %forbidden :: 403 - %nonexistent :: 404 - %offline :: 504 - == --- diff --git a/pkg/arvo/sur/spider.hoon b/pkg/arvo/sur/spider.hoon new file mode 120000 index 000000000..12ae2c187 --- /dev/null +++ b/pkg/arvo/sur/spider.hoon @@ -0,0 +1 @@ +../../base-dev/sur/spider.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/tapp.hoon b/pkg/arvo/sur/tapp.hoon deleted file mode 100644 index c2901c235..000000000 --- a/pkg/arvo/sur/tapp.hoon +++ /dev/null @@ -1,45 +0,0 @@ -|* [poke-data=mold out-peer-data=mold] -|% -:: -:: Possible async calls -:: -+$ card - $% [%scry =path] - [%wait wire @da] - [%rest wire @da] - [%poke wire dock poke-data] - [%peer wire dock path] - [%pull wire dock ~] - [%diff out-peer-data] - [%request wire request:http outbound-config:iris] - [%cancel-request wire ~] - [%connect wire binding:eyre term] - [%http-response =http-event:http] - [%rule wire %turf %put turf] - [%source wire whos=(set ship) src=source:jael] - [%sources wire ~] - [%new-event wire =ship =udiff:point:jael] - [%listen wire whos=(set ship) =source:jael] - [%flog wire flog:dill] - == -:: -:: Possible async responses -:: -+$ sign - $% [%scry-result result=*] - [%wake error=(unit tang)] - [%coup =dock error=(unit tang)] - [%quit =dock =path] - [%reap =dock =path error=(unit tang)] - [%bound success=? =binding:eyre] - [%http-response response=client-response:iris] - [%source whos=(set ship) =source:jael] - == -:: -:: Outstanding contracts -:: -+$ contract - $% [%wait at=@da] - [%request ~] - == --- diff --git a/pkg/arvo/sur/verb.hoon b/pkg/arvo/sur/verb.hoon deleted file mode 100644 index f7d19f658..000000000 --- a/pkg/arvo/sur/verb.hoon +++ /dev/null @@ -1,12 +0,0 @@ -|% -+$ event - $% [%on-init ~] - [%on-load ~] - [%on-poke =mark] - [%on-watch =path] - [%on-leave =path] - [%on-agent =wire sign=term] - [%on-arvo =wire vane=term sign=term] - [%on-fail =term] - == --- \ No newline at end of file diff --git a/pkg/arvo/sur/verb.hoon b/pkg/arvo/sur/verb.hoon new file mode 120000 index 000000000..1a6100d9c --- /dev/null +++ b/pkg/arvo/sur/verb.hoon @@ -0,0 +1 @@ +../../base-dev/sur/verb.hoon \ No newline at end of file diff --git a/pkg/arvo/sys.kelvin b/pkg/arvo/sys.kelvin new file mode 100644 index 000000000..b7464903a --- /dev/null +++ b/pkg/arvo/sys.kelvin @@ -0,0 +1 @@ +[%zuse 420] diff --git a/pkg/arvo/sys/arvo.hoon b/pkg/arvo/sys/arvo.hoon index 35133e055..a0cbfcc2c 100644 --- a/pkg/arvo/sys/arvo.hoon +++ b/pkg/arvo/sys/arvo.hoon @@ -165,6 +165,7 @@ :: $vile: reflexive constants :: $waif: arvo task, from anywhere :: $wasp: arvo task, from Outside +:: $weft: kelvin version, tag and number :: $worm: compiler cache :: $wisp: arvo task, larval stage :: $wynn: kelvin stack @@ -252,11 +253,13 @@ :: %what: update from files :: %whey: produce $mass :: XX remove, scry :: %verb: toggle laconicity + :: %whiz: prime vane caches :: $% [%trim p=@ud] [%what p=(list (pair path (cask)))] [%whey ~] [%verb p=(unit ?)] + [%whiz ~] == +$ wasp :: %crud: reroute $ovum with $goof @@ -267,6 +270,7 @@ [%wack p=@uvJ] [%wyrd p=vere] == ++$ weft [lal=@tas num=@ud] +$ worm $: :: +nest, +play, and +mint :: @@ -279,7 +283,7 @@ $>(?(%wack %wyrd) wasp) [%whom p=ship] == -+$ wynn (list (pair term @ud)) ++$ wynn (list weft) -- => :: ~% %hex ..ut ~ @@ -291,14 +295,23 @@ |=(b=beam =*(s scot `path`[(s %p p.b) q.b (s r.b) s.b])) :: ++ de-beam + ~/ %de-beam |= p=path ^- (unit beam) ?. ?=([@ @ @ *] p) ~ ?~ who=(slaw %p i.p) ~ ?~ des=?~(i.t.p (some %$) (slaw %tas i.t.p)) ~ :: XX +sym ;~(pose low (easy %$)) - ?~ ved=(slay i.t.t.p) ~ - ?. ?=([%$ case] u.ved) ~ - `(unit beam)`[~ [`ship`u.who `desk`u.des `case`p.u.ved] t.t.t.p] + ?~ ved=(de-case i.t.t.p) ~ + `[[`ship`u.who `desk`u.des u.ved] t.t.t.p] +:: +++ de-case + ~/ %de-case + |= =knot + ^- (unit case) + ?^ num=(slaw %ud knot) `[%ud u.num] + ?^ wen=(slaw %da knot) `[%da u.wen] + ?~ lab=(slaw %tas knot) ~ + `[%tas u.lab] :: ++ en-omen |= [vis=view bem=beam] @@ -308,6 +321,7 @@ ~(rent co [%many $/tas/way.vis $/tas/car.vis ~]) :: ++ de-omen + ~/ %de-omen |= pax=path ^- (unit [vis=view bem=beam]) ?~ pax ~ @@ -352,10 +366,10 @@ |= kel=wynn ^- ? ?: =(~ kel) & - =^ las=(pair term @ud) kel kel + =^ las=weft kel kel |- ^- ? ?~ kel & - ?& (gte q.las q.i.kel) + ?& (gte num.las num.i.kel) $(las i.kel, kel t.kel) == :: +need: require kelvins @@ -372,7 +386,7 @@ ~_ :+ %rose [" " ~ ~] :~ =+ p.u.wyr - leaf/"%{(trip p)} %{(scow %ud q)} required;" + leaf/"%{(trip lal)} %{(scow %ud num)} required;" ?~ q.u.wyr leaf/"runtime missing support" leaf/"runtime only supports %{(scow %ud u.q.u.wyr)}" @@ -381,20 +395,20 @@ ~> %mean.'wyrd' !! :: - |- ^- (unit (pair (pair term @ud) (unit @ud))) + |- ^- (unit (pair weft (unit @ud))) ?~ hav ~ :: :: fel: %&: runtime kelvin for [i.hav] :: %|: no specified runtime support :: =/ fel - |- ^- (each @ud (pair term @ud)) + |- ^- (each @ud weft) ?~ run |/i.hav - ?:(=(p.i.hav p.i.run) &/q.i.run $(run t.run)) + ?:(=(lal.i.hav lal.i.run) &/num.i.run $(run t.run)) :: ?- -.fel %| `[p.fel ~] - %& ?.((lte p.fel q.i.hav) `[i.hav `p.fel] $(hav t.hav)) + %& ?.((lte p.fel num.i.hav) `[i.hav `p.fel] $(hav t.hav)) == -- :: @@ -1000,8 +1014,11 @@ ++ settle |= van=vase ^- (pair vase worm) - =/ [rig=vase wor=worm] (~(slym wa *worm) van *vane-sample) - [van +:(~(slap wa wor) rig [%limb %scry])] + =| sac=worm + =^ rig=vase sac (~(slym wa sac) van *vane-sample) + =^ gat=vase sac (~(slap wa sac) rig [%limb %scry]) + =^ pro=vase sac (~(slap wa sac) gat [%limb %$]) + [van +:(~(mint wa sac) p.pro [%$ 7])] :: :: XX pass identity to preserve behavior? :: @@ -1286,7 +1303,7 @@ (sort ~(tap by van.mod) |=([[a=@tas *] [b=@tas *]] (aor a b))) :: :~ :+ %reports %| - =/ bem=beam [[our %home da+now] /whey] + =/ bem=beam [[our %home da+now] /whey] ::TODO %base? %+ turn von |= [nam=term =vane] =/ met (peek [~ ~] nam bem) @@ -1470,6 +1487,9 @@ %verb ..pith(lac.fad ?~(p.waif !lac.fad u.p.waif)) %what ~(kel what p.waif) %whey ..pith(out [[//arvo mass/whey] out]) + :: + %whiz + ..pith(van.mod (~(run by van.mod) |=(vane (settle:va:part vase)))) == :: ++ peek @@ -1521,7 +1541,7 @@ %wyrd ?. (sane:wyrd kel.p.buz) ~>(%mean.'wyrd: insane' !!) %- %+ need:wyrd kel.p.buz - ^- (list (pair term @)) + ^- wynn :~ hoon/hoon-version arvo/arvo lull/;;(@ud q:(slap lul.mod limb/%lull)) @@ -1689,7 +1709,7 @@ =. van.mod (~(run by van.mod) |=(=vane vane(worm *worm))) :: %- %+ need:wyrd kel.ver.zen - ^- (list (pair term @)) + ^- wynn :~ hoon/hoon-version arvo/arvo lull/;;(@ud q:(slap lul.mod limb/%lull)) @@ -1781,7 +1801,7 @@ =/ lul $:u.lul =/ zus $:u.zus %- %+ need:wyrd kel.u.ver - ^- (list (pair term @)) + ^- wynn :~ hoon/hoon-version arvo/arvo lull/;;(@ud q:(slap lul limb/%lull)) @@ -1868,7 +1888,7 @@ %wyrd ?. (sane:wyrd kel.p.wip) ~>(%mean.'wyrd: insane' !!) %- %+ need:wyrd kel.p.wip - ^- (list (pair term @)) + ^- wynn :* hoon/hoon-version arvo/arvo ?~ lul ~ diff --git a/pkg/arvo/sys/hoon.hoon b/pkg/arvo/sys/hoon.hoon index d84d3a35c..3ffd858c3 100644 --- a/pkg/arvo/sys/hoon.hoon +++ b/pkg/arvo/sys/hoon.hoon @@ -259,6 +259,8 @@ ++ head |*(^ ,:+<-) :: get head ++ same |*(* +<) :: identity :: +++ succ |=(@ +(+<)) :: successor +:: ++ tail |*(^ ,:+<+) :: get tail ++ test |=(^ =(+<- +<+)) :: equality :: @@ -8764,6 +8766,7 @@ %peek peek %repo repo %rest rest + %sink sink %tack tack %toss toss %wrap wrap @@ -10838,7 +10841,7 @@ |- ^- type ?~ lov sut $(lov t.lov, sut (face i.lov sut)) - :: :: + :: ++ sint :: reduce by reference |= $: :: hod: expand holds :: @@ -10911,6 +10914,39 @@ %- ~(gas in *(set type)) (turn leg |=([p=type q=hoon] (play(sut p) q))) :: + ++ sink + ~/ %sink + |^ ^- cord + ?- sut + %void 'void' + %noun 'noun' + [%atom *] (rap 3 'atom ' p.sut ' ' ?~(q.sut '~' u.q.sut) ~) + [%cell *] (rap 3 'cell ' (mup p.sut) ' ' (mup q.sut) ~) + [%face *] (rap 3 'face ' ?@(p.sut p.sut (mup p.sut)) ' ' (mup q.sut) ~) + [%fork *] (rap 3 'fork ' (mup p.sut) ~) + [%hint *] (rap 3 'hint ' (mup p.sut) ' ' (mup q.sut) ~) + [%hold *] (rap 3 'hold ' (mup p.sut) ' ' (mup q.sut) ~) + :: + [%core *] + %+ rap 3 + :~ 'core ' + (mup p.sut) + ' ' + ?~(p.p.q.sut '~' u.p.p.q.sut) + ' ' + q.p.q.sut + ' ' + r.p.q.sut + ' ' + (mup q.q.sut) + ' ' + (mup p.r.q.sut) + == + == + :: + ++ mup |=(* (scot %p (mug +<))) + -- + :: ++ take |= [vit=vein duz=$-(type type)] ^- (pair axis type) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 5d1c9b6f5..14d4b5b57 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1069,14 +1069,23 @@ :::: :: (1d2) :: +$ blew [p=@ud q=@ud] :: columns rows - +$ belt :: old belt + +$ belt :: client input + $? bolt :: simple input + $% [%mod mod=?(%ctl %met %hyp) key=bolt] :: w/ modifier + [%txt p=(list @c)] :: utf32 text + ::TODO consider moving %hey, %rez, %yow here :: + ::TMP forward backwards-compatibility :: + :: :: + [%ctl p=@c] :: + [%met p=@c] :: + == == :: + +$ bolt :: simple input + $@ @c :: simple keystroke $% [%aro p=?(%d %l %r %u)] :: arrow key [%bac ~] :: true backspace - [%ctl p=@c] :: control-key [%del ~] :: true delete - [%met p=@c] :: meta-key + [%hit r=@ud c=@ud] :: mouse click [%ret ~] :: return - [%txt p=(list @c)] :: utf32 text == :: +$ blit :: old blit $% [%bel ~] :: make a noise @@ -1626,15 +1635,15 @@ $% [%boon payload=*] :: ames response [%done error=(unit error:ames)] :: ames message (n)ack [%onto p=(each suss tang)] :: about agent - [%unto p=sign:agent] :: + [%unto p=unto] :: == :: +$ task :: incoming request $~ [%vega ~] :: - $% [%conf dap=term] :: start agent - [%deal p=sock q=term r=deal] :: full transmission - [%goad force=? agent=(unit dude)] :: rebuild agent(s) + $% [%deal p=sock q=term r=deal] :: full transmission [%sear =ship] :: clear pending queues - [%fade dap=term style=?(%slay %idle %jolt)] :: put app to sleep + [%jolt =desk =dude] :: (re)start agent + [%idle =dude] :: suspend agent + [%nuke =dude] :: delete agent $>(%init vane-task) :: set owner $>(%trim vane-task) :: trim state $>(%vega vane-task) :: report upgrade @@ -1669,11 +1678,16 @@ +$ neat $% [%arvo =note-arvo] [%agent [=ship name=term] =deal] + [%pyre =tang] == +$ deal $% [%raw-poke =mark =noun] task:agent == + +$ unto + $% [%raw-fact =mark =noun] + sign:agent + == :: :: +agent: app core :: @@ -1683,8 +1697,9 @@ +$ step (quip card form) +$ card (wind note gift) +$ note - $% [%arvo =note-arvo] - [%agent [=ship name=term] =task] + $% [%agent [=ship name=term] =task] + [%arvo note-arvo] + [%pyre =tang] == +$ task $% [%watch =path] @@ -2107,6 +2122,7 @@ [%g task:gall] [%i task:iris] [%j task:jael] + [%$ %whiz ~] [@tas %meta vase] == :: full vane names are required in vanes @@ -2159,6 +2175,11 @@ :: %clay: external edit :: $>(%into task:clay) + :: %clay: synchronous commit + :: + :: TODO: make $yuki an option for %into? + :: + $>(%park task:clay) :: %eyre: learn ports of live http servers :: $>(%live task:eyre) diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index fb09a2ebe..41742600b 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -1567,7 +1567,7 @@ =| =point =. life.point life =. keys.point (my [life crypto-suite public-key]~) - =. sponsor.point `(scry-for-sponsor ship) + =. sponsor.point `(^^sein:title rof our now ship) :: (on-publ-full (my [ship point]~)) :: @@ -1670,7 +1670,7 @@ =. sponsor.peer-state ?^ sponsor.point u.sponsor.point - (scry-for-sponsor ship) + (^^sein:title rof our now ship) :: automatically set galaxy route, since unix handles lookup :: =? route.peer-state ?=(%czar (clan:title ship)) @@ -1680,14 +1680,6 @@ (~(put by peers.ames-state) ship %known peer-state) :: event-core - :: +scry-for-sponsor: ask jael for .who's sponsoring ship - :: - ++ scry-for-sponsor - |= who=ship - ^- ship - ;; ship - =< q.q %- need %- need - (rof ~ %j `beam`[[our %sein %da now] /(scot %p who)]) -- :: +on-take-turf: relay %turf move from jael to unix :: diff --git a/pkg/arvo/sys/vane/clay.hoon b/pkg/arvo/sys/vane/clay.hoon index 993ac2703..379f39c0f 100644 --- a/pkg/arvo/sys/vane/clay.hoon +++ b/pkg/arvo/sys/vane/clay.hoon @@ -96,7 +96,6 @@ lab=(map @tas aeon) :: labels mim=(map path mime) :: mime cache fod=ford-cache :: ford cache - fer=(unit reef-cache) :: reef cache == :: :: :: Commit state. @@ -131,14 +130,6 @@ casts=(map mars [res=vase dez=(set [dir=? =path])]) tubes=(map mars [res=tube dez=(set [dir=? =path])]) == -:: $reef-cache: built system files -:: -+$ reef-cache - $: hoon=vase - arvo=vase - lull=vase - zuse=vase - == :: :: Hash of a blob, for lookup in the object store (lat.ran) :: @@ -177,6 +168,8 @@ hez=(unit duct) :: sync duct cez=(map @ta crew) :: permission groups pud=(unit [=desk =yoki]) :: pending update + :: REMOVE on next upgrade + dist-upgraded=_| :: are we in dist yet? == :: :: :: Object store. @@ -312,6 +305,8 @@ $> $? %info :: internal edit %merg :: merge desks %fuse :: merge many + %park :: + %perm :: %pork :: %warp :: %werp :: @@ -322,7 +317,10 @@ $>(%flog task:dill) :: == :: $: %g :: to %gall - $>(%deal task:gall) :: + $> $? %deal + %jolt + == + task:gall == :: $: %j :: by %jael $>(%public-keys task:jael) :: @@ -348,6 +346,12 @@ == :: gift :: == :: + $: %gall + $> $? %onto + %unto + == + gift:gall + == $: %jael :: $>(%public-keys gift:jael) :: == == :: @@ -431,30 +435,13 @@ [ducts (print-wove wove)] :: ++ fusion - => |% - :: +an: $ankh interface door + :: +wrap: external wrapper + :: + ++ wrap + |* [* state:ford] + [+<- +<+>-] :: cache.state :: - ++ an - |_ nak=ankh - :: +dug: produce ankh at path - :: - ++ dug - |= =path - ^- (unit ankh) - ?~ path `nak - ?~ kid=(~(get by dir.nak) i.path) - ~ - $(nak u.kid, path t.path) - :: +get: produce file at path - :: - ++ get - |= =path - ^- (unit cage) - ?~ nik=(dug path) ~ - ?~ fil.u.nik ~ - `q.u.fil.u.nik - -- ++ with-face |=([face=@tas =vase] vase(p [%face face p.vase])) ++ with-faces =| res=(unit vase) @@ -464,13 +451,6 @@ =/ faz (with-face i.vaz) =. res `?~(res faz (slop faz u.res)) $(vaz t.vaz) - -- - |% - :: +wrap: external wrapper - :: - ++ wrap - |* [* state:ford] - [+<- +<+>-] :: cache.state :: ++ ford !. @@ -490,8 +470,7 @@ cycle=(set build) == +$ args - $: bud=vase - =ankh + $: =ankh deletes=(set path) changes=(map path (each page lobe)) file-store=(map lobe blob) @@ -527,6 +506,7 @@ ?: (~(has in cycle.nub) vale+path) ~|(cycle+vale+path^stack.nub !!) =. cycle.nub (~(put in cycle.nub) vale+path) + ::~> %slog.0^leaf/"ford: read file {(spud path)}" ?^ change=(~(get by changes) path) =^ page nub ?: ?=(%& -.u.change) @@ -537,7 +517,7 @@ [cage nub] ?< (~(has in deletes) path) ~| %file-not-found^path - :_(nub (need (~(get an ankh) path))) + :_(nub (need (~(get an:cloy ankh) path))) :: +build-nave: build a statically typed mark core :: ++ build-nave @@ -557,6 +537,7 @@ =^ top stack.nub pop-stack =. naves.cache.nub (~(put by naves.cache.nub) mak [vase.res top]) [vase.res nub] + :: ~> %slog.0^leaf/"ford: make mark {}" =^ cor=vase nub (build-fit %mar mak) =/ gad=vase (slap cor limb/%grad) ?@ q.gad @@ -588,7 +569,7 @@ -- :_ nub ^- vase :: vase of nave - %+ slap (slop (with-face cor+cor) bud) + %+ slap (slop (with-face cor+cor) !>(..zuse)) !, *hoon =/ typ _+<.cor =/ dif _*diff:grad:cor @@ -631,6 +612,7 @@ =. marks.cache.nub (~(put by marks.cache.nub) mak [dais.res top]) [dais.res nub] =^ nav=vase nub (build-nave mak) + :: ~> %slog.0^leaf/"ford: make dais {}" :_ nub ^- dais |_ sam=vase @@ -685,6 +667,7 @@ [vase.res nub] :: try +grow; is there a +grow core with a .b arm? :: + :: ~> %slog.0^leaf/"ford: make cast {} -> {}" =^ old=vase nub (build-fit %mar a) ?: =/ ram (mule |.((slap old !,(*hoon grow)))) ?: ?=(%| -.ram) %.n @@ -744,6 +727,7 @@ =. tubes.cache.nub (~(put by tubes.cache.nub) [a b] [tube.res top]) [tube.res nub] =^ gat=vase nub (build-cast a b) + :: ~> %slog.0^leaf/"ford: make tube {} -> {}" :_(nub |=(v=vase (slam gat v))) :: ++ lobe-to-page @@ -832,6 +816,7 @@ =. stack.nub =- [(sy - ~) stack.nub] ?:(?=(%| -.dep) dep [& dir.p.dep]) + :: ~> %slog.0^leaf/"ford: make file {(spud path)}" =^ cag=cage nub (read-file path) ?> =(%hoon p.cag) =/ tex=tape (trip !<(@t q.cag)) @@ -854,7 +839,7 @@ |= =path ^- [(map @ta vase) state] =/ fiz=(list @ta) - =/ nuk=(unit _ankh) (~(dug an ankh) path) + =/ nuk=(unit _ankh) (~(dug an:cloy ankh) path) ?~ nuk ~ %+ murn ~(tap by dir.u.nuk) @@ -873,7 +858,8 @@ :: ++ run-pile |= =pile - =^ sut=vase nub (run-tauts bud %sur sur.pile) + =/ sut=vase !>(..zuse) + =^ sut=vase nub (run-tauts sut %sur sur.pile) =^ sut=vase nub (run-tauts sut %lib lib.pile) =^ sut=vase nub (run-raw sut raw.pile) =^ sut=vase nub (run-raz sut raz.pile) @@ -1045,13 +1031,13 @@ ^- path =/ paz (segments pax) |- ^- path - ?~ paz ~|(no-file+pre^pax !!) + ?~ paz ~_(leaf/"clay: no files match /{(trip pre)}/{(trip pax)}/hoon" !!) =/ pux=path pre^(snoc i.paz %hoon) ?: (~(has in deletes) pux) $(paz t.paz) ?: (~(has by changes) pux) pux - ?^ (~(get an ankh) pux) + ?^ (~(get an:cloy ankh) pux) pux $(paz t.paz) -- @@ -1173,6 +1159,12 @@ |= mof=(list move) %_(+> mow (weld (flop mof) mow)) :: + :: Queue a list of moves, to be emitted before the rest + :: + ++ lime + |= mof=(list move) + %_(+> mow (weld mow (flop mof))) + :: :: Produce either null or a result along a subscription. :: :: Producing null means subscription has been completed or cancelled. @@ -1315,8 +1307,7 @@ ++ balk-all (duct-lift balk) ++ bleb-all (duct-lift bleb) :: - ++ static-ford-args - [zuse:(need fer.dom) ank.dom ~ ~ lat.ran fod.dom] + ++ static-ford-args [ank.dom ~ ~ lat.ran fod.dom] :: :: Transfer a request to another ship's clay. :: @@ -1524,6 +1515,12 @@ %& q.p.yoki %| (~(run by q.p.yoki) |=(=lobe |+lobe)) == + :: find desk kelvin + :: + =/ kel=weft (get-kelvin yoki) + ?. |(=(%base syd) =(kel [%zuse zuse])) + ~>(%mean.|.(leaf/"clay: bad-kelvin, {<[need=zuse/zuse have=kel]>}") !!) + :: =/ old-yaki ?: =(0 let.dom) *yaki @@ -1536,25 +1533,25 @@ :: promote and fill in ankh :: promote and fill in mime cache :: - ?: &(=(%home syd) !updated) + =/ invalid (~(uni in deletes) ~(key by changes)) + ?: &(=(%base syd) !updated (~(any in invalid) is-kernel-path)) (sys-update yoki new-data) + :: + ~? (did-kernel-update invalid) %clay-kernel-updated + =? updated updated (did-kernel-update invalid) + => ?. updated . + ~>(%slog.0^leaf/"clay: rebuilding {} after kernel update" .) :: clear caches if zuse reloaded :: - =/ is-zuse-new=? (need-reef-update changes) =. fod.dom - ?: is-zuse-new - *ford-cache - (promote-ford fod.dom deletes ~(key by changes)) - =. fer.dom `(build-reef fer.dom ~(key by changes) new-data) - =? ank.dom is-zuse-new *ankh - =? changes is-zuse-new - (changes-for-upgrade q.old-yaki deletes changes) + ?: updated *ford-cache + (promote-ford fod.dom invalid) + =? ank.dom updated *ankh + =? changes updated (changes-for-upgrade q.old-yaki deletes changes) :: - =/ =args:ford:fusion - [zuse:(need fer.dom) ank.dom deletes changes lat.ran fod.dom] + =/ =args:ford:fusion [ank.dom deletes changes lat.ran fod.dom] :: - =^ change-cages ford-cache.args - (checkout-changes args changes) + =^ change-cages ford-cache.args (checkout-changes args changes) =/ sane-continuation (sane-changes changes change-cages) =/ new-blobs=(map lobe blob) %- malt @@ -1597,9 +1594,152 @@ =. mim.dom (apply-changes-to-mim mim.dom mim) =. fod.dom ford-cache.args =. ..park (emil (print q.old-yaki data)) - :: + =? ..park &(updated !dist-upgraded.ruf) migrate-dist wake:(ergo mim) :: + ++ migrate-dist + ~> %slog.0^'clay: migrating for third-party software distribution' + |^ ^+ ..park + =. ..park purge + :: first make sure gall has molted and has :hood running + :: + =. ..park (emit hen %pass /dist/hood %g %jolt %home %hood) + :: now ask :hood to install all the new desks + :: + :: NOTE: reverse order, since we're prepending moves each time + :: + =. ..park (install-from-tmp %bitcoin) + =. ..park (install-from-tmp %webterm) + =. ..park (install-from-tmp %landscape) + =. ..park (install-from-tmp %garden) + =. ..park (install-from-tmp %base) + ..park(dist-upgraded.ruf &) + :: + ++ purge + ^+ ..park + =/ wux=(list [=wove dux=(set duct)]) ~(tap by qyx) + |- ^+ ..park + ?~ wux ..park + =/ rov rove.wove.i.wux + =? qyx + ?+ -.rov | + %sing ?=([%a * %app %publish %hoon ~] mood.rov) + %next ?=([%a * %app %publish %hoon ~] mood.rov) + == + (~(del by qyx) wove.i.wux) + $(wux t.wux) + :: + ++ install-from-tmp + |= =desk + ^+ ..park + =/ sen (^^sein:title rof our now our) + %- lime + |^ ^- (list move) + =- (murn - same) + ^- (list (unit move)) + :~ `create-desk + `install-local + :: + ?: =(sen our) ~ + `install-remote + :: + ?: =(%base desk) ~ + `publish-desk + == + :: + ++ create-desk ^- move + :^ hen %pass /dist/create/[desk] + %^ new-desk:cloy desk + (latest-tako %home) + ;;((map path page) (cue (get-tmp-jam desk))) + :: + ++ publish-desk ^- move + :^ hen %pass /dist/public/[desk] + [%c %perm desk / %r `[%black ~]] + :: + ++ install-local ^- move + :^ hen %pass /dist/install-local/[desk] + [%g %deal [our our] %hood %poke %kiln-install !>([desk our desk])] + :: + ++ install-remote ^- move + =/ rem ?:(=(%base desk) %kids desk) + :: + :^ hen %pass /dist/install-remote/[desk] + [%g %deal [our our] %hood %poke %kiln-install !>([desk sen rem])] + -- + :: + ++ latest-tako + |= =desk + ^- (unit tako) + ?~ doj=(~(get by dos.rom) desk) ~ + =, dom.u.doj + (~(get by hit) let) + :: + ++ get-tmp-jam + |= =desk + ^- @ + ~| [%missing-tmp-desk-jam desk] + ?~ tmp=(~(get by dir.ank.dom) ~.tmp) !! + ?~ new=(~(get by dir.u.tmp) desk) !! + ?~ jam=(~(get by dir.u.new) ~.jam) !! + ?~ fil.u.jam !! + =* fil u.fil.u.jam + ?> =(%jam p.q.fil) + ;;(@ q.q.q.fil) + -- + :: +is-kernel-path: should changing .pax cause a kernel or vane reload? + :: + ++ is-kernel-path |=(pax=path ?=([%sys *] pax)) + :: + ++ did-kernel-update + |= invalid=(set path) + ?. |(=(%base syd) &(=(%home syd) !dist-upgraded.ruf)) + | + %- ~(any in invalid) + |=(p=path &((is-kernel-path p) !?=([%sys %vane *] p))) + :: +get-kelvin: read the desk's kernel version from /sys/kelvin + :: + ++ get-kelvin + |= =yoki + ^- weft + |^ ?- -.yoki + %| + %- lobe-to-weft + ~> %mean.(cat 3 'clay: missing /sys/kelvin on ' syd) + ~| ~(key by q.p.yoki) + (~(got by q.p.yoki) /sys/kelvin) + :: + %& + =/ fil=(each page lobe) + ~> %mean.(cat 3 'clay: missing /sys/kelvin on ' syd) + ~| ~(key by q.p.yoki) + (~(got by q.p.yoki) /sys/kelvin) + ?- -.fil + %& (page-to-weft p.fil) + %| (lobe-to-weft p.fil) + == + == + ++ lobe-to-weft + |= =lobe + ^- weft + =/ =blob (lobe-to-blob:ze lobe) + =/ =page + ?- -.blob + %direct q.blob + %delta r.blob + == + (page-to-weft page) + ++ page-to-weft + |= =page + ^- weft + ?+ p.page ~|(clay-bad-kelvin-mark/p.page !!) + %kelvin ;;(weft q.page) + %mime + =+ ;;(=mime q.page) + !<(weft (slap !>(~) (ream q.q.mime))) + == + -- + :: :: Find which files changed or were deleted :: ++ get-changes @@ -1647,10 +1787,13 @@ :: Make sure to invalidate any paths whose '-'s or '/'s could be :: converted in an import; i.e. /mar, /lib, and /sur hoon files. :: + :: If anything in the kernel other than a vane updated, + :: clear the cache. + :: ++ promote-ford - |= [=ford-cache deletes=(set path) changes=(set path)] + |= [=ford-cache invalid=(set path)] ^+ ford-cache - =/ invalid=(set path) (~(uni in deletes) changes) + :: =. invalid %- ~(gas in invalid) %- zing @@ -1693,62 +1836,6 @@ $(builds t.builds) (~(put by $(builds t.builds)) i.builds) :: - ++ build-reef - => |% - +$ reef-step - :: vary: source or dependencies changed - :: deep: source and dependencies match kernel - :: - [vary=? deep=?] - -- - :: - |= $: fer=(unit reef-cache) - invalid=(set path) - data=(map path (each page lobe)) - == - |^ ^- reef-cache - =/ [tep=reef-step ref=reef-cache] - ?^ fer - [[vary=| deep=&] u.fer] - [[vary=& deep=&] *reef-cache] - :: - =^ hon tep (build tep /sys/hoon hoon.ref !>(**) !,(*hoon ..ride)) - =^ rav tep (build tep /sys/arvo arvo.ref hon !,(*hoon ..part)) - =^ lul tep (build tep /sys/lull lull.ref rav !,(*hoon .)) - =^ zus tep (build tep /sys/zuse zuse.ref lul !,(*hoon .)) - [hon rav lul zus] - :: - ++ build - |= [tep=reef-step pax=path pre=vase sub=vase pro=hoon] - ^- (pair vase reef-step) - =/ ful (weld pax /hoon) - ?. ?| vary.tep - (~(has in invalid) ful) - == - [pre tep] - =. vary.tep & - =/ src (path-to-cord data ful) - :: - ?: &(deep.tep (deep pax src)) - [(slap !>(..zuse) pro) tep] - :: - =/ nam=term ?.(?=([@ta @ta *] pax) %$ i.t.pax) - ~> %slog.0^leaf+"clay: building %{(trip nam)} on %{(trip syd)}" - =/ gen - ~_ leaf+"%{(trip nam)}-parse-fail" - (rain ful src) - ~_ leaf+"%{(trip nam)}-compile-fail" - [(slap (slap sub gen) pro) tep(deep |)] - :: - ++ deep - |= [pax=path src=cord] - ^- ? - =/ dat (rof `[our ~ ~] $/[[our $/da/now] mod/fat/pax]) - ?: |(?=(~ dat) ?=(~ u.dat)) | - =/ nod !<((axal (cask)) q.u.u.dat) - &(?=(^ fil.nod) ?=(%hoon p.u.fil.nod) =(src q.u.fil.nod)) - -- - :: ++ page-to-cord |= =page ^- @t @@ -1936,8 +2023,7 @@ =/ original=(map path (each page lobe)) (~(run by q.yaki) |=(=lobe |+lobe)) (~(uni by original) changes) - =/ =args:ford:fusion - [zuse:(need fer.dom) *ankh ~ all-changes lat.ran *ford-cache] + =/ =args:ford:fusion [*ankh ~ all-changes lat.ran *ford-cache] =^ all-change-cages ford-cache.args (checkout-changes args all-changes) =/ ccs=(list [=path =lobe =cage]) ~(tap by change-cages) @@ -2002,19 +2088,6 @@ test-ankh (~(got by dir.test-ankh) ta) == :: - :: Find reef dependency changes - :: - ++ need-reef-update - |= changes=(map path (each page lobe)) - ^- ? - %+ lien ~(tap by changes) - |= [=path *] - ?| =(/sys/hoon/hoon path) - =(/sys/arvo/hoon path) - =(/sys/lull/hoon path) - =(/sys/zuse/hoon path) - == - :: :: Delay current update until sys update is complete :: ++ sys-update @@ -2096,7 +2169,7 @@ |= [k=beak v=(unit dome:clay)] ^- tank =/ received=tape ?~(v "missing" "received") - leaf+"{} {received}" + leaf+"{<(en-beam k ~)>} {received}" :_ discarded leaf+"fusing into {} from {} {} - overwriting prior fuse" =. fiz (make-melt bas con) @@ -2113,8 +2186,11 @@ :: responses we get for the merge will cause take-fuse to crash :: =. fiz *melt - ((slog [leaf+"clay: fuse failed, missing {}"]~) ..take-fuse) - ?> (~(has by sto.fiz) bec) + =/ msg=tape <(en-beam bec ~)> + ((slog [leaf+"clay: fuse failed, missing {msg}"]~) ..take-fuse) + ?. (~(has by sto.fiz) bec) + =/ msg=tape <(en-beam bec ~)> + ((slog [leaf+"clay: got strange fuse response {}"]~) ..take-fuse) =. fiz :+ bas.fiz con.fiz (~(put by sto.fiz) bec `!<(dome:clay q.r.u.riot)) @@ -2135,7 +2211,6 @@ |- ^+ ..take-fuse ?~ merges - =/ t=tang [leaf+"{} fused from {} {}" ~] =. ..take-fuse (done-fuse clean-state %& ~) (park | [%| continuation-yaki(p (flop parents))] rag) =/ [bec=beak g=germ] i.merges @@ -2143,7 +2218,8 @@ =/ result (merge-helper p.bec q.bec g ali-dom `continuation-yaki) ?- -.result %| - (done-fuse clean-state %| %fuse-merge-failed p.result) + =/ failing-merge=tape "{} {}" + (done-fuse clean-state %| %fuse-merge-failed leaf+failing-merge p.result) :: %& =/ merge-result=(unit merge-result) +.result @@ -2802,8 +2878,7 @@ =. mon (~(put by mon) pot [her syd case] spur) =/ =yaki (~(got by hut.ran) (~(got by hit.dom) let.dom)) =/ changes (~(run by q.yaki) |=(=lobe |+lobe)) - =/ =args:ford:fusion - [zuse:(need fer.dom) ank.dom ~ changes lat.ran fod.dom] + =/ =args:ford:fusion [ank.dom ~ changes lat.ran fod.dom] =^ mim ford-cache.args (checkout-mime args ~ ~(key by changes)) =. mim.dom (apply-changes-to-mim mim.dom mim) @@ -3004,10 +3079,10 @@ =/ vale-result %- mule |. %- wrap:fusion - :: Use %home's marks to validate, so we don't have to build the + :: Use %base's marks to validate, so we don't have to build the :: foreign hoon/zuse :: - =/ args %*(static-ford-args . dom dom:(~(got by dos.rom) %home)) + =/ args %*(static-ford-args . dom dom:(~(got by dos.rom) %base)) (page-to-cage:(ford:fusion args) peg) ?: ?=(%| -.vale-result) %- (slog >%validate-x-failed< p.vale-result) @@ -3401,6 +3476,19 @@ [new-cach.rov fod.dom] (read-unknown mool.rov(case [%ud u.aeon.rov]) new-cach.rov) =. new-cach.rov n + ?: ?& !(complete old-cach.rov) + (complete new-cach.rov) + == + :_ fod.dom :- %& + %- malt + %+ murn ~(tap in paths.mool.rov) + |= [=care =path] + ^- (unit [mood (unit (each cage lobe))]) + =/ cached (~(get by new-cach.rov) [care path]) + ?. ?=([~ ~ *] cached) + %- (slog 'clay: strange new-cache' >[care path cached]< ~) + ~ + `u=[[care [%ud let.dom] path] u.u.cached] :: if they're still not both complete, wait again. :: ?. ?& (complete old-cach.rov) @@ -3418,18 +3506,14 @@ ?< |(?=(~ old-cach-value) ?=(~ new-cach-value)) =/ new-entry=(unit (pair mood (unit (each cage lobe)))) =/ =mood [car [%ud u.aeon.rov] pax] + ?~ u.new-cach-value + :: if new does not exist, always notify + :: + `[mood ~] ?~ u.old-cach-value - ?~ u.new-cach-value - :: not added - :: - ~ :: added :: `[mood `u.u.new-cach-value] - ?~ u.new-cach-value - :: deleted - :: - `[mood ~] ?: (equivalent-data:ze u.u.new-cach-value u.u.old-cach-value) :: unchanged :: @@ -3660,7 +3744,7 @@ =/ lower=@ud 1 |- :: a should be excluded, so wait until we're past it - ?: =(lower +(a)) + ?: (gte lower +(a)) acc =/ res=(set tako) (reachable-takos (~(got by hit.dom) lower)) $(acc (~(uni in acc) res), lower +(lower)) @@ -3668,7 +3752,7 @@ =| acc=(set tako) =/ upper=@ud b |- - ?: =(upper a) + ?: (lte upper a) acc =/ res=(set tako) (reachable-takos (~(got by hit.dom) upper)) $(acc (~(uni in acc) res), upper (dec upper)) @@ -3721,19 +3805,23 @@ |= [=aeon =path] ^- [(unit (unit (each cage lobe))) ford-cache] ?. =(aeon let.dom) + ~> %slog.0^leaf/"clay: %a unknown aeon {<[syd aeon path]>}" [~ fod.dom] =/ cached=(unit [=vase *]) (~(get by files.fod.dom) path) ?^ cached :_(fod.dom [~ ~ %& %vase !>(vase.u.cached)]) =/ x (read-x aeon path) ?~ x + ~> %slog.0^leaf/"clay: %a can't read file at path {<[syd aeon path]>}" [~ fod.dom] ?~ u.x + ~> %slog.0^leaf/"clay: %a no file at path {<[syd aeon path]>}" [[~ ~] fod.dom] :: should never happen at current aeon ?: ?=(%| -.u.u.x) [~ fod.dom] =^ =vase fod.dom + ~_ leaf/"clay: %a build failed {<[syd aeon path]>}" %- wrap:fusion (build-file:(ford:fusion static-ford-args) path) :_(fod.dom [~ ~ %& %vase !>(vase)]) @@ -3998,6 +4086,10 @@ ++ read-u |= [yon=aeon pax=path] ^- (unit (unit (each [%flag (hypo ?)] lobe))) + :: if asked for version 0, that never exists, so always give false + :: + ?: =(0 yon) + ``[%& %flag -:!>(*?) |] :: if asked for a future version, we don't have an answer :: ?~ tak=(~(get by hit.dom) yon) @@ -4145,9 +4237,10 @@ [~ fod] :: virtualize to catch and produce deterministic failures :: - !. + !: =- ?: ?=(%& -<) p.- - ((slog leaf+"gall: read-at-aeon fail {}" p.-) [[~ ~] fod]) + %. [[~ ~] fod] + (slog leaf+"clay: read-at-aeon fail {<[desk=syd mun]>}" p.-) %- mule |. ?- care.mun %d @@ -4210,7 +4303,7 @@ :: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: =| :: instrument state - $: ver=%8 :: vane version + $: ver=%10 :: vane version ruf=raft :: revision tree == :: |= [now=@da eny=@uvJ rof=roof] :: current invocation @@ -4302,7 +4395,7 @@ [mos ..^$] :: %init - [~ ..^$(hun.rom.ruf hen)] + [~ ..^$(hun.rom.ruf hen, dist-upgraded.ruf &)] :: %into =. hez.ruf `hen @@ -4312,7 +4405,7 @@ =/ bem=beam ?^ bem u.bem - [[our %home %ud 1] ~] + [[our %base %ud 1] ~] :: TODO: remove this fallback? =/ dos (~(get by dos.rom.ruf) q.bem) ?~ dos !! :: fire next in queue @@ -4464,41 +4557,93 @@ ++ load => |% +$ raft-any - $% [%8 raft-8] + $% [%10 raft-10] + [%9 raft-9] + [%8 raft-8] [%7 raft-7] [%6 raft-6] == - +$ raft-8 raft + +$ raft-10 raft + +$ raft-9 + $: rom=room :: domestic + hoy=(map ship rung) :: foreign + ran=rang :: hashes + mon=(map term beam) :: mount points + hez=(unit duct) :: sync duct + cez=(map @ta crew) :: permission groups + pud=(unit [=desk =yoki]) :: pending update + == :: + +$ raft-8 + $: rom=room-8 + hoy=(map ship rung-8) + ran=rang + mon=(map term beam) + hez=(unit duct) + cez=(map @ta crew) + pud=(unit [=desk =yoki]) + == + +$ room-8 + $: hun=duct + dos=(map desk dojo-8) + == + +$ rung-8 + $: rus=(map desk rede-8) + == + +$ dojo-8 + $: qyx=cult + dom=dome-8 + per=regs + pew=regs + fiz=melt + == + +$ dome-8 + $: ank=ankh + let=aeon + hit=(map aeon tako) + lab=(map @tas aeon) + mim=(map path mime) + fod=ford-cache + fer=* :: reef cache, obsolete + == + +$ rede-8 + $: lim=@da + ref=(unit rind) + qyx=cult + dom=dome-8 + per=regs + pew=regs + fiz=melt + == +$ raft-7 - $: rom=room-7 - hoy=(map ship rung-7) - ran=rang - mon=(map term beam) - hez=(unit duct) - cez=(map @ta crew) - pud=(unit [=desk =yoki]) - == + $: rom=room-7 + hoy=(map ship rung-7) + ran=rang + mon=(map term beam) + hez=(unit duct) + cez=(map @ta crew) + pud=(unit [=desk =yoki]) + == +$ room-7 - $: hun=duct - dos=(map desk dojo-7) - == + $: hun=duct + dos=(map desk dojo-7) + == +$ rung-7 - $: rus=(map desk rede-7) - == + $: rus=(map desk rede-7) + == +$ dojo-7 - $: qyx=cult - dom=dome - per=regs - pew=regs - == + $: qyx=cult + dom=dome-8 + per=regs + pew=regs + == +$ rede-7 - $: lim=@da - ref=(unit rind) - qyx=cult - dom=dome - per=regs - pew=regs - == + $: lim=@da + ref=(unit rind) + qyx=cult + dom=dome-8 + per=regs + pew=regs + == +$ ford-cache-7 ford-cache +$ raft-6 $: rom=room-6 :: domestic @@ -4523,7 +4668,7 @@ lab=(map @tas aeon) :: labels mim=(map path mime) :: mime cache fod=ford-cache-6 :: ford cache - fer=(unit reef-cache) :: reef cache + fer=* :: reef cache == +$ rung-6 $: rus=(map desk rede-6) @@ -4542,7 +4687,9 @@ |^ =? old ?=(%6 -.old) 7+(raft-6-to-7 +.old) =? old ?=(%7 -.old) 8+(raft-7-to-8 +.old) - ?> ?=(%8 -.old) + =? old ?=(%8 -.old) 9+(raft-8-to-9 +.old) + =? old ?=(%9 -.old) 10+(raft-9-to-10 +.old) + ?> ?=(%10 -.old) ..^^$(ruf +.old) :: +raft-6-to-7: delete stale ford caches (they could all be invalid) :: @@ -4572,7 +4719,7 @@ dos.rom %- ~(run by dos.rom.raf) |= doj=dojo-7 - ^- dojo + ^- dojo-8 [qyx.doj dom.doj per.doj pew.doj *melt] :: hoy @@ -4580,9 +4727,36 @@ |= =rung-7 %- ~(run by rus.rung-7) |= r=rede-7 - ^- rede + ^- rede-8 [lim.r ref.r qyx.r dom.r per.r pew.r *melt] == + :: +raft-8-to-9: remove reef cache + :: + ++ raft-8-to-9 + |= raf=raft-8 + ^- raft-9 + %= raf + dos.rom + %- ~(run by dos.rom.raf) + |= =dojo-8 + ^- dojo + =/ dom dom.dojo-8 + dojo-8(dom [ank.dom let.dom hit.dom lab.dom mim.dom *ford-cache]) + :: + hoy + %- ~(run by hoy.raf) + |= =rung-8 + %- ~(run by rus.rung-8) + |= =rede-8 + ^- rede + =/ dom dom.rede-8 + rede-8(dom [ank.dom let.dom hit.dom lab.dom mim.dom *ford-cache]) + == + :: +raft-9-to-10: add .dist-upgraded + ++ raft-9-to-10 + |= raf=raft-9 + ^- raft-10 + raf(pud [pud.raf dist-upgraded=|]) -- :: ++ scry :: inspect @@ -4653,6 +4827,15 @@ ^+ [*(list move) ..^$] ?^ dud ~|(%clay-take-dud (mean tang.u.dud)) + ?: ?=([%dist *] tea) + ?: ?=(%onto +<.hin) + [~ ..^$] + ?> ?=(%unto +<.hin) + ?> ?=(%poke-ack -.p.hin) + ?~ p.p.hin + [~ ..^$] + =+ ((slog 'clay: dist migration failed' u.p.p.hin) ~) + !! :: ?: ?=([%merge @ @ @ @ ~] tea) ?> ?=(%writ +<.hin) @@ -4806,6 +4989,8 @@ :: %boon !! %lost !! + %onto !! + %unto !! %writ %- (slog leaf+"clay: strange writ (expected on upgrade to Fusion)" ~) [~ ..^$] diff --git a/pkg/arvo/sys/vane/dill.hoon b/pkg/arvo/sys/vane/dill.hoon index 4e08fc0e0..16bcf51fe 100644 --- a/pkg/arvo/sys/vane/dill.hoon +++ b/pkg/arvo/sys/vane/dill.hoon @@ -52,9 +52,8 @@ task:dill :: == :: $: %g :: - $> $? %conf :: + $> $? %jolt :: %deal :: - %goad :: == :: task:gall :: == :: @@ -106,7 +105,6 @@ %flow +> %harm +> %hail (send %hey ~) - %belt (send `dill-belt`p.kyz) %text (from %out (tuba p.kyz)) %crud :: (send `dill-belt`[%cru p.kyz q.kyz]) (crud p.kyz q.kyz) @@ -116,6 +114,18 @@ %pack (dump kyz) %crop (dump trim+p.kyz) %verb (pass /verb %$ kyz) + :: + %belt + %- send + ::TMP forwards compatibility with next-dill + :: + ?@ p.kyz [%txt p.kyz ~] + ?: ?=(%hit -.p.kyz) [%txt ~] + ?. ?=(%mod -.p.kyz) p.kyz + =/ =@c + ?@ key.p.kyz key.p.kyz + ?:(?=(?(%bac %del %ret) -.key.p.kyz) `@`-.key.p.kyz ~-) + ?:(?=(%met mod.p.kyz) [%met c] [%ctl c]) == :: ++ crud @@ -197,38 +207,31 @@ ?: ?=(%qit -.bit) (dump %logo ~) (done %blit [bit ~]) - :: XX move :: - ++ sein + ++ sponsor ^- ship =/ dat=(unit (unit cage)) (rof `[our ~ ~] j/[[our sein/da/now] /(scot %p our)]) ;;(ship q.q:(need (need dat))) :: ++ init :: initialize - (pass /merg/home [%c %merg %kids our %home da+now %init]) + (pass /merg/base [%c %merg %kids our %base da+now %init]) :: ++ mere :: continue init ^+ . =/ myt (flop (fall tem ~)) - =/ can (clan:title our) =. tem ~ - =. +> (pass / %g %conf ram) - =? +> ?=(?(%earl %duke %king) can) - (ota sein %kids) - :: make kids desk publicly readable, so syncs work. - :: - =. +> (show %kids) - =. +> hood-set-boot-apps - =. +> peer - |- ^+ +>+ - ?~ myt +>+ - $(myt t.myt, +>+ (send i.myt)) + =. ..mere (pass / %g %jolt %base ram) + =. ..mere (show-desk %kids) + =. ..mere drum-watch + |- ^+ ..mere + ?~ myt ..mere + $(myt t.myt, ..mere (send i.myt)) :: ++ into :: preinitialize |= gyl=(list gill) =. tem `(turn gyl |=(a=gill [%yow a])) - (pass / [%c %warp our %home `[%sing %y [%ud 1] /]]) + (pass / [%c %warp our %base `[%sing %y [%ud 1] /]]) :: ++ send :: send action |= bet=dill-belt @@ -237,25 +240,29 @@ +>(tem `[bet u.tem]) (deal / [%poke [%dill-belt -:!>(bet) bet]]) :: - ++ hood-set-boot-apps - (deal / [%poke %drum-set-boot-apps !>(lit.all)]) - :: - ++ peer + ++ drum-watch (deal / [%watch /drum]) :: - ++ show :: permit reads on desk + ++ show-desk :: permit reads on desk |= des=desk (pass /show [%c %perm des / r+`[%black ~]]) :: - ++ ota - |= syn=[ship desk] - (deal /sync %poke %kiln-ota !>(`syn)) + ++ kiln-install + |= [loc=desk =ship rem=desk] + (deal /install %poke %kiln-install !>([loc ship rem])) + :: + ++ kiln-sync + |= [loc=desk =ship rem=desk] + (deal /sync %poke %kiln-sync !>([loc ship rem])) :: ++ take :: receive |= [tea=wire sih=sign] ^+ +> ?- sih [%gall %onto *] + :: NOTE effects during initial boot sequence are ignored, + :: so :hood compilation errors will not print; slog if desired + :: :: ~& [%take-gall-onto +>.sih] ?- -.+>.sih %| (crud %onto p.p.+>.sih) @@ -264,13 +271,19 @@ :: [%gall %unto *] :: ~& [%take-gall-unto +>.sih] - ?- -.+>.sih - %poke-ack ?~(p.p.+>.sih +>.$ (crud %coup u.p.p.+>.sih)) - %kick peer - %watch-ack ?~ p.p.+>.sih - +>.$ - (dump:(crud %reap u.p.p.+>.sih) %logo ~) - %fact (from ;;(dill-blit q:`vase`+>+>.sih)) + ?- -.+>.sih + %raw-fact !! + %kick drum-watch + %poke-ack ?~(p.p.+>.sih +>.$ (crud %coup u.p.p.+>.sih)) + %watch-ack + ?~ p.p.+>.sih + +>.$ + (dump:(crud %reap u.p.p.+>.sih) %logo ~) + :: + %fact + ?. ?=(%dill-blit p.cage.p.+>.sih) + +>.$ + (from ;;(dill-blit q.q.cage.p.+>.sih)) == :: [%clay %note *] diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 8072cbd50..562c33b46 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -30,6 +30,9 @@ $% [%rest p=@da] [%wait p=@da] == == + $: %c + $>(%warp task:clay) + == :: %d: to dill :: $: %d @@ -53,6 +56,12 @@ $: %gall gift:gall :: $>(%unto gift:gall) + :: + == + $: %clay + gift:clay + :: $>(%writ gift:clay) + :: == == -- :: more structures @@ -545,6 +554,7 @@ :: +per-server-event: per-event server core :: ++ per-server-event + ~% %eyre-per-server-event ..part ~ :: gate that produces the +per-server-event core from event information :: |= [[eny=@ =duct now=@da rof=roof] state=server-state] @@ -727,7 +737,7 @@ :: attempt to find conversion gate to mime :: =/ tub=(unit tube:clay) - (find-tube mark %mime) + (find-tube i.site.req mark %mime) ?~ tub (error-response 500 "no tube from {(trip mark)} to mime") :: attempt conversion, then send results :: @@ -740,11 +750,15 @@ == :: ++ find-tube - |= [from=mark to=mark] + |= [dap=term from=mark to=mark] ^- (unit tube:clay) ?: =(from to) `(bake same vase) + =/ des=(unit (unit cage)) + (do-scry %gd dap ~) + ?. ?=([~ ~ *] des) ~ + =+ !<(=desk q.u.u.des) =/ tub=(unit (unit cage)) - (do-scry %cc %home /[from]/[to]) + (do-scry %cc desk /[from]/[to]) ?. ?=([~ ~ %tube *] tub) ~ `!<(tube:clay q.u.u.tub) :: @@ -772,7 +786,7 @@ :* duct %pass /run-app-request/[eyre-id] %g %deal [our our] app %poke %handle-http-request - !>([eyre-id inbound-request]) + !>(`[@ta inbound-request:eyre]`[eyre-id inbound-request]) == == :: +cancel-request: handles a request being externally aborted @@ -1196,15 +1210,21 @@ ?~ maybe-channel=(~(get by session.channel-state.state) channel-id) %^ return-static-data-on-duct 404 'text/html' (error-page 404 %.y url.request ~) - :: if there's already a duct listening to this channel, we must 400 - :: - ?: ?=([%| *] state.u.maybe-channel) - %^ return-static-data-on-duct 400 'text/html' - (error-page 400 %.y url.request "channel already bound") :: when opening an event-stream, we must cancel our timeout timer + :: if there's no duct already bound. Else, kill the old request + :: and replace it :: - =. moves - [(cancel-timeout-move channel-id p.state.u.maybe-channel) moves] + =^ cancel-moves state + ?. ?=([%| *] state.u.maybe-channel) + :_ state + (cancel-timeout-move channel-id p.state.u.maybe-channel)^~ + =/ cancel-heartbeat + ?~ heartbeat.u.maybe-channel ~ + :_ ~ + %+ cancel-heartbeat-move channel-id + [date duct]:u.heartbeat.u.maybe-channel + =- [(weld cancel-heartbeat -<) ->] + (handle-response(duct p.state.u.maybe-channel) [%cancel ~]) :: the request may include a 'Last-Event-Id' header :: =/ maybe-last-event-id=(unit @ud) @@ -1231,9 +1251,11 @@ ::NOTE these will only fail if the mark and/or json types changed, :: since conversion failure also gets caught during first receive. :: we can't do anything about this, so consider it unsupported. - ?~ sign=(channel-event-to-sign channel-event) $ - ?~ json=(sign-to-json request-id u.sign) $ - $(events [(event-json-to-wall id u.json) events]) + =/ sign + (channel-event-to-sign u.maybe-channel request-id channel-event) + ?~ sign $ + ?~ jive=(sign-to-json u.maybe-channel request-id u.sign) $ + $(events [(event-json-to-wall id +.u.jive) events]) :: send the start event to the client :: =^ http-moves state @@ -1273,7 +1295,7 @@ |= =channel channel(events ~, state [%| duct], heartbeat (some [heartbeat-time duct])) :: - [[heartbeat (weld http-moves moves)] state] + [[heartbeat :(weld http-moves cancel-moves moves)] state] :: +acknowledge-events: removes events before :last-event-id on :channel-id :: ++ acknowledge-events @@ -1499,8 +1521,12 @@ :: if conversion succeeds, we *can* send it. if the client is actually :: connected, we *will* send it immediately. :: + =/ jive=(unit (quip move json)) + (sign-to-json u.channel request-id sign) =/ json=(unit json) - (sign-to-json request-id sign) + ?~(jive ~ `+.u.jive) + =? moves ?=(^ jive) + (weld moves -.u.jive) =* sending &(?=([%| *] state.u.channel) ?=(^ json)) :: =/ next-id next-id.u.channel @@ -1578,7 +1604,7 @@ ^= data %- wall-to-octs %+ event-json-to-wall next-id - (need (sign-to-json request-id %kick ~)) + +:(need (sign-to-json u.channel request-id %kick ~)) :: complete=%.n == @@ -1597,18 +1623,33 @@ ^- channel-event ?. ?=(%fact -.sign) sign [%fact [p q.q]:cage.sign] + :: +app-to-desk + :: + ++ app-to-desk + |= [=channel request-id=@ud] + ^- (unit desk) + =/ sub (~(get by subscriptions.channel) request-id) + ?~ sub + ((slog leaf+"eyre: no subscription for request-id {}" ~) ~) + =/ des=(unit (unit cage)) + (rof ~ %gd [our app.u.sub da+now] ~) + ?. ?=([~ ~ *] des) + ((slog leaf+"eyre: no desk for app {(trip app.u.sub)}" ~) ~) + `!<(=desk q.u.u.des) :: +channel-event-to-sign: attempt to recover a sign from a channel-event :: ++ channel-event-to-sign ~% %eyre-channel-event-to-sign ..part ~ - |= event=channel-event + |= [=channel request-id=@ud event=channel-event] ^- (unit sign:agent:gall) ?. ?=(%fact -.event) `event :: rebuild vase for fact data :: + =/ des=(unit desk) (app-to-desk channel request-id) + ?~ des ~ =* have=mark mark.event =/ val=(unit (unit cage)) - (rof ~ %cb [our %home da+now] /[have]) + (rof ~ %cb [our u.des da+now] /[have]) ?. ?=([~ ~ *] val) ((slog leaf+"eyre: no mark {(trip have)}" ~) ~) =+ !<(=dais:clay q.u.u.val) @@ -1619,32 +1660,36 @@ :: +sign-to-json: render sign from request-id as json channel event :: ++ sign-to-json - |= [request-id=@ud =sign:agent:gall] - ^- (unit json) + ~% %sign-to-json ..part ~ + |= [=channel request-id=@ud =sign:agent:gall] + ^- (unit (quip move json)) :: for facts, we try to convert the result to json :: - =/ jsyn=(unit sign:agent:gall) - ?. ?=(%fact -.sign) `sign - ?: ?=(%json p.cage.sign) `sign + =/ [from=(unit [=desk =mark]) jsyn=(unit sign:agent:gall)] + ?. ?=(%fact -.sign) [~ `sign] + ?: ?=(%json p.cage.sign) [~ `sign] :: find and use tube from fact mark to json :: + =/ des=(unit desk) (app-to-desk channel request-id) + ?~ des [~ ~] + :: =* have=mark p.cage.sign =* desc=tape "from {(trip have)} to json" - =/ tube=(unit tube:clay) - =/ tuc=(unit (unit cage)) - (rof ~ %cc [our %home da+now] /[have]/json) - ?. ?=([~ ~ *] tuc) ~ - `!<(tube:clay q.u.u.tuc) - ?~ tube - ((slog leaf+"eyre: no tube {desc}" ~) ~) - :: - =/ res (mule |.((u.tube q.cage.sign))) - ?: ?=(%& -.res) - `[%fact %json p.res] - ((slog leaf+"eyre: failed tube {desc}" ~) ~) - :: + =/ convert=(unit vase) + =/ cag=(unit (unit cage)) + (rof ~ %cf [our u.des da+now] /[have]/json) + ?. ?=([~ ~ *] cag) ~ + `q.u.u.cag + ?~ convert + ((slog leaf+"eyre: no convert {desc}" ~) [~ ~]) + ~| "conversion failed {desc}" + [`[u.des have] `[%fact %json (slym u.convert q.q.cage.sign)]] ?~ jsyn ~ %- some + :- ?~ from ~ + :_ ~ + :^ duct %pass /conversion-cache/[mark.u.from] + [%c %warp our desk.u.from `[%sing %f da+now /[mark.u.from]/json]] =* sign u.jsyn =, enjs:format %- pairs @@ -1665,7 +1710,7 @@ :- 'json' ~| [%unexpected-fact-mark p.cage.sign] ?> =(%json p.cage.sign) - ;;(json q.q.cage.sign) + !<(json q.cage.sign) == :: %kick @@ -1696,7 +1741,7 @@ =/ res %- handle-response :* %continue - data=(some (as-octs:mimes:html '\0a')) + data=(some (as-octs:mimes:html ':\0a')) complete=%.n == =/ http-moves -.res @@ -1929,9 +1974,9 @@ ?=([%'~_~' *] path.binding) :: runtime == [| bindings.state] - (insert-binding [binding duct action] bindings.state) + [& (insert-binding [binding duct action] bindings.state)] :_ state - [duct %give %bound success binding]~ + [duct %give %bound & binding]~ :: +remove-binding: removes a binding if it exists and is owned by this duct :: ++ remove-binding @@ -2052,28 +2097,29 @@ |= url=@t ^- [[ext=(unit @ta) site=(list @t)] args=(list [key=@t value=@t])] (fall (rush url ;~(plug apat:de-purl:html yque:de-purl:html)) [[~ ~] ~]) +:: +insert-binding: add a new binding, replacing any existing at its path :: ++ insert-binding - |= [[=binding =duct =action] bindings=(list [=binding =duct =action])] - =/ to-search bindings - |- ^- [? _bindings] - ?^ to-search - ?: =(binding binding.i.to-search) - [| bindings] - :: - $(to-search t.to-search) - :- & - :: store in reverse alphabetical order so that longer paths are first + |= $: new=[=binding =duct =action] + bindings=(list [=binding =duct =action]) + == + ^+ bindings + ?~ bindings [new]~ + =* bid binding.i.bindings + :: replace already bound paths :: - %- flop - %+ sort [[binding duct action] bindings] - |= [[a=^binding *] [b=^binding *]] + ?: =([site path]:bid [site path]:binding.new) + ~> %slog.[0 leaf+"eyre: replacing existing binding at {<`path`path.bid>}"] + [new t.bindings] + :: if new comes before bid, prepend it. + :: otherwise, continue our search. :: - ?: =(site.a site.b) - (aor path.a path.b) - :: alphabetize based on site - :: - (aor ?~(site.a '' u.site.a) ?~(site.b '' u.site.b)) + =; new-before-bid=? + ?: new-before-bid [new bindings] + [i.bindings $(bindings t.bindings)] + ?: =(site.binding.new site.bid) + (aor path.bid path.binding.new) + (aor (fall site.bid '') (fall site.binding.new '')) :: ++ channel-wire |= [channel-id=@t request-id=@ud] @@ -2117,6 +2163,8 @@ :: initial value for the login handler :: =. bindings.server-state.ax + =- (roll - insert-binding) + ^- (list [binding ^duct action]) :~ [[~ /~/login] duct [%authentication ~]] [[~ /~/logout] duct [%logout ~]] [[~ /~/channel] duct [%channel ~]] @@ -2320,14 +2368,15 @@ :: |^ ^- [(list move) _http-server-gate] :: - ?+ i.wire - ~|([%bad-take-wire wire] !!) + ?+ i.wire + ~|([%bad-take-wire wire] !!) :: - %run-app-request run-app-request - %watch-response watch-response - %sessions sessions - %channel channel - %acme acme-ack + %run-app-request run-app-request + %watch-response watch-response + %sessions sessions + %channel channel + %acme acme-ack + %conversion-cache `http-server-gate == :: ++ run-app-request @@ -2424,8 +2473,9 @@ :: ?(%poke %subscription) ?> ?=([%gall %unto *] sign) - ~| wire + ~| eyre-sub=wire ?> ?=([@ @ @t @ *] wire) + ?< ?=(%raw-fact -.p.sign) =* channel-id i.t.t.wire =* request-id i.t.t.t.wire =* extra-wire t.t.t.t.wire diff --git a/pkg/arvo/sys/vane/gall.hoon b/pkg/arvo/sys/vane/gall.hoon index 690fa615e..af07252e2 100644 --- a/pkg/arvo/sys/vane/gall.hoon +++ b/pkg/arvo/sys/vane/gall.hoon @@ -12,9 +12,9 @@ :: $move: Arvo-level move :: +$ move [=duct move=(wind note-arvo gift-arvo)] -:: $state-7: overall gall state, versioned +:: $state-8: overall gall state, versioned :: -+$ state-7 [%7 state] ++$ state-8 [%8 state] :: $state: overall gall state :: :: system-duct: TODO document @@ -55,7 +55,7 @@ +$ yoke $: control-duct=duct nonce=@t - live=? + live=? ::TODO remove, replaced by -.agent =stats =watches agent=(each agent vase) @@ -64,7 +64,7 @@ == :: $blocked-move: enqueued move to an agent :: -+$ blocked-move [=duct =routes move=(each deal sign:agent)] ++$ blocked-move [=duct =routes move=(each deal unto)] :: $stats: statistics :: :: change: how many moves this agent has processed @@ -116,8 +116,7 @@ :: $spore: structures for update, produced by +stay :: +$ spore - $: %7 - wipe-eyre-subs=_| ::NOTE band-aid for #3196, remove on next upgrade + $: %8 system-duct=duct outstanding=(map [wire duct] (qeu remote-request)) contacts=(set ship) @@ -159,17 +158,25 @@ ~< %slog.[0 leaf+"gall: molted"] :: +molt should never notify its client about agent changes :: - =- [(skip -< |=(move ?=([* %give %onto *] +<))) ->] + =- :_ -> + %+ welp + (skip -< |=(move ?=([* %give %onto *] +<))) + [^duct %pass /whiz/gall %$ %whiz ~]~ =/ adult adult-core =. state.adult - [%7 system-duct outstanding contacts yokes=~ blocked]:spore + [%8 system-duct outstanding contacts yokes=~ blocked]:spore =/ mo-core (mo-abed:mo:adult duct) =. mo-core =/ apps=(list [dap=term =egg]) ~(tap by eggs.spore) - ~? wipe-eyre-subs.spore - [%g %wiping-eyre-subs] |- ^+ mo-core ?~ apps mo-core + ?. =(%base q.beak.egg.i.apps) + ~> %slog.[0 leaf+"gall: suspending {}"] + =. old-state.egg.i.apps + =/ old old-state.egg.i.apps + |/?-(-.old %| p.old, %& p.old) + =/ ap-core (ap-abut:ap:mo-core i.apps) + $(apps t.apps, mo-core ap-abet:ap-core) ~> %slog.[0 leaf+"gall: upgrading {}"] =/ ap-core (ap-abut:ap:mo-core i.apps) =? ap-core ?=(%& -.old-state.egg.i.apps) @@ -177,18 +184,6 @@ ?^ tan (mean u.tan) ap-core - =? ap-core wipe-eyre-subs.spore - =/ ducts=(list ^duct) - %+ skim ~(tap in ~(key by inbound.watches.egg.i.apps)) - |= =^duct - %+ lien duct - |= =path - ?=(^ (find /e/channel/subscription path)) - |- - ?~ ducts ap-core - =. ap-core - ap-load-delete:ap-core(agent-duct i.ducts) - $(ducts t.ducts) $(apps t.apps, mo-core ap-abet:ap-core) =. mo-core (mo-subscribe-to-agent-builds:mo-core now) =^ moves adult-gate mo-abet:mo-core @@ -200,7 +195,7 @@ =* call-args +< ?: =(~ eggs.spore) ~> %slog.[0 leaf+"gall: direct morphogenesis"] - =. state.adult-gate [- +>]:spore(eggs *(map term yoke)) + =. state.adult-gate spore(eggs *(map term yoke)) (call:adult-core call-args) ?^ dud ~> %slog.[0 leaf+"gall: pupa call dud"] @@ -211,13 +206,13 @@ (molt duct `[duct %slip %g task]) :: ++ scry scry:adult-core - ++ stay ~|(%gall-subinvolution !!) + ++ stay spore ++ take |= [=wire =duct dud=(unit goof) sign=sign-arvo] =* take-args +< ?: =(~ eggs.spore) ~> %slog.[0 leaf+"gall: direct morphogenesis"] - =. state.adult-gate [- +>]:spore(eggs *(map term yoke)) + =. state.adult-gate spore(eggs *(map term yoke)) (take:adult-core take-args) ?^ dud ~> %slog.[0 leaf+"gall: pupa take dud"] @@ -227,18 +222,44 @@ (molt duct `[duct %pass wire %b %huck sign]) :: ++ load - |= old=^spore - =. spore old - ?. =(~ eggs.spore) - pupal-gate - ~> %slog.[0 leaf+"gall: direct morphogenesis"] - %_ adult-gate - state [- +>]:spore(eggs *(map term yoke)) - == + |^ |= old=spore-any + =? old ?=(%7 -.old) + (spore-7-to-8 old) + ?> ?=(%8 -.old) + =. spore old + ?. =(~ eggs.spore) + pupal-gate + ~> %slog.[0 leaf+"gall: direct morphogenesis"] + %_ adult-gate + state spore(eggs *(map term yoke)) + == + :: + +$ spore-any $%(^spore spore-7) + +$ spore-7 + $: %7 + wipe-eyre-subs=_| ::NOTE band-aid for #3196 + system-duct=duct + outstanding=(map [wire duct] (qeu remote-request)) + contacts=(set ship) + eggs=(map term egg) + blocked=(map term (qeu blocked-move)) + == + :: + ++ spore-7-to-8 + |= old=spore-7 + ^- ^spore + :- %8 + =. eggs.old + %- ~(urn by eggs.old) + |= [a=term e=egg] + ::NOTE kiln will kick off appropriate app revival + e(old-state [%| p.old-state.e]) + +>.old + -- -- :: adult gall vane interface, for type compatibility with pupa :: -=| state=state-7 +=| state=state-8 |= [now=@da eny=@uvJ rof=roof] =* gall-payload . =< ~% %gall-wrap ..mo ~ @@ -269,6 +290,25 @@ ++ mo-abet [(flop moves) gall-payload] ++ mo-pass |=(p=[wire note-arvo] mo-core(moves [[hen pass+p] moves])) ++ mo-give |=(g=gift mo-core(moves [[hen give+g] moves])) + ++ mo-past + |= =(list [wire note-arvo]) + ?~ list + mo-core + =. mo-core (mo-pass i.list) + $(list t.list) + :: +mo-jolt: (re)start agent if not already started on this desk + :: + ++ mo-jolt + |= [dap=term =ship =desk] + ^+ mo-core + =/ yak (~(get by yokes.state) dap) + ?~ yak + (mo-boot dap ship desk) + ?. -.agent.u.yak + (mo-boot dap ship desk) + ?. =(desk q.beak.u.yak) + (mo-boot dap ship desk) + mo-core :: +mo-boot: ask %ford to build us a core for the specified agent. :: ++ mo-boot @@ -277,26 +317,6 @@ =/ =case [%da now] =/ =wire /sys/cor/[dap]/(scot %p ship)/[desk]/(scot case) (mo-pass wire %c %warp ship desk ~ %sing %a case /app/[dap]/hoon) - :: +mo-reboot: ask %ford to rebuild the specified agent - :: - ++ mo-reboot - |= [dap=term =ship] - ^+ mo-core - =/ gent (~(got by yokes.state) dap) - =* desk q.beak.gent - (mo-boot:(mo-abed control-duct.gent) dap ship desk) - :: +mo-goad: rebuild agent(s) - :: - ++ mo-goad - |= agent=(unit dude) - ^+ mo-core - ?^ agent - ~| goad-gone+u.agent - (mo-reboot u.agent our) - =/ agents=(list term) ~(tap in ~(key by yokes.state)) - |- ^+ mo-core - ?~ agents mo-core - $(agents t.agents, mo-core (mo-reboot i.agents our)) :: +mo-receive-core: receives an app core built by %ford. :: :: Presuming we receive a good core, we first check to see if the agent @@ -314,15 +334,19 @@ |= [dap=term bek=beak =agent] ^+ mo-core :: - =/ existing (~(get by yokes.state) dap) - =/ re ?~(existing "" "re") - ~> %slog.[0 leaf+"gall: {re}loading {}"] + =/ yak (~(get by yokes.state) dap) + =/ tex + ?~ yak "installing" + ?- -.agent.u.yak + %& "reloading" + %| "reviving" + == + ~> %slog.[0 leaf+"gall: {tex} {}"] :: - ?^ existing + ?^ yak =. yokes.state - (~(put by yokes.state) dap u.existing(beak bek)) - =/ =routes [disclosing=~ attributing=our] - =/ ap-core (ap-abed:ap dap routes) + (~(put by yokes.state) dap u.yak(beak bek)) + =/ ap-core (ap-abed:ap dap `our) =. ap-core (ap-reinstall:ap-core agent) =. mo-core ap-abet:ap-core (mo-clear-queue dap) @@ -338,8 +362,7 @@ :: =/ old mo-core =/ wag - =/ =routes [disclosing=~ attributing=our] - =/ ap-core (ap-abed:ap dap routes) + =/ ap-core (ap-abed:ap dap `our) (ap-upgrade-state:ap-core ~) :: =/ maybe-tang -.wag @@ -362,30 +385,40 @@ |= date=@da ^+ mo-core =. mo-core (mo-abed system-duct.state) - =/ =wire /sys/lyv - =. mo-core (mo-pass /sys/lyv %c %warp our %home ~) - =/ =mool:clay - :- da+date - %- ~(gas in *(set [care:clay path])) - :* [%z /sys/hoon/hoon] + :: + =/ sources=(jug desk [care:clay path]) + %+ ~(put by *(jug desk [care:clay path])) %base + %- sy + :~ [%z /sys/hoon/hoon] [%z /sys/arvo/hoon] [%z /sys/lull/hoon] [%z /sys/zuse/hoon] [%z /sys/vane/gall/hoon] - %+ murn ~(tap by yokes.state) - |= [dap=term =yoke] - ^- (unit [care:clay path]) - ?: ?=(%| -.agent.yoke) - ~ - `[%a /app/[dap]/hoon] + [%z /sys/kelvin] == - (mo-pass wire %c %warp our %home ~ %mult mool) + :: + =. sources + =/ apps=(list [dap=term =yoke]) ~(tap by yokes.state) + |- ^+ sources + ?~ apps + sources + =? sources ?=(%& -.agent.yoke.i.apps) + (~(put ju sources) q.beak.yoke.i.apps %a /app/[dap.i.apps]/hoon) + $(apps t.apps) + :: + %- mo-past + %- zing + %+ turn ~(tap by sources) + |= [=desk paths=(set [care:clay path])] + :~ [/sys/lyv %c %warp our desk ~] + [/sys/lyv %c %warp our desk ~ %mult da+date paths] + == :: +mo-scry-agent-cage: read $agent core from clay :: ++ mo-scry-agent-cage - |= [dap=term =case:clay] + |= [dap=term =desk =case:clay] ^- (each agent tang) - =/ bek=beak [our %home case] + =/ bek=beak [our desk case] =/ sky (rof ~ %ca bek /app/[dap]/hoon) ?~ sky |+[leaf+"gall: {} scry blocked"]~ ?~ u.sky |+[leaf+"gall: {} scry failed"]~ @@ -494,72 +527,60 @@ :: ++ mo-handle-sys ~/ %mo-handle-sys - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core :: - ?+ -.path !! - %lyv (mo-handle-sys-lyv path sign-arvo) - %era (mo-handle-sys-era path sign-arvo) - %cor (mo-handle-sys-cor path sign-arvo) - %lag (mo-handle-sys-lag path sign-arvo) - %req (mo-handle-sys-req path sign-arvo) - %way (mo-handle-sys-way path sign-arvo) + ?+ -.wire !! + %lyv (mo-handle-sys-lyv wire sign-arvo) + %era (mo-handle-sys-era wire sign-arvo) + %cor (mo-handle-sys-cor wire sign-arvo) + %lag (mo-handle-sys-lag wire sign-arvo) + %req (mo-handle-sys-req wire sign-arvo) + %way (mo-handle-sys-way wire sign-arvo) == :: +mo-handle-sys-era: receive update about contact :: ++ mo-handle-sys-era - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core ?> ?=([%jael %public-keys *] sign-arvo) - ?> ?=([%era ~] path) + ?> ?=([%era ~] wire) ?. ?=(%breach -.public-keys-result.sign-arvo) mo-core (mo-breach who.public-keys-result.sign-arvo) :: +mo-handle-sys-cor: receive a built agent from %clay :: ++ mo-handle-sys-cor - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core :: - ?> ?=([%cor @ @ @ @ ~] path) - =/ [dap=term her=@ta desk=@ta dat=@ta ~] t.path - =/ tim (slav da+dat) - =/ =beak [(slav %p her) desk da+tim] + ?> ?=([%cor @ @ @ @ ~] wire) + =/ [dap=term her=@ta desk=@ta dat=@ta ~] t.wire + =/ =beak [(slav %p her) desk da+now] ?> ?=([?(%behn %clay) %writ *] sign-arvo) - |^ ^+ mo-core ?~ p.sign-arvo - (fail leaf+"gall: failed to build agent {}" ~) + (mean leaf+"gall: failed to build agent {}" ~) =/ cag=cage r.u.p.sign-arvo ?. =(%vase p.cag) - (fail leaf+"gall: bad %writ {} for {}" ~) + (mean leaf+"gall: bad %writ {} for {}" ~) =/ res (mule |.(!<(agent !<(vase q.cag)))) ?: ?=(%| -.res) - (fail leaf+["gall: bad agent {}"] p.res) + (mean leaf+["gall: bad agent {}"] p.res) =. mo-core (mo-receive-core dap beak p.res) - (mo-subscribe-to-agent-builds tim) - :: - ++ fail - |= =tang - ^+ mo-core - =. mo-core (mo-give %onto |+tang) - =/ =case [%da tim] - =/ =wire /sys/cor/[dap]/[her]/[desk]/(scot case) - (mo-pass wire %c %warp p.beak desk ~ %next %a case /app/[dap]/hoon) - -- + (mo-subscribe-to-agent-builds now) :: +mo-handle-sys-lyv: handle notice that agents have been rebuilt :: ++ mo-handle-sys-lyv - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core - ?> ?=([%lyv ~] path) + ?> ?=([%lyv ~] wire) ?> ?=([?(%behn %clay) %wris *] sign-arvo) - =/ bek=beak [our %home p.sign-arvo] - =/ nex=(list [=care:clay =^path]) ~(tap in q.sign-arvo) + =/ nex=(list [=care:clay =path]) ~(tap in q.sign-arvo) ~> %slog.[0 leaf+"gall: reloading agents"] ~< %slog.[0 leaf+"gall: reloaded agents"] - =; cor (mo-subscribe-to-agent-builds:cor p.p.sign-arvo) + =; cor (mo-subscribe-to-agent-builds:cor now) %+ roll nex - |= [[=care:clay =^path] cor=_mo-core] + |= [[=care:clay =path] cor=_mo-core] ^+ cor :: We throw away %z results because we only have them to guarantee :: molting. Clay will tell us if e.g. changing hoon.hoon affects @@ -567,18 +588,27 @@ :: ?. =(%a care) cor + ~| path=path =/ dap dap:;;([%app dap=@tas %hoon ~] path) - =/ rag (mo-scry-agent-cage dap p.sign-arvo) + =/ yok=(unit yoke) (~(get by yokes.state) dap) + ?~ yok + ~> %slog.[0 leaf+"gall: no agent to reload: {}"] + cor + ?: ?=(%| -.agent.u.yok) + ~> %slog.[0 leaf+"gall: dead agent reload: {}"] + cor + =/ bek=beak [our q.beak.u.yok da+now] + =/ rag (mo-scry-agent-cage dap q.bek da+now) ?: ?=(%| -.rag) (mean p.rag) (mo-receive-core:cor dap bek p.rag) :: +mo-handle-sys-lag: handle an ames %clog notification :: ++ mo-handle-sys-lag - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core :: - ?> ?=([%lag ~] path) + ?> ?=([%lag ~] wire) ?> ?=([%ames %clog *] sign-arvo) :: =/ agents=(list term) ~(tap in ~(key by yokes.state)) @@ -586,8 +616,7 @@ ?~ agents mo-core :: =. mo-core - =/ =routes [disclosing=~ attributing=our] - =/ app (ap-abed:ap i.agents routes) + =/ app (ap-abed:ap i.agents `our) ap-abet:(ap-clog:app ship.sign-arvo) :: $(agents t.agents) @@ -595,25 +624,26 @@ :: :: TODO: what should we do if the remote nacks our %pull? ++ mo-handle-sys-req - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core :: - ?> ?=([%req @ @ ~] path) - =/ him (slav %p i.t.path) - =/ dap i.t.t.path + ?> ?=([%req @ @ ~] wire) + =/ him (slav %p i.t.wire) + =/ dap i.t.t.wire :: ?> ?=([?(%gall %behn) %unto *] sign-arvo) - =/ =sign:agent +>.sign-arvo + =/ =unto +>.sign-arvo :: - ?- -.sign + ?- -.unto + %raw-fact ~|([%gall-raw-req wire] !!) %poke-ack =/ err=(unit error:ames) - ?~ p.sign ~ - `[%poke-ack u.p.sign] + ?~ p.unto ~ + `[%poke-ack u.p.unto] (mo-give %done err) :: %fact - =+ [mark noun]=[p q.q]:cage.sign + =+ [mark noun]=[p q.q]:cage.unto (mo-give %boon %d mark noun) :: %kick @@ -621,8 +651,8 @@ :: %watch-ack =/ err=(unit error:ames) - ?~ p.sign ~ - `[%watch-ack u.p.sign] + ?~ p.unto ~ + `[%watch-ack u.p.unto] (mo-give %done err) == :: +mo-handle-sys-way: handle response to outgoing remote request @@ -696,19 +726,19 @@ :: ++ mo-handle-use ~/ %mo-handle-use - |= [=path =sign-arvo] + |= [=wire =sign-arvo] ^+ mo-core :: - ?. ?=([@ @ @ *] path) - ~& [%mo-handle-use-bad-path path] + ?. ?=([@ @ @ *] wire) + ~& [%mo-handle-use-bad-wire wire] !! :: - =/ dap=term i.path + =/ dap=term i.wire =/ yoke (~(get by yokes.state) dap) ?~ yoke %- (slog leaf+"gall: {} dead, got {<+<.sign-arvo>}" ~) mo-core - ?. =(nonce.u.yoke i.t.path) + ?. =(nonce.u.yoke i.t.wire) %- (slog leaf+"gall: got old {<+<.sign-arvo>} for {}" ~) mo-core ?. ?=([?(%gall %behn) %unto *] sign-arvo) @@ -716,30 +746,30 @@ %- (slog leaf+"gall: {} dozing, dropping {<+<.sign-arvo>}" ~) mo-core =/ app - =/ =ship (slav %p i.t.t.path) + =/ =ship (slav %p i.t.t.wire) =/ =routes [disclosing=~ attributing=ship] (ap-abed:ap dap routes) :: - =. app (ap-generic-take:app t.t.t.path sign-arvo) + =. app (ap-generic-take:app t.t.t.wire sign-arvo) ap-abet:app - ?> ?=([%out @ @ *] t.t.path) - =/ =ship (slav %p i.t.t.t.path) + ?> ?=([%out @ @ *] t.t.wire) + =/ =ship (slav %p i.t.t.t.wire) =/ =routes [disclosing=~ attributing=ship] - =/ =sign:agent +>.sign-arvo + =/ =unto +>.sign-arvo ?: ?=(%| -.agent.u.yoke) =/ blocked=(qeu blocked-move) =/ waiting (~(get by blocked.state) dap) =/ deals (fall waiting *(qeu blocked-move)) - =/ deal [hen routes |+sign] + =/ deal [hen routes |+unto] (~(put to deals) deal) :: - %- (slog leaf+"gall: {} dozing, got {<-.sign>}" ~) + %- (slog leaf+"gall: {} dozing, got {<-.unto>}" ~) %_ mo-core blocked.state (~(put by blocked.state) dap blocked) == =/ app (ap-abed:ap dap routes) =. app - (ap-specific-take:app t.t.path sign) + (ap-specific-take:app t.t.wire unto) ap-abet:app :: +mo-clear-queue: clear blocked tasks from the specified running agent. :: @@ -755,14 +785,12 @@ ?: =(~ blocked) =. blocked.state (~(del by blocked.state) dap) mo-core - =^ [=duct =routes blocker=(each deal sign:agent)] blocked + =^ [=duct =routes blocker=(each deal unto)] blocked ~(get to blocked) + ?: ?=(%| -.blocker) $ =/ =move =/ =sock [attributing.routes our] - =/ card - ?: ?=(%& -.blocker) - [%slip %g %deal sock dap p.blocker] - [%pass /clear-huck %b %huck `sign-arvo`[%gall %unto p.blocker]] + =/ card [%slip %g %deal sock dap p.blocker] [duct card] $(moves [move moves]) :: +mo-filter-queue: remove all blocked tasks from ship. @@ -788,33 +816,26 @@ =? new-blocked !=(ship attributing.routes.mov) (~(put to new-blocked) mov) $ - :: +mo-fade: put app to sleep + :: +mo-idle: put agent to sleep :: - ++ mo-fade - |= [dap=term style=?(%slay %idle %jolt)] + ++ mo-idle + |= dap=dude ^+ mo-core - =/ =routes [disclosing=~ attributing=our] - =/ app (ap-abed:ap dap routes) - =. mo-core ap-abet:(ap-fade:app style) - =. mo-core - ?- style - %slay mo-core(yokes.state (~(del by yokes.state) dap)) - %idle mo-core - %jolt (mo-boot dap our %home) - == - =? mo-core !?=(%jolt style) (mo-subscribe-to-agent-builds now) - mo-core - :: +mo-beak: assemble a beak for the specified agent. + ?. (~(has by yokes.state) dap) + ~> %slog.0^leaf/"gall: ignoring %idle for {}, not running" + mo-core + ap-abet:ap-idle:(ap-abed:ap dap `our) + :: +mo-nuke: delete agent completely :: - ++ mo-beak - |= dap=term - ^- beak - ?^ yoke=(~(get by yokes.state) dap) - beak.u.yoke - :: XX this fallback is necessary, as .term could be either the source - :: or the destination app. ie, it might not exist locally ... - :: - [our %home %da now] + ++ mo-nuke + |= dap=dude + ^+ mo-core + ?. (~(has by yokes.state) dap) + ~> %slog.0^leaf/"gall: ignoring %nuke for {}, not running" + mo-core + ~> %slog.0^leaf/"gall: nuking {}" + =. mo-core ap-abet:ap-nuke:(ap-abed:ap dap `our) + mo-core(yokes.state (~(del by yokes.state) dap)) :: +mo-peek: call to +ap-peek (which is not accessible outside of +mo). :: ++ mo-peek @@ -834,7 +855,8 @@ :: %raw-poke =/ =case:clay da+now - =/ sky (rof ~ %cb [our %home case] /[mark.deal]) + =/ =desk q.beak:(~(got by yokes.state) dap) + =/ sky (rof ~ %cb [our desk case] /[mark.deal]) ?- sky ?(~ [~ ~]) =/ ror "gall: raw-poke fail :{(trip dap)} {}" @@ -848,7 +870,7 @@ (mo-give %unto %poke-ack `[leaf+ror p.res]) =. mo-core %+ mo-pass /nowhere - [%c %warp our %home ~ %sing %b case /[mark.deal]] + [%c %warp our desk ~ %sing %b case /[mark.deal]] (mo-apply-sure dap routes [%poke mark.deal p.res]) == :: @@ -856,7 +878,8 @@ =/ =case:clay da+now =/ =mars:clay [p.cage mark]:deal =/ mars-path /[a.mars]/[b.mars] - =/ sky (rof ~ %cc [our %home case] mars-path) + =/ =desk q.beak:(~(got by yokes.state) dap) + =/ sky (rof ~ %cc [our desk case] mars-path) ?- sky ?(~ [~ ~]) =/ ror "gall: poke cast fail :{(trip dap)} {}" @@ -870,7 +893,7 @@ (mo-give %unto %poke-ack `[leaf+ror p.res]) =. mo-core %+ mo-pass /nowhere - [%c %warp our %home ~ %sing %c case /[a.mars]/[b.mars]] + [%c %warp our desk ~ %sing %c case /[a.mars]/[b.mars]] (mo-apply-sure dap routes [%poke mark.deal p.res]) == == @@ -932,31 +955,12 @@ ++ mo-handle-ames-response |= =ames-response ^+ mo-core - ?- -.ames-response - :: %d: diff; ask clay to validate .noun as .mark - :: - %d - =/ =case:clay da+now - =/ sky (rof ~ %cb [our %home case] /[mark.ames-response]) - ?- sky - ?(~ [~ ~]) - (mean leaf+"gall: ames mark fail {}" ~) + :: %d: diff; ask clay to validate .noun as .mark + :: %x: kick; tell agent the publisher canceled the subscription :: - [~ ~ *] - =+ !<(=dais:clay q.u.u.sky) - =/ res (mule |.((vale:dais noun.ames-response))) - ?: ?=(%| -.res) - (mean leaf+"gall: ames vale fail {}" p.res) - =. mo-core - %+ mo-pass /nowhere - [%c %warp our %home ~ %sing %b case /[mark.ames-response]] - (mo-give %unto %fact mark.ames-response p.res) - == - :: - :: %x: kick; tell agent the publisher canceled the subscription - :: - %x - (mo-give %unto %kick ~) + ?- -.ames-response + %d (mo-give %unto %raw-fact mark.ames-response noun.ames-response) + %x (mo-give %unto %kick ~) == :: +ap: agent engine :: @@ -970,7 +974,7 @@ agent-duct=duct agent-moves=(list move) agent-config=(list (each suss tang)) - current-agent=yoke + =yoke == ++ ap-core . :: +ap-abed: initialise state for an agent, with the supplied routes. @@ -988,27 +992,26 @@ ++ ap-abut |= [dap=term =egg] ^+ ap-core - =/ =yoke + =/ yak=^yoke ?: ?=(%| -.old-state.egg) egg - =/ res (mo-scry-agent-cage dap da+now) + =/ res (mo-scry-agent-cage dap q.beak.egg da+now) ?: ?=(%| -.res) (mean p.res) egg(p.old-state `agent`p.res) - =/ =routes [disclosing=~ attributing=our] - (ap-yoke dap routes yoke) + (ap-yoke dap `our yak) :: +ap-yoke: initialize agent state, starting from a $yoke :: ++ ap-yoke - |= [dap=term =routes =yoke] + |= [dap=term =routes yak=^yoke] ^+ ap-core - =. stats.yoke - :+ +(change.stats.yoke) - (shaz (mix (add dap change.stats.yoke) eny)) + =. stats.yak + :+ +(change.stats.yak) + (shaz (mix (add dap change.stats.yak) eny)) now =. agent-name dap =. agent-routes routes - =. current-agent yoke + =. yoke yak =. agent-duct hen ap-core :: +ap-abet: resolve moves. @@ -1016,7 +1019,7 @@ ++ ap-abet ^+ mo-core :: - =/ running (~(put by yokes.state) agent-name current-agent) + =/ running (~(put by yokes.state) agent-name yoke) =/ moves =/ giver |=(report=(each suss tang) [hen %give %onto report]) =/ from-suss (turn agent-config giver) @@ -1026,38 +1029,30 @@ yokes.state running moves moves == - :: +ap-fade: put affairs in order. :: - :: For %gone, remove all incoming and outgoing subscriptions. + ++ ap-idle + ?: ?=(%| -.agent.yoke) ap-core + ap-core(agent.yoke |+on-save:ap-agent-core) :: - ++ ap-fade - |= style=?(%slay %idle %jolt) + ++ ap-nuke ^+ ap-core - ?- style - %jolt ap-core - %idle - =. agent.current-agent |+on-save:ap-agent-core - ap-core - :: - %slay - =/ out=(list [[=wire =ship =term] ? =path]) - ~(tap by outbound.watches.current-agent) - =/ inbound-paths=(set path) - %- silt - %+ turn ~(tap by inbound.watches.current-agent) - |= [=duct =ship =path] - path - =/ will=(list card:agent:gall) - %+ welp - ?: =(~ inbound-paths) - ~ - [%give %kick ~(tap in inbound-paths) ~]~ - %+ turn ~(tap by outbound.watches.current-agent) - |= [[=wire =ship =term] ? =path] - [%pass wire %agent [ship term] %leave ~] - =^ maybe-tang ap-core (ap-ingest ~ |.([will *agent])) - ap-core - == + =/ out=(list [[=wire =ship =term] ? =path]) + ~(tap by outbound.watches.yoke) + =/ inbound-paths=(set path) + %- silt + %+ turn ~(tap by inbound.watches.yoke) + |= [=duct =ship =path] + path + =/ will=(list card:agent:gall) + %+ welp + ?: =(~ inbound-paths) + ~ + [%give %kick ~(tap in inbound-paths) ~]~ + %+ turn ~(tap by outbound.watches.yoke) + |= [[=wire =ship =term] ? =path] + [%pass wire %agent [ship term] %leave ~] + =^ maybe-tang ap-core (ap-ingest ~ |.([will *agent])) + ap-core :: +ap-from-internal: internal move to move. :: :: We convert from cards to duct-indexed moves when resolving @@ -1097,17 +1092,16 @@ %- zing %+ turn ducts |= =duct + ^- (list move) ~? &(=(duct system-duct.state) !=(agent-name %hood)) [%agent-giving-on-system-duct agent-name -.gift] - ^- (list move) - =/ =mark - (~(gut by marks.current-agent) duct p.cage) + =/ =mark (~(gut by marks.yoke) duct p.cage) :: ?: =(mark p.cage) [duct %give %unto %fact cage.gift]~ =/ =mars:clay [p.cage mark] =/ =case:clay da+now - =/ bek=beak [our %home case] + =/ bek=beak [our q.beak.yoke case] =/ mars-path /[a.mars]/[b.mars] =/ sky (rof ~ %cc bek mars-path) ?- sky @@ -1121,7 +1115,9 @@ ?: ?=(%| -.res) %- (slog leaf+"watch-as fact conversion failure" p.res) (ap-kill-up-slip duct) - :~ [duct %pass /nowhere %c %warp our %home ~ %sing %c case mars-path] + :~ :* duct %pass /nowhere %c %warp our q.beak.yoke ~ + %sing %c case mars-path + == [duct %give %unto %fact b.mars p.res] == == @@ -1130,13 +1126,19 @@ =/ =duct system-duct.state =/ =wire p.card =/ =neet q.card + ?: ?=(%pyre -.neet) + %: mean + leaf/"gall: %pyre from {}, killing event" + leaf/"wire: {}" + tang.neet + == =. wire ?- -.neet %agent [%out (scot %p ship.neet) name.neet wire] %huck [%out (scot %p ship.neet) name.neet wire] %arvo [(scot %p attributing.agent-routes) wire] == - =. wire [%use agent-name nonce.current-agent wire] + =. wire [%use agent-name nonce.yoke wire] =/ =note-arvo ?- -.neet %arvo note-arvo.neet @@ -1151,7 +1153,7 @@ |= =ship ^+ ap-core =/ in=(list [=duct =^ship =path]) - ~(tap by inbound.watches.current-agent) + ~(tap by inbound.watches.yoke) |- ^+ ap-core ?^ in =? ap-core =(ship ship.i.in) @@ -1160,7 +1162,7 @@ $(in t.in) :: =/ out=(list [[=wire =^ship =term] ? =path]) - ~(tap by outbound.watches.current-agent) + ~(tap by outbound.watches.yoke) |- ^+ ap-core ?~ out ap-core @@ -1183,7 +1185,7 @@ ^+ ap-core :: =/ in=(list [=duct =^ship =path]) - ~(tap by inbound.watches.current-agent) + ~(tap by inbound.watches.yoke) |- ^+ ap-core ?~ in ap-core :: @@ -1194,8 +1196,8 @@ :: +ap-agent-core: agent core with current bowl and state :: ++ ap-agent-core - ?> ?=(%& -.agent.current-agent) - ~(. p.agent.current-agent ap-construct-bowl) + ?> ?=(%& -.agent.yoke) + ~(. p.agent.yoke ap-construct-bowl) :: +ap-ducts-from-paths: get ducts subscribed to paths :: ++ ap-ducts-from-paths @@ -1204,7 +1206,7 @@ ?~ target-paths ?~ target-ship ~[agent-duct] - %+ murn ~(tap by inbound.watches.current-agent) + %+ murn ~(tap by inbound.watches.yoke) |= [=duct =ship =path] ^- (unit ^duct) ?: =(target-ship `ship) @@ -1219,7 +1221,7 @@ ++ ap-ducts-from-path |= [target-path=path target-ship=(unit ship)] ^- (list duct) - %+ murn ~(tap by inbound.watches.current-agent) + %+ murn ~(tap by inbound.watches.yoke) |= [=duct =ship =path] ^- (unit ^duct) ?: ?& =(target-path path) @@ -1273,7 +1275,7 @@ =/ tub=(unit tube:clay) ?: =(have want) `(bake same ^vase) =/ tuc=(unit (unit cage)) - (rof ~ %cc [our %home da+now] /[have]/[want]) + (rof ~ %cc [our q.beak.yoke da+now] /[have]/[want]) ?. ?=([~ ~ *] tuc) ~ `!<(tube:clay q.u.u.tuc) ?~ tub @@ -1291,14 +1293,21 @@ ?: is-ok ap-core (ap-kill-down wire [other-ship other-agent]) + :: +ap-move: send move + :: + ++ ap-move + |= =(list move) + ap-core(agent-moves (weld (flop list) agent-moves)) :: +ap-give: return result. :: ++ ap-give |= =gift:agent - ^+ ap-core - =/ internal-moves - (weld (ap-from-internal %give gift) agent-moves) - ap-core(agent-moves internal-moves) + (ap-move (ap-from-internal %give gift)) + :: +ap-pass: request action. + :: + ++ ap-pass + |= [=path =neet] + (ap-move (ap-from-internal %pass path neet)) :: +ap-construct-bowl: set up bowl. :: ++ ap-construct-bowl @@ -1307,22 +1316,14 @@ attributing.agent-routes :: guest agent-name :: agent == :: - :* wex=outbound.watches.current-agent :: outgoing - sup=inbound.watches.current-agent :: incoming + :* wex=outbound.watches.yoke :: outgoing + sup=inbound.watches.yoke :: incoming == :: - :* act=change.stats.current-agent :: tick - eny=eny.stats.current-agent :: nonce - now=time.stats.current-agent :: time - byk=beak.current-agent :: source + :* act=change.stats.yoke :: tick + eny=eny.stats.yoke :: nonce + now=time.stats.yoke :: time + byk=beak.yoke :: source == == - :: +ap-pass: request action. - :: - ++ ap-pass - |= [=path =neet] - ^+ ap-core - =/ internal-moves - (ap-from-internal %pass path neet) - ap-core(agent-moves (weld internal-moves agent-moves)) :: +ap-reinstall: reinstall. :: ++ ap-reinstall @@ -1330,11 +1331,11 @@ |= =agent ^+ ap-core =/ old-state=vase - ?: ?=(%& -.agent.current-agent) + ?: ?=(%& -.agent.yoke) on-save:ap-agent-core - p.agent.current-agent + p.agent.yoke =^ error ap-core - (ap-install(agent.current-agent &+agent) `old-state) + (ap-install(agent.yoke &+agent) `old-state) ?~ error ap-core (mean >%load-failed< u.error) @@ -1343,7 +1344,7 @@ ++ ap-subscribe-as |= [=mark =path] ^+ ap-core - =. marks.current-agent (~(put by marks.current-agent) agent-duct mark) + =. marks.yoke (~(put by marks.yoke) agent-duct mark) (ap-subscribe path) :: +ap-subscribe: apply %watch. :: @@ -1352,8 +1353,8 @@ |= pax=path ^+ ap-core =/ incoming [attributing.agent-routes pax] - =. inbound.watches.current-agent - (~(put by inbound.watches.current-agent) agent-duct incoming) + =. inbound.watches.yoke + (~(put by inbound.watches.yoke) agent-duct incoming) =^ maybe-tang ap-core %+ ap-ingest %watch-ack |. (on-watch:ap-agent-core pax) @@ -1395,7 +1396,7 @@ :: +ap-specific-take: specific take. :: ++ ap-specific-take - |= [=wire =sign:agent] + |= [=wire =unto] ^+ ap-core ~| wire=wire ?> ?=([%out @ @ *] wire) @@ -1403,13 +1404,34 @@ =/ other-agent i.t.t.wire =/ =dock [other-ship other-agent] =/ agent-wire t.t.t.wire + :: + =^ =sign:agent ap-core + ?. ?=(%raw-fact -.unto) + [unto ap-core] + =/ =case:clay da+now + ?: ?=(%spider agent-name) + :- [%fact mark.unto !>(noun.unto)] + ap-core + =/ sky (rof ~ %cb [our q.beak.yoke case] /[mark.unto]) + ?. ?=([~ ~ *] sky) + (mean leaf+"gall: ames mark fail {}" ~) + :: + =+ !<(=dais:clay q.u.u.sky) + =/ res (mule |.((vale:dais noun.unto))) + ?: ?=(%| -.res) + (mean leaf+"gall: ames vale fail {}" p.res) + :- [%fact mark.unto p.res] + %- ap-move :_ ~ + :^ hen %pass /nowhere + [%c %warp our q.beak.yoke ~ %sing %b case /[mark.unto]] + :: :: if subscription ack or close, handle before calling user code :: - =? outbound.watches.current-agent ?=(%kick -.sign) - %- ~(del by outbound.watches.current-agent) + =? outbound.watches.yoke ?=(%kick -.sign) + %- ~(del by outbound.watches.yoke) [agent-wire dock] ?: ?& ?=(%watch-ack -.sign) - !(~(has by outbound.watches.current-agent) [agent-wire dock]) + !(~(has by outbound.watches.yoke) [agent-wire dock]) == %- %: slog leaf+"{}: got ack for nonexistent subscription" @@ -1419,11 +1441,11 @@ == ap-core :: - =? outbound.watches.current-agent ?=(%watch-ack -.sign) + =? outbound.watches.yoke ?=(%watch-ack -.sign) ?^ p.sign - %- ~(del by outbound.watches.current-agent) + %- ~(del by outbound.watches.yoke) [agent-wire dock] - %+ ~(jab by outbound.watches.current-agent) [agent-wire dock] + %+ ~(jab by outbound.watches.yoke) [agent-wire dock] |= [acked=? =path] =. . ?. acked @@ -1453,13 +1475,11 @@ =^ maybe-tang ap-core (ap-upgrade-state old-agent-state) :: =. agent-config - =/ =term ?~(old-agent-state %boot %bump) - =/ possibly-suss - ?~ maybe-tang - =/ =suss [agent-name term now] - [%.y suss] - [%.n u.maybe-tang] - [possibly-suss agent-config] + :_ agent-config + ^- (each suss tang) + ?^ maybe-tang + |/u.maybe-tang + &/[agent-name ?~(old-agent-state %boot %bump) now] :: [maybe-tang ap-core] :: +ap-upgrade-state: low-level install. @@ -1481,8 +1501,8 @@ ^+ ap-core :: %= ap-core - inbound.watches.current-agent - (~(del by inbound.watches.current-agent) agent-duct) + inbound.watches.yoke + (~(del by inbound.watches.yoke) agent-duct) == :: +ap-load-delete: load delete. :: @@ -1490,13 +1510,13 @@ ^+ ap-core :: =/ maybe-incoming - (~(get by inbound.watches.current-agent) agent-duct) + (~(get by inbound.watches.yoke) agent-duct) ?~ maybe-incoming ap-core :: =/ incoming u.maybe-incoming - =. inbound.watches.current-agent - (~(del by inbound.watches.current-agent) agent-duct) + =. inbound.watches.yoke + (~(del by inbound.watches.yoke) agent-duct) :: =^ maybe-tang ap-core %+ ap-ingest ~ |. @@ -1600,9 +1620,9 @@ ?: ?=(%| -.result) `ap-core :: - =. agent.current-agent &++.p.result + =. agent.yoke &++.p.result =/ moves (zing (turn -.p.result ap-from-internal)) - =. inbound.watches.current-agent + =. inbound.watches.yoke (ap-handle-kicks moves) (ap-handle-peers moves) :: +ap-handle-kicks: handle cancels of inbound.watches @@ -1621,7 +1641,7 @@ :: =/ quit-map=bitt (malt (turn quits |=(=duct [duct *[ship path]]))) - (~(dif by inbound.watches.current-agent) quit-map) + (~(dif by inbound.watches.yoke) quit-map) :: +ap-handle-peers: handle new outbound.watches :: ++ ap-handle-peers @@ -1638,8 +1658,8 @@ ?> ?=([%use @ @ %out @ @ *] wire) =/ short-wire t.t.t.t.t.t.wire =/ =dock [q.p q]:q.move.move - =. outbound.watches.current-agent - (~(del by outbound.watches.current-agent) [short-wire dock]) + =. outbound.watches.yoke + (~(del by outbound.watches.yoke) [short-wire dock]) $(moves t.moves, new-moves [move new-moves]) ?. ?=([* %pass * %g %deal * * ?(%watch %watch-as) *] move) $(moves t.moves, new-moves [move new-moves]) @@ -1652,17 +1672,17 @@ %watch path.r.q.move.move %watch-as path.r.q.move.move == - ?: (~(has by outbound.watches.current-agent) short-wire dock) + ?: (~(has by outbound.watches.yoke) short-wire dock) =. ap-core =/ =tang ~[leaf+"subscribe wire not unique" >agent-name< >short-wire< >dock<] =/ have - (~(got by outbound.watches.current-agent) short-wire dock) + (~(got by outbound.watches.yoke) short-wire dock) %- (slog >out=have< tang) (ap-error %watch-not-unique tang) :: reentrant, maybe bad? $(moves t.moves) - =. outbound.watches.current-agent - (~(put by outbound.watches.current-agent) [short-wire dock] [| path]) + =. outbound.watches.yoke + (~(put by outbound.watches.yoke) [short-wire dock] [| path]) $(moves t.moves, new-moves [move new-moves]) -- -- @@ -1680,7 +1700,6 @@ :: =/ mo-core (mo-abed:mo duct) ?- -.task - %conf mo-abet:(mo-boot:mo-core dap.task our %home) %deal =/ [=sock =term =deal] [p q r]:task ?. =(q.sock our) @@ -1688,7 +1707,6 @@ mo-abet:(mo-send-foreign-request:mo-core q.sock term deal) mo-abet:(mo-handle-local:mo-core p.sock term deal) :: - %goad mo-abet:(mo-goad:mo-core agent.task) %init [~ gall-payload(system-duct.state duct)] %plea =/ =ship ship.task @@ -1705,7 +1723,9 @@ mo-abet :: %sear mo-abet:(mo-filter-queue:mo-core ship.task) - %fade mo-abet:(mo-fade:mo-core dap.task style.task) + %jolt mo-abet:(mo-jolt:mo-core dude.task our desk.task) + %idle mo-abet:(mo-idle:mo-core dude.task) + %nuke mo-abet:(mo-nuke:mo-core dude.task) %trim [~ gall-payload] %vega [~ gall-payload] == @@ -1748,7 +1768,34 @@ =([%$ %da now] coin) =(our ship) == - [~ ~ noun+!>((~(has by yokes.state) dap))] + =; hav=? + [~ ~ noun+!>(hav)] + =/ yok=(unit yoke) (~(get by yokes.state) dap) + ?~(yok | -.agent.u.yok) + :: + ?: ?& =(%d care) + =(~ path) + =([%$ %da now] coin) + =(our ship) + == + =/ yok=(unit yoke) (~(get by yokes.state) dap) + ?~ yok + [~ ~] + [~ ~ desk+!>(q.beak.u.yok)] + :: + ?: ?& =(%e care) + =(~ path) + =([%$ %da now] coin) + =(our ship) + == + :+ ~ ~ + :- %apps !> ^- (set [=dude live=?]) + =* syd=desk dap + %+ roll ~(tap by yokes.state) + |= [[=dude =yoke] acc=(set [=dude live=?])] + ?. =(syd q.beak.yoke) + acc + (~(put in acc) [dude -.agent.yoke]) :: ?. =(our ship) ~ @@ -1760,19 +1807,23 @@ ~ =/ =routes [~ ship] (mo-peek:mo dap routes care path) -:: +stay: save without cache +:: +stay: save without cache; suspend non-%base agents +:: +:: TODO: superfluous? see +molt :: ++ stay ^- spore - =; eggs=(map term egg) [- | +]:state(yokes eggs) + =; eggs=(map term egg) state(yokes eggs) %- ~(run by yokes.state) |= =yoke ^- egg %= yoke agent - ?: ?=(%& -.agent.yoke) + ?: ?=(%| -.agent.yoke) + [%| p.agent.yoke] + ?: =(%base q.beak.yoke) [%& on-save:p.agent.yoke] - [%| p.agent.yoke] + [%| on-save:p.agent.yoke] == :: +take: response :: @@ -1784,6 +1835,9 @@ ~&(%gall-take-dud ((slog tang.u.dud) [~ gall-payload])) ?: =(/nowhere wire) [~ gall-payload] + ?: =(/clear-huck wire) + =/ =gift ?>(?=([%behn %heck %gall *] syn) +>+.syn) + [[duct %give gift]~ gall-payload] :: ~| [%gall-take-failed wire] ?> ?=([?(%sys %use) *] wire) diff --git a/pkg/arvo/sys/vane/iris.hoon b/pkg/arvo/sys/vane/iris.hoon index 0f9e7fcee..01e80eb56 100644 --- a/pkg/arvo/sys/vane/iris.hoon +++ b/pkg/arvo/sys/vane/iris.hoon @@ -332,6 +332,7 @@ :: :: TODO: We should gracefully retry on restart instead of just sending a :: cancel. + :: TODO we might not want to do that though! :: =/ moves=(list move) %+ turn ~(tap by connection-by-duct.state.ax) diff --git a/pkg/arvo/sys/vane/jael.hoon b/pkg/arvo/sys/vane/jael.hoon index 20a055577..25e23a266 100644 --- a/pkg/arvo/sys/vane/jael.hoon +++ b/pkg/arvo/sys/vane/jael.hoon @@ -563,7 +563,8 @@ +>.$ :: [%gall %unto *] - ?- +>-.hin + ?- +>-.hin + %raw-fact !! %kick ~|([%jael-unexpected-quit tea hin] !!) %poke-ack ?~ p.p.+>.hin @@ -937,12 +938,13 @@ :: only eagerly update lyf if we were behind the chain life :: =? lyf.own - ?& (gth life lyf.own) - :: - =+ pon=(~(get by pos.zim) our) - ?~ pon | - (lth lyf.own life.u.pon) - == + ?| ?=(%earl (clan:title our)) + ?& (gth life lyf.own) + :: + =+ pon=(~(get by pos.zim) our) + ?~ pon | + (lth lyf.own life.u.pon) + == == life =. jaw.own (~(put by jaw.own) life ring) (exec yen.own [%give %private-keys lyf.own jaw.own]) diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 168c15863..238eab774 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -1587,14 +1587,15 @@ :::: ++keccak:crypto :: (2b7) keccak family :: :::: ++ keccak + ~% %kecc ..part ~ |% :: :: keccak :: - ++ keccak-224 |=(a=octs (keccak 1.152 448 224 a)) - ++ keccak-256 |=(a=octs (keccak 1.088 512 256 a)) - ++ keccak-384 |=(a=octs (keccak 832 768 384 a)) - ++ keccak-512 |=(a=octs (keccak 576 1.024 512 a)) + ++ keccak-224 ~/ %k224 |=(a=octs (keccak 1.152 448 224 a)) + ++ keccak-256 ~/ %k256 |=(a=octs (keccak 1.088 512 256 a)) + ++ keccak-384 ~/ %k384 |=(a=octs (keccak 832 768 384 a)) + ++ keccak-512 ~/ %k512 |=(a=octs (keccak 576 1.024 512 a)) :: ++ keccak (cury (cury hash keccak-f) padding-keccak) :: @@ -3391,6 +3392,11 @@ :: :: ++no:dejs:format ++ no :: number as cord |=(jon=json ?>(?=([%n *] jon) p.jon)) + :: :: ++nu:dejs:format + ++ nu :: parse number as hex + |= jon=json + ?> ?=([%s *] jon) + (rash p.jon hex) :: :: ++of:dejs:format ++ of :: object as frond |* wer=(pole [cord fist]) @@ -3440,6 +3446,11 @@ =/ ten ~|(key+key.wer (wit.wer (~(get by jom) key.wer))) ?~(t.wer ten [ten ((ou-raw t.wer) jom)]) == + :: :: ++oj:dejs:format + ++ oj :: object as jug + |* =fist + ^- $-(json (jug cord _(fist *json))) + (om (as fist)) :: :: ++om:dejs:format ++ om :: object as map |* wit=fist @@ -3466,6 +3477,12 @@ :: :: ++sa:dejs:format ++ sa :: string as tape |=(jon=json ?>(?=([%s *] jon) (trip p.jon))) + :: :: ++sd:dejs:format + ++ sd :: string @ud as date + |= jon=json + ^- @da + ?> ?=(%s -.jon) + `@da`(rash p.jon dem:ag) :: :: ++se:dejs:format ++ se :: string as aura |= aur=@tas @@ -3580,6 +3597,15 @@ ?. ?=([%s *] jon) ~ (bind (stud:chrono:userlib p.jon) |=(a=date (year a))) :: + ++ dank :: tank + ^- $-(json (unit tank)) + %+ re *tank |. ~+ + %- of :~ + leaf+sa + palm+(ot style+(ot mid+sa cap+sa open+sa close+sa ~) lines+(ar dank) ~) + rose+(ot style+(ot mid+sa open+sa close+sa ~) lines+(ar dank) ~) + == + :: ++ di :: millisecond date (cu from-unix-ms:chrono:userlib ni) :: @@ -3653,6 +3679,12 @@ |* [pre=* wit=fist] (cu |*(* [pre +<]) wit) :: + ++ re :: recursive reparsers + |* [gar=* sef=_|.(fist)] + |= jon=json + ^- (unit _gar) + ((sef) jon) + :: ++ sa :: string as tape |= jon=json ?.(?=([%s *] jon) ~ (some (trip p.jon))) @@ -3698,6 +3730,64 @@ (some (~(run by lum) need)) -- ::dejs-soft -- +:: |cloy: clay helpers +:: +++ cloy + =, clay + |% + ++ new-desk + |= [=desk tako=(unit tako) files=(map path page)] + [%c %park desk &/[(drop tako) (~(run by files) (lead %&))] *rang] + :: +an: $ankh interface door + :: + ++ an + |_ nak=ankh + :: +dug: produce ankh at path + :: + ++ dug + |= =path + ^- (unit ankh) + ?~ path `nak + ?~ kid=(~(get by dir.nak) i.path) + ~ + $(nak u.kid, path t.path) + :: +get: produce file at path + :: + ++ get + |= =path + ^- (unit cage) + ?~ nik=(dug path) ~ + ?~ fil.u.nik ~ + `q.u.fil.u.nik + :: +mup: convert sub-tree at .pre to (map path [lobe cage]) + :: + ++ mup + |= pre=path + =- ~? =(~ -) [%oh-no-empty pre] + - + ^- (map path [lobe cage]) + =/ nek=(unit ankh) (dug pre) + ?~ nek + ~& [%oh-no-empty-pre pre ~(key by dir.nak)] + ~ + =. nak u.nek + ~? =(~ nak) [%oh-no-empty-nak pre] + =| pax=path + =| res=(map path [=lobe =cage]) + |- ^+ res + =? res ?=(^ fil.nak) (~(put by res) pax u.fil.nak) + :: =/ anz=(list [seg=@ta =ankh]) ~(tap by dir.nak) + :: |- ^+ res + :: ?~ anz res + :: %_ $ + :: anz t.anz + :: res ^$(pax (snoc pax seg.i.anz), nak ankh.i.anz) + :: == + %+ roll ~(tap by dir.nak) + |= [[seg=@ta =ankh] res=_res] + ^$(pax (snoc pax seg), nak ankh, res res) + -- + -- :: :: :::: ++differ :: (2d) hunt-mcilroy :: :::: @@ -4758,9 +4848,23 @@ :: (both hed ((..^$ +.b) +.a)) -- ::wired :: :: -:::: ++title :: (2j) namespace +:::: ++title :: (2j) identity :: :::: ++ title + :: deep core: for vane use, with $roof for scrying + :: + :: TODO: refactor to share high-level gates like +saxo + :: among the three cores + :: + => |% + ++ sein + |= [rof=roof our=ship now=@da who=ship] + ;; ship + =< q.q %- need %- need + (rof ~ %j `beam`[[our %sein %da now] /(scot %p who)]) + -- + :: middle core: for userspace use, with .^ + :: => |% :: :: ++clan:title ++ clan :: ship to rank @@ -4799,6 +4903,8 @@ %pawn (end 4 who) == -- + :: surface core: stateless queries for default numeric sponsorship + :: |% :: :: ++cite:title ++ cite :: render ship diff --git a/pkg/arvo/ted/aqua/ames.hoon b/pkg/arvo/ted/aqua/ames.hoon index e609353a4..80125cbc7 100644 --- a/pkg/arvo/ted/aqua/ames.hoon +++ b/pkg/arvo/ted/aqua/ames.hoon @@ -18,7 +18,7 @@ |= [our=ship who=@p] ^- (list card:agent:gall) %+ emit-aqua-events our - [%event who [//newt/0v1n.2m9vh %born ~]]~ + [%event who [/a/newt/0v1n.2m9vh %born ~]]~ :: ++ handle-send |= [our=ship now=@da sndr=@p way=wire %send lan=lane:ames pac=@] @@ -26,7 +26,7 @@ =/ rcvr=ship (lane-to-ship lan) =/ hear-lane (ship-to-lane sndr) %+ emit-aqua-events our - [%event rcvr //newt/0v1n.2m9vh %hear hear-lane pac]~ + [%event rcvr /a/newt/0v1n.2m9vh %hear hear-lane pac]~ :: +lane-to-ship: decode a ship from an aqua lane :: :: Special-case one comet, since its address doesn't fit into a lane. diff --git a/pkg/arvo/ted/aqua/behn.hoon b/pkg/arvo/ted/aqua/behn.hoon index 517d2f3c7..1b5ac2092 100644 --- a/pkg/arvo/ted/aqua/behn.hoon +++ b/pkg/arvo/ted/aqua/behn.hoon @@ -40,7 +40,7 @@ ^+ ..abet-pe =. this %- emit-aqua-events - [%event who [//behn/0v1n.2m9vh %born ~]]~ + [%event who [/b/behn/0v1n.2m9vh %born ~]]~ ..abet-pe :: ++ handle-doze @@ -82,7 +82,7 @@ :_ ~ ^- aqua-event :+ %event who - [//behn/0v1n.2m9vh [%wake ~]] + [/b/behn/0v1n.2m9vh [%wake ~]] ..abet-pe -- -- diff --git a/pkg/arvo/ted/aqua/eyre-azimuth.hoon b/pkg/arvo/ted/aqua/eyre-azimuth.hoon index 1700c5d61..4a098961b 100644 --- a/pkg/arvo/ted/aqua/eyre-azimuth.hoon +++ b/pkg/arvo/ted/aqua/eyre-azimuth.hoon @@ -179,7 +179,7 @@ :_ ~ :* %event her - //http-client/0v1n.2m9vh + /i/http-client/0v1n.2m9vh %receive num.u.ask [%start [200 ~] `(as-octs:mimes:html resp) &] @@ -274,7 +274,7 @@ =/ clan (clan:title who) ?- clan ?(%czar %king %duke) - ;< ~ bind:m (raw-ship:ph-io who `(dawn who ~)) + ;< ~ bind:m (init-ship:ph-io who |) (pure:m state) :: ?(%earl %pawn) @@ -294,7 +294,7 @@ =/ rank ?:(=(%earl clan) "moon" "comet") "|{rank} {(scow %p who)}, =public-key {(scow %uw pass)}" ;< ~ bind:m (dojo:ph-io spon com) - ;< ~ bind:m (raw-ship:ph-io who `(dawn who `seed)) + ;< ~ bind:m (init-ship:ph-io who |) (pure:m state) == :: diff --git a/pkg/arvo/ted/aqua/eyre.hoon b/pkg/arvo/ted/aqua/eyre.hoon index 6c1d85c1d..b8a7b7616 100644 --- a/pkg/arvo/ted/aqua/eyre.hoon +++ b/pkg/arvo/ted/aqua/eyre.hoon @@ -39,7 +39,7 @@ ^+ ..abet-pe =. this %- emit-aqua-events - [%event who [//http/0v1n.2m9vh %born ~]]~ + [%event who [/i/http/0v1n.2m9vh %born ~]]~ ..abet-pe :: ++ handle-thus @@ -81,7 +81,7 @@ ..abet-pe =. http-requests (~(del in http-requests) num) =. this - (emit-aqua-events [%event who [//http/0v1n.2m9vh %receive num [%start [p.res q.res] r.res &]]]~) + (emit-aqua-events [%event who [/i/http/0v1n.2m9vh %receive num [%start [p.res q.res] r.res &]]]~) ..abet-pe :: :: Got error in HTTP response diff --git a/pkg/arvo/ted/jam-all-desks.hoon b/pkg/arvo/ted/jam-all-desks.hoon new file mode 100644 index 000000000..fa52d5a49 --- /dev/null +++ b/pkg/arvo/ted/jam-all-desks.hoon @@ -0,0 +1,29 @@ +/- spider +/+ strandio, jammer=desk-jam +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([~ desks=(list desk)] arg) +=? desks =(~ desks) + :~ %base + %garden + %landscape + %webterm + %bitcoin + == +^- form:m +:: +;< [our=ship syd=desk =case:clay] bind:m get-beak:strandio +=/ now=@da ?>(?=(%da -.case) p.case) +:: +;< ~ bind:m + %- send-raw-card:strandio + =- [%pass /tmp-desks %arvo %c %info %base %& -] + ^- soba:clay + %+ turn desks + |= =desk + [/tmp/[desk]/jam %ins %jam %noun (jam-desk:jammer our desk now)] +:: +(pure:m !>(ok=&)) diff --git a/pkg/arvo/ted/ph/add.hoon b/pkg/arvo/ted/ph/add.hoon index e5507cbee..3a0004c05 100644 --- a/pkg/arvo/ted/ph/add.hoon +++ b/pkg/arvo/ted/ph/add.hoon @@ -5,8 +5,8 @@ |= args=vase =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) +;< ~ bind:m (init-ship ~bud &) ;< ~ bind:m (dojo ~bud "[%test-result (add 2 3)]") ;< ~ bind:m (wait-for-output ~bud "[%test-result 5]") -;< ~ bind:m end-simple +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/boot-az.hoon b/pkg/arvo/ted/ph/boot-az.hoon index a430d620f..44a012e64 100644 --- a/pkg/arvo/ted/ph/boot-az.hoon +++ b/pkg/arvo/ted/ph/boot-az.hoon @@ -4,8 +4,8 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m end-azimuth +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/boot-planet.hoon b/pkg/arvo/ted/ph/boot-planet.hoon index 2b4937154..c5042c872 100644 --- a/pkg/arvo/ted/ph/boot-planet.hoon +++ b/pkg/arvo/ted/ph/boot-planet.hoon @@ -5,8 +5,8 @@ |= vase =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) -;< ~ bind:m (raw-ship ~marbud ~) -;< ~ bind:m (raw-ship ~linnup-torsyx ~) -;< ~ bind:m end-simple +;< ~ bind:m (init-ship ~bud &) +;< ~ bind:m (init-ship ~marbud &) +;< ~ bind:m (init-ship ~linnup-torsyx &) +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/breach-hi-aqua.hoon b/pkg/arvo/ted/ph/breach-hi-aqua.hoon index 473ddb846..8b8d70f3c 100644 --- a/pkg/arvo/ted/ph/breach-hi-aqua.hoon +++ b/pkg/arvo/ted/ph/breach-hi-aqua.hoon @@ -1,19 +1,19 @@ /- spider -/+ *ph-io, *ph-util +/+ *ph-io, *ph-util, strandio =, strand=strand:spider ^- thread:spider |= vase =/ m (strand ,vase) ;< =bowl:spider bind:m get-bowl -;< ~ bind:m start-simple -;< ~ bind:m init-azimuth -;< ~ bind:m (spawn-aqua ~bud) -;< ~ bind:m (spawn-aqua ~dev) -;< ~ bind:m (init-ship ~bud) -;< ~ bind:m (init-ship ~dev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~dev |) +;< ~ bind:m (sleep:strandio ~s10) ;< ~ bind:m (send-hi ~bud ~dev) -;< ~ bind:m (breach-and-hear-aqua ~dev ~bud) +;< ~ bind:m (breach-and-hear ~dev ~bud) ;< ~ bind:m (send-hi-not-responding ~bud ~dev) -;< ~ bind:m (init-ship ~dev) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (wait-for-output ~bud "hi ~dev successful") (pure:m *vase) diff --git a/pkg/arvo/ted/ph/breach-hi-cousin.hoon b/pkg/arvo/ted/ph/breach-hi-cousin.hoon index 5984913e7..d2f4dd658 100644 --- a/pkg/arvo/ted/ph/breach-hi-cousin.hoon +++ b/pkg/arvo/ted/ph/breach-hi-cousin.hoon @@ -8,20 +8,19 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m - start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~mardev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~dev) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~mardev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~mardev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~dev |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~mardev |) ;< ~ bind:m (send-hi ~marbud ~mardev) -;< ~ bind:m (breach-and-hear az ~mardev ~marbud) +;< ~ bind:m (breach-and-hear ~mardev ~marbud) ;< ~ bind:m (send-hi-not-responding ~marbud ~mardev) -;< ~ bind:m (real-ship az ~mardev) +;< ~ bind:m (init-ship ~mardev |) ;< ~ bind:m (wait-for-output ~marbud "hi ~mardev successful") -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/breach-hi.hoon b/pkg/arvo/ted/ph/breach-hi.hoon index 2c484a602..e25553088 100644 --- a/pkg/arvo/ted/ph/breach-hi.hoon +++ b/pkg/arvo/ted/ph/breach-hi.hoon @@ -4,16 +4,15 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m - start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (send-hi ~bud ~dev) -;< ~ bind:m (breach-and-hear az ~dev ~bud) +;< ~ bind:m (breach-and-hear ~dev ~bud) ;< ~ bind:m (send-hi-not-responding ~bud ~dev) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (wait-for-output ~bud "hi ~dev successful") -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/breach-multiple.hoon b/pkg/arvo/ted/ph/breach-multiple.hoon index d486f9d43..33eca2ea8 100644 --- a/pkg/arvo/ted/ph/breach-multiple.hoon +++ b/pkg/arvo/ted/ph/breach-multiple.hoon @@ -6,19 +6,19 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< file=@t bind:m (touch-file ~bud %kids %foo) -;< ~ bind:m (check-file-touched ~marbud %home file) -;< ~ bind:m (breach-and-hear az ~bud ~marbud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (breach-and-hear az ~marbud ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< file=@t bind:m (touch-file ~bud %kids %bar) -;< file=@t bind:m (touch-file ~bud %kids %baz) -;< ~ bind:m (check-file-touched ~marbud %home file) -;< ~ bind:m end-azimuth +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< file=@t bind:m (touch-file ~bud %kids %foo) +;< ~ bind:m (check-file-touched ~marbud %home file) +;< ~ bind:m (breach-and-hear ~bud ~marbud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (breach-and-hear ~marbud ~bud) +;< ~ bind:m (init-ship ~marbud |) +;< file=@t bind:m (touch-file ~bud %kids %bar) +;< file=@t bind:m (touch-file ~bud %kids %baz) +;< ~ bind:m (check-file-touched ~marbud %home file) +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/breach-sudden.hoon b/pkg/arvo/ted/ph/breach-sudden.hoon index ba03c2168..6e1c91ece 100644 --- a/pkg/arvo/ted/ph/breach-sudden.hoon +++ b/pkg/arvo/ted/ph/breach-sudden.hoon @@ -8,19 +8,19 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< file=@t bind:m (touch-file ~bud %kids %foo) -;< ~ bind:m (check-file-touched ~marbud %home file) -;< ~ bind:m (breach az ~bud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< file=@t bind:m (touch-file ~bud %kids %foo) +;< ~ bind:m (check-file-touched ~marbud %home file) +;< ~ bind:m (breach ~bud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (dojo ~bud "|merge %home ~marbud %kids, =gem %only-this") -;< file=@t bind:m (touch-file ~bud %kids %bar) -;< file=@t bind:m (touch-file ~bud %kids %baz) -;< ~ bind:m (check-file-touched ~marbud %home file) -;< ~ bind:m end-azimuth +;< file=@t bind:m (touch-file ~bud %kids %bar) +;< file=@t bind:m (touch-file ~bud %kids %baz) +;< ~ bind:m (check-file-touched ~marbud %home file) +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/breach-sync.hoon b/pkg/arvo/ted/ph/breach-sync.hoon index 5464594bc..e40cf9f68 100644 --- a/pkg/arvo/ted/ph/breach-sync.hoon +++ b/pkg/arvo/ted/ph/breach-sync.hoon @@ -6,23 +6,23 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) ;< file=@t bind:m (touch-file ~bud %kids %foo) ;< ~ bind:m (check-file-touched ~marbud %home file) :: Merge so that when we unify history with the %only-this merge later, we :: don't get a spurious conflict in %home :: ;< ~ bind:m (dojo ~marbud "|merge %kids our %home") -;< ~ bind:m (breach-and-hear az ~bud ~marbud) -;< ~ bind:m (real-ship az ~bud) +;< ~ bind:m (breach-and-hear ~bud ~marbud) +;< ~ bind:m (init-ship ~bud |) ;< ~ bind:m (dojo ~bud "|merge %kids ~marbud %kids, =gem %only-this") ;< file=@t bind:m (touch-file ~bud %kids %bar) ;< file=@t bind:m (touch-file ~bud %kids %baz) ;< ~ bind:m (check-file-touched ~marbud %home file) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/change-file.hoon b/pkg/arvo/ted/ph/change-file.hoon index cfbf3ab24..34b3b4d4e 100644 --- a/pkg/arvo/ted/ph/change-file.hoon +++ b/pkg/arvo/ted/ph/change-file.hoon @@ -5,8 +5,8 @@ |= vase =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) +;< ~ bind:m (init-ship ~bud &) ;< file=@t bind:m (touch-file ~bud %home %foo) ;< ~ bind:m (check-file-touched ~bud %home file) -;< ~ bind:m end-simple +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/child-sync.hoon b/pkg/arvo/ted/ph/child-sync.hoon index 381a67064..1d67a4e51 100644 --- a/pkg/arvo/ted/ph/child-sync.hoon +++ b/pkg/arvo/ted/ph/child-sync.hoon @@ -5,10 +5,10 @@ |= vase =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) -;< ~ bind:m (raw-ship ~marbud ~) +;< ~ bind:m (init-ship ~bud &) +;< ~ bind:m (init-ship ~marbud &) ;< file=@t bind:m (touch-file ~bud %home %foo) ;< ~ bind:m (dojo ~bud "|merge %kids our %home") ;< ~ bind:m (check-file-touched ~marbud %home file) -;< ~ bind:m end-simple +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/child-update.hoon b/pkg/arvo/ted/ph/child-update.hoon index d505e74ea..e377aed6e 100644 --- a/pkg/arvo/ted/ph/child-update.hoon +++ b/pkg/arvo/ted/ph/child-update.hoon @@ -6,12 +6,12 @@ |^ =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) -;< ~ bind:m (raw-ship ~marbud ~) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) ;< [path @t] bind:m (modify ~bud %home) ;< [=path file=@t] bind:m (modify ~bud %kids) ;< ~ bind:m (check-touched ~marbud %kids path file) -;< ~ bind:m end-simple +;< ~ bind:m end (pure:m *vase) :: ++ modify diff --git a/pkg/arvo/ted/ph/group-rejoin.hoon b/pkg/arvo/ted/ph/group-rejoin.hoon index 9fcf2e8ac..c2e7c272d 100644 --- a/pkg/arvo/ted/ph/group-rejoin.hoon +++ b/pkg/arvo/ted/ph/group-rejoin.hoon @@ -42,27 +42,26 @@ ^- thread:spider |= args=vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~zod) -;< ~ bind:m (spawn az ~marzod) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~zod) +;< ~ bind:m (spawn ~marzod) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) ;< ~ bind:m (wait-for-goad ~marbud) -;< ~ bind:m (real-ship az ~zod) -;< ~ bind:m (real-ship az ~marzod) +;< ~ bind:m (init-ship ~zod |) +;< ~ bind:m (init-ship ~marzod |) ;< ~ bind:m (wait-for-goad ~marzod) ;< ~ bind:m (start-group-agents ~marbud) ;< ~ bind:m (start-group-agents ~marzod) ;< ~ bind:m (dojo ~marbud ":group-store|create 'test-group'") ;< ~ bind:m (wait-for-output ~marbud ">=") ;< ~ bind:m (sleep ~s1) -;< ~ bind:m (breach-and-hear az ~marzod ~marbud) -;< ~ bind:m (real-ship az ~marzod) +;< ~ bind:m (breach-and-hear ~marzod ~marbud) +;< ~ bind:m (init-ship ~marzod |) ;< ~ bind:m (wait-for-goad ~marzod) ;< ~ bind:m (start-group-agents ~marzod) ;< ~ bind:m (sleep ~s3) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-az.hoon b/pkg/arvo/ted/ph/hi-az.hoon index b5354cdea..5133e1222 100644 --- a/pkg/arvo/ted/ph/hi-az.hoon +++ b/pkg/arvo/ted/ph/hi-az.hoon @@ -4,12 +4,11 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (send-hi ~bud ~dev) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-comet-az.hoon b/pkg/arvo/ted/ph/hi-comet-az.hoon index 5b82b5e71..9e4eb737b 100644 --- a/pkg/arvo/ted/ph/hi-comet-az.hoon +++ b/pkg/arvo/ted/ph/hi-comet-az.hoon @@ -5,22 +5,21 @@ |= vase =/ m (strand ,vase) =/ comet ~bosrym-podwyl-magnes-dacrys--pander-hablep-masrym-marbud -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (real-ship az ~bud) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (init-ship ~bud |) :: -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (real-ship az ~marbud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (init-ship ~marbud |) :: -;< ~ bind:m (real-ship az comet) -;< ~ bind:m (send-hi comet ~bud) +;< ~ bind:m (init-ship comet |) +;< ~ bind:m (send-hi comet ~bud) :: -;< ~ bind:m (spawn az ~linnup-torsyx) -;< ~ bind:m (real-ship az ~linnup-torsyx) +;< ~ bind:m (spawn ~linnup-torsyx) +;< ~ bind:m (init-ship ~linnup-torsyx |) :: ;< ~ bind:m (send-hi comet ~linnup-torsyx) ;< ~ bind:m (send-hi ~linnup-torsyx comet) :: -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-cousin-az.hoon b/pkg/arvo/ted/ph/hi-cousin-az.hoon index 7facac1aa..c7010cbdc 100644 --- a/pkg/arvo/ted/ph/hi-cousin-az.hoon +++ b/pkg/arvo/ted/ph/hi-cousin-az.hoon @@ -4,16 +4,15 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (spawn az ~mardev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~dev) -;< ~ bind:m (real-ship az ~mardev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (spawn ~mardev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~dev |) +;< ~ bind:m (init-ship ~mardev |) ;< ~ bind:m (send-hi ~mardev ~marbud) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-linnup-az-backward.hoon b/pkg/arvo/ted/ph/hi-linnup-az-backward.hoon index e072f801a..a7052138d 100644 --- a/pkg/arvo/ted/ph/hi-linnup-az-backward.hoon +++ b/pkg/arvo/ted/ph/hi-linnup-az-backward.hoon @@ -4,14 +4,13 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~linnup-torsyx) -;< ~ bind:m (real-ship az ~linnup-torsyx) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~bud) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~linnup-torsyx) +;< ~ bind:m (init-ship ~linnup-torsyx |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~bud |) ;< ~ bind:m (send-hi ~linnup-torsyx ~marbud) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-linnup-az.hoon b/pkg/arvo/ted/ph/hi-linnup-az.hoon index abcfd4151..cdea3c006 100644 --- a/pkg/arvo/ted/ph/hi-linnup-az.hoon +++ b/pkg/arvo/ted/ph/hi-linnup-az.hoon @@ -4,14 +4,13 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~linnup-torsyx) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~linnup-torsyx) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~linnup-torsyx) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~linnup-torsyx |) ;< ~ bind:m (send-hi ~linnup-torsyx ~marbud) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-marbud-az.hoon b/pkg/arvo/ted/ph/hi-marbud-az.hoon index a53d81a85..010e27445 100644 --- a/pkg/arvo/ted/ph/hi-marbud-az.hoon +++ b/pkg/arvo/ted/ph/hi-marbud-az.hoon @@ -4,12 +4,11 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) ;< ~ bind:m (send-hi ~bud ~marbud) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-nephew-az.hoon b/pkg/arvo/ted/ph/hi-nephew-az.hoon index 286367edd..dbe1a5fba 100644 --- a/pkg/arvo/ted/ph/hi-nephew-az.hoon +++ b/pkg/arvo/ted/ph/hi-nephew-az.hoon @@ -4,14 +4,13 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (send-hi ~dev ~marbud) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi-uncle-az.hoon b/pkg/arvo/ted/ph/hi-uncle-az.hoon index c73b10cb4..f3a004044 100644 --- a/pkg/arvo/ted/ph/hi-uncle-az.hoon +++ b/pkg/arvo/ted/ph/hi-uncle-az.hoon @@ -4,14 +4,13 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (send-hi ~marbud ~dev) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/hi.hoon b/pkg/arvo/ted/ph/hi.hoon index 1c2b0db91..02ecd1b8f 100644 --- a/pkg/arvo/ted/ph/hi.hoon +++ b/pkg/arvo/ted/ph/hi.hoon @@ -5,9 +5,9 @@ |= vase =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) -;< ~ bind:m (raw-ship ~dev ~) -;< ~ bind:m (raw-ship ~dev ~) +;< ~ bind:m (init-ship ~bud &) +;< ~ bind:m (init-ship ~dev &) +;< ~ bind:m (init-ship ~dev &) ;< ~ bind:m (send-hi ~bud ~dev) -;< ~ bind:m end-simple +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/lib-hooks.hoon b/pkg/arvo/ted/ph/lib-hooks.hoon index 1f2aa5966..77d357a79 100644 --- a/pkg/arvo/ted/ph/lib-hooks.hoon +++ b/pkg/arvo/ted/ph/lib-hooks.hoon @@ -1,6 +1,7 @@ /- spider -/+ *ph-io, *strandio +/+ io=ph-io, *strandio => +=, io |% ++ strand strand:spider ++ start-agents @@ -27,12 +28,11 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider - bind:m start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (start-agents ~bud) ;< ~ bind:m (start-agents ~dev) ;< ~ bind:m (send-hi ~bud ~dev) @@ -61,5 +61,6 @@ ;< ~ bind:m (dojo ~dev ":graph-store +dbug") ;< ~ bind:m (dojo ~bud ":graph-push-hook +dbug %bowl") ;< ~ bind:m (dojo ~bud ":graph-store +dbug") -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) +::(pure:m *vase) diff --git a/pkg/arvo/ted/ph/migrate/end.hoon b/pkg/arvo/ted/ph/migrate/end.hoon new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/arvo/ted/ph/migrate/make-groups.hoon b/pkg/arvo/ted/ph/migrate/make-groups.hoon new file mode 100644 index 000000000..4e814ddae --- /dev/null +++ b/pkg/arvo/ted/ph/migrate/make-groups.hoon @@ -0,0 +1,49 @@ +/- spider, + graph-store, + graph-view, + post, + *resource, + *group +/+ *ph-io, strandio +=, strand=strand:spider +=> +|% +:: +++ create-group + |= our=@p + %^ dojo-thread our %group-create + :- %group-view-action + :* %create + %group-1 + [%open ~ ~] + 'Test Group' + 'A description' + == +:: +++ join-group + |= our=@p + %^ poke-app our %group-view + :- %group-view-action + :* %join + [~zod %group-1] + ~zod + == +-- +:: +^- thread:spider +|= vase +=/ m (strand ,vase) +;< ~ bind:m start-simple +;< ~ bind:m (create-group ~zod) +;< ~ bind:m (join-group ~bus) +;< ~ bind:m (join-group ~web) +;< ~ bind:m (send-hi ~zod ~bus) +;< ~ bind:m (send-hi ~zod ~web) +;< ~ bind:m (send-hi ~bus ~zod) +;< ~ bind:m (send-hi ~bus ~web) +;< ~ bind:m (send-hi ~web ~zod) +;< ~ bind:m (send-hi ~web ~bus) +(pure:m *vase) + + + diff --git a/pkg/arvo/ted/ph/migrate/setup.hoon b/pkg/arvo/ted/ph/migrate/setup.hoon new file mode 100644 index 000000000..71b420b90 --- /dev/null +++ b/pkg/arvo/ted/ph/migrate/setup.hoon @@ -0,0 +1,38 @@ +/- spider, + graph-store, + graph-view, + post, + *resource, + *group +/+ *ph-io, strandio +=, strand=strand:spider +=> +|% +:: +++ create-group + |= our=@p + %^ dojo-thread our %group-create + :- %group-view-action + :* %create + %group-1 + [%open ~ ~] + 'Test Group' + 'A description' + == +:: +++ hang + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + `[%wait ~] +-- +:: +^- thread:spider +|= vase +=/ m (strand ,vase) +;< ~ bind:m start-simple +;< ~ bind:m hang +(pure:m *vase) + + + diff --git a/pkg/arvo/ted/ph/migrate/wait.hoon b/pkg/arvo/ted/ph/migrate/wait.hoon new file mode 100644 index 000000000..7eda30b9c --- /dev/null +++ b/pkg/arvo/ted/ph/migrate/wait.hoon @@ -0,0 +1,42 @@ +/- spider, + graph-store, + graph-view, + post, + *resource, + *group +/+ *ph-io, strandio +=, strand=strand:spider +=> +|% +:: +++ create-group + |= our=@p + %^ dojo-thread our %group-create + :- %group-view-action + :* %create + %group-1 + [%open ~ ~] + 'Test Group' + 'A description' + == +:: +++ join-group + |= our=@p + %^ poke-app our %group-view + :- %group-view-action + :* %join + [~zod %group-1] + ~zod + == +-- +:: +^- thread:spider +|= vase +=/ m (strand ,vase) +;< ~ bind:m start-simple +;< ~ bind:m (sleep ~s10) +;< ~ bind:m end +(pure:m *vase) + + + diff --git a/pkg/arvo/ted/ph/moon-az.hoon b/pkg/arvo/ted/ph/moon-az.hoon index 4cfcbb601..22a077941 100644 --- a/pkg/arvo/ted/ph/moon-az.hoon +++ b/pkg/arvo/ted/ph/moon-az.hoon @@ -4,20 +4,19 @@ ^- thread:spider |= vase =/ m (strand ,vase) -;< az=tid:spider bind:m - start-azimuth -;< ~ bind:m (spawn az ~bud) -;< ~ bind:m (spawn az ~marbud) -;< ~ bind:m (spawn az ~linnup-torsyx) -;< ~ bind:m (spawn az ~dev) -;< ~ bind:m (real-ship az ~bud) -;< ~ bind:m (real-ship az ~marbud) -;< ~ bind:m (real-ship az ~linnup-torsyx) -;< ~ bind:m (real-ship az ~linnup-torsyx-linnup-torsyx) +;< ~ bind:m start-azimuth +;< ~ bind:m (spawn ~bud) +;< ~ bind:m (spawn ~marbud) +;< ~ bind:m (spawn ~linnup-torsyx) +;< ~ bind:m (spawn ~dev) +;< ~ bind:m (init-ship ~bud |) +;< ~ bind:m (init-ship ~marbud |) +;< ~ bind:m (init-ship ~linnup-torsyx |) +;< ~ bind:m (init-ship ~linnup-torsyx-linnup-torsyx |) ;< ~ bind:m (send-hi ~bud ~linnup-torsyx-linnup-torsyx) ;< ~ bind:m (send-hi ~linnup-torsyx-linnup-torsyx ~marbud) -;< ~ bind:m (real-ship az ~dev) +;< ~ bind:m (init-ship ~dev |) ;< ~ bind:m (send-hi ~linnup-torsyx-linnup-torsyx ~dev) ;< ~ bind:m (send-hi ~dev ~linnup-torsyx-linnup-torsyx) -;< ~ bind:m end-azimuth +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/ph/second-cousin-hi.hoon b/pkg/arvo/ted/ph/second-cousin-hi.hoon index 60f18b96c..02e7a3b22 100644 --- a/pkg/arvo/ted/ph/second-cousin-hi.hoon +++ b/pkg/arvo/ted/ph/second-cousin-hi.hoon @@ -5,12 +5,12 @@ |= vase =/ m (strand ,vase) ;< ~ bind:m start-simple -;< ~ bind:m (raw-ship ~bud ~) -;< ~ bind:m (raw-ship ~marbud ~) -;< ~ bind:m (raw-ship ~linnup-torsyx ~) -;< ~ bind:m (raw-ship ~dev ~) -;< ~ bind:m (raw-ship ~mardev ~) -;< ~ bind:m (raw-ship ~mitnep-todsut ~) +;< ~ bind:m (init-ship ~bud &) +;< ~ bind:m (init-ship ~marbud &) +;< ~ bind:m (init-ship ~linnup-torsyx &) +;< ~ bind:m (init-ship ~dev &) +;< ~ bind:m (init-ship ~mardev &) +;< ~ bind:m (init-ship ~mitnep-todsut &) ;< ~ bind:m (send-hi ~linnup-torsyx ~mitnep-todsut) -;< ~ bind:m end-simple +;< ~ bind:m end (pure:m *vase) diff --git a/pkg/arvo/ted/aggregator/nonce.hoon b/pkg/arvo/ted/roller/nonce.hoon similarity index 100% rename from pkg/arvo/ted/aggregator/nonce.hoon rename to pkg/arvo/ted/roller/nonce.hoon diff --git a/pkg/arvo/ted/aggregator/send.hoon b/pkg/arvo/ted/roller/send.hoon similarity index 76% rename from pkg/arvo/ted/aggregator/send.hoon rename to pkg/arvo/ted/roller/send.hoon index 51f0d4e1f..443f0cb5f 100644 --- a/pkg/arvo/ted/aggregator/send.hoon +++ b/pkg/arvo/ted/roller/send.hoon @@ -1,6 +1,6 @@ -:: aggregator/send: send rollup tx +:: roller/send: send rollup tx :: -/- rpc=json-rpc, *aggregator +/- rpc=json-rpc, *dice /+ naive, ethereum, ethio, strandio :: :: @@ -9,7 +9,7 @@ =/ m (strand:strandio ,vase) |^ ^- form:m -=* not-sent (pure:m !>(%.y^next-gas-price)) +:: =* not-sent (pure:m !>(%.n^next-gas-price)) :: =/ =address:ethereum (address-from-prv:key:ethereum pk) ;< expected-nonce=@ud bind:m @@ -17,7 +17,8 @@ :: if chain expects a different nonce, don't send this transaction :: ?. =(nonce expected-nonce) - not-sent + ~& [%unexpected-nonce nonce expected+expected-nonce] + (pure:m !>(%.n^[%not-sent %unexpected-nonce])) :: if a gas-price of 0 was specified, fetch the recommended one :: ;< use-gas-price=@ud bind:m @@ -26,12 +27,15 @@ :: =/ batch-data=octs %+ cad:naive 3 + %- flop %+ roll txs |= [=raw-tx:naive out=(list octs)] - %+ weld - out - :_ [raw.raw-tx ~] - (met 3 sig.raw-tx)^sig.raw-tx + [raw.raw-tx 65^sig.raw-tx out] +:: TODO: keep this to avoid sending bad batches or disregard? +:: +?~ (parse-roll:naive q.batch-data) + (pure:m !>(%.n^[%not-sent %batch-parse-error])) +:: :: each l2 signature is 65 bytes + XX bytes for the raw data :: from the ethereum yellow paper: :: gasLimit = G_transaction + G_txdatanonzero × dataByteLength @@ -49,8 +53,7 @@ ;< balance=@ud bind:m (get-balance:ethio endpoint address) ?: (gth max-cost balance) - ~& [%insufficient-aggregator-balance address] - not-sent + (pure:m !>(%.n^[%not-sent %insufficient-roller-balance])) :: ::NOTE this fails the thread if sending fails, which in the app gives us :: the "retry with same gas price" behavior we want @@ -66,14 +69,18 @@ q.batch-data chain-id == +:: log batch tx-hash to getTransactionReceipt(tx-hash) +:: +~? &(?=(%result -.response) ?=(%s -.res.response)) + ^-([nonce=@ud batch-hash=@t] nonce^(so:dejs:format res.response)) %- pure:m -!> ^- (each @ud @t) -?+ -.response %.n^'unexpected rpc response' - %error %.n^message.response - :: TODO: - :: check that tx-hash in +.response is non-zero? - :: log tx-hash to getTransactionReceipt(tx-hash)? - :: enforce max here, or in app? +!> ^- (each @ud [term @t]) +:: TODO: capture if the tx fails (e.g. Runtime Error: revert) +:: check that tx-hash in +.response is non-zero? +:: enforce max here, or in app? +:: +?+ -.response %.n^[%error 'unexpected rpc response'] + %error %.n^[%error message.response] :: add five gwei to gas price of next attempt :: %result %.y^(add use-gas-price 5.000.000.000) diff --git a/pkg/arvo/ted/rpc.hoon b/pkg/arvo/ted/rpc.hoon deleted file mode 100644 index 3e037bf9b..000000000 --- a/pkg/arvo/ted/rpc.hoon +++ /dev/null @@ -1,13 +0,0 @@ -/- spider, rpc=json-rpc -/+ strandio, bcu=bitcoin-utils -=, strand=strand:spider -=> -|% -++ blah 2 --- -^- thread:spider -|= arg=vase -:: =+ !<([~ a=@ud] arg) -=/ m (strand ,vase) -^- form:m -(pure:m !>(blah)) diff --git a/pkg/arvo/ted/test.hoon b/pkg/arvo/ted/test.hoon index a25496fc2..43a81700c 100644 --- a/pkg/arvo/ted/test.hoon +++ b/pkg/arvo/ted/test.hoon @@ -66,7 +66,7 @@ =/ fire-arm=nock ~| [%failed-to-compile-test-arm name] q:(~(mint ut typ) p:!>(*tang) [%limb name]) - [name |.(;;(tang .*(cor fire-arm)))] + [name |.(;;(tang ~>(%bout.[1 name] .*(cor fire-arm))))] :: +has-test-prefix: does the arm define a test we should run? :: ++ has-test-prefix diff --git a/pkg/arvo/ted/work.hoon b/pkg/arvo/ted/work.hoon index 798511ee4..150e145d1 100644 --- a/pkg/arvo/ted/work.hoon +++ b/pkg/arvo/ted/work.hoon @@ -11,7 +11,7 @@ |= arg=vase =/ m (strand ,vase) ^- form:m -=+ !<(desks=(list desk) arg) +=+ !<([~ desks=(list desk)] arg) =? desks =(~ desks) [%work]~ |- ^- form:m =* loop $ diff --git a/pkg/arvo/tests/lib/ethereum/rlp.hoon b/pkg/arvo/tests/lib/ethereum/rlp.hoon index 802c5320a..f2d5ea58e 100644 --- a/pkg/arvo/tests/lib/ethereum/rlp.hoon +++ b/pkg/arvo/tests/lib/ethereum/rlp.hoon @@ -36,6 +36,14 @@ :+ "set of three" 0xc7c0.c1c0.c3c0.c1c0 l+[l+~ l+[l+~ ~] l+[l+~ l+[l+~ ~] ~] ~] + :: + :+ "list with zero byte" + 0xc311.0022 + l+~[b+1^0x11 b+1^0x0 b+1^0x22] + :: + :+ "list of zero bytes" + 0xc300.0000 + l+~[b+1^0x0 b+1^0x0 b+1^0x0] == :: |% @@ -48,8 +56,8 @@ %+ weld %+ category "encode" %+ expect-eq - !> dat - !> (encode rlp) + !> `@ux`dat + !> `@ux`(encode rlp) %+ category "decode" %+ expect-eq !> rlp diff --git a/pkg/arvo/tests/lib/ethereum/signing.hoon b/pkg/arvo/tests/lib/ethereum/signing.hoon index fc4cc61c1..94f0954c7 100644 --- a/pkg/arvo/tests/lib/ethereum/signing.hoon +++ b/pkg/arvo/tests/lib/ethereum/signing.hoon @@ -51,4 +51,103 @@ dcf7.12fc.3667.bb5a.cb13.94a0.382f.0c95.7ef4. 20dd.dfaa.e6f8.beaa.09c1.f162.a5a8.37a3.7237. 77c2.9c6a.7a05.65a5 +:: +++ test-signing-transaction-to-zero + %+ expect-eq + !> %+ sign-typed-transaction:key:ethereum + :- %0x0 + :* 14 + 5.000.000.000 + 21.000 + 0x0 + 100.000.000.000.000.000 + 0x0 + 0x3 + == + 0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459. + c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058 + !> 0xf86c.0e85.012a.05f2.0082.5208.9400.0000.0000. + 0000.0000.0000.0000.0000.0000.0000.0088.0163. + 4578.5d8a.0000.8029.a0f6.9c2c.fb99.2673.928e. + 9fdd.5056.487d.3664.48e3.37c3.c024.4187.544a. + 231e.c67a.98a0.0d6d.eb23.173b.26eb.62c7.3ad2. + 3bc2.afb9.efac.6879.f6b2.8063.f686.586e.31da. + 2343 +:: +++ test-signing-transaction-1559 + %+ expect-eq + !> 0x2f8.7303.0b84.3b9a.ca00.8501.2a05.f200.8252. + 0894.24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2. + c4c2.7a17.8801.6345.785d.8a00.0080.c080.a05d. + dc02.7d72.48d2.d542.75c7.3f1b.5bac.edd6.5af9. + d136.5829.e637.7473.1ebf.5ca6.86a0.404b.71cc. + a3d0.409f.dd84.9857.fb15.0f7d.f943.9fca.c425. + c141.236a.a963.6528.2bb5 + !> %+ sign-typed-transaction:key:ethereum + :- %0x2 + :* 0x3 + 11 + 1.000.000.000 + 5.000.000.000 + 21.000 + 0x24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.c4c2.7a17 + 100.000.000.000.000.000 + 0x0 + ~ + == + 0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459. + c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058 +:: +++ test-signing-transaction-1559-access-list + %+ expect-eq + !> 0x2.f8ac.030c.8477.3594.0085.0254.0be4.0082. + 7530.9424.f963.d69f.36d5.1cc4.0d52.082d.4978. + d2c4.c27a.1788.0163.4578.5d8a.0000.80f8.38f7. + 9424.f963.d69f.36d5.1cc4.0d52.082d.4978.d2c4. + c27a.17e1.a000.0000.0000.0000.0000.0000.0000. + 0000.0000.0000.0000.0000.0000.0000.0000.0000. + 0101.a015.5039.4a51.0a1a.601a.54fb.147d.e17f. + a6b9.bd41.9bdb.1654.de06.b7bc.3481.f67e.4ba0. + 4e88.0574.d378.6ede.1de2.586a.fe98.e30f.d63c. + ef3b.e31c.76a9.a0bd.66a8.aef7.8191 + !> %+ sign-typed-transaction:key:ethereum + :- %0x2 + :* 0x3 + 12 + 2.000.000.000 + 10.000.000.000 + 30.000 + 0x24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.c4c2.7a17 + 100.000.000.000.000.000 + 0x0 + %+ ~(add ja *(jar address:ethereum @ux)) + 0x24f9.63d6.9f36.d51c.c40d.5208.2d49.78d2.c4c2.7a17 + 0x1 + == + 0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459. + c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058 +:: +++ test-signing-transaction-1559-to-zero + %+ expect-eq + !> 0x2f8.7303.0f84.3b9a.ca00.8501.2a05.f200.8252. + 0894.0000.0000.0000.0000.0000.0000.0000.0000. + 0000.0000.8801.6345.785d.8a00.0080.c080.a0c5. + 43ea.1ee9.04d1.5f9f.d23d.e881.672f.06f3.41e2. + 69e0.fedc.1ed0.4f0b.20f0.1679.06a0.442e.fe89. + 1bb6.48cf.d39b.20aa.5b1f.8a16.7be2.0ee2.d45b. + 3d3d.7b0a.bce5.1dc7.1232 + !> %+ sign-typed-transaction:key:ethereum + :- %0x2 + :* 0x3 + 15 + 1.000.000.000 + 5.000.000.000 + 21.000 + 0x0 + 100.000.000.000.000.000 + 0x0 + ~ + == + 0x7f50.12dc.a92e.4aef.d3e1.a9f7.e761.f459. + c350.74e0.2f0c.93eb.5bb2.dafb.f5ea.8058 -- diff --git a/pkg/arvo/tests/lib/naive.hoon b/pkg/arvo/tests/lib/naive.hoon index ea1801b15..aa107df84 100644 --- a/pkg/arvo/tests/lib/naive.hoon +++ b/pkg/arvo/tests/lib/naive.hoon @@ -1,16 +1,37 @@ /+ *test, naive, ethereum, azimuth, *naive-transactions :: |% -++ n |=([=^state:naive =^input:naive] (%*(. naive lac |) verifier 1.337 +<)) +:: This gate passes a state and input to naive.hoon for both L1 and L2 +:: transactions. Every transaction implemented in this test suite utilizes it. :: +++ n + |= [=^state:naive input=_+:*^input:naive] + (%*(. naive lac &) verifier 1.337 state 0 input) +:: +++ orm ((on ship point:naive) por:naive) ++ addr address-from-prv:key:ethereum :: -++ log - |= [log-name=@ux data=@ux topics=(lest @)] - ^- ^input:naive - [%log *@ux data log-name topics] +:: The next section of this core generates "universes" of Azimuth points, each +:: of which is intended for particular test(s). There are more of these +:: than strictly necessary - we utilize different galaxies/etc to perform +:: different kinds of tests, and using different @p's helps to remember +:: what the galaxy was set up to test when reading the tests. :: -:: ~bud is so that we aren't testing something impossible in Azimuth, like a star spawned before its sponsor galaxy +:: ~zod is for testing potential padding issues caused by leading or trailing +:: zeroes. +:: +++ init-zod + |= =^state:naive + ^- [effects:naive ^state:naive] + =^ f1 state (n state (owner-changed:l1 ~zod (addr %zod-key-0))) + =^ f2 state (n state (owner-changed:l1 ~dopzod (addr %dopzod-key-0))) + =^ f3 state (n state (changed-spawn-proxy:l1 ~zod (addr %zod-skey-0))) + =^ f4 state (n state (changed-spawn-proxy:l1 ~zod deposit-address:naive)) + =^ f5 state (n state (owner-changed:l1 ~dopzod deposit-address:naive)) + [:(welp f1 f2 f3 f4 f5) state] +:: +:: ~bud is so that we aren't testing something impossible in Azimuth, like a +:: star spawned before its sponsor galaxy :: ++ init-bud |= =^state:naive @@ -24,106 +45,207 @@ ^- [effects:naive ^state:naive] (n state (owner-changed:l1 ~wes (addr %wes-key-0))) :: -:: ~rut is for "full testing" -:: ~rigrut is L1 star -:: ~larsyx-mapmeg is L1 planet under ~rigrut -:: ~holrut is L1 star w/ L2 spawn proxy -:: ~rabsum-ravtyd is L1 planet under ~holrut -:: ~dovmul-mogryt is L2 planet under ~holrut made w/ %own proxy -:: ~pidted-dacnum is L2 planet under ~holrut made w/ %spawn proxy predeposited -:: TODO: L2 planet ~nacbes-mogmev made with L2 spawn proxy postdeposited (currently doesnt work) +:: ~rut and the accompanying points beneath is for testing nearly every +:: sort of properly-formed L2 transactions unrelated to sponsorship +:: actions, each submitted as a single-transaction batch. In particular +:: it tests %transfer-point, %configure-keys, %spawn, %set-management-proxy +:: %set-spawn-proxy, and %set-transfer-proxy. See +test-rut for more +:: information. :: -:: ~losrut is L2 star -:: ~radres-tinnyl is L1 planet under ~losrut -:: ~pinpun-pilsun is L2 planet under ~losrut made w/ %own proxy -:: ~habtyc-nibpyx is L2 planet under ~losrut made w/ %spawn proxy predeposited -:: ~disryt-nolpet is L2 planet under ~losrut made w/ %spawn proxy postdeposited +:: ~rut is %l1 galaxy +:: ~tyl is %spawn galxy :: -:: nonces in the end state (0 if not stated): -:: ~holrut %own 1 -:: ~losrut %own 2 -:: ~losrut %spawn 1 +:: ~rigrut is %l1 star +:: ~larsyx-mapmeg is %l1 planet under ~rigrut +:: ~holrut is %spawn star +:: ~rabsum-ravtyd is %l1 planet under ~holrut +:: ~dovmul-mogryt is %l2 planet under ~holrut made w/ %own proxy +:: ~pidted-dacnum is %l2 planet under ~holrut made w/ %spawn proxy predeposited :: -:: ~red is for testing escapes. -:: ~rigred is L1 star -:: ~losred is L2 star +:: ~losrut is %l2 star +:: ~radres-tinnyl is %l1 planet under ~losrut +:: ~pinpun-pilsun is %l2 planet under ~losrut made w/ %own proxy +:: ~habtyc-nibpyx is %l2 planet under ~losrut made w/ %spawn proxy predeposited +:: ~disryt-nolpet is %l2 planet under ~losrut made w/ %spawn proxy postdeposited :: ++ init-rut-full |= =^state:naive ^- [effects:naive ^state:naive] - =/ dm-spawn [[~holrut %own] %spawn ~dovmul-mogryt (addr %holrut-dm-key-0)] - =/ dm-xfer [[~dovmul-mogryt %transfer] %transfer-point (addr %holrut-dm-key-0) &] - =/ pd-spawn [[~holrut %spawn] %spawn ~pidted-dacnum (addr %holrut-pd-key-0)] - =/ pd-xfer [[~pidted-dacnum %transfer] %transfer-point (addr %holrut-pd-key-0) &] - =/ pp-spawn [[~losrut %own] %spawn ~pinpun-pilsun (addr %losrut-pp-key-0)] - =/ pp-xfer [[~pinpun-pilsun %transfer] %transfer-point (addr %losrut-pp-key-0) &] - =/ hn-spawn [[~losrut %spawn] %spawn ~habtyc-nibpyx (addr %losrut-hn-key-0)] - =/ hn-xfer [[~habtyc-nibpyx %transfer] %transfer-point (addr %losrut-hn-key-0) &] - =/ dn-spawn [[~losrut %spawn] %spawn ~disryt-nolpet (addr %losrut-dn-key-0)] - =/ dn-xfer [[~disryt-nolpet %transfer] %transfer-point (addr %losrut-dn-key-0) &] - =/ losrut-sproxy [[~losrut %spawn] %set-spawn-proxy (addr %losrut-skey-1)] - =/ losrut-mproxy [[~losrut %own] %set-management-proxy (addr %losrut-mkey-0)] - =/ dm-mkey [[~dovmul-mogryt %own] %set-management-proxy (addr %holrut-dm-mkey-0)] - =/ pd-mkey [[~pidted-dacnum %own] %set-management-proxy (addr %holrut-pd-mkey-0)] - =/ pp-mkey [[~pinpun-pilsun %own] %set-management-proxy (addr %losrut-pp-mkey-0)] - =/ hn-mkey [[~habtyc-nibpyx %own] %set-management-proxy (addr %losrut-hn-mkey-0)] - =/ dn-mkey [[~disryt-nolpet %own] %set-management-proxy (addr %losrut-dn-mkey-0)] - =^ f1 state (n state (owner-changed:l1 ~rut (addr %rut-key-0))) - =^ f2 state (n state (owner-changed:l1 ~rigrut (addr %rigrut-key-0))) - =^ f3 state (n state (owner-changed:l1 ~holrut (addr %holrut-key-0))) - =^ f4 state (n state (owner-changed:l1 ~losrut (addr %losrut-key-0))) - =^ f5 state (n state (owner-changed:l1 ~larsyx-mapmeg (addr %rigrut-lm-key-0))) - =^ f6 state (n state (owner-changed:l1 ~rabsum-ravtyd (addr %holrut-rr-key-0))) - =^ f7 state (n state (owner-changed:l1 ~radres-tinnyl (addr %losrut-rt-key-0))) - =^ f8 state (n state (changed-spawn-proxy:l1 ~holrut (addr %holrut-skey-0))) - =^ f8 state (n state (changed-spawn-proxy:l1 ~losrut (addr %losrut-skey-0))) - =^ f8 state (n state (changed-spawn-proxy:l1 ~holrut deposit-address:naive)) - =^ f9 state (n state %bat q:(gen-tx 0 dm-spawn %holrut-key-0)) - =^ f10 state (n state %bat q:(gen-tx 0 pd-spawn %holrut-skey-0)) - =^ f11 state (n state (owner-changed:l1 ~losrut deposit-address:naive)) - =^ f12 state (n state %bat q:(gen-tx 0 pp-spawn %losrut-key-0)) - =^ f13 state (n state %bat q:(gen-tx 0 hn-spawn %losrut-skey-0)) - =^ f14 state (n state %bat q:(gen-tx 1 losrut-sproxy %losrut-skey-0)) - =^ f15 state (n state %bat q:(gen-tx 2 dn-spawn %losrut-skey-1)) - =^ f16 state (n state %bat q:(gen-tx 0 dm-xfer %holrut-dm-key-0)) - =^ f17 state (n state %bat q:(gen-tx 0 pd-xfer %holrut-pd-key-0)) - =^ f18 state (n state %bat q:(gen-tx 0 pp-xfer %losrut-pp-key-0)) - =^ f19 state (n state %bat q:(gen-tx 0 hn-xfer %losrut-hn-key-0)) - =^ f20 state (n state %bat q:(gen-tx 0 dn-xfer %losrut-dn-key-0)) - :: the following sets proxies for testing with various proxies - =^ p1 state (n state (changed-management-proxy:l1 ~rut (addr %rut-mkey-0))) - =^ p2 state (n state (changed-management-proxy:l1 ~rigrut (addr %rigrut-mkey-0))) - =^ p3 state (n state (changed-management-proxy:l1 ~larsyx-mapmeg (addr %rigrut-lm-mkey-0))) - =^ p4 state (n state (changed-management-proxy:l1 ~holrut (addr %holrut-mkey-0))) - =^ p5 state (n state (changed-management-proxy:l1 ~rabsum-ravtyd (addr %holrut-rr-mkey-0))) - =^ p6 state (n state (changed-management-proxy:l1 ~radres-tinnyl (addr %losrut-rt-mkey-0))) - =^ p7 state (n state %bat q:(gen-tx 0 dm-mkey %holrut-dm-key-0)) - =^ p8 state (n state %bat q:(gen-tx 0 pd-mkey %holrut-pd-key-0)) - =^ p9 state (n state %bat q:(gen-tx 0 pp-mkey %losrut-pp-key-0)) - =^ p10 state (n state %bat q:(gen-tx 0 hn-mkey %losrut-hn-key-0)) - =^ p11 state (n state %bat q:(gen-tx 0 dn-mkey %losrut-dn-key-0)) - =^ p12 state (n state %bat q:(gen-tx 1 losrut-mproxy %losrut-key-0)) - :: end of ~rut points, beginning of ~red. TODO this should be removed - :: once i move %escape to +test-red. or maybe %escape should stay here - :: because its the simplest? - =^ g1 state (n state (owner-changed:l1 ~red (addr %red-key-0))) - =^ g2 state (n state (owner-changed:l1 ~rigred (addr %rigred-key-0))) - =^ g3 state (n state (owner-changed:l1 ~losred (addr %losred-key-0))) - =^ g4 state (n state (owner-changed:l1 ~losred deposit-address:naive)) + :: + =/ dm-spawn + [[~holrut %own] %spawn ~dovmul-mogryt (addr %holrut-dm-key-0)] + =/ pd-spawn + [[~holrut %spawn] %spawn ~pidted-dacnum (addr %holrut-pd-key-0)] + :: + =/ pp-spawn + [[~losrut %own] %spawn ~pinpun-pilsun (addr %losrut-pp-key-0)] + =/ hn-spawn + [[~losrut %spawn] %spawn ~habtyc-nibpyx (addr %losrut-hn-key-0)] + =/ dn-spawn + [[~losrut %spawn] %spawn ~disryt-nolpet (addr %losrut-dn-key-0)] + =/ losrut-sproxy + [[~losrut %spawn] %set-spawn-proxy (addr %losrut-skey-1)] + =/ losrut-mproxy + [[~losrut %own] %set-management-proxy (addr %losrut-mkey-0)] + =/ losrut-tproxy + [[~losrut %own] %set-transfer-proxy (addr %losrut-tkey-0)] + :: + =/ dm-xfer + [[~dovmul-mogryt %transfer] %transfer-point (addr %holrut-dm-key-0) &] + =/ dm-tproxy + [[~dovmul-mogryt %own] %set-transfer-proxy (addr %dm-tkey-0)] + =/ dm-mproxy + [[~dovmul-mogryt %own] %set-management-proxy (addr %holrut-dm-mkey-0)] + :: + =/ pd-xfer + [[~pidted-dacnum %transfer] %transfer-point (addr %holrut-pd-key-0) &] + =/ pd-tproxy + [[~pidted-dacnum %own] %set-transfer-proxy (addr %pd-tkey-0)] + =/ pd-mproxy + [[~pidted-dacnum %own] %set-management-proxy (addr %holrut-pd-mkey-0)] + :: + :: + =/ pp-xfer + [[~pinpun-pilsun %transfer] %transfer-point (addr %losrut-pp-key-0) &] + =/ pp-tproxy + [[~pinpun-pilsun %own] %set-transfer-proxy (addr %pp-tkey-0)] + =/ pp-mproxy + [[~pinpun-pilsun %own] %set-management-proxy (addr %losrut-pp-mkey-0)] + :: + =/ hn-xfer + [[~habtyc-nibpyx %transfer] %transfer-point (addr %losrut-hn-key-0) &] + =/ hn-tproxy + [[~habtyc-nibpyx %own] %set-transfer-proxy (addr %hn-tkey-0)] + =/ hn-mproxy + [[~habtyc-nibpyx %own] %set-management-proxy (addr %losrut-hn-mkey-0)] + :: + =/ dn-xfer + [[~disryt-nolpet %transfer] %transfer-point (addr %losrut-dn-key-0) &] + =/ dn-tproxy + [[~disryt-nolpet %own] %set-transfer-proxy (addr %dn-tkey-0)] + =/ dn-mproxy + [[~disryt-nolpet %own] %set-management-proxy (addr %losrut-dn-mkey-0)] + :: + =^ f1 state + (n state (owner-changed:l1 ~rut (addr %rut-key-0))) + =^ f2 state + (n state (owner-changed:l1 ~rigrut (addr %rigrut-key-0))) + =^ f3 state + (n state (owner-changed:l1 ~holrut (addr %holrut-key-0))) + =^ f4 state + (n state (owner-changed:l1 ~losrut (addr %losrut-key-0))) + =^ f5 state + (n state (owner-changed:l1 ~larsyx-mapmeg (addr %rigrut-lm-key-0))) + =^ f6 state + (n state (owner-changed:l1 ~rabsum-ravtyd (addr %holrut-rr-key-0))) + =^ f7 state + (n state (owner-changed:l1 ~radres-tinnyl (addr %losrut-rt-key-0))) + =^ f8 state + (n state (changed-spawn-proxy:l1 ~rut (addr %rut-skey-0))) + =^ f9 state + (n state (changed-spawn-proxy:l1 ~holrut (addr %holrut-skey-0))) + =^ f10 state + (n state (changed-spawn-proxy:l1 ~losrut (addr %losrut-skey-0))) + =^ f11 state + (n state (changed-spawn-proxy:l1 ~holrut deposit-address:naive)) + :: + =^ f12 state + (n state %bat q:(gen-tx 0 dm-spawn %holrut-key-0)) + =^ f13 state + (n state %bat q:(gen-tx 0 pd-spawn %holrut-skey-0)) + =^ f14 state + (n state (owner-changed:l1 ~losrut deposit-address:naive)) + =^ f15 state + (n state %bat q:(gen-tx 0 pp-spawn %losrut-key-0)) + =^ f16 state + (n state %bat q:(gen-tx 0 hn-spawn %losrut-skey-0)) + =^ f17 state + (n state %bat q:(gen-tx 1 losrut-sproxy %losrut-skey-0)) + =^ f18 state + (n state %bat q:(gen-tx 2 dn-spawn %losrut-skey-1)) + =^ f19 state + (n state %bat q:(gen-tx 0 dm-xfer %holrut-dm-key-0)) + =^ f20 state + (n state %bat q:(gen-tx 0 pd-xfer %holrut-pd-key-0)) + =^ f21 state + (n state %bat q:(gen-tx 0 pp-xfer %losrut-pp-key-0)) + =^ f22 state + (n state %bat q:(gen-tx 0 hn-xfer %losrut-hn-key-0)) + =^ f23 state + (n state %bat q:(gen-tx 0 dn-xfer %losrut-dn-key-0)) + :: + =^ p1 state + (n state (changed-management-proxy:l1 ~rut (addr %rut-mkey-0))) + =^ p2 state + (n state (changed-management-proxy:l1 ~rigrut (addr %rigrut-mkey-0))) + =^ p3 state + (n state (changed-management-proxy:l1 ~larsyx-mapmeg (addr %rigrut-lm-mkey-0))) + =^ p4 state + (n state (changed-management-proxy:l1 ~holrut (addr %holrut-mkey-0))) + =^ p5 state + (n state (changed-management-proxy:l1 ~rabsum-ravtyd (addr %holrut-rr-mkey-0))) + =^ p6 state + (n state (changed-management-proxy:l1 ~radres-tinnyl (addr %losrut-rt-mkey-0))) + =^ p7 state + (n state %bat q:(gen-tx 0 dm-mproxy %holrut-dm-key-0)) + =^ p8 state + (n state %bat q:(gen-tx 0 pd-mproxy %holrut-pd-key-0)) + =^ p9 state + (n state %bat q:(gen-tx 0 pp-mproxy %losrut-pp-key-0)) + =^ p10 state + (n state %bat q:(gen-tx 0 hn-mproxy %losrut-hn-key-0)) + =^ p11 state + (n state %bat q:(gen-tx 0 dn-mproxy %losrut-dn-key-0)) + =^ p12 state + (n state %bat q:(gen-tx 1 losrut-mproxy %losrut-key-0)) + =^ p13 state + (n state (changed-transfer-proxy:l1 ~rut (addr %rut-tkey-0))) + =^ p14 state + (n state (changed-transfer-proxy:l1 ~rigrut (addr %rigrut-tkey-0))) + =^ p15 state + (n state (changed-transfer-proxy:l1 ~larsyx-mapmeg (addr %lm-tkey-0))) + =^ p16 state + (n state (changed-transfer-proxy:l1 ~holrut (addr %holrut-tkey-0))) + =^ p17 state + (n state (changed-transfer-proxy:l1 ~rabsum-ravtyd (addr %rr-tkey-0))) + =^ p18 state + (n state (changed-transfer-proxy:l1 ~radres-tinnyl (addr %rt-tkey-0))) + =^ p19 state + (n state %bat q:(gen-tx 2 losrut-tproxy %losrut-key-0)) + =^ p20 state + (n state %bat q:(gen-tx 1 dm-tproxy %holrut-dm-key-0)) + =^ p21 state + (n state %bat q:(gen-tx 1 pd-tproxy %holrut-pd-key-0)) + =^ p22 state + (n state %bat q:(gen-tx 1 pp-tproxy %losrut-pp-key-0)) + =^ p23 state + (n state %bat q:(gen-tx 1 hn-tproxy %losrut-hn-key-0)) + =^ p24 state + (n state %bat q:(gen-tx 1 dn-tproxy %losrut-dn-key-0)) + =^ t1 state + (n state (owner-changed:l1 ~tyl (addr %tyl-key-0))) + =^ t2 state + (n state (changed-spawn-proxy:l1 ~tyl (addr %tyl-skey-0))) + =^ t3 state + (n state (changed-spawn-proxy:l1 ~tyl deposit-address:naive)) + =^ t4 state + (n state (changed-management-proxy:l1 ~tyl (addr %tyl-mkey-0))) + =^ t5 state + (n state (changed-transfer-proxy:l1 ~tyl (addr %tyl-tkey-0))) + :: :- ;: welp f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 - f19 f20 + f19 f20 f21 f22 f23 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 - p11 p12 - g1 g2 g3 g4 + p11 p12 p13 p14 p15 p16 p17 p18 + p19 p20 p21 p22 p23 p24 + t1 t2 t3 t4 t5 == state :: :: +init-red-full adds another galaxy to the ~rut universe, ~red, and additional -:: points helpful for testing sponsorship actions. this has been separated from -:: ~rut because the concerns are different enough from the other actions that -:: its cleaner to do them separately +:: points used for testing sponsorship actions. :: ++ init-red-full |= =^state:naive @@ -131,22 +253,31 @@ =/ pp-escape [[~pinpun-pilsun %own] %escape ~losred] =/ dm-escape [[~dovmul-mogryt %own] %escape ~rigred] =/ lm-escape [[~larsyx-mapmeg %own] %escape ~losred] - =^ f1 state (init-rut-full state) - :: TODO uncomment the below once %escape is moved to +test-red - :: =^ f21 state (n state (owner-changed:l1 ~red (addr %red-key-0))) - :: =^ f22 state (n state (owner-changed:l1 ~rigred (addr %rigred-key-0))) - :: =^ f23 state (n state (owner-changed:l1 ~losred (addr %losred-key-0))) - :: =^ f24 state (n state (owner-changed:l1 ~losred deposit-address:naive)) - :: L1->L1 will happen later, its the most complicated - :: each pending escape will be followed by an adopt, reject, or cancel-escape + =/ rr-escape [[~rabsum-ravtyd %own] %escape ~rigred] + =^ f1 state (init-rut-full state) + =^ f2 state (n state (owner-changed:l1 ~red (addr %red-key-0))) + =^ f3 state (n state (owner-changed:l1 ~rigred (addr %rigred-key-0))) + =^ f4 state (n state (owner-changed:l1 ~losred (addr %losred-key-0))) + =^ f5 state + (n state (changed-management-proxy:l1 ~rigred (addr %rigred-mkey-0))) + =^ f6 state + (n state (changed-management-proxy:l1 ~losred (addr %losred-mkey-0))) + =^ f7 state (n state (owner-changed:l1 ~losred deposit-address:naive)) + :: each pending escape will be followed by a %adopt, %reject, or + :: %cancel-escape + :: L1->L1 + :: + =^ f8 state (n state %bat q:(gen-tx 0 rr-escape %holrut-rr-key-0)) :: L2->L2 - =^ f2 state (n state %bat q:(gen-tx 0 pp-escape %losrut-pp-key-0)) + :: + =^ f9 state (n state %bat q:(gen-tx 2 pp-escape %losrut-pp-key-0)) :: L2->L1 - =^ f3 state (n state %bat q:(gen-tx 0 dm-escape %holrut-dm-key-0)) + :: + =^ f10 state (n state %bat q:(gen-tx 2 dm-escape %holrut-dm-key-0)) :: L1->L2 - =^ f4 state (n state %bat q:(gen-tx 0 lm-escape %rigrut-lm-key-0)) - [:(welp f1 f2 f3 f4) state] -:: + :: + =^ f11 state (n state %bat q:(gen-tx 0 lm-escape %rigrut-lm-key-0)) + [:(welp f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11) state] :: :: ~dopbud is for testing L1 ownership with L2 spawn proxy :: @@ -155,7 +286,8 @@ ^- [effects:naive ^state:naive] =^ f1 state (init-bud state) =^ f2 state (n state (owner-changed:l1 ~dopbud (addr %dopbud-key-0))) - =^ f3 state (n state (changed-spawn-proxy:l1 ~dopbud deposit-address:naive)) + =^ f3 state + (n state (changed-spawn-proxy:l1 ~dopbud deposit-address:naive)) [:(welp f1 f2 f3) state] :: :: ~marbud is for testing L2 ownership @@ -173,11 +305,9 @@ ++ init-litbud |= =^state:naive ^- [effects:naive ^state:naive] - :: ~bud should already be spawned, though trying to init ~bud again shouldn't matter i think? - =^ f1 state (init-bud state) - =^ f2 state (n state (owner-changed:l1 ~litbud (addr %litbud-key-0))) - =^ f3 state (n state (owner-changed:l1 ~litbud deposit-address:naive)) - [:(welp f2 f3) state] + =^ f1 state (n state (owner-changed:l1 ~litbud (addr %litbud-key-0))) + =^ f2 state (n state (owner-changed:l1 ~litbud deposit-address:naive)) + [:(welp f1 f2) state] :: :: ~sambud is for testing L1 stars :: @@ -188,12 +318,18 @@ =^ f2 state (n state (owner-changed:l1 ~sambud (addr %sambud-key-0))) [:(welp f1 f2) state] :: -:: generates all possible transactions and maps them to whether they ought -:: to succeed +:: +l2-event-gen is a core used to generate all permutations of +:: [=rank owner=? nonce=? =dominion:naive =proxy:naive =tx-type] +:: as well as whether such an event ought to succeed as a L2 transaction, +:: assuming that arguments are appropriate. The gates in this core are +:: only utilized by +test-rut, but the types are used elsewhere in addition. +:: +:: We note that while +test-rut only tests actions unrelated to sponsorship, +:: +l2-event-gen deals with all L2 transaction types for the sake of potential +:: future needs. :: ++ l2-event-gen |% - :: +$ rank ?(%galaxy %star %planet) +$ tx-type $? %transfer-point %spawn @@ -211,312 +347,296 @@ +$ event-list (list event) +$ success-map (map event ?) +$ event-jar (jar @p event) + +$ full-tx [nonce=@ =tx:naive pk=@] + +$ tx-list (list full-tx) :: ++ make-success-map - :: +make-success-map maps each event to whether or not that combination of factors - :: ought to succeed or fail, for testing purposes. this is not a complete description atm - :: for instance, it does not take into account whether you are trying to spawn a planet - :: available to you or move to a sponsor of the correct rank. + :: +make-success-map maps each $event to a flag denoting whether or not such + :: a L2 transaction ought to succeed or fail, assuming that the arguments for + :: the transaction are appropriate for the transaction (e.g. ~marzod + :: attempting to spawn ~wicdev-wisryt). :: - :: it is also done in a more verbose style than strictly necessary to make it easier - :: to read through and determine why a particular event is labeled with %.y or %.n - :: and to make it easier to do future modifications + :: This is done in a more verbose style than strictly necessary to make it + :: easier to read through and determine why a particular $event maps to %.y + :: or %.n :: |= =event-list ^- success-map =| =success-map |^ ?~ event-list success-map =/ cur-event i.event-list - :: check owner or nonce first - ?: ?| =(owner.cur-event %.n) - =(nonce.cur-event %.n) + ?: ?| =(owner.cur-event %.n) :: if owner or nonce are wrong then the + =(nonce.cur-event %.n) :: event fails == (add-event-check cur-event %.n) - :: check dominion next - ?- dominion.cur-event - %l1 (add-event-check cur-event (l1-check cur-event)) - %spawn (add-event-check cur-event (spawnd-check cur-event)) - %l2 (add-event-check cur-event (l2-check cur-event)) + :: :: we first switch on dominion since + ?- dominion.cur-event :: it cleaves the largest differences + %l1 :: in what is permitted + (add-event-check cur-event (l1-check cur-event)) + :: + %spawn + (add-event-check cur-event (spawnd-check cur-event)) + :: + %l2 + (add-event-check cur-event (l2-check cur-event)) == :: ++ add-event-check |= [=event suc=?] %= ^$ - success-map (~(put by success-map) event suc) event-list +.event-list + success-map (~(put by success-map) event suc) == :: - ++ l1-check + ++ l1-check :: checks for %l1 dominion |^ |= cur-event=event ^- ? + :: Switch on which proxy is attempting the transaction. + :: L1 points are allowed to perform L2 sponsorship actions, which can be + :: performed with either %own or %manage proxies. + :: ?- proxy.cur-event - %own (manage-own-check cur-event) - %spawn %.n - %manage (manage-own-check cur-event) - %vote %.n - %transfer %.n + %own (manage-own-check cur-event) :: sponsorship tx allowed + %spawn %.n :: cannot do sponsorship tx + %manage (manage-own-check cur-event) :: sponsorship tx allowed + %vote %.n :: cannot do any L2 tx + %transfer %.n :: cannot do sponsorship tx == :: - ++ manage-own-check - |^ + ++ manage-own-check :: %own and %manage are + |^ :: identical in %l1 |= cur-event=event ^- ? - ?- rank.cur-event - %galaxy (galaxy-check cur-event) - %star (star-check cur-event) + ?- rank.cur-event :: switch on rank + %galaxy (galaxy-check cur-event) :: each rank has different + %star (star-check cur-event) :: allowed actions %planet (planet-check cur-event) == ++ galaxy-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %adopt %.y - %reject %.y - %detach %.y + ?+ tx-type.cur-event %.n :: galaxies do not have sponsors + %adopt %.y :: can adopt on L2 + %reject %.y :: can reject on L2 + %detach %.y :: can detach on L2 == ++ star-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %adopt %.y - %reject %.y - %detach %.y - %escape %.y - %cancel-escape %.y + ?+ tx-type.cur-event %.n :: may only do L2 sponsorship tx + %adopt %.y :: can %adopt on L2 + %reject %.y :: can %reject on L2 + %detach %.y :: can %detach on L2 + %escape %.y :: can %escape on L2 + %cancel-escape %.y :: can %cancel-escape on L2 == ++ planet-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %escape %.y - %cancel-escape %.y + ?+ tx-type.cur-event %.n :: planets do not have sponsees + %escape %.y :: can %escape on L2 + %cancel-escape %.y :: can %cancel-escape on L2 == :: - -- :: +manage-own-check + -- :: end +manage-own-check in %l1 :: - -- :: +l1-check + -- :: end +l1-check :: - ++ spawnd-check + ++ spawnd-check :: checks for %spawn dominion |^ |= cur-event=event ^- ? - ?- rank.cur-event - %galaxy %.n - %star (star-check cur-event) - %planet %.n + ?- rank.cur-event :: switch on rank + %galaxy (galaxy-check cur-event) :: galaxies can be on %spawn + %star (star-check cur-event) :: stars can be on %spawn + %planet %.n :: planets cannot be on %spawn == - ++ star-check + ++ star-check :: %spawn dominion star check |^ |= cur-event=event ^- ? - ?- proxy.cur-event - %own (ownp-check cur-event) - %manage (managep-check cur-event) - %spawn (spawnp-check cur-event) - %vote %.n - %transfer %.n + ?- proxy.cur-event :: switch on proxy + %own (ownp-check cur-event) :: can do sponsorship and spawn + %manage (managep-check cur-event) :: can do sponsorship tx + %spawn (spawnp-check cur-event) :: can do spawn tx + %vote %.n :: stars have no %vote proxy + %transfer %.n :: cannot sponsor/spawn == ++ ownp-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %spawn %.y - %adopt %.y - %reject %.y - %detach %.y - %escape %.y - %cancel-escape %.y - %set-spawn-proxy %.y + ?+ tx-type.cur-event %.n :: only sponsorship/spawn tx + %spawn %.y :: can %spawn on L2 + %adopt %.y :: can %adopt on L2 + %reject %.y :: can %reject on L2 + %detach %.y :: can %detach on L2 + %escape %.y :: can %escape on L2 + %cancel-escape %.y :: can %cancel-escape on L2 + %set-spawn-proxy %.y :: can %set-spawn-proxy on L2 == - ++ managep-check - |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %adopt %.y - %reject %.y - %detach %.y - %escape %.y - %cancel-escape %.y + ++ managep-check :: %configure-keys disallowed + |= cur-event=event ^- ? :: for %spawn dominion + ?+ tx-type.cur-event %.n :: only sponsorship actions + %adopt %.y :: can %adopt on L2 + %reject %.y :: can %reject on L2 + %detach %.y :: can %detach on L2 + %escape %.y :: can %escape on L2 + %cancel-escape %.y :: can %cancel-escape on L2 == ++ spawnp-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %spawn %.y - %set-spawn-proxy %.y + ?+ tx-type.cur-event %.n :: only spawn tx allowed + %spawn %.y :: can %spawn on L2 + %set-spawn-proxy %.y :: can %set-spawn-proxy on L2 == - -- :: +star-check + -- :: end +star-check in %spawn :: - -- :: +spawnd-check + ++ galaxy-check :: %spawn dominion galaxy check + |^ + |= cur-event=event ^- ? + ?- proxy.cur-event :: switch on proxy + %own (ownp-check cur-event) :: can do sponsorship and spawn + %manage (managep-check cur-event) :: can do sponsorship tx + %spawn (spawnp-check cur-event) :: can do spawn tx + %vote %.n :: no L2 %vote proxy allowed + %transfer %.n :: cannot sponsor/spawn + == + ++ ownp-check + |= cur-event=event ^- ? + ?+ tx-type.cur-event %.n :: only sponsorship/spawn tx + %spawn %.y :: can %spawn on L2 + %adopt %.y :: can %adopt on L2 + %reject %.y :: can %reject on L2 + %detach %.y :: can %detach on L2 + %set-spawn-proxy %.y :: can %set-spawn-proxy on L2 + == + ++ managep-check :: %configure-keys disallowed + |= cur-event=event ^- ? :: for %spawn dominion + ?+ tx-type.cur-event %.n :: only sponsorship actions + %adopt %.y :: can %adopt on L2 + %reject %.y :: can %reject on L2 + %detach %.y :: can %detach on L2 + == + ++ spawnp-check + |= cur-event=event ^- ? + ?+ tx-type.cur-event %.n :: only spawn tx allowed + %spawn %.y :: can %spawn on L2 + %set-spawn-proxy %.y :: can %set-spawn-proxy on L2 + == + -- :: end +galaxy-check in %spawn + :: + -- :: end +spawnd-check :: - ++ l2-check + ++ l2-check :: checks for %l2 dominion |^ |= cur-event=event ^- ? - ?- rank.cur-event - %galaxy %.n - %star (star-check cur-event) - %planet (planet-check cur-event) + ?- rank.cur-event :: switch on rank + %galaxy %.n :: no %l2 dominion galaxies + %star (star-check cur-event) :: stars can be on %l2 + %planet (planet-check cur-event) :: planets can be on %l2 == ++ star-check |^ |= cur-event=event ^- ? - ?- proxy.cur-event - %own %.y - %manage (managep-check cur-event) - %spawn (spawnp-check cur-event) - %vote %.n - %transfer (transferp-check cur-event) + ?- proxy.cur-event :: switch on proxy + %own %.y :: all L2 tx allowed + %manage (managep-check cur-event) :: %manage proxy tx allowed + %spawn (spawnp-check cur-event) :: %spawn tx allowed + %vote %.n :: stars have no %vote proxy + %transfer (xferp-check cur-event) :: %transfer proxy tx allowed == ++ managep-check |= cur-event=event ^- ? - ?- tx-type.cur-event - %configure-keys %.y - %escape %.y + ?- tx-type.cur-event :: switch on tx-type + %configure-keys %.y :: permitted tx identical to L1 + %escape %.y :: management proxy permissions %cancel-escape %.y %adopt %.y %reject %.y %detach %.y %set-management-proxy %.y - %set-spawn-proxy %.n - %set-transfer-proxy %.n - %transfer-point %.n - %spawn %.n + %set-spawn-proxy %.n :: disallowed events given + %set-transfer-proxy %.n :: explicit cases to make it + %transfer-point %.n :: more clear that this is the + %spawn %.n :: same as L1 == ++ spawnp-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %spawn %.y - %set-spawn-proxy %.y + ?+ tx-type.cur-event %.n :: permitted tx identical to L1 + %spawn %.y :: spawn proxy permissions + %set-spawn-proxy %.y == - ++ transferp-check - |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n + ++ xferp-check + |= cur-event=event ^- ? :: permitted tx identical to L1 + ?+ tx-type.cur-event %.n :: transfer proxy permissions %transfer-point %.y - %set-transfer-proxy %.n + %set-transfer-proxy %.y == - -- :: +star-check - ++ planet-check + -- :: end +star-check in %l2 + ++ planet-check :: checks for %l2 planets |^ |= cur-event=event ^- ? - ?- proxy.cur-event - %own (ownp-check cur-event) - %manage (managep-check cur-event) - %spawn %.n - %vote %.n - %transfer (transferp-check cur-event) + ?- proxy.cur-event :: switch on proxy + %own (ownp-check cur-event) :: permitted tx identical to L1 + %manage (managep-check cur-event) :: permitted tx identical to L1 + %spawn %.n :: planets have no %spawn proxy + %vote %.n :: planets have no %vote proxy + %transfer (xferp-check cur-event) :: permitted tx identical to L1 == ++ ownp-check |= cur-event=event ^- ? - ?- tx-type.cur-event - %transfer-point %.y - %spawn %.n + ?- tx-type.cur-event :: permitted tx identical to L1 + %transfer-point %.y :: ownership proxy permissions %configure-keys %.y + %set-management-proxy %.y + %set-transfer-proxy %.y %escape %.y %cancel-escape %.y + %spawn %.n %adopt %.n %reject %.n %detach %.n - %set-management-proxy %.y %set-spawn-proxy %.n - %set-transfer-proxy %.y == ++ managep-check |= cur-event=event ^- ? - ?+ tx-type.cur-event %.n - %configure-keys %.y + ?+ tx-type.cur-event %.n :: permitted tx identical to L1 + %configure-keys %.y :: management proxy permissions %escape %.y %cancel-escape %.y %set-management-proxy %.y == - ++ transferp-check - |= cur-event=event ^- ? - ?+ tx-type.cur-event %.y + ++ xferp-check + |= cur-event=event ^- ? :: permitted tx identica to L1 + ?+ tx-type.cur-event %.n :: transfer proxy permissions %transfer-point %.y %set-transfer-proxy %.y == :: - -- :: +planet-check + -- :: end %l2 +planet-check :: - -- :: +l2-check + -- :: end +l2-check :: - -- :: make-success-map + -- :: end +make-success-map :: - ++ filter-tx-type - |= [typs=(list =tx-type) =event-list] - |^ - (skim event-list filter) - ++ filter - :: I think I can shorten this a bit with a fold or something - |= =event ^- ? - =/ match=? %.n - |- - ?~ typs match - =/ cur-typ i.typs - %= $ - match |(match =(cur-typ tx-type.event)) - typs t.typs - == - -- - :: - ++ filter-proxy - |= [=proxy:naive =event-list] - |^ - (skim event-list filter) - ++ filter - |= =event - =(proxy.event proxy) - -- - :: - ++ filter-rank - |= [=rank =event-list] - |^ - (skim event-list filter) - ++ filter - |= =event - =(rank.event rank) - -- - :: - ++ filter-owner - |= [owner=? =event-list] - |^ - (skim event-list filter) - ++ filter - |= =event - =(owner.event owner) - -- - :: - ++ filter-nonce - |= [nonce=? =event-list] - |^ - (skim event-list filter) - ++ filter - |= =event - =(nonce.event nonce) - -- - :: - ++ filter-dominion - |= [=dominion:naive =event-list] - |^ - (skim event-list filter) - ++ filter - |= =event - =(dominion.event dominion) - -- + :: creates a list of all values of $event for use by +test-rut :: ++ make-event-list ^- event-list =| =event-list - =/ rank-i 1 - |- + =+ rank-i=1 + |^ ?: (gth rank-i 3) (remove-wrong-dominion event-list) - =/ owner-i 0 + =+ owner-i=0 |- ?. (lte owner-i 1) ^$(rank-i +(rank-i)) - =/ nonce-i 0 + =+ nonce-i=0 |- ?. (lte nonce-i 1) ^$(owner-i +(owner-i)) - =/ dominion-i 1 + =+ dominion-i=1 |- ?. (lte dominion-i 3) ^$(nonce-i +(nonce-i)) - =/ proxy-i 1 + =+ proxy-i=1 |- ?. (lte proxy-i 5) ^$(dominion-i +(dominion-i)) - =/ tx-type-i 1 + =+ tx-type-i=1 |- ?. (lte tx-type-i 11) ^$(proxy-i +(proxy-i)) @@ -531,106 +651,120 @@ == event-list == + :: + ++ num-to-flag + |= val=@ud ^- ? + ?+ val !! + %0 %.y + %1 %.n + == + :: + ++ num-to-rank + |= val=@ud ^- rank + ?+ val !! + %1 %galaxy + %2 %star + %3 %planet + == + :: + ++ num-to-dominion + |= val=@ud ^- dominion:naive + ?+ val !! + %1 %l1 + %2 %l2 + %3 %spawn + == + :: + ++ num-to-proxy + |= val=@ud ^- proxy:naive + ?+ val !! + %1 %own + %2 %spawn + %3 %manage + %4 %vote + %5 %transfer + == + :: + ++ num-to-tx-type + |= val=@ud ^- tx-type + ?+ val !! + %1 %transfer-point + %2 %spawn + %3 %configure-keys + %4 %escape + %5 %cancel-escape + %6 %adopt + %7 %reject + %8 %detach + %9 %set-management-proxy + %10 %set-spawn-proxy + %11 %set-transfer-proxy + == + :: + -- :: end +make-event-list + :: + :: used to remove values of +make-event-list that have planets in the %spawn + :: dominion or galaxies in the %l2 dominion + :: + :: TODO: Why does this not work when I put it inside the above trap? :: ++ remove-wrong-dominion - |= in=event-list - =| =event-list + |= in=event-list ^- event-list + =| out=event-list |- - ?~ in event-list - =/ current-event i.in - ?: ?& =(rank.current-event %galaxy) - !=(dominion.current-event %l1) + ?~ in out + ?: ?& =(rank.i.in %galaxy) + =(dominion.i.in %l2) == $(in t.in) - ?: ?& =(rank.current-event %planet) - =(dominion.current-event %spawn) + ?: ?& =(rank.i.in %planet) + =(dominion.i.in %spawn) == $(in t.in) %= $ in t.in - event-list current-event^event-list + out i.in^out == :: - ++ num-to-flag - |= val=@ud ^- ? - ?+ val !! - %0 %.y - %1 %.n - == + :: jar of events for +test-rut. each @p is mapped to a list of events + :: it ought to attempt. This is done according to rank. :: - ++ num-to-rank - |= val=@ud ^- rank - ?+ val !! - %1 %galaxy - %2 %star - %3 %planet - == - :: - ++ num-to-dominion - |= val=@ud ^- dominion:naive - ?+ val !! - %1 %l1 - %2 %l2 - %3 %spawn - == - :: - ++ num-to-proxy - |= val=@ud ^- proxy:naive - ?+ val !! - %1 %own - %2 %spawn - %3 %manage - %4 %vote - %5 %transfer - == - :: - ++ num-to-tx-type - |= val=@ud ^- tx-type - ?+ val !! - %1 %transfer-point - %2 %spawn - %3 %configure-keys - %4 %escape - %5 %cancel-escape - %6 %adopt - %7 %reject - %8 %detach - %9 %set-management-proxy - %10 %set-spawn-proxy - %11 %set-transfer-proxy - == - :: - :: jar of events for rut. each @p is mapped to a list of events - :: it ought to test, and +success-map says whether or not that - :: event should succed or fail + :: This gate may be modified to filter out a subset of events you wish to + :: test by commenting out or modifying parts of the filter gate. Remember that + :: +test-rut is only designed to test %spawn, %transfer-point, + :: %configure-keys, %set-management-proxy, %set-spawn-proxy, and + :: %set-transfer-proxy. Adding in other transaction types will result in a + :: crash. :: ++ gen-rut-jar - ^- (jar @p event) + ^~ ^- (jar @p event) =/ filter ;: cork (cury filter-owner %.y) - (cury filter-proxy %manage) + ::(cury filter-proxy %spawn) (cury filter-nonce %.y) - ::(cury filter-rank %star) - ::(cury filter-dominion %l2) + ::(cury filter-rank %galaxy) + ::(cury filter-dominion %l1) %- cury :- filter-tx-type - :* %spawn - %transfer-point + :* ::%spawn + ::%transfer-point %configure-keys - %set-management-proxy - ::%set-spawn-proxy :: planets can set spawn proxy atm - %set-transfer-proxy - ::%escape + ::%set-management-proxy + ::%set-spawn-proxy + ::%set-transfer-proxy ~ == == =/ filtered-events (filter make-event-list) - =| mgmt-jar=(jar @p event) + =| rut-jar=(jar @p event) |^ - ?~ filtered-events mgmt-jar + ?~ filtered-events rut-jar =/ current-event i.filtered-events ?: =(rank.current-event %galaxy) - (list-in-jar (ly ~[~rut]) current-event) + ?+ dominion.current-event !! + %l1 (list-in-jar (ly ~[~rut]) current-event) + %spawn (list-in-jar (ly ~[~tyl]) current-event) + == ?: =(rank.current-event %star) ?- dominion.current-event %l1 (list-in-jar (ly ~[~rigrut]) current-event) @@ -641,10 +775,11 @@ ?+ dominion.current-event !! %l1 %- list-in-jar :- %- ly - :^ ~larsyx-mapmeg + :* ~larsyx-mapmeg ~rabsum-ravtyd - ~radres-tinnyl - ~ + ~radres-tinnyl + ~ + == current-event %l2 %- list-in-jar :- %- ly @@ -658,37 +793,74 @@ current-event == $(filtered-events t.filtered-events) + :: adds event to the list associated to each value of ships in rut-jar :: ++ list-in-jar |= [ships=(list ship) =event] - ^+ mgmt-jar - =/ new-jar mgmt-jar + ^+ rut-jar |- - ?~ ships %= ^^$ - mgmt-jar new-jar - filtered-events +.filtered-events - == - =. new-jar (~(add ja new-jar) i.ships event) + ?~ ships + ^^$(filtered-events +.filtered-events) + =. rut-jar (~(add ja rut-jar) i.ships event) $(ships t.ships) - :: - -- + -- :: end +gen-rut-jar :: - + ++ filter-tx-type + |= [typs=(list =tx-type) =event-list] + %+ skim + event-list + |=(=event (lien typs |=(=tx-type =(tx-type tx-type.event)))) :: - -- + ++ filter-proxy + |= [=proxy:naive =event-list] + (skim event-list |=(=event =(proxy.event proxy))) + :: + ++ filter-rank + |= [=rank =event-list] + (skim event-list |=(=event =(rank.event rank))) + :: + ++ filter-owner + |= [owner=? =event-list] + (skim event-list |=(=event =(owner.event owner))) + :: + ++ filter-nonce + |= [nonce=? =event-list] + (skim event-list |=(=event =(nonce.event nonce))) + :: + ++ filter-dominion + |= [=dominion:naive =event-list] + (skim event-list |=(=event =(dominion.event dominion))) + :: + :: Takes in a list of full-tx and turns them into a batch=@ to be submitted to + :: +n. The ordering on the list is the order in which the transactions are + :: processed. + :: + ++ tx-list-to-batch + |= =tx-list ^- @ + (can 3 (turn tx-list gen-tx)) + :: + -- :: end +l2-event-gen +:: +:: This core generates L1 transaction logs. It is important to keep in mind +:: that Azimuth already handles the logic on what is or is not allowed on L1, +:: so if you tell naive.hoon that ~zod adopted ~hodler without ~hodler having +:: escaped to ~zod first, ~zod will be the new sponsor of ~hodler anyways. In +:: the real world, such an action would have been blocked by the smart contract +:: and never made its way to naive.hoon. :: ++ l1 |% + :: This gate takes in raw information for L1 transactions and formats them + :: appropriately for use with +n. :: - :: Azimuth.sol events + ++ log + |= [log-name=@ux data=@ux topics=(list @)] + [%log *@ux data log-name topics] :: ++ owner-changed |= [=ship =address] (log owner-changed:log-names:naive *@ux ship address ~) :: - :: TODO: Activated (not in lib/naive.hoon) - :: TODO: Spawned (not in lib/naive.hoon) - :: ++ escape-requested |= [escapee=ship parent=ship] (log escape-requested:log-names:naive *@ux escapee parent ~) @@ -738,15 +910,15 @@ |= [=ship =address] (log changed-voting-proxy:log-names:naive *@ux ship address ~) :: - :: TODO: ChangedDns (lib/naive still has TODOs) - :: - :: Ecliptic.sol events + ++ changed-dns + |= [data=@] + (log changed-dns:log-names:naive data ~) :: ++ approval-for-all |= [owner=address operator=address approved=@] (log approval-for-all:log-names:naive approved owner operator ~) :: - -- + -- :: end +l1 :: -- :: @@ -772,7 +944,6 @@ :: :: rut tests :: -:: ++ common-mgmt %mgmt-key-0 ++ common-spwn %spwn-key-0 ++ common-vote %vote-key-0 @@ -780,6 +951,7 @@ ++ common-tran %tran-key-0 ++ rut-ship-list %- ly :* ~rut + ~tyl ~holrut ~rigrut ~losrut @@ -795,8 +967,10 @@ == :: :: initial keys for each point under ~rut +:: ++ default-own-keys %- my:nl :* [~rut %rut-key-0] + [~tyl %tyl-key-0] [~holrut %holrut-key-0] [~rigrut %rigrut-key-0] [~losrut %losrut-key-0] @@ -813,6 +987,7 @@ :: ++ default-manage-keys %- my:nl :* [~rut %rut-mkey-0] + [~tyl %tyl-mkey-0] [~holrut %holrut-mkey-0] [~rigrut %rigrut-mkey-0] [~losrut %losrut-mkey-0] @@ -826,56 +1001,98 @@ [~radres-tinnyl %losrut-rt-mkey-0] ~ == +++ default-spawn-keys %- my:nl + :* [~rut %rut-skey-0] + [~tyl %tyl-skey-0] + [~holrut %holrut-skey-0] + [~losrut %losrut-skey-1] + [~rigrut %rigrut-skey-0] + ~ + == +:: +++ default-xfer-keys %- my:nl + :* [~rut %rut-tkey-0] + [~tyl %tyl-tkey-0] + [~rigrut %rigrut-tkey-0] + [~larsyx-mapmeg %lm-tkey-0] + [~holrut %holrut-tkey-0] + [~rabsum-ravtyd %rr-tkey-0] + [~radres-tinnyl %rt-tkey-0] + [~losrut %losrut-tkey-0] + [~dovmul-mogryt %dm-tkey-0] + [~pinpun-pilsun %pp-tkey-0] + [~pidted-dacnum %pd-tkey-0] + [~habtyc-nibpyx %hn-tkey-0] + [~disryt-nolpet %dn-tkey-0] + ~ + == +:: +:: sponsorship tests +++ losrut-own [~losrut %own] +++ losrut-mgmt [~losrut %manage] +++ holrut-own [~holrut %own] +++ holrut-mgmt [~holrut %manage] +++ rigrut-own [~rigrut %own] +++ rigrut-mgmt [~rigrut %manage] +++ losred-own [~losred %own] +++ losred-mgmt [~losred %manage] +++ rigred-own [~rigred %own] +++ rigred-mgmt [~rigred %manage] :: -- +=/ init-rut-simple (init-rut-full *^state:naive) +=/ init-red-simple (init-red-full *^state:naive) :: :: Tests :: |% -:: new tests +:: This test spawns a "full galaxy" containing all varieties of points. It then +:: saves this initial state, and runs single transaction batches for all +:: possible L2 "event types". It compares the entire new state to the entire +:: initial state and checks for the expected state change. It then resets the +:: state to the initial state and tries the next event on the list. :: -:: this test spawns a "full galaxy" containing all varieties of points. it then -:: saves this initial state, and runs single transaction batches for all possible -:: L2 "event types". it compares the entire new state to the entire initial state and checks for -:: the expected state change. it then resets the state to the initial state and -:: tries the next event in on the list. +:: More specifically, there is a $jar called event-jar that maps ships to +:: lists of events it should try. It then picks off a ship, tries all the events +:: in the list associated to it as described above, and then moves on to the +:: next ship, until it has exhausted all values in the lists in the jar. :: -:: more specifically, there is a $jar called event-jar that maps ships to lists of -:: events it should try. it then picks off a ship, tries all the events in the list -:: associated to it as described above, and then moves on to the next ship, until -:: the jar is empty. -:: -:: this arm does not test any L1 transactions beyond the ones needed to spawn the -:: galaxy (+init-rut). +:: This arm does not test any L1 transactions beyond the ones needed to spawn +:: the galaxy (+init-rut). :: ++ test-rut ^- tang =, l2-event-gen + :: Initialize the PKI state, the list of ships to iterate through, and the + :: map from $event to ? :: - =/ event-jar gen-rut-jar - =| =^state:naive - =^ f state (init-rut-full state) - =/ initial-state state + =| initial-state=^state:naive + =^ f initial-state init-rut-simple =/ ship-list rut-ship-list =/ suc-map (make-success-map make-event-list) + :: Iterate through ships and get the list of events to try with that ship. :: |- ^- tang ?~ ship-list ~ %+ weld $(ship-list t.ship-list) - =/ cur-ship i.ship-list + =* cur-ship i.ship-list %+ category (scow %p cur-ship) - =/ current-events (~(get ja event-jar) cur-ship) + =/ cur-events (~(get ja gen-rut-jar) cur-ship) + :: Iterate through events and try to perform each one with cur-ship using + :: supplied default arguments. :: - |- ^- tang - ?~ current-events ~ - %+ weld $(current-events t.current-events) - =/ cur-event i.current-events + |^ ^- tang + ?~ cur-events ~ + %+ weld $(cur-events t.cur-events) + :: + =* cur-event i.cur-events %+ category (weld "dominion " (scow %tas dominion.cur-event)) %+ category (weld "proxy " (scow %tas proxy.cur-event)) %+ category (weld "tx-type " (scow %tas tx-type.cur-event)) %+ category (weld "owner? " (scow %f owner.cur-event)) %+ category (weld "correct nonce? " (scow %f nonce.cur-event)) + %+ category (weld "success map " (scow %f (~(got by suc-map) cur-event))) :: - =/ cur-point (~(got by points.initial-state) cur-ship) + =/ cur-point (got:orm points.initial-state cur-ship) =* own own.cur-point =/ cur-nonce ?- proxy.cur-event @@ -885,15 +1102,16 @@ %vote nonce.voting-proxy.own %transfer nonce.transfer-proxy.own == - :: wrong nonce and/or wrong owner do not increment nonce - =/ new-nonce ?: &(nonce.cur-event owner.cur-event) - +(cur-nonce) - cur-nonce - :: - =/ state initial-state + =/ new-nonce %^ calculate-nonce + cur-event + cur-nonce + address.transfer-proxy.own =/ expect-state initial-state - |^ + :: + |^ :: begin expected state trap %+ expect-eq + :: expected state + :: !> |^ ^- ^state:naive ?. (~(got by suc-map) cur-event) @@ -912,16 +1130,22 @@ %set-spawn-proxy set-spwn-proxy %set-transfer-proxy set-xfer-proxy %spawn (new-point which-spawn) - %escape (set-escape which-escape-l2) == :: ++ set-keys ^- ^state:naive =/ new-keys - %= cur-point - life.keys.net +(life.keys.net:(~(got by points.initial-state) cur-ship)) - suite.keys.net suit - auth.keys.net auth - crypt.keys.net encr + %= cur-point + suite.keys.net + suit + :: + auth.keys.net + auth + :: + crypt.keys.net + encr + :: + life.keys.net + +(life.keys.net:(got:orm points.initial-state cur-ship)) == (alter-state new-keys) :: @@ -929,6 +1153,7 @@ =/ new-xfer %= cur-point address.owner.own (addr %transfer-test) + address.transfer-proxy.own 0x0 == (alter-state new-xfer) :: @@ -953,33 +1178,34 @@ == (alter-state new-xfer) :: - ++ set-escape - |= =ship ^- ^state:naive - =/ new-escp - %= cur-point - escape.net (some ship) - == - (alter-state new-escp) - :: ++ new-point - :: TODO clean up this horrifying gate |= =ship ^- ^state:naive =| new-point=point:naive =/ spawned - %= new-point - dominion %l2 - address.owner.own (addr (~(got by default-own-keys) cur-ship)) - address.transfer-proxy.own (addr %spawn-test) - sponsor.net [has=%.y who=cur-ship] + %= new-point + dominion + %l2 + :: + sponsor.net + [has=%.y who=cur-ship] + :: + address.transfer-proxy.own + (addr %spawn-test) + :: + address.owner.own + (addr (~(got by default-own-keys) cur-ship)) == - =/ expect-state (alter-state cur-point) :: this updates the nonce of the spawner + :: The following updates the nonce of the spawner + :: + =/ expect-state (alter-state cur-point) %= expect-state - points (~(put by points.expect-state) ship spawned) + points (put:orm points.expect-state ship spawned) == :: ++ alter-state :: this updates the expect-state with the new point, and takes :: care of incrementing the nonce as well. + :: |= alt-point=point:naive ^- ^state:naive =/ updated-point=point:naive ?- proxy.cur-event @@ -990,17 +1216,24 @@ %transfer alt-point(nonce.transfer-proxy.own new-nonce) == %= expect-state - points (~(put by points.expect-state) cur-ship updated-point) + points (put:orm points.expect-state cur-ship updated-point) == :: - -- :: end of expected state + -- :: end of expected state trap + :: :: actual state + :: !> - |^ ^- ^state:naive + |^ ^- ^state:naive :: begin actual state trap + =| state=^state:naive + :: The following is basically just tall form exploded view of a + :: parameterization of the same =^ call used to modify the PKI state + :: used everywhere else in the test suite. + :: =^ f state %- n - :+ state + :+ initial-state %bat =< q %- gen-tx @@ -1011,11 +1244,26 @@ proxy.cur-event def-args ?: owner.cur-event - ?+ proxy.cur-event %wrong-key - %own (~(got by default-own-keys) cur-ship) - %manage (~(got by default-manage-keys) cur-ship) + ?+ proxy.cur-event + %wrong-key + :: + %own + (~(got by default-own-keys) cur-ship) + :: + %manage + (~(got by default-manage-keys) cur-ship) + :: + %transfer + (~(got by default-xfer-keys) cur-ship) + :: + %spawn + ?: ?| =(rank.cur-event %galaxy) + =(rank.cur-event %star) + == + (~(got by default-spawn-keys) cur-ship) + %wrong-key == - %wrong-key + %wrong-key :: if not owner then use wrong key state :: ++ def-args @@ -1025,11 +1273,6 @@ %spawn [%spawn which-spawn (addr %spawn-test)] %transfer-point [%transfer-point (addr %transfer-test) |] %configure-keys [%configure-keys encr auth suit |] - %escape [%escape which-escape-l2] - :: %cancel-escape - :: %adopt - :: %reject - :: %detach %set-management-proxy [%set-management-proxy (addr %proxy-test)] %set-spawn-proxy [%set-spawn-proxy (addr %proxy-test)] %set-transfer-proxy [%set-transfer-proxy (addr %proxy-test)] @@ -1037,15 +1280,12 @@ :: -- :: +def-args :: - -- :: end of actual state - :: - ++ encr (shax 'You will forget that you ever read this sentence.') - ++ auth (shax 'You cant know that this sentence is true.') - ++ suit 1 + -- :: end of actual state trap :: ++ which-spawn ^- ship ?+ cur-ship !! %~rut ~hasrut + %~tyl ~hastyl %~rigrut ~batbec-tapmep %~larsyx-mapmeg ~nocryl-tobned %~holrut ~namtuc-ritnux @@ -1059,50 +1299,1044 @@ %~disryt-nolpet ~tapfur-fitsep == :: - ++ which-escape-l1 ^- ship - :: escaping to a L1 point - ?- rank.cur-event - %galaxy ~red - %star ~red - %planet ~rigred - == - ++ which-escape-l2 ^- ship - :: escaping to a L2 point - ?- rank.cur-event - %galaxy ~red - %star ~red - %planet ~losred - == + -- :: end of +expect-eq trap :: - -- :: end of +expect-eq + ++ calculate-nonce + |= [cur-event=event cur-nonce=@ xfer-address=@ux] + ?: &(nonce.cur-event owner.cur-event) + ?- proxy.cur-event + ?(%own %manage) + +(cur-nonce) + :: + %spawn + ?- rank.cur-event + %galaxy ?- dominion.cur-event + ?(%l1 %spawn) +(cur-nonce) + %l2 cur-nonce + == + %star ?- dominion.cur-event + %l1 cur-nonce + ?(%spawn %l2) +(cur-nonce) + == + %planet cur-nonce + == + :: end %spawn case + %transfer + ?~ xfer-address + cur-nonce + +(cur-nonce) + :: + %vote + cur-nonce + == + cur-nonce + :: + -- :: end of test trap :: -:: ++ test-red ^- tang +:: The following are sponsorship tests. They probably ought to be consolidated +:: into one large test. :: -++ test-marbud-l2-change-keys-new ^- tang +:: Each arm is named according to the scheme is test-galaxy-X-Y-action-L-N. +:: X is the layer of the sponsee, Y is the layer of the sponsor, L is the +:: layer of the action, and N (which does not appear for all tests) is an +:: index denoting which test of the (X,Y,L) tuple it is (according to which +:: order it appears in the table), as some of these have multiple setups +:: necessary to test the action. +:: +:: Each row of the following table has one or more tests that cover it. +:: Above each test is a comment with the row that that test is testing. +:: Thus you can grep for the line and find the appropriate test. A few of +:: the tests cannot be performed here - there are the ones marked by !! +:: but we include what the tests would look like anyways as a comment. +:: These are ones involving L1 actions where Azimuth would prevent the +:: situation from ever occurring. naive.hoon does not make these checks, +:: and so the corresponding tests would fail. For example, you could submit +:: a layer 1 adopt action of a star on any planet regardless of whether it +:: has escaped to that star, and naive.hoon will allow the adoption to work. +:: Such an action would be prevented by Azimuth before it ever got to +:: naive.hoon, so if naive.hoon does receive such a log then it presumes +:: it to be correct. This is also why there are no tests where L2 ships +:: attempt to perform L1 actions. naive.hoon ignores these actions so +:: they're no-ops, but Azimuth also wouldn't allow them in the first place +:: since as far as Azimuth is concerned, all L2 ships belong to the deposit +:: address, so the L1 action would be signed with the wrong key anyways. +:: +:: * on the left means all possible states, on the right it means no change. +:: !! means that case can never happen per L1 contract. +:: L1-cancel can be triggered by "cancel escape" by the child or "reject +:: by the sponsor. +:: A1 and A2 are arbitrary but distinct ships one class above the main ship +:: Event | E_1 | E_2 | S_1 | S_2 | -> | E_1 | E_2 | S_1 | S_2 +:: L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | * +:: L1-cancel A1 | ~ | * | * | * | -> !! :: no cancel if not escaping +:: L1-cancel A1 | A1 | * | * | * | -> | ~ | ~ | * | * +:: L1-adopt A1 | A1 | * | * | * | -> | ~ | ~ | A1 | A2 +:: L1-adopt A1 | ~ | * | * | * | -> !! :: no adopt if not escaping +:: L1-adopt A1 | A2 | * | * | * | -> !! :: no adopt if not escaping +:: L1-detach A1 | * | * | A1 | A1 | -> | * | * | ~ | ~ +:: L1-detach A1 | * | * | A1 | A2 | -> | * | * | ~ | A2 +:: L1-detach A1 | * | * | A1 | ~ | -> | * | * | ~ | ~ +:: L2-escape A1 | * | * | * | * | -> | * | A1 | * | * +:: L2-cancel A1 | * | * | * | * | -> | * | ~ | * | * +:: L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1 +:: L2-adopt A1 | * | A2 | * | * | -> | * | A2 | * | * +:: L2-adopt A1 | * | ~ | * | * | -> | * | ~ | * | * +:: L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | * +:: L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | * +:: L2-reject A1 | * | ~ | * | * | -> | * | ~ | * | * +:: L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~ +:: L2-detach A1 | * | * | * | A2 | -> | * | * | * | A2 +:: L2-detach A1 | * | * | * | ~ | -> | * | * | * | ~ +:: +++ test-rut-l1-l1-escape-l1 ^- tang +:: L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | * + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state (escape-requested:l1 ~rabsum-ravtyd ~rigred)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +++ test-rut-l1-l2-escape-l1 ^- tang + :: L1-escape A1 | * | * | * | * | -> | A1 | A1 | * | * + %+ expect-eq + !> [[~ ~losred] %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state (escape-requested:l1 ~larsyx-mapmeg ~losred)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) +:: +++ test-red-l2-l2-adopt-l2-1 ^- tang + :: L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1 + =/ pp-adopt [losred-own %adopt ~pinpun-pilsun] + =/ pp-m-adopt [losred-mgmt %adopt ~pinpun-pilsun] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~losred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 pp-adopt %losred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + :: + %+ expect-eq + !> [~ %.y ~losred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 pp-m-adopt %losred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + == +:: +++ test-red-l1-l2-adopt-l2-1 + :: L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1 + =/ lm-adopt [losred-own %adopt ~larsyx-mapmeg] + =/ lm-m-adopt [losred-mgmt %adopt ~larsyx-mapmeg] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~losred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-adopt %losred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + :: + %+ expect-eq + !> [~ %.y ~losred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-m-adopt %losred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + == +:: +++ test-red-l2-l1-adopt-l2-1 + :: L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1 + =/ dm-adopt [rigred-own %adopt ~dovmul-mogryt] + =/ dm-m-adopt [rigred-mgmt %adopt ~dovmul-mogryt] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~rigred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 dm-adopt %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + :: + %+ expect-eq + !> [~ %.y ~rigred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 dm-m-adopt %rigred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + == +:: +++ test-red-l1-l1-adopt-l2-1 + :: L2-adopt A1 | * | A1 | * | * | -> | * | ~ | * | A1 + =/ rr-adopt [rigred-own %adopt ~rabsum-ravtyd] + =/ rr-m-adopt [rigred-mgmt %adopt ~rabsum-ravtyd] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~rigred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-adopt %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.y ~rigred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-m-adopt %rigred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +++ test-red-l1-l1-adopt-l2-2 + :: L2-adopt A1 | * | A2 | * | * | -> | * | A2 | * | * + =/ rr-adopt [losred-own %adopt ~rabsum-ravtyd] + =/ rr-m-adopt [losred-mgmt %adopt ~rabsum-ravtyd] + :: + ;: weld + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-adopt %losred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-m-adopt %losred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +++ test-rut-l1-l1-adopt-l2-3 ^- tang + :: L2-adopt A1 | * | ~ | * | * | -> | * | ~ | * | * + :: + =/ rr-h-detach [1 [holrut-own %detach ~rabsum-ravtyd] %holrut-key-0] + =/ rr-h-m-detach [0 [holrut-mgmt %detach ~rabsum-ravtyd] %holrut-mkey-0] + =/ rr-adopt [0 [losred-own %adopt ~rabsum-ravtyd] %losred-key-0] + =/ rr-m-adopt [0 [losred-mgmt %adopt ~rabsum-ravtyd] %losred-mkey-0] + :: + =, l2-event-gen + =/ rr-batch-1=tx-list (limo ~[rr-h-detach rr-adopt]) + =/ rr-batch-2=tx-list (limo ~[rr-h-m-detach rr-m-adopt]) + :: + =/ init-state=^state:naive +:init-rut-simple + ;: weld + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat q:(gen-tx rr-h-detach)) + =^ f state (n state %bat q:(gen-tx rr-adopt)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.n ~holrut] + + !> + =| =^state:naive + =^ f state (n init-state %bat (tx-list-to-batch rr-batch-1)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat q:(gen-tx rr-h-m-detach)) + =^ f state (n state %bat q:(gen-tx rr-m-adopt)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat (tx-list-to-batch rr-batch-2)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +:: the following tests L2 %rejects +++ test-red-l2-l2-reject-l2-1 ^- tang + :: L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | * + =/ pp-reject [losred-own %reject ~pinpun-pilsun] + =/ pp-m-reject [losred-mgmt %reject ~pinpun-pilsun] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 pp-reject %losred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + :: + %+ expect-eq + !> [~ %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 pp-m-reject %losred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + == +:: +++ test-red-l2-l1-reject-l2-1 ^- tang + :: L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | * + =/ dm-reject [rigred-own %reject ~dovmul-mogryt] + =/ dm-m-reject [rigred-mgmt %reject ~dovmul-mogryt] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 dm-reject %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + :: + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 dm-m-reject %rigred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + == +:: +++ test-red-l1-l2-reject-l2-1 ^- tang + :: L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | * + =/ lm-reject [losred-own %reject ~larsyx-mapmeg] + =/ lm-m-reject [losred-mgmt %reject ~larsyx-mapmeg] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-reject %losred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + :: + %+ expect-eq + !> [~ %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-m-reject %losred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + == +:: +++ test-red-l1-l1-reject-l2-1 ^- tang + :: L2-reject A1 | * | A1 | * | * | -> | * | ~ | * | * + =/ rr-reject [rigred-own %reject ~rabsum-ravtyd] + =/ rr-m-reject [rigred-mgmt %reject ~rabsum-ravtyd] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-reject %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-m-reject %rigred-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +++ test-red-l2-l2-reject-l2-2 ^- tang + :: L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | * + =/ pp-reject [losrut-own %reject ~pinpun-pilsun] + =/ pp-m-reject [losrut-mgmt %reject ~pinpun-pilsun] + :: + ;: weld + %+ expect-eq + !> [[~ ~losred] %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 2 pp-reject %losrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + :: + %+ expect-eq + !> [[~ ~losred] %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 pp-m-reject %losrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + == +:: +++ test-red-l2-l1-reject-l2-2 ^- tang + :: L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | * + =/ dm-reject [holrut-own %reject ~dovmul-mogryt] + =/ dm-m-reject [holrut-mgmt %reject ~dovmul-mogryt] + :: + ;: weld + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 1 dm-reject %holrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + :: + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 dm-m-reject %holrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + == +:: +++ test-red-l1-l2-reject-l2-2 ^- tang + :: L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | * + =/ lm-reject [rigrut-own %reject ~larsyx-mapmeg] + =/ lm-m-reject [rigrut-mgmt %reject ~larsyx-mapmeg] + :: + ;: weld + %+ expect-eq + !> [[~ ~losred] %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-reject %rigrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + :: + %+ expect-eq + !> [[~ ~losred] %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-m-reject %rigrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + == +:: +++ test-red-l1-l1-reject-l2-2 ^- tang + :: L2-reject A1 | * | A2 | * | * | -> | * | A2 | * | * + =/ rr-reject [holrut-own %reject ~rabsum-ravtyd] + =/ rr-m-reject [holrut-mgmt %reject ~rabsum-ravtyd] + :: + ;: weld + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 1 rr-reject %holrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [[~ ~rigred] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rr-m-reject %holrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +++ test-red-l1-l1-reject-l2-3 ^- tang + :: L2-reject A1 | * | ~ | * | * | -> | * | ~ | * | * + =/ rt-reject [holrut-own %reject ~radres-tinnyl] + =/ rt-m-reject [holrut-mgmt %reject ~radres-tinnyl] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 1 rt-reject %holrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~radres-tinnyl) + :: + %+ expect-eq + !> [~ %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 rt-m-reject %holrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~radres-tinnyl) + == +:: +:: the following tests L2 %cancel-escape +:: +++ test-red-l2-l2-cancel-escape-l2 ^- tang + :: L2-cancel A1 | * | * | * | * | -> | * | ~ | * | * + =/ pp-cancel-escape [[~pinpun-pilsun %own] %cancel-escape ~losred] + =/ pp-m-cancel-escape [[~pinpun-pilsun %manage] %cancel-escape ~losred] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 3 pp-cancel-escape %losrut-pp-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + :: + %+ expect-eq + !> [~ %.y ~losrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 0 pp-m-cancel-escape %losrut-pp-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + == +:: +++ test-red-l2-l1-cancel-escape-l2 ^- tang + :: L2-cancel A1 | * | * | * | * | -> | * | ~ | * | * + =/ dm-cancel-escape [[~dovmul-mogryt %own] %cancel-escape ~rigred] + =/ dm-m-cancel-escape [[~dovmul-mogryt %manage] %cancel-escape ~rigred] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 3 dm-cancel-escape %holrut-dm-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + :: + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 0 dm-m-cancel-escape %holrut-dm-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + == +:: +++ test-red-l1-l2-cancel-escape-l2 ^- tang + :: L2-cancel A1 | * | * | * | * | -> | * | ~ | * | * + =/ lm-cancel-escape [[~larsyx-mapmeg %own] %cancel-escape ~losred] + =/ lm-m-cancel-escape [[~larsyx-mapmeg %manage] %cancel-escape ~losred] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 1 lm-cancel-escape %rigrut-lm-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + :: + %+ expect-eq + !> [~ %.y ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 0 lm-m-cancel-escape %rigrut-lm-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + == +:: +++ test-red-l1-l1-cancel-escape-l2 ^- tang + :: L2-cancel A1 | * | * | * | * | -> | * | ~ | * | * + =/ rr-cancel-escape [[~rabsum-ravtyd %own] %cancel-escape ~rigred] + =/ rr-m-cancel-escape [[~rabsum-ravtyd %manage] %cancel-escape ~rigred] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 1 rr-cancel-escape %holrut-rr-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f + state + (n state %bat q:(gen-tx 0 rr-m-cancel-escape %holrut-rr-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +++ test-rut-l2-l2-detach-l2-1 ^- tang + :: L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~ + =/ pp-detach [losrut-own %detach ~pinpun-pilsun] + =/ pp-m-detach [losrut-mgmt %detach ~pinpun-pilsun] + :: + ;: weld + %+ expect-eq + !> [~ %.n ~losrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 3 pp-detach %losrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + :: + %+ expect-eq + !> [~ %.n ~losrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 pp-m-detach %losrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~pinpun-pilsun) + == +:: +++ test-rut-l2-l1-detach-l2-1 ^- tang + :: L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~ + =/ rt-detach [losrut-own %detach ~radres-tinnyl] + =/ rt-m-detach [losrut-mgmt %detach ~radres-tinnyl] + :: + ;: weld + %+ expect-eq + !> [~ %.n ~losrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 3 rt-detach %losrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~radres-tinnyl) + :: + %+ expect-eq + !> [~ %.n ~losrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 rt-m-detach %losrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~radres-tinnyl) + == +:: +++ test-rut-l1-l2-detach-l2-1 ^- tang + :: L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~ + =/ dm-detach [holrut-own %detach ~dovmul-mogryt] + =/ dm-m-detach [holrut-mgmt %detach ~dovmul-mogryt] + :: + ;: weld + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 1 dm-detach %holrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 dm-m-detach %holrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~dovmul-mogryt) + == +:: +++ test-rut-l1-l1-detach-l2-1 ^- tang + :: L2-detach A1 | * | * | * | A1 | -> | * | * | * | ~ + =/ lm-detach [rigrut-own %detach ~larsyx-mapmeg] + =/ lm-m-detach [rigrut-mgmt %detach ~larsyx-mapmeg] + :: + ;: weld + %+ expect-eq + !> [~ %.n ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 lm-detach %rigrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + :: + %+ expect-eq + !> [~ %.n ~rigrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 lm-m-detach %rigrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) + == +:: +++ test-rut-l1-l1-detach-l2-2 ^- tang + :: L2-detach A1 | * | * | * | A2 | -> | * | * | * | A2 + :: + =/ rr-detach [rigrut-own %detach ~rabsum-ravtyd] + =/ rr-m-detach [rigrut-mgmt %detach ~rabsum-ravtyd] + :: + ;: weld + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 rr-detach %rigrut-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 rr-m-detach %rigrut-mkey-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +++ test-rut-l1-l1-detach-l2-3 ^- tang + :: L2-detach A1 | * | * | * | ~ | -> | * | * | * | ~ + :: + =/ rr-h-detach [1 [holrut-own %detach ~rabsum-ravtyd] %holrut-key-0] + =/ rr-h-m-detach [0 [holrut-mgmt %detach ~rabsum-ravtyd] %holrut-mkey-0] + =/ rr-detach [0 [rigrut-own %detach ~rabsum-ravtyd] %rigrut-key-0] + =/ rr-m-detach [0 [rigrut-mgmt %detach ~rabsum-ravtyd] %rigrut-mkey-0] + :: + =, l2-event-gen + =/ rr-detach-batch-1=tx-list (limo rr-h-detach rr-detach ~) + =/ rr-detach-batch-2=tx-list (limo rr-h-m-detach rr-m-detach ~) + :: + =/ init-state=^state:naive +:init-rut-simple + ;: weld + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat q:(gen-tx rr-h-detach)) + =^ f state (n state %bat q:(gen-tx rr-detach)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat (tx-list-to-batch rr-detach-batch-1)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat q:(gen-tx rr-h-m-detach)) + =^ f state (n state %bat q:(gen-tx rr-m-detach)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat (tx-list-to-batch rr-detach-batch-2)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + + == +:: +:: The following tests are miscellaneous sponsorship tests between +:: two L1 points that test a few of the edge cases, like a L1 escape +:: followed by a L2 adopt. +:: +++ test-red-l1-escape-l2-adopt ^- tang + =/ rr-adopt [rigred-own %adopt ~rabsum-ravtyd] + %+ expect-eq + !> [~ %.y ~rigred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state (escape-requested:l1 ~rabsum-ravtyd ~rigred)) + =^ f state (n state %bat q:(gen-tx 0 rr-adopt %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +:: The following test fails because the action would be prevented +:: by Azimuth but is not by naive.hoon. +:: +:: ++ test-red-l2-escape-l1-adopt ^- tang +:: :: shouldn't be possible to accept a L2 escape with a L1 adopt +:: %+ expect-eq +:: !> [[~ ~rigred] %.y ~holrut] +:: :: +:: !> +:: =| =^state:naive +:: =^ f state init-red-simple +:: =^ f state (n state (escape-accepted:l1 ~rabsum-ravtyd ~rigred)) +:: [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +++ test-rut-l1-adoption-on-l2-wrong-key-or-nonce + =/ rr-escape [[~rabsum-ravtyd %own] %escape ~rigred] + =/ rr-adopt [rigred-own %adopt ~rabsum-ravtyd] + :: + =/ init-state +:init-rut-simple + :: + ;: weld + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state (n init-state %bat q:(gen-tx 1 rr-escape %wrong-key)) + =^ f state (n state %bat q:(gen-tx 0 rr-adopt %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + :: + %+ expect-eq + !> [~ %.y ~holrut] + :: + !> + =| =^state:naive + =^ f + state + (n init-state %bat q:(gen-tx 999 rr-escape %holrut-rr-key-0)) + =^ f state (n state %bat q:(gen-tx 0 rr-adopt %rigred-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) + == +:: +++ test-own-sponsor-l2-escape + =/ rr-escape [[~rabsum-ravtyd %own] %escape ~holrut] + :: + %+ expect-eq + !> [[~ ~holrut] %.y ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 rr-escape %holrut-rr-key-0)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +++ test-rut-l1-detach-1 + :: L1-detach A1 | * | * | A1 | A1 | -> | * | * | ~ | ~ + :: this checks that if you have the same sponsor on L1 and L2, then + :: a L1 detach makes you lose both + :: + :: ~rabsum-ravtyd is a L1 planet under a L1 star so would theortically + :: already be sponsored by ~holrut on L1. this already appears in + :: the L2 state as being sponsored by ~holrut, but we will go through + :: with adopting ~rabsum-ravtyd on L2 anyways before the L1 detach + :: + =/ rr-escape [[~rabsum-ravtyd %own] %escape ~holrut] + =/ rr-adopt [holrut-own %adopt ~rabsum-ravtyd] + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 0 rr-escape %holrut-rr-key-0)) + =^ f state (n state %bat q:(gen-tx 1 rr-adopt %holrut-key-0)) + =^ f state (n state (lost-sponsor:l1 ~rabsum-ravtyd ~holrut)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +++ test-red-l1-detach-2 + :: this takes a L1 planet with L1 sponsor that acquires a L2 sponsor + :: and is then detached by their L1 sponsor + :: + :: L1-detach A1 | * | * | A1 | A2 | -> | * | * | ~ | A2 + :: + =/ lm-adopt [losred-own %adopt ~larsyx-mapmeg] + :: + %+ expect-eq + !> [~ %.y ~losred] + :: + !> + =| =^state:naive + =^ f state init-red-simple + =^ f state (n state %bat q:(gen-tx 0 lm-adopt %losred-key-0)) + =^ f state (n state (lost-sponsor:l1 ~larsyx-mapmeg ~rigrut)) + [escape.net sponsor.net]:(got:orm points.state ~larsyx-mapmeg) +:: +++ test-rut-l1-detach-3 + :: L1-detach A1 | * | * | A1 | ~ | -> | * | * | ~ | ~ + :: Since we don't see L1 state explicitly, we can't really test + :: this transition here. But I've included it for completeness sake + =/ rr-detach [holrut-own %detach ~rabsum-ravtyd] + :: + %+ expect-eq + !> [~ %.n ~holrut] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state %bat q:(gen-tx 1 rr-detach %holrut-key-0)) + =^ f state (n state (escape-requested:l1 ~rabsum-ravtyd ~holrut)) + =^ f state (n state (escape-accepted:l1 ~rabsum-ravtyd ~holrut)) + =^ f state (n state (lost-sponsor:l1 ~rabsum-ravtyd ~holrut)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +:: The L1 action in the following test would be prevented by Azimuth +:: but is not by naive.hoon, so this test would fail. +:: +:: ++ test-rut-l1-l1-cancel-l1-1 +:: :: L1-cancel A1 | ~ | * | * | * | -> !! +:: :: no cancel if not escaping +:: :: Note we're using ~rut so there are no initial escapes +:: :: +:: %+ expect-eq +:: !> ~ +:: :: +:: !> +:: =| =^state:naive +:: =^ f state init-rut-simple +:: =^ f state (n state (escape-canceled:l1 ~rabsum-ravtyd ~rigred)) +:: escape.net:(got:orm points.state ~rabsum-ravtyd) +:: +++ test-rut-l1-l1-cancel-l1-2 + :: L1-cancel A1 | A1 | * | * | * | -> | ~ | ~ | * | * + %+ expect-eq + !> ~ + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state (escape-requested:l1 ~rabsum-ravtyd ~rigred)) + =^ f state (n state (escape-canceled:l1 ~rabsum-ravtyd ~rigred)) + escape.net:(got:orm points.state ~rabsum-ravtyd) +:: +++ test-rut-l1-l1-adopt-l1-1 + :: L1-adopt A1 | A1 | * | * | * | -> | ~ | ~ | A1 | A2 + %+ expect-eq + !> [~ %.y ~rigred] + :: + !> + =| =^state:naive + =^ f state init-rut-simple + =^ f state (n state (escape-requested:l1 ~rabsum-ravtyd ~rigred)) + =^ f state (n state (escape-accepted:l1 ~rabsum-ravtyd ~rigred)) + [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +:: These commented out tests fail, but it is because L1 adopt is only +:: accepted if Azimuth allows it. So these rows of the table +:: cannot be tested here. +:: +:: ++ test-rut-l1-l1-adopt-l1-2 +:: :: L1-adopt A1 | ~ | * | * | * | -> !! +:: :: no adopt if not escaping +:: %+ expect-eq +:: !> [~ %.y ~holrut] +:: :: +:: !> +:: =| =^state:naive +:: =^ f state init-rut-simple +:: =^ f state (n state (escape-accepted:l1 ~rabsum-ravtyd ~rigred)) +:: [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: :: +:: ++ test-rut-l1-l1-adopt-l1-3 +:: :: L1-adopt A1 | A2 | * | * | * | -> !! +:: :: no adopt if not escaping +:: %+ expect-eq +:: !> [[~ ~rigrut] %.y ~holrut] +:: :: +:: !> +:: =| =^state:naive +:: =^ f state init-rut-simple +:: =^ f state (n state (escape-requested:l1 ~rabsum-ravtyd ~rigrut)) +:: =^ f state (n state (escape-accepted:l1 ~rabsum-ravtyd ~rigred)) +:: [escape.net sponsor.net]:(got:orm points.state ~rabsum-ravtyd) +:: +:: The remaining tests are not categorized in any particular way. Some of them +:: are already covered by +test-rut but have been left in since they can't +:: hurt. +:: +++ test-marbud-l2-change-keys-whole-state ^- tang =/ new-keys [%configure-keys encr auth suit |] =| =^state:naive =^ f state (init-marbud state) - =/ marbud-point (~(got by points.state) ~marbud) + =/ marbud-point (got:orm points.state ~marbud) =/ new-marbud marbud-point(keys.net [1 suit auth encr], nonce.owner.own 1) :: %+ expect-eq - !> state(points (~(put by points.state) ~marbud new-marbud)) + !> state(points (put:orm points.state ~marbud new-marbud)) :: !> - =^ f state (n state %bat q:(gen-tx 0 [marbud-own new-keys] %marbud-key-0)) + =^ f + state + (n state %bat q:(gen-tx 0 [marbud-own new-keys] %marbud-key-0)) state - :: -:: old tests +:: ++ test-log ^- tang %+ expect-eq !> :- [%point ~bud %owner (addr %bud-key-0)]~ + :- %0 :_ [~ ~] :_ [~ ~] :- ~bud - %*(. *point:naive dominion %l1, owner.own (addr %bud-key-0)^0, who.sponsor.net ~bud) + %* . *point:naive + dominion %l1 + owner.own (addr %bud-key-0)^0 + who.sponsor.net ~bud + == :: !> - %^ naive verifier 1.337 :- *^state:naive + %^ naive verifier 1.337 :+ *^state:naive 0 :* %log *@ux *@ux owner-changed:log-names:naive (@ux ~bud) (addr %bud-key-0) ~ == @@ -1114,21 +2348,37 @@ !> =| =^state:naive =^ f state (init-marbud state) - dominion:(~(got by points.state) ~marbud) + dominion:(got:orm points.state ~marbud) :: -++ test-batch ^- tang - =/ marbud-transfer [marbud-own %transfer-point (addr %marbud-key-0) |] - =/ marbud-transfer-2 [marbud-own %transfer-point (addr %marbud-key-1) |] +++ test-transfer-batch ^- tang + =/ marbud-transfer + [0 [marbud-own %transfer-point (addr %marbud-key-0) |] %marbud-key-0] + =/ marbud-transfer-2 + [1 [marbud-own %transfer-point (addr %marbud-key-1) |] %marbud-key-0] :: - %+ expect-eq - !> [(addr %marbud-key-1) 2] + =, l2-event-gen + =/ marbud-batch=tx-list (limo marbud-transfer marbud-transfer-2 ~) :: - !> - =| =^state:naive - =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-transfer %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 marbud-transfer-2 %marbud-key-0)) - owner.own:(~(got by points.state) ~marbud) + ;: weld + %+ expect-eq + !> [(addr %marbud-key-1) 2] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat q:(gen-tx marbud-transfer)) + =^ f state (n state %bat q:(gen-tx marbud-transfer-2)) + owner.own:(got:orm points.state ~marbud) + :: + %+ expect-eq + !> [(addr %marbud-key-1) 2] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch marbud-batch)) + owner.own:(got:orm points.state ~marbud) + == :: ++ test-l1-changed-spawn-proxy ^- tang %+ expect-eq @@ -1138,7 +2388,7 @@ =| =^state:naive =^ f state (init-bud state) =^ f state (n state (changed-spawn-proxy:l1 ~bud (addr %bud-skey))) - spawn-proxy.own:(~(got by points.state) ~bud) + spawn-proxy.own:(got:orm points.state ~bud) :: ++ test-l1-changed-transfer-proxy ^- tang %+ expect-eq @@ -1148,7 +2398,7 @@ =| =^state:naive =^ f state (init-bud state) =^ f state (n state (changed-transfer-proxy:l1 ~bud (addr %bud-key-1))) - transfer-proxy.own:(~(got by points.state) ~bud) + transfer-proxy.own:(got:orm points.state ~bud) :: ++ test-l1-changed-management-proxy ^- tang %+ expect-eq @@ -1158,7 +2408,7 @@ =| =^state:naive =^ f state (init-bud state) =^ f state (n state (changed-management-proxy:l1 ~bud (addr %bud-mkey))) - management-proxy.own:(~(got by points.state) ~bud) + management-proxy.own:(got:orm points.state ~bud) :: ++ test-l1-changed-voting-proxy ^- tang %+ expect-eq @@ -1168,7 +2418,7 @@ =| =^state:naive =^ f state (init-bud state) =^ f state (n state (changed-voting-proxy:l1 ~bud (addr %bud-vkey))) - voting-proxy.own:(~(got by points.state) ~bud) + voting-proxy.own:(got:orm points.state ~bud) :: ++ test-l1-changed-keys ^- tang =/ life 1 @@ -1181,7 +2431,7 @@ =| =^state:naive =^ f state (init-bud state) =^ f state (n state (changed-keys:l1 new-keys)) - |1:keys.net:(~(got by points.state) ~bud) + |1:keys.net:(got:orm points.state ~bud) :: ++ test-l1-star-escape-requested ^- tang %+ expect-eq @@ -1192,7 +2442,7 @@ =^ f state (init-wes state) =^ f state (init-sambud state) =^ f state (n state (escape-requested:l1 ~sambud ~wes)) - escape.net:(~(got by points.state) ~sambud) + escape.net:(got:orm points.state ~sambud) :: ++ test-l1-star-escape-canceled ^- tang %+ expect-eq @@ -1204,7 +2454,7 @@ =^ f state (init-sambud state) =^ f state (n state (escape-requested:l1 ~sambud ~wes)) =^ f state (n state (escape-canceled:l1 ~sambud ~wes)) - escape.net:(~(got by points.state) ~sambud) + escape.net:(got:orm points.state ~sambud) :: ++ test-l1-star-adopt-accept ^- tang %+ expect-eq @@ -1216,7 +2466,7 @@ =^ f state (init-sambud state) =^ f state (n state (escape-requested:l1 ~sambud ~wes)) =^ f state (n state (escape-accepted:l1 ~sambud ~wes)) - [escape.net sponsor.net]:(~(got by points.state) ~sambud) + [escape.net sponsor.net]:(got:orm points.state ~sambud) :: ++ test-l1-star-lost-sponsor ^- tang %+ expect-eq @@ -1226,9 +2476,7 @@ =| =^state:naive =^ f state (init-sambud state) =^ f state (n state (lost-sponsor:l1 ~sambud ~bud)) - [escape.net sponsor.net]:(~(got by points.state) ~sambud) -:: -:: TODO: sponsorship tests for l1 planets, and L1/L2 sponsorship tests + [escape.net sponsor.net]:(got:orm points.state ~sambud) :: ++ test-l2-set-spawn-proxy ^- tang =/ marbud-sproxy [marbud-own %set-spawn-proxy (addr %marbud-skey)] @@ -1240,7 +2488,7 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 marbud-sproxy %marbud-key-0)) - spawn-proxy.own:(~(got by points.state) ~marbud) + spawn-proxy.own:(got:orm points.state ~marbud) :: ++ test-l2-set-transfer-proxy ^- tang =/ marbud-tproxy [marbud-own %set-transfer-proxy (addr %marbud-tkey)] @@ -1252,7 +2500,7 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 marbud-tproxy %marbud-key-0)) - transfer-proxy.own:(~(got by points.state) ~marbud) + transfer-proxy.own:(got:orm points.state ~marbud) :: ++ test-l2-set-management-proxy ^- tang =/ marbud-mproxy [marbud-own %set-management-proxy (addr %marbud-mkey)] @@ -1264,7 +2512,7 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 marbud-mproxy %marbud-key-0)) - management-proxy.own:(~(got by points.state) ~marbud) + management-proxy.own:(got:orm points.state ~marbud) :: ++ test-l2-dopbud-spawn-proxy-deposit ^- tang %+ expect-eq @@ -1273,7 +2521,7 @@ !> =| =^state:naive =^ f state (init-dopbud state) - dominion:(~(got by points.state) ~dopbud) + dominion:(got:orm points.state ~dopbud) :: ++ test-l2-sambud-spawn-proxy-predeposit ^- tang %+ expect-eq @@ -1282,9 +2530,13 @@ !> =| =^state:naive =^ f state (init-sambud state) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey))) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) - spawn-proxy.own:(~(got by points.state) ~sambud) + =^ f + state + (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey))) + =^ f + state + (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) + spawn-proxy.own:(got:orm points.state ~sambud) :: ++ test-l2-sambud-own-spawn-proxy-postdeposit ^- tang =/ sambud-sproxy [[~sambud %own] %set-spawn-proxy (addr %sambud-skey-0)] @@ -1294,55 +2546,93 @@ !> =| =^state:naive =^ f state (init-sambud state) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) =^ f state (n state %bat q:(gen-tx 0 sambud-sproxy %sambud-key-0)) - spawn-proxy.own:(~(got by points.state) ~sambud) + spawn-proxy.own:(got:orm points.state ~sambud) :: ++ test-l2-sambud-spawn-spawn-proxy-postdeposit ^- tang =/ sambud-sproxy [[~sambud %spawn] %set-spawn-proxy (addr %sambud-skey-1)] %+ expect-eq - !> [(addr %sambud-skey-1) 0] + !> [(addr %sambud-skey-1) 1] :: !> =| =^state:naive =^ f state (init-sambud state) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey-0))) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey-0))) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) =^ f state (n state %bat q:(gen-tx 0 sambud-sproxy %sambud-skey-0)) - spawn-proxy.own:(~(got by points.state) ~sambud) + spawn-proxy.own:(got:orm points.state ~sambud) :: ++ test-l2-sambud-spawn-proxy-predeposit-spawn ^- tang + =/ l2-sproxy [[~sambud %spawn] %set-spawn-proxy (addr %sambud-skey-1)] =/ lf-spawn [[~sambud %spawn] %spawn ~lisdur-fodrys (addr %lf-key-0)] - %+ expect-eq - !> [`@ux`(addr %lf-key-0) 0] - :: - !> - =| =^state:naive - =^ f state (init-sambud state) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey))) - =^ f state (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) - =^ f state (n state %bat q:(gen-tx 0 lf-spawn %sambud-skey)) - transfer-proxy.own:(~(got by points.state) ~lisdur-fodrys) -:: + ;: weld + %+ expect-eq + !> [`@ux`(addr %lf-key-0) 0] + :: + !> + =| =^state:naive + =^ f state (init-sambud state) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey-0))) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) + =^ f state + (n state %bat q:(gen-tx 0 lf-spawn %sambud-skey-0)) + transfer-proxy.own:(got:orm points.state ~lisdur-fodrys) + :: + %+ expect-eq + !> [`@ux`(addr %lf-key-0) 0] + :: + !> + =| =^state:naive + =^ f state (init-sambud state) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud (addr %sambud-skey-0))) + =^ f state + (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) + =^ f state + (n state %bat q:(gen-tx 0 l2-sproxy %sambud-skey-0)) + =^ f state + (n state %bat q:(gen-tx 1 lf-spawn %sambud-skey-1)) + transfer-proxy.own:(got:orm points.state ~lisdur-fodrys) + == ++ test-linnup-torsyx-spawn ^- tang :: try to spawn a L2 planet with a L2 planet - =/ rt-spawn [lt-own %spawn ~radres-tinnyl (addr %rt-key-0)] - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [lt-xfr %transfer-point (addr %lt-key-0) &] + =/ rt-spawn + [lt-own %spawn ~radres-tinnyl (addr %rt-key-0)] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [lt-xfr %transfer-point (addr %lt-key-0) &] :: - %- expect-fail - |. - =| =^state:naive - =^ f state (init-marbud state) - =^ f state (init-litbud state) - =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (init-litbud state) + =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) + =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =/ lt-point (got:orm points.state ~linnup-torsyx) + =/ new-lt lt-point(nonce.owner.own 1) + =/ no-op-state state(points (put:orm points.state ~linnup-torsyx new-lt)) + :: + %+ expect-eq + !> no-op-state + :: + !> =^ f state (n state %bat q:(gen-tx 0 rt-spawn %lt-key-0)) state :: ++ test-marbud-l2-spawn ^- tang - =/ marbud-sproxy [marbud-own %set-spawn-proxy (addr %marbud-skey)] - =/ lt-spawn [%spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-spawn + [%spawn ~linnup-torsyx (addr %lt-key-0)] + =/ marbud-sproxy + [0 [marbud-own %set-spawn-proxy (addr %marbud-skey)] %marbud-key-0] + =, l2-event-gen + =/ spawn-batch=tx-list + (limo marbud-sproxy [0 [marbud-spn lt-spawn] %marbud-skey] ~) :: ;: weld %+ expect-eq @@ -1352,8 +2642,9 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 [marbud-own lt-spawn] %marbud-key-0)) - transfer-proxy.own:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 [marbud-own lt-spawn] %marbud-key-0)) + transfer-proxy.own:(got:orm points.state ~linnup-torsyx) :: %+ expect-eq :: Tests l2 spawning with spawn proxy @@ -1362,27 +2653,44 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-sproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [marbud-spn lt-spawn] %marbud-skey)) - transfer-proxy.own:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx marbud-sproxy)) + =^ f state + (n state %bat q:(gen-tx 0 [marbud-spn lt-spawn] %marbud-skey)) + transfer-proxy.own:(got:orm points.state ~linnup-torsyx) + :: + %+ expect-eq + :: Tests l2 spawning with spawn proxy as a batch + !> [`@ux`(addr %lt-key-0) 0] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch spawn-batch)) + transfer-proxy.own:(got:orm points.state ~linnup-torsyx) == :: ++ test-marbud-l2-double-spawn ^- tang - :: Attempts to spawn the same planet twice, once with ownership and once with spawn proxy + :: Attempts to spawn the same planet twice, once with ownership and once + :: with spawn proxy =/ marbud-sproxy [marbud-own %set-spawn-proxy (addr %marbud-skey)] =/ lt-spawn-0 [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] =/ lt-spawn-1 [marbud-spn %spawn ~linnup-torsyx (addr %lt-key-1)] + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat q:(gen-tx 0 marbud-sproxy %marbud-key-0)) + =^ f state (n state %bat q:(gen-tx 1 lt-spawn-0 %marbud-key-0)) + =/ marbud-point (got:orm points.state ~marbud) + =/ new-marbud marbud-point(nonce.spawn-proxy.own 1) + =/ no-op-state state(points (put:orm points.state ~marbud new-marbud)) :: - %- expect-fail - |. - =| =^state:naive - =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-sproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 lt-spawn-0 %marbud-key-0)) + %+ expect-eq + !> no-op-state + :: + !> =^ f state (n state %bat q:(gen-tx 0 lt-spawn-1 %marbud-skey)) state :: -:: ++ test-marbud-l2-change-keys ^- tang =/ new-keys [%configure-keys encr auth suit |] =/ marbud-mproxy [marbud-own %set-management-proxy (addr %marbud-mkey)] @@ -1394,8 +2702,9 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 [marbud-own new-keys] %marbud-key-0)) - |1:keys.net:(~(got by points.state) ~marbud) + =^ f state + (n state %bat q:(gen-tx 0 [marbud-own new-keys] %marbud-key-0)) + |1:keys.net:(got:orm points.state ~marbud) :: %+ expect-eq !> [suit auth encr] @@ -1404,22 +2713,39 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 marbud-mproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [marbud-mgt new-keys] %marbud-mkey)) - |1:keys.net:(~(got by points.state) ~marbud) + =^ f state + (n state %bat q:(gen-tx 0 [marbud-mgt new-keys] %marbud-mkey)) + |1:keys.net:(got:orm points.state ~marbud) :: - :: TODO: make sure nobody else can change these keys == :: -:: TODO: transfer breach via transfer proxy ++ test-marbud-l2-proxies-transfer ^- tang - =/ marbud-new-keys [marbud-own %configure-keys encr auth suit |] - =/ marbud-sproxy [marbud-own %set-spawn-proxy (addr %marbud-skey)] - =/ marbud-mproxy [marbud-own %set-management-proxy (addr %marbud-mkey)] - =/ marbud-tproxy [marbud-own %set-transfer-proxy (addr %marbud-key-1)] - =/ marbud-transfer-breach [marbud-own %transfer-point (addr %marbud-key-1) &] - =/ marbud-transfer-no-breach [marbud-own %transfer-point (addr %marbud-key-1) |] - =/ marbud-xfr-breach [marbud-xfr %transfer-point (addr %marbud-key-1) &] - =/ marbud-xfr-no-breach [marbud-xfr %transfer-point (addr %marbud-key-1) |] + =/ marbud-new-keys + [0 [marbud-own %configure-keys encr auth suit |] %marbud-key-0] + =/ marbud-sproxy + [0 [marbud-own %set-spawn-proxy (addr %marbud-skey)] %marbud-key-0] + =/ marbud-mproxy + [1 [marbud-own %set-management-proxy (addr %marbud-mkey)] %marbud-key-0] + =/ marbud-tproxy + [2 [marbud-own %set-transfer-proxy (addr %marbud-key-1)] %marbud-key-0] + =/ marbud-transfer-breach + [1 [marbud-own %transfer-point (addr %marbud-key-1) &] %marbud-key-0] + =/ marbud-transfer-no-breach + [1 [marbud-own %transfer-point (addr %marbud-key-1) |] %marbud-key-0] + =/ marbud-xfr-breach + [0 [marbud-xfr %transfer-point (addr %marbud-key-1) &] %marbud-key-1] + =/ marbud-xfr-no-breach + [0 [marbud-xfr %transfer-point (addr %marbud-key-1) |] %marbud-key-1] + :: + =, l2-event-gen + =/ test1=tx-list + (ly marbud-sproxy marbud-mproxy marbud-tproxy marbud-xfr-breach ~) + =/ test2=tx-list + (ly marbud-new-keys marbud-transfer-breach ~) + =/ test3=tx-list + (ly marbud-sproxy marbud-mproxy marbud-tproxy marbud-xfr-no-breach ~) + =/ test4=tx-list + (ly marbud-new-keys marbud-transfer-no-breach ~) :: ;: weld %+ expect-eq @@ -1436,12 +2762,30 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-sproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 marbud-mproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 2 marbud-tproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 marbud-xfr-breach %marbud-key-1)) + =^ f state (n state %bat q:(gen-tx marbud-sproxy)) + =^ f state (n state %bat q:(gen-tx marbud-mproxy)) + =^ f state (n state %bat q:(gen-tx marbud-tproxy)) + =^ f state (n state %bat q:(gen-tx marbud-xfr-breach)) ^- [[@ @] [@ @] [@ @] [@ @] [@ @]] - own:(~(got by points.state) ~marbud) + own:(got:orm points.state ~marbud) + :: + %+ expect-eq + :: batch version + :: + !> + :* [(addr %marbud-key-1) 3] :: ownership + [0 0] :: spawn-proxy + [0 0] :: management-proxy + [0 0] :: voting-proxy + [0 1] :: transfer-proxy + == + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch test1)) + ^- [[@ @] [@ @] [@ @] [@ @] [@ @]] + own:(got:orm points.state ~marbud) :: %+ expect-eq :: Tests that networking keys are reset on transfer with breach @@ -1451,9 +2795,20 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-new-keys %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 marbud-transfer-breach %marbud-key-0)) - |1:keys.net:(~(got by points.state) ~marbud) + =^ f state (n state %bat q:(gen-tx marbud-new-keys)) + =^ f state (n state %bat q:(gen-tx marbud-transfer-breach)) + |1:keys.net:(got:orm points.state ~marbud) + :: + %+ expect-eq + :: batch version + !> + [0 0 0] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch test2)) + |1:keys.net:(got:orm points.state ~marbud) :: %+ expect-eq :: Tests that proxies are not reset when transfering without breach @@ -1468,12 +2823,29 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-sproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 marbud-mproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 2 marbud-tproxy %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 marbud-xfr-no-breach %marbud-key-1)) + =^ f state (n state %bat q:(gen-tx marbud-sproxy)) + =^ f state (n state %bat q:(gen-tx marbud-mproxy)) + =^ f state (n state %bat q:(gen-tx marbud-tproxy)) + =^ f state (n state %bat q:(gen-tx marbud-xfr-no-breach)) ^- [[@ @] [@ @] [@ @] [@ @] [@ @]] - own:(~(got by points.state) ~marbud) + own:(got:orm points.state ~marbud) + :: + %+ expect-eq + :: batch version + !> + :* [(addr %marbud-key-1) 3] :: ownership + [(addr %marbud-skey) 0] :: spawn-proxy + [(addr %marbud-mkey) 0] :: management-proxy + [0 0] :: voting-proxy + [0 1] :: transfer-proxy + == + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch test3)) + ^- [[@ @] [@ @] [@ @] [@ @] [@ @]] + own:(got:orm points.state ~marbud) :: %+ expect-eq :: Tests that networking keys are not reset when transfering without breach @@ -1483,21 +2855,39 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 marbud-new-keys %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 marbud-transfer-no-breach %marbud-key-0)) - |1:keys.net:(~(got by points.state) ~marbud) + =^ f state (n state %bat q:(gen-tx marbud-new-keys)) + =^ f state (n state %bat q:(gen-tx marbud-transfer-no-breach)) + |1:keys.net:(got:orm points.state ~marbud) + :: + %+ expect-eq + :: batch version + !> + [suit auth encr] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch test4)) + |1:keys.net:(got:orm points.state ~marbud) == :: :: TODO: life+rift changes via transfer proxy :: ++ test-marbud-life-rift ^- tang - =/ new-keys-no-reset [marbud-own %configure-keys encr auth suit |] - =/ new-keys-yes-reset [marbud-own %configure-keys encr auth suit &] - =/ zero-keys-no-reset [marbud-own %configure-keys 0 0 0 |] - =/ zero-keys-yes-reset [marbud-own %configure-keys 0 0 0 &] - =/ marbud-transfer-no-breach [marbud-own %transfer-point (addr %marbud-key-1) |] - =/ marbud-transfer-yes-breach [marbud-own %transfer-point (addr %marbud-key-1) &] - =/ marbud-own-1 [~marbud %marbud-key-1 %own] + =/ new-keys-no-reset + [marbud-own %configure-keys encr auth suit |] + =/ new-keys-yes-reset + [marbud-own %configure-keys encr auth suit &] + =/ zero-keys-no-reset + [marbud-own %configure-keys 0 0 0 |] + =/ zero-keys-yes-reset + [marbud-own %configure-keys 0 0 0 &] + =/ marbud-transfer-no-breach + [marbud-own %transfer-point (addr %marbud-key-1) |] + =/ marbud-transfer-yes-breach + [marbud-own %transfer-point (addr %marbud-key-1) &] + =/ marbud-own-1 + [~marbud %marbud-key-1 %own] :: ;: weld %+ expect-eq @@ -1509,7 +2899,7 @@ =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 new-keys-no-reset %marbud-key-0)) =^ f state (n state %bat q:(gen-tx 1 new-keys-no-reset %marbud-key-0)) - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: %+ expect-eq :: breach=%.y @@ -1519,7 +2909,7 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: %+ expect-eq :: networking keys set incremenets life, reset=%.y @@ -1530,10 +2920,16 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) :: inc life and rift - =^ f state (n state %bat q:(gen-tx 1 zero-keys-no-reset %marbud-key-0)) :: inc life - =^ f state (n state %bat q:(gen-tx 2 zero-keys-yes-reset %marbud-key-0)) :: inc rift - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + :: inc life and rift + =^ f state + (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) + :: inc life + =^ f state + (n state %bat q:(gen-tx 1 zero-keys-no-reset %marbud-key-0)) + :: inc rift + =^ f state + (n state %bat q:(gen-tx 2 zero-keys-yes-reset %marbud-key-0)) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: %+ expect-eq :: Keep the same keys while breaching via %configure-keys @@ -1543,9 +2939,13 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) :: inc life and rift - =^ f state (n state %bat q:(gen-tx 1 new-keys-yes-reset %marbud-key-0)) :: inc life and rift - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + :: inc life and rift + =^ f state + (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) + :: inc life and rift + =^ f state + (n state %bat q:(gen-tx 1 new-keys-yes-reset %marbud-key-0)) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: %+ expect-eq :: @@ -1554,11 +2954,13 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 new-keys-no-reset %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 1 marbud-transfer-no-breach %marbud-key-0)) - :: TODO: shouldn't the nonce by zero for the next tx? - =^ f state (n state %bat q:(gen-tx 2 zero-keys-yes-reset %marbud-key-1)) - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + =^ f state + (n state %bat q:(gen-tx 0 new-keys-no-reset %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 1 marbud-transfer-no-breach %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 2 zero-keys-yes-reset %marbud-key-1)) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: %+ expect-eq :: set networking keys, then transfer and set networking keys with breach @@ -1568,27 +2970,36 @@ !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 new-keys-no-reset %marbud-key-0)) :: inc life - =^ f state (n state %bat q:(gen-tx 1 marbud-transfer-yes-breach %marbud-key-0)) :: inc life and rift - :: TODO: shouldn't the nonce by zero for the next tx? - =^ f state (n state %bat q:(gen-tx 2 new-keys-no-reset %marbud-key-1)) ::inc life - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + :: inc life + =^ f state + (n state %bat q:(gen-tx 0 new-keys-no-reset %marbud-key-0)) + :: inc life and rift + =^ f state + (n state %bat q:(gen-tx 1 marbud-transfer-yes-breach %marbud-key-0)) + :: inc life + =^ f state + (n state %bat q:(gen-tx 2 new-keys-no-reset %marbud-key-1)) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: %+ expect-eq :: networking keys set incremenets life, reset=%.y :: then zero keys and transfer, should increment rift but not life - :: TODO: transferring and reset with already zeroed keys ought to incr rift but not life, right? - :: but currently the transfer w/ reset increments both life and rift, despite keys already being 0 :: !> [2 2] :: !> =| =^state:naive =^ f state (init-marbud state) - =^ f state (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) :: inc life and rift - =^ f state (n state %bat q:(gen-tx 1 zero-keys-no-reset %marbud-key-0)) :: inc life - =^ f state (n state %bat q:(gen-tx 2 marbud-transfer-yes-breach %marbud-key-0)) :: inc rift - [rift.net life.keys.net]:(~(got by points.state) ~marbud) + :: inc life and rift + =^ f state + (n state %bat q:(gen-tx 0 new-keys-yes-reset %marbud-key-0)) + :: inc life + =^ f state + (n state %bat q:(gen-tx 1 zero-keys-no-reset %marbud-key-0)) + :: inc rift + =^ f state + (n state %bat q:(gen-tx 2 marbud-transfer-yes-breach %marbud-key-0)) + [rift.net life.keys.net]:(got:orm points.state ~marbud) :: == :: @@ -1602,7 +3013,7 @@ =| =^state:naive =^ f state (init-dopbud state) =^ f state (n state %bat q:(gen-tx 0 pp-spawn %dopbud-key-0)) - transfer-proxy.own:(~(got by points.state) ~palsep-picdun) + transfer-proxy.own:(got:orm points.state ~palsep-picdun) :: ++ test-dopbud-l2-spawn-after-transfer ^- tang =/ pp-spawn [dopbud-own %spawn ~palsep-picdun (addr %pp-key-0)] @@ -1617,41 +3028,13 @@ =^ f state (n state %bat q:(gen-tx 0 pp-spawn %dopbud-key-0)) =^ f state (n state (owner-changed:l1 ~dopbud (addr %dopbud-key-1))) =^ f state (n state %bat q:(gen-tx 1 lr-spawn %dopbud-key-1)) - transfer-proxy.own:(~(got by points.state) ~laclur-rachul) -:: -:: ++ test-sambud-double-spawn ^- tang -:: :: -:: :: TODO: Not sure of the right way to write this test yet. Current iteration -:: :: doesn't even compile -:: :: -:: %- expect-fail -:: |. -:: ?< -:: ?= [`@ux`(addr %ld-key-1) 0] -:: =| =^state:naive -:: =^ f state (init-sambud state) -:: =^ f state (n state (owner-changed:l1 ~lisdur-fodrys (addr %ld-key-0))) -:: =^ f state (n state (changed-spawn-proxy:l1 ~sambud deposit-address:naive)) -:: =^ f state (n state %bat q:(spawn:l2 0 ~sambud %sambud-key-0 %own ~lisdur-fodrys (addr %ld-key-1))) -:: transfer-proxy.own:(~(got by points.state) ~lisdur-fodrys) -:: %.n -:: -:: ++ test-sambud-double-spawn-w-proxy ^- tang -:: :: -:: :: Same confusion as above -:: :: -:: %- expect-fail -:: |. -:: =| =^state:naive -:: =^ f state (init-sambud state) -:: =^ f state (n state (owner-changed:l1 ~lisdur-fodrys (addr %ld-key-0))) -:: =^ f state (n state (owner-changed:l1 ~sambud deposit-address:naive)) -:: =^ f state (n state %bat q:(spawn:l2 0 ~sambud %sambud-key-0 %own ~lisdur-fodrys (addr %ld-key-1))) -:: state + transfer-proxy.own:(got:orm points.state ~laclur-rachul) :: ++ test-linnup-torsyx-l2-transfer-ownership ^- tang - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [%transfer-point (addr %lt-key-0) &] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [%transfer-point (addr %lt-key-0) &] :: %+ expect-eq !> [`@ux`(addr %lt-key-0) 0] @@ -1660,13 +3043,17 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [lt-xfr lt-transfer-yes-breach] %lt-key-0)) - owner.own:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 [lt-xfr lt-transfer-yes-breach] %lt-key-0)) + owner.own:(got:orm points.state ~linnup-torsyx) :: ++ test-palsep-picdun-l2-transfer-ownership ^- tang - =/ pp-xfr [~palsep-picdun %transfer] - =/ pp-spawn [dopbud-own %spawn ~palsep-picdun (addr %pp-key-0)] - =/ pp-transfer-yes-breach [pp-xfr %transfer-point (addr %pp-key-0) &] + =/ pp-xfr + [~palsep-picdun %transfer] + =/ pp-spawn + [dopbud-own %spawn ~palsep-picdun (addr %pp-key-0)] + =/ pp-transfer-yes-breach + [pp-xfr %transfer-point (addr %pp-key-0) &] %+ expect-eq !> [`@ux`(addr %pp-key-0) 0] :: @@ -1675,11 +3062,13 @@ =^ f state (init-dopbud state) =^ f state (n state %bat q:(gen-tx 0 pp-spawn %dopbud-key-0)) =^ f state (n state %bat q:(gen-tx 0 pp-transfer-yes-breach %pp-key-0)) - owner.own:(~(got by points.state) ~palsep-picdun) + owner.own:(got:orm points.state ~palsep-picdun) :: ++ test-linnup-torsyx-l2-escape-request ^- tang - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [lt-xfr %transfer-point (addr %lt-key-0) &] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [lt-xfr %transfer-point (addr %lt-key-0) &] :: %+ expect-eq !> [~ ~litbud] @@ -1688,14 +3077,19 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (init-litbud state) - =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) - escape.net:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) + escape.net:(got:orm points.state ~linnup-torsyx) :: ++ test-linnup-torsyx-l2-cancel-escape-request ^- tang - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [lt-xfr %transfer-point (addr %lt-key-0) &] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [lt-xfr %transfer-point (addr %lt-key-0) &] :: %+ expect-eq !> ~ @@ -1704,15 +3098,21 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (init-litbud state) - =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 1 [lt-own [%cancel-escape ~litbud]] %lt-key-0)) - escape.net:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) + =^ f state + (n state %bat q:(gen-tx 1 [lt-own [%cancel-escape ~litbud]] %lt-key-0)) + escape.net:(got:orm points.state ~linnup-torsyx) :: ++ test-linnup-torsyx-l2-adopt-accept ^- tang - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [lt-xfr %transfer-point (addr %lt-key-0) &] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [lt-xfr %transfer-point (addr %lt-key-0) &] :: %+ expect-eq !> [~ %.y ~litbud] @@ -1721,17 +3121,22 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (init-litbud state) - =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [litbud-own [%adopt ~linnup-torsyx]] %litbud-key-0)) - [escape.net sponsor.net]:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) + =^ f state + %- n :+ state %bat =< q + (gen-tx 0 [litbud-own [%adopt ~linnup-torsyx]] %litbud-key-0) + [escape.net sponsor.net]:(got:orm points.state ~linnup-torsyx) :: ++ test-linnup-torsyx-l2-adopt-reject ^- tang - :: TODO: at the moment the default sponsor is always ~zod, but it should probably - :: be ~marbud here - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [lt-xfr %transfer-point (addr %lt-key-0) &] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [lt-xfr %transfer-point (addr %lt-key-0) &] :: %+ expect-eq !> ~ @@ -1740,15 +3145,22 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (init-litbud state) - =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 0 [litbud-own [%reject ~linnup-torsyx]] %litbud-key-0)) - escape.net:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 [lt-own [%escape ~litbud]] %lt-key-0)) + =^ f state + %- n :+ state %bat =< q + (gen-tx 0 [litbud-own [%reject ~linnup-torsyx]] %litbud-key-0) + escape.net:(got:orm points.state ~linnup-torsyx) :: ++ test-linnup-torsyx-l2-detach ^- tang - =/ lt-spawn [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] - =/ lt-transfer-yes-breach [lt-xfr %transfer-point (addr %lt-key-0) &] + =/ lt-spawn + [marbud-own %spawn ~linnup-torsyx (addr %lt-key-0)] + =/ lt-transfer-yes-breach + [lt-xfr %transfer-point (addr %lt-key-0) &] :: %+ expect-eq !> [~ %.n ~marbud] @@ -1757,36 +3169,562 @@ =| =^state:naive =^ f state (init-marbud state) =^ f state (init-litbud state) - =^ f state (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) - =^ f state (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) - =^ f state (n state %bat q:(gen-tx 1 [marbud-own [%detach ~linnup-torsyx]] %marbud-key-0)) - [escape.net sponsor.net]:(~(got by points.state) ~linnup-torsyx) + =^ f state + (n state %bat q:(gen-tx 0 lt-spawn %marbud-key-0)) + =^ f state + (n state %bat q:(gen-tx 0 lt-transfer-yes-breach %lt-key-0)) + =^ f state + %- n :+ state %bat =< q + (gen-tx 1 [marbud-own [%detach ~linnup-torsyx]] %marbud-key-0) + [escape.net sponsor.net]:(got:orm points.state ~linnup-torsyx) :: -:: TODO: signature format changed; regenerate +:: Fuzz tests. These just feed the L2 contract various forms of garbage. +:: They should all be no-ops. :: -:: ++ test-metamask-signature ^- tang -:: =/ meta-owner=address -:: (hex-to-num:ethereum '0xb026b0AA6e686F2386051b31A03E5fB95513e1c0') -:: =/ tx 0x123.0000.0102.0a00.0001.0200 -:: =/ sig -:: %- hex-to-num:ethereum -:: :: Must reverse endianness of tx to sign in metamask -:: :: -:: %^ cat 3 -:: '0x5b85936ab7b9db8d72416648e6eb1b844a4545ddb7c7c646a74bc3a4fb001a2' -:: '8583bf12ca837b289036a6cc9e6359ed07dda2b87929b5dd7189a3057a395341f1c' +++ test-fuzz-octs +:: this test just throws completely random octs at naive.hoon +:: + =+ [seed=`@`%test-fuzz-octs i=0] + =| =^state:naive + =^ f state init-red-simple + =/ init-state state + |- ^- tang + ?: =(i 10) ~ + %+ weld $(seed (shas `@`%versace seed), i +(i)) + =/ state init-state + =/ rng ~(. og seed) + =^ proxy rng (raws:rng 8) + =^ ship rng (raws:rng 32) + =^ action rng (raws:rng 8) + =^ junk-length rng (rads:rng 200) + :: increment junk-length to prevent 0 case + =^ junk rng (raws:rng +(junk-length)) + =^ nonce rng (rads:rng 999) + =^ key rng (raws:rng 256) + =/ fuzz=octs + %: cad:naive 3 + 1^proxy + 4^ship + 1^action + (met 3 junk)^junk + ~ + == + =/ random-tx + %^ sign-tx key nonce fuzz + :: + %+ expect-eq + !> init-state + :: :: + !> + =^ f state (n state %bat q:random-tx) + state +:: +++ test-fuzz-valid-ship-key +:: this test uses a valid ship and key but otherwise +:: hands the contract garbage +:: + =+ [seed=`@`%test-fuzz-valid-ship-key i=0] + =| =^state:naive + =^ f state init-red-simple + =/ init-state state + |- ^- tang + ?: =(i 100) ~ + %+ weld $(seed (shas `@`%iceberg-simpson seed), i +(i)) + =/ state init-state + =/ rng ~(. og seed) + =/ ship ~pinpun-pilsun + =^ proxy rng (raws:rng 8) + =^ action rng (raws:rng 8) + =^ junk-length rng (rads:rng 200) + :: increment junk-length to prevent 0 case + =^ junk rng (raws:rng +(junk-length)) + =^ nonce rng (rads:rng 999) + =/ fuzz=octs + %: cad:naive 3 + 1^proxy + 4^ship + 1^action + (met 3 junk)^junk + ~ + == + =/ random-tx + %^ sign-tx %losrut-pp-key-0 nonce fuzz + :: + %+ expect-eq + !> init-state + :: :: + !> + =^ f state (n state %bat q:random-tx) + state +:: +++ test-fuzz-valid-ship-key-proxy-nonce +:: this test uses a valid ship, key, proxy, nonce but otherwise +:: hands the contract garbage +:: + =+ [seed=`@`%test-fuzz-valid-ship-key-proxy-nonce i=0] + =| =^state:naive + =^ f state init-red-simple + =/ init-state state + |- ^- tang + ?: =(i 100) ~ + %+ weld $(seed (shas `@`%tiptoe seed), i +(i)) + =/ state init-state + =/ rng ~(. og seed) + =/ ship=@p ~pinpun-pilsun + =^ action rng (raws:rng 8) + =^ junk-length rng (rads:rng 200) + :: increment junk-length to prevent case of 0 + =^ junk rng (raws:rng +(junk-length)) + =/ fuzz=octs + %: cad:naive 3 + 1^(can 0 3^%0 5^0 ~) :: %own proxy + 4^ship + 1^action + (met 3 junk)^junk + ~ + == + =/ random-tx + %^ sign-tx %losrut-pp-key-0 1 fuzz + :: + %+ expect-eq + !> init-state + :: + !> + =^ f state (n state %bat q:random-tx) + state +:: +:: I think the following test ought to be trying something else: +:: checking to see if valid transactions followed by garbage still +:: process the valid tx +:: ++ test-fuzz-after-tx +:: :: this creates a valid transaction of each type but then adds +:: :: random bits to the end of it +:: :: +:: =+ [seed=`@`%test-fuzz-after-tx1 i=0] +:: =| =^state:naive +:: =^ f state init-red-simple +:: =/ init-state state +:: |- ^- tang +:: ?: =(i 11) ~ :: 10 attempts for each transaction type +:: %+ weld $(seed (shas `@`%howmuchisfour seed), i +(i)) +:: =+ j=0 +:: |^ ^- tang +:: ?: =(j 11) ~ :: there are 10 transaction types +:: %+ weld $(seed (shas `@`%eris seed), j +(j)) +:: =/ rng ~(. og seed) +:: =^ junk-length rng (rads:rng 200) +:: ::increment to prevent zero-length junk +:: =^ junk rng (raws:rng +(junk-length)) +:: =/ tx-octs=octs +:: ?+ j !! +:: %0 do-spawn +:: %1 do-transfer-point +:: %2 do-configure-keys +:: %3 do-escape +:: %4 do-cancel-escape +:: %5 do-adopt +:: %6 do-reject +:: %7 do-detach +:: %8 do-set-management-proxy +:: %9 do-set-spawn-proxy +:: %10 do-set-transfer-proxy +:: == +:: =/ fuzz (mix (lsh [3 (met 3 q:tx-octs)] junk) q:tx-octs) +:: =/ fuzz-octs=octs [(met 3 fuzz) fuzz] +:: :: the conditionals that follow are to ensure the correct key and +:: :: nonce are used. +:: =/ random-tx +:: ?: =(j 4) +:: %^ sign-tx %holrut-rr-key-0 1 fuzz-octs +:: ?: |(=(j 5) =(j 6)) +:: %^ sign-tx %rigred-key-0 0 fuzz-octs +:: %^ sign-tx %losrut-key-0 2 fuzz-octs :: :: +:: =/ state init-state +:: %+ category (weld "fuzz tx type " (scow %ud j)) :: %+ expect-eq -:: !> [0x123 0] +:: !> init-state :: :: :: !> -:: =| =^state:naive -:: =^ f state (init-marbud state) -:: :: =^ f state (n state %bat q:(transfer-point:l2 0 ~marbud (key ~marbud) %own &)) -:: :: =^ f state (n state %bat q:(set-transfer-proxy:l2 1 ~marbud %own 0x123)) -:: =^ f state -:: %^ n state %bat -:: q:(transfer-point:l2 0 ~marbud %marbud-key-0 meta-owner %own &) -:: =^ f state (n state %bat (cat 3 sig tx)) -:: transfer-proxy.own:(~(got by points.state) ~marbud) +:: =^ f state (n state %bat q:random-tx) +:: ~& ['tx-type' j] +:: state +:: :: +:: ++ do-spawn ^- octs +:: =/ from [ship=~losrut proxy=%own] +:: =/ sptx=skim-tx:naive [%spawn ~mishus-loplus (addr %nowhere)] +:: =/ tx=tx:naive [from sptx] +:: (gen-tx-octs tx) +:: ++ do-transfer-point ^- octs +:: =/ from [ship=~losrut proxy=%own] +:: =/ xrtx=skim-tx:naive [%transfer-point (addr %somewhere) &] +:: =/ tx=tx:naive [from xrtx] +:: (gen-tx-octs tx) +:: ++ do-configure-keys ^- octs +:: =/ from [ship=~losrut proxy=%own] +:: =/ cftx=skim-tx:naive +:: [%configure-keys (shax 'uno') (shax 'dos') (shax 'tres') |] +:: =/ tx=tx:naive [from cftx] +:: (gen-tx-octs tx) +:: ++ do-escape ^- octs +:: =/ from [ship=~losrut proxy=%own] +:: =/ estx=skim-tx:naive [%escape ~red] +:: =/ tx=tx:naive [from estx] +:: (gen-tx-octs tx) +:: ++ do-cancel-escape ^- octs +:: =/ from [ship=~rabsum-ravtyd proxy=%own] +:: =/ cetx=skim-tx:naive [%cancel-escape ~rigred] +:: =/ tx=tx:naive [from cetx] +:: (gen-tx-octs tx) +:: ++ do-adopt ^- octs +:: =/ from [ship=~rigred proxy=%own] +:: =/ adtx=skim-tx:naive [%adopt ~rabsum-ravtyd] +:: =/ tx=tx:naive [from adtx] +:: (gen-tx-octs tx) +:: ++ do-reject ^- octs +:: =/ from [ship=~rigred proxy=%own] +:: =/ rjtx=skim-tx:naive [%adopt ~rabsum-ravtyd] +:: =/ tx=tx:naive [from rjtx] +:: (gen-tx-octs tx) +:: ++ do-detach +:: =/ from [ship=~losrut proxy=%own] +:: =/ dttx=skim-tx:naive [%detach ~rabsum-ravtyd] +:: =/ tx=tx:naive [from dttx] +:: (gen-tx-octs tx) +:: ++ do-set-management-proxy +:: =/ from [ship=~losrut proxy=%own] +:: =/ mgtx=skim-tx:naive [%set-management-proxy (addr %new-mgmt)] +:: =/ tx=tx:naive [from mgtx] +:: (gen-tx-octs tx) +:: ++ do-set-spawn-proxy +:: =/ from [ship=~losrut proxy=%own] +:: =/ sptx=skim-tx:naive [%set-spawn-proxy (addr %new-spawn)] +:: =/ tx=tx:naive [from sptx] +:: (gen-tx-octs tx) +:: ++ do-set-transfer-proxy +:: =/ from [ship=~losrut proxy=%own] +:: =/ tftx=skim-tx:naive [%set-transfer-proxy (addr %new-xfer)] +:: =/ tx=tx:naive [from tftx] +:: (gen-tx-octs tx) +:: -- +:: +:: the following tests are to ensure that padding of zeroes creates +:: no issues +:: +++ test-zod-spawn-to-zero + =/ bz-spawn [[~zod %spawn] %spawn ~binzod 0x0] + :: + %+ expect-eq + !> [0x0 0] + :: + !> + =| =^state:naive + =^ f state (init-zod state) + =^ f state (n state %bat q:(gen-tx 0 bz-spawn %zod-skey-0)) + transfer-proxy.own:(got:orm points.state ~binzod) +:: +++ test-zod-spawn-proxy + =/ bz-spawn [[~zod %spawn] %spawn ~binzod (addr %binzod-key-0)] + :: + %+ expect-eq + !> [`@ux`(addr %binzod-key-0) 0] + :: + !> + =| =^state:naive + =^ f state (init-zod state) + =^ f state (n state %bat q:(gen-tx 0 bz-spawn %zod-skey-0)) + transfer-proxy.own:(got:orm points.state ~binzod) +:: +++ test-dopzod-spawn + =/ tm-spawn [[~dopzod %own] %spawn ~tasben-monbur (addr %tm)] + :: + %+ expect-eq + !> [`@ux`(addr %tm) 0] + :: + !> + =| =^state:naive + =^ f state (init-zod state) + =^ f state (n state %bat q:(gen-tx 0 tm-spawn %dopzod-key-0)) + transfer-proxy.own:(got:orm points.state ~tasben-monbur) +:: +++ test-address-padding + :: tells ~dopzod to spawn ~tasben-monbur at 0x00000000001111111111 + =/ spawn-octs=octs + %: cad:naive 3 + 1^(can 0 3^%0 5^0 ~) :: %own proxy + 4^~dopzod + 1^%1 :: %spawn + 4^~tasben-monbur + 20^(can 3 10^0 1^1 9^0 ~) + ~ + == + =/ signed-tx=octs + %^ sign-tx %dopzod-key-0 0 spawn-octs + :: + %+ expect-eq + !> [`@ux`(can 3 10^0 1^1 9^0 ~) 0] + :: + !> + =| =^state:naive + =^ f state (init-zod state) + =^ f state (n state %bat q:signed-tx) + transfer-proxy.own:(got:orm points.state ~tasben-monbur) +:: +:: TODO: L1 tests with leading zeroes. in particular, changing +:: keys uses data.log, so keys with leading zeroes might run into +:: issues +:: +++ test-batch-generation + =, l2-event-gen + =/ marbud-transfer [marbud-own %transfer-point (addr %marbud-key-0) |] + =/ marbud-transfer-2 [marbud-own %transfer-point (addr %marbud-key-1) |] + :: + =/ tx-1=full-tx [0 marbud-transfer %marbud-key-0] + =/ tx-2=full-tx [1 marbud-transfer-2 %marbud-key-0] + =/ txs=tx-list (limo ~[tx-1 tx-2]) + %+ expect-eq + !> [(addr %marbud-key-1) 2] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch txs)) + owner.own:(got:orm points.state ~marbud) +:: +++ test-changed-dns + :: uses actual data from ETH transaction + :: 0x51a26c3b100ad1c7aa8d593068df60465046d437edc3e939fadee4056791fd13 + :: + =/ data %- crip + ;: weld + "0x000000000000000000000000000000" + "00000000000000000000000000000000" + "60000000000000000000000000000000" + "00000000000000000000000000000000" + "a0000000000000000000000000000000" + "00000000000000000000000000000000" + "e0000000000000000000000000000000" + "00000000000000000000000000000000" + "0975726269742e6f7267000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "0975726269742e6f7267000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "00000000000000000000000000000000" + "0975726269742e6f7267000000000000" + "00000000000000000000000000000000" + "00" + == + :: + %+ expect-eq + !> `(list @t)`['urbit.org' 'urbit.org' 'urbit.org' ~] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state (changed-dns:l1 (hex-to-num:ethereum data))) + dns.state +:: +++ test-approval-for-all + =| operators=(jug address address) + =/ op1 (~(put ju operators) (addr %test1) (addr %test2)) + =/ del1 (~(del ju op1) (addr %test1) (addr %test2)) + =/ op2 (~(put ju op1) (addr %test1) (addr %test3)) + =/ del2 (~(del ju op2) (addr %test1) (addr %test2)) + :: + ;: weld + %+ expect-eq + !> op1 + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test2) 1)) + operators.state + :: + %+ expect-eq + !> del1 + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test2) 1)) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test2) 0)) + operators.state + :: + %+ expect-eq + !> op2 + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test2) 1)) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test3) 1)) + operators.state + :: + %+ expect-eq + !> del2 + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test2) 1)) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test3) 1)) + =^ f state + (n state (approval-for-all:l1 (addr %test1) (addr %test2) 0)) + operators.state + == +:: +++ test-metamask-signature ^- tang + =/ meta-owner=address + (hex-to-num:ethereum '0x57694bb21054b54d55e6c03387D082B3AFf902f6') + =/ tx-octs (gen-tx-octs [from=[~marbud %own] [%transfer-point 0x1234 &]]) + :: Must reverse endianness as below for Metamask signature + :: =/ signabletx (prepare-for-sig 1.337 1 tx-octs) + :: =/ signabletx-rev (rev 3 p.signabletx q.signabletx) + :: Generated with myetherwallet w/ metamask. + =/ sig + %- hex-to-num:ethereum + %^ cat 3 '0x2c331a47caeb758c617624882d99737eea96a492bf0af7a44c42fc5fd2' + 'c535c15c36704ab91688f4ef3735ab3fbd17a15f012dfd22ce5c5de62e03657113619a1c' + :: + %+ expect-eq + !> [0x1234 2] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state + %^ n state %bat + q:(gen-tx 0 [marbud-own %transfer-point meta-owner &] %marbud-key-0) + =^ f state (n state %bat (cat 3 sig q:tx-octs)) + owner.own:(got:orm points.state ~marbud) +:: +++ test-trezor-signature ^- tang + =/ trezor-owner=address + (hex-to-num:ethereum '0x9e00bb696bb406e14706ad47535bd1a449f3611e') + =/ tx-octs (gen-tx-octs [from=[~marbud %own] [%transfer-point 0x1234 &]]) + :: Must reverse endianness as below for Trezor signature + :: =/ signabletx (prepare-for-sig 1.337 1 tx-octs) + :: =/ signabletx-rev (rev 3 p.signabletx q.signabletx) + :: Generated with myetherwallet w/ Trezor Model T. + =/ sig + %- hex-to-num:ethereum + %^ cat 3 '0xb064428c293494dbee2967c1068807a8e241185c471cd547256708fe8d' + '2860ad7e8668aac3b61115c13aad325da87ed6c9526b495b2d996d6d43c060d00b12c21b' + :: + %+ expect-eq + !> [0x1234 2] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state + %^ n state %bat + q:(gen-tx 0 [marbud-own %transfer-point trezor-owner &] %marbud-key-0) + =^ f state (n state %bat (cat 3 sig q:tx-octs)) + owner.own:(got:orm points.state ~marbud) +:: +++ test-ledger-signatures ^- tang + :: We have two tests here to account for the different format of the v byte + :: in the signature as compared to MM and Trezor - it is 00 or 01 as opposed + :: to 1b or 1c. + =/ ledger-owner-1=address + (hex-to-num:ethereum '0xd6442b0668b478f407e08ff7215262e4118ccc12') + =/ ledger-owner-2=address + (hex-to-num:ethereum '0x8c611e9061a1e7bd77acb4c9869cdbca1346f70d') + =/ tx-octs (gen-tx-octs [from=[~marbud %own] [%transfer-point 0x1234 &]]) + :: Must reverse endianness as below for Trezor signature + :: =/ signabletx (prepare-for-sig 1.337 1 tx-octs) + :: =/ signabletx-rev (rev 3 p.signabletx q.signabletx) + :: Generated with myetherwallet w/ Ledger Nano S. + =/ sig-1 + %- hex-to-num:ethereum + %^ cat 3 '0x0f95347681767f9381dc82b1f26f2dbd4ccb56a98102f548b48d919b69' + '76749b70c71e3134d309b5974532af87ceaed7161cb1cdf3147f91a86d77371547a21101' + =/ sig-2 + %- hex-to-num:ethereum + %^ cat 3 '0xecb2ccff0167b5103484cea072e398426a7bce9fffa1b98ddfecd58a2f' + '80d99804737eeda2dc67147366f510af8e8cde4a97a007cc216439002498b368e2613e00' + :: + =| init-state=^state:naive + =^ f init-state (init-marbud init-state) + ;: weld + %+ expect-eq + !> [0x1234 2] + :: + !> + =| =^state:naive + =^ f state + %^ n init-state %bat + q:(gen-tx 0 [marbud-own %transfer-point ledger-owner-1 &] %marbud-key-0) + =^ f state (n state %bat (cat 3 sig-1 q:tx-octs)) + owner.own:(got:orm points.state ~marbud) + :: + %+ expect-eq + !> [0x1234 2] + :: + !> + =| =^state:naive + =^ f state + %^ n init-state %bat + q:(gen-tx 0 [marbud-own %transfer-point ledger-owner-2 &] %marbud-key-0) + =^ f state (n state %bat (cat 3 sig-2 q:tx-octs)) + owner.own:(got:orm points.state ~marbud) + == +:: +++ test-large-batch-parse ^- tang + =/ batch-size 5.000 :: should be an even number + =/ tx-1=tx:naive [marbud-own %transfer-point (addr %marbud-key-1) |] + =/ tx-2=tx:naive [marbud-own %transfer-point (addr %marbud-key-0) |] + :: + =/ bat=octs + %+ cad:naive 3 + %+ join + (gen-tx 1 tx-2 %marbud-key-1) + (reap +((div batch-size 2)) (gen-tx 0 tx-1 %marbud-key-0)) + :: + =| =^state:naive + =^ f state (init-marbud state) + %+ expect-eq + !> +(batch-size) + :: + !> + ~& > %starting-large-parse + =/ r (parse-roll:naive q.bat) + ~& > %ending-large-parse + (lent r) +:: +++ test-large-batch-full ^- tang + :: XX bump up to 5k + :: + =/ batch-size 50 :: should be an even number + :: + =/ tx-1=tx:naive [marbud-own %transfer-point (addr %marbud-key-1) |] + =/ tx-2=tx:naive [marbud-own %transfer-point (addr %marbud-key-0) |] + =/ batch=tx-list:l2-event-gen + %+ spun (join tx-2 (reap +((div batch-size 2)) tx-1)) + |= [b=tx:naive c=@] + ?: =((mod c 2) 0) + [[c b %marbud-key-0] +(c)] + [[c b %marbud-key-1] +(c)] + :: + %+ expect-eq + !> [`@ux`(addr %marbud-key-1) +(batch-size)] + :: + !> + =| =^state:naive + =^ f state (init-marbud state) + =^ f state (n state %bat (tx-list-to-batch:l2-event-gen batch)) + owner.own:(got:orm points.state ~marbud) +:: -- diff --git a/pkg/arvo/tests/sys/vane/clay.hoon b/pkg/arvo/tests/sys/vane/clay.hoon index 457a810db..cd8951206 100644 --- a/pkg/arvo/tests/sys/vane/clay.hoon +++ b/pkg/arvo/tests/sys/vane/clay.hoon @@ -85,7 +85,6 @@ |. =/ ford %: ford:fusion - bud *ankh:clay deletes=~ changes=(my [/lib/self/hoon &+hoon+source]~) @@ -101,7 +100,6 @@ ++ test-mar-mime ^- tang =/ ford %: ford:fusion - bud *ankh:clay deletes=~ changes=(my [/mar/mime/hoon &+hoon+mar-mime]~) @@ -122,7 +120,6 @@ ++ test-mar-udon ^- tang =/ ford %: ford:fusion - bud *ankh:clay deletes=~ ^= changes @@ -154,7 +151,6 @@ == =/ ford %: ford:fusion - bud *ankh:clay deletes=~ changes @@ -174,7 +170,6 @@ == =/ ford %: ford:fusion - bud *ankh:clay deletes=~ changes @@ -195,7 +190,6 @@ == =/ ford %: ford:fusion - bud *ankh:clay deletes=~ changes @@ -210,7 +204,6 @@ ++ test-gen-hello ^- tang =/ ford %: ford:fusion - bud *ankh:clay deletes=~ changes=(my [/gen/hello/hoon &+hoon+gen-hello]~) @@ -231,7 +224,6 @@ ++ test-lib-strandio ^- tang =/ ford %: ford:fusion - bud *ankh:clay deletes=~ ^= changes diff --git a/pkg/arvo/tests/sys/vane/eyre.hoon b/pkg/arvo/tests/sys/vane/eyre.hoon index 6710fa2ae..2439258e4 100644 --- a/pkg/arvo/tests/sys/vane/eyre.hoon +++ b/pkg/arvo/tests/sys/vane/eyre.hoon @@ -18,7 +18,7 @@ :: results1 :: -++ test-duplicate-bindings +++ test-overwrite-bindings :: =^ results1 eyre-gate %- eyre-call :* @@ -38,7 +38,7 @@ call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] expected-moves=[duct=~[/app1] %give %bound %.y [~ /]]~ == - :: app2 tries to bind to the same path and fails + :: app2 tries to bind to the same path and succeeds :: =^ results3 eyre-gate %- eyre-call :* @@ -46,7 +46,7 @@ now=~1111.1.3 scry=scry-provides-code call-args=[duct=~[/app2] ~ [%connect [~ /] %app2]] - expected-moves=[duct=~[/app2] %give %bound %.n [~ /]]~ + expected-moves=[duct=~[/app2] %give %bound %.y [~ /]]~ == :: ;: weld @@ -126,54 +126,6 @@ !>(%.n) !>((host-matches:eyre-gate `'example.com' `'blah.com')) == -:: -++ test-cant-remove-other-ducts-binding - :: - =^ results1 eyre-gate - %- eyre-call :* - eyre-gate - now=~1111.1.1 - scry=scry-provides-code - call-args=[duct=~[/init] ~ [%init ~]] - expected-moves=~ - == - :: app1 binds successfully - :: - =^ results2 eyre-gate - %- eyre-call :* - eyre-gate - now=~1111.1.2 - scry=scry-provides-code - call-args=[duct=~[/app1] ~ [%connect [~ /] %app1]] - expected-moves=[duct=~[/app1] %give %bound %.y [~ /]]~ - == - :: app2 tries to steal the binding by disconnecting the path - :: - =^ results3 eyre-gate - %- eyre-call :* - eyre-gate - now=~1111.1.3 - scry=scry-provides-code - call-args=[duct=~[/app2] ~ [%disconnect [~ /]]] - expected-moves=~ - == - :: app2 doesn't bind successfully because it couldn't remove app1's binding - :: - =^ results4 eyre-gate - %- eyre-call :* - eyre-gate - now=~1111.1.4 - scry=scry-provides-code - call-args=[duct=~[/app2] ~ [%connect [~ /] %app2]] - expected-moves=[duct=~[/app2] %give %bound %.n [~ /]]~ - == - :: - ;: weld - results1 - results2 - results3 - results4 - == :: tests that when we have no match, that we fall back to the built-in 404 :: ++ test-builtin-four-oh-four @@ -2346,6 +2298,7 @@ ++ scry-provides-code ^- roof |= [gang =view =beam] ^- (unit (unit cage)) + ?: =(%gd view) ``noun+!>(%base) ?: &(=(%ca view) =(/gen/handler/hoon s.beam)) :+ ~ ~ vase+!>(!>(|=(* |=(* [[%404 ~] ~])))) diff --git a/pkg/arvo/tests/sys/vane/gall.hoon b/pkg/arvo/tests/sys/vane/gall.hoon index f80820c74..43b8569d3 100644 --- a/pkg/arvo/tests/sys/vane/gall.hoon +++ b/pkg/arvo/tests/sys/vane/gall.hoon @@ -22,9 +22,9 @@ (gall-call gall-gate time *roof call-args expected-moves) :: -.res -:: +test-conf: test %conf; TODO: test clay response +:: +test-jolt: test %jolt; TODO: test clay response :: -++ test-conf +++ test-jolt ^- tang :: =/ =duct ~[/init] @@ -33,13 +33,13 @@ =/ ship ~nec :: =/ call-args - =/ =task:gall [%conf dap] + =/ =task:gall [%jolt %base dap] [duct task] :: =/ =move:gall-gate - =/ =wire /sys/cor/[dap]/(scot %p ship)/home/(scot %da time) + =/ =wire /sys/cor/[dap]/(scot %p ship)/base/(scot %da time) =/ =note-arvo - [%c %warp ship %home ~ %sing %a da+time /app/[dap]/hoon] + [%c %warp ship %base ~ %sing %a da+time /app/[dap]/hoon] [duct %pass wire note-arvo] :: =/ expected-moves=(list move:gall-gate) ~[move] diff --git a/pkg/arvo/tests/sys/zuse/crypto/scrypt.hoon b/pkg/arvo/tests/sys/zuse/crypto/scrypt.hoon index e943c196a..73e9dbf60 100644 --- a/pkg/arvo/tests/sys/zuse/crypto/scrypt.hoon +++ b/pkg/arvo/tests/sys/zuse/crypto/scrypt.hoon @@ -21,10 +21,7 @@ !> `@ux`(hsh pw salt n r p 64) :: ++ vectors - :: TODO: until scrypt has been jetted, we can only test the - :: first vector; the others do not finish in a reasonable - :: amount of time. - %+ scag 1 ^- (list vector) + ^- (list vector) :~ :* 0x0 @@ -37,8 +34,8 @@ == :: :* - 0x7061.7373.776f.7264 - 0x4e61.436c + `@ux`'password' + `@ux`'NaCl' 1.024 8 16 0xfdba.be1c.9d34.7200.7856.e719.0d01.e9fe. 7c6a.d7cb.c823.7830.e773.7663.4b37.3162. @@ -47,8 +44,8 @@ == :: :* - 0x70.6c65.6173.656c.6574.6d65.696e - 0x536f.6469.756d.4368.6c6f.7269.6465 + `@ux`'pleaseletmein' + `@ux`'SodiumChloride' 16.384 8 1 0x7023.bdcb.3afd.7348.461c.06cd.81fd.38eb. fda8.fbba.904f.8e3e.a9b5.43f6.545d.a1f2. @@ -57,8 +54,8 @@ == :: :* - 0x70.6c65.6173.656c.6574.6d65.696e - 0x536f.6469.756d.4368.6c6f.7269.6465 + `@ux`'pleaseletmein' + `@ux`'SodiumChloride' 1.048.576 8 1 0x2101.cb9b.6a51.1aae.addb.be09.cf70.f881. ec56.8d57.4a2f.fd4d.abe5.ee98.20ad.aa47. diff --git a/pkg/arvo/tmp/base.jam b/pkg/arvo/tmp/base.jam new file mode 100644 index 000000000..435ca593f --- /dev/null +++ b/pkg/arvo/tmp/base.jam @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d227633641c8abb68d16633e110467fd4a4330c921496312d75b471677e2a02 +size 3057639 diff --git a/pkg/arvo/tmp/bitcoin.jam b/pkg/arvo/tmp/bitcoin.jam new file mode 100644 index 000000000..87e36bb36 --- /dev/null +++ b/pkg/arvo/tmp/bitcoin.jam @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66e64f702b542347f1d8e267dc87c542e3f8f537278f6a221aa6d7d793b21d55 +size 461160 diff --git a/pkg/arvo/tmp/garden.jam b/pkg/arvo/tmp/garden.jam new file mode 100644 index 000000000..bc3a6971f --- /dev/null +++ b/pkg/arvo/tmp/garden.jam @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb475f30c6d6c68b3c31ce46155a1e3d98b18359b6750b7bb6b00e429187e1ef +size 376635 diff --git a/pkg/arvo/tmp/landscape.jam b/pkg/arvo/tmp/landscape.jam new file mode 100644 index 000000000..f31d727ea --- /dev/null +++ b/pkg/arvo/tmp/landscape.jam @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45a54c6e05e3db80b3cc9746a65f185da29d8644d7a0bf953fade9f15a78dad4 +size 1812725 diff --git a/pkg/arvo/tmp/webterm.jam b/pkg/arvo/tmp/webterm.jam new file mode 100644 index 000000000..726d88c1a --- /dev/null +++ b/pkg/arvo/tmp/webterm.jam @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fe9b7b9b38fa7f16f8ec234984c44c616856937eff50353e11eb62c173f6b09 +size 306377 diff --git a/pkg/base-dev/desk.bill b/pkg/base-dev/desk.bill new file mode 100644 index 000000000..7f45256db --- /dev/null +++ b/pkg/base-dev/desk.bill @@ -0,0 +1,5 @@ +:~ :- %apes + ~ + :- %fish + ~ +== diff --git a/pkg/base-dev/lib/agentio.hoon b/pkg/base-dev/lib/agentio.hoon new file mode 100644 index 000000000..9b0e45006 --- /dev/null +++ b/pkg/base-dev/lib/agentio.hoon @@ -0,0 +1,139 @@ +=> + |% + ++ card card:agent:gall + -- +:: +|_ =bowl:gall +++ scry + |= [desk=@tas =path] + %+ weld + /(scot %p our.bowl)/[desk]/(scot %da now.bowl) + path +:: +++ pass + |_ =wire + ++ poke + |= [=dock =cage] + [%pass wire %agent dock %poke cage] + :: + ++ poke-our + |= [app=term =cage] + ^- card + (poke [our.bowl app] cage) + :: + ++ poke-self + |= =cage + ^- card + (poke-our dap.bowl cage) + :: + ++ arvo + |= =note-arvo + ^- card + [%pass wire %arvo note-arvo] + :: + ++ watch + |= [=dock =path] + [%pass (watch-wire path) %agent dock %watch path] + :: + ++ watch-our + |= [app=term =path] + (watch [our.bowl app] path) + :: + ++ watch-wire + |= =path + ^+ wire + ?. ?=(~ wire) + wire + agentio-watch+path + :: + ++ leave + |= =dock + [%pass wire %agent dock %leave ~] + :: + ++ leave-our + |= app=term + (leave our.bowl app) + :: + ++ leave-path + |= [=dock =path] + =. wire + (watch-wire path) + (leave dock) + :: + ++ wait + |= p=@da + (arvo %b %wait p) + :: + ++ rest + |= p=@da + (arvo %b %wait p) + :: + ++ warp + |= [wer=ship =riff:clay] + (arvo %c %warp wer riff) + :: + ++ warp-our + |= =riff:clay + (warp our.bowl riff) + :: + :: right here, right now + ++ warp-slim + |= [genre=?(%sing %next) =care:clay =path] + =/ =mood:clay + [care r.byk.bowl path] + =/ =rave:clay + ?:(?=(%sing genre) [genre mood] [genre mood]) + (warp-our q.byk.bowl `rave) + :: + ++ connect + |= [=binding:eyre app=term] + (arvo %e %connect binding app) + -- +:: +++ fact-curry + |* [=mark =mold] + |= [paths=(list path) fac=mold] + (fact mark^!>(fac) paths) +:: +++ fact-kick + |= [=path =cage] + ^- (list card) + :~ (fact cage ~[path]) + (kick ~[path]) + == +:: +++ fact-init + |= =cage + ^- card + [%give %fact ~ cage] +:: +++ fact-init-kick + |= =cage + ^- (list card) + :~ (fact cage ~) + (kick ~) + == +:: +++ fact + |= [=cage paths=(list path)] + ^- card + [%give %fact paths cage] +:: +++ fact-all + |= =cage + ^- (unit card) + =/ paths=(set path) + %- ~(gas in *(set path)) + %+ turn ~(tap by sup.bowl) + |=([duct ship =path] path) + ?: =(~ paths) ~ + `(fact cage ~(tap in paths)) +:: +++ kick + |= paths=(list path) + [%give %kick paths ~] +:: +++ kick-only + |= [=ship paths=(list path)] + [%give %kick paths `ship] +-- diff --git a/pkg/base-dev/lib/azimuth.hoon b/pkg/base-dev/lib/azimuth.hoon new file mode 100644 index 000000000..0d42991ad --- /dev/null +++ b/pkg/base-dev/lib/azimuth.hoon @@ -0,0 +1,454 @@ +:: azimuth: constants and utilities +:: +/+ ethereum +:: +=> => [azimuth-types ethereum-types .] + |% + +$ complete-ship + $: state=point + history=(list diff-point) ::TODO maybe block/event nr? :: newest first + keys=(map life pass) + == + :: + ++ fleet (map @p complete-ship) + :: + ++ eth-type + |% + ++ point + :~ [%bytes-n 32] :: encryptionKey + [%bytes-n 32] :: authenticationKey + %bool :: hasSponsor + %bool :: active + %bool :: escapeRequested + %uint :: sponsor + %uint :: escapeRequestedTo + %uint :: cryptoSuiteVersion + %uint :: keyRevisionNumber + %uint :: continuityNumber + == + ++ deed + :~ %address :: owner + %address :: managementProxy + %address :: spawnProxy + %address :: votingProxy + %address :: transferProxy + == + -- + :: + ++ eth-noun + |% + +$ point + $: encryption-key=octs + authentication-key=octs + has-sponsor=? + active=? + escape-requested=? + sponsor=@ud + escape-to=@ud + crypto-suite=@ud + key-revision=@ud + continuity-number=@ud + == + +$ deed + $: owner=address + management-proxy=address + spawn-proxy=address + voting-proxy=address + transfer-proxy=address + == + -- + :: + ++ function + |% + ++ azimuth + $% [%points who=@p] + [%rights who=@p] + [%get-spawned who=@p] + [%dns-domains ind=@ud] + == + -- + :: + :: # diffs + :: + ++ update + $% [%full ships=(map ship point) dns=dnses heard=events] + [%difs dis=(list (pair event-id diff-azimuth))] + == + :: + :: # constants + :: + :: contract addresses + ++ contracts mainnet-contracts + ++ mainnet-contracts + |% + :: azimuth: data contract + :: + ++ azimuth + 0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb + :: + ++ ecliptic + 0x6ac0.7b7c.4601.b5ce.11de.8dfe.6335.b871.c7c4.dd4d + :: + ++ linear-star-release + 0x86cd.9cd0.992f.0423.1751.e376.1de4.5cec.ea5d.1801 + :: + ++ conditional-star-release + 0x8c24.1098.c3d3.498f.e126.1421.633f.d579.86d7.4aea + :: + ++ delegated-sending + 0xf790.8ab1.f1e3.52f8.3c5e.bc75.051c.0565.aeae.a5fb + :: + :: launch: block number of azimuth deploy + :: + ++ launch 6.784.800 + :: + :: public: block number of azimuth becoming independent + :: + ++ public 7.033.765 + -- + :: + :: Testnet contract addresses + :: + ++ ropsten-contracts + |% + ++ azimuth + 0x308a.b6a6.024c.f198.b57e.008d.0ac9.ad02.1988.6579 + :: + ++ ecliptic + 0x8b9f.86a2.8921.d9c7.05b3.113a.755f.b979.e1bd.1bce + :: + ++ linear-star-release + 0x1f8e.dd03.1ee4.1474.0aed.b39b.84fb.8f2f.66ca.422f + :: + ++ conditional-star-release + 0x0 + :: + ++ delegated-sending + 0x3e8c.a510.354b.c2fd.bbd6.1502.52d9.3105.c9c2.7bbe + :: + ++ launch 4.601.630 + ++ public launch + -- + :: + :: Local contract addresses + :: + :: These addresses are only reproducible if you use the deploy + :: script in bridge + :: + ++ local-contracts + |% + ++ ecliptic + 0x56db.68f2.9203.ff44.a803.faa2.404a.44ec.bb7a.7480 + ++ azimuth + 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 + ++ delegated-sending + 0xb71c.0b6c.ee1b.cae5.6dfe.95cd.9d3e.41dd.d7ea.fc43 + ++ linear-star-release + 0x3c3.dc12.be65.8158.d1d7.f9e6.6e08.ec40.99c5.68e4 + ++ conditional-star-release + 0x35eb.3b10.2d9c.1b69.ac14.69c1.b1fe.1799.850c.d3eb + ++ launch 0 + ++ public 0 + -- + :: + :: ++ azimuth 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 :: local bridge + :: hashes of ship event signatures + ++ azimuth-events + |% + :: + :: OwnerChanged(uint32,address) + ++ owner-changed + 0x16d0.f539.d49c.6cad.822b.767a.9445.bfb1. + cf7e.a6f2.a6c2.b120.a7ea.4cc7.660d.8fda + :: + :: Activated(uint32) + ++ activated + 0xe74c.0380.9d07.69e1.b1f7.06cc.8414.258c. + d1f3.b6fe.020c.d15d.0165.c210.ba50.3a0f + :: + :: Spawned(uint32,uint32) + ++ spawned + 0xb2d3.a6e7.a339.f5c8.ff96.265e.2f03.a010. + a854.1070.f374.4a24.7090.9644.1508.1546 + :: + :: EscapeRequested(uint32,uint32) + ++ escape-requested + 0xb4d4.850b.8f21.8218.141c.5665.cba3.79e5. + 3e9b.b015.b51e.8d93.4be7.0210.aead.874a + :: + :: EscapeCanceled(uint32,uint32) + ++ escape-canceled + 0xd653.bb0e.0bb7.ce83.93e6.24d9.8fbf.17cd. + a590.2c83.28ed.0cd0.9988.f368.90d9.932a + :: + :: EscapeAccepted(uint32,uint32) + ++ escape-accepted + 0x7e44.7c9b.1bda.4b17.4b07.96e1.00bf.7f34. + ebf3.6dbb.7fe6.6549.0b1b.fce6.246a.9da5 + :: + :: LostSponsor(uint32,uint32) + ++ lost-sponsor + 0xd770.4f9a.2519.3dbd.0b0c.b4a8.09fe.ffff. + a7f1.9d1a.ae88.17a7.1346.c194.4482.10d5 + :: + :: ChangedKeys(uint32,bytes32,bytes32,uint32,uint32) + ++ changed-keys + 0xaa10.e7a0.117d.4323.f1d9.9d63.0ec1.69be. + bb3a.988e.8957.70e3.5198.7e01.ff54.23d5 + :: + :: BrokeContinuity(uint32,uint32) + ++ broke-continuity + 0x2929.4799.f1c2.1a37.ef83.8e15.f79d.d91b. + cee2.df99.d63c.d1c1.8ac9.68b1.2951.4e6e + :: + :: ChangedSpawnProxy(uint32,address) + ++ changed-spawn-proxy + 0x9027.36af.7b3c.efe1.0d9e.840a.ed0d.687e. + 35c8.4095.122b.2505.1a20.ead8.866f.006d + :: + :: ChangedTransferProxy(uint32,address) + ++ changed-transfer-proxy + 0xcfe3.69b7.197e.7f0c.f067.93ae.2472.a9b1. + 3583.fecb.ed2f.78df.a14d.1f10.796b.847c + :: + :: ChangedManagementProxy(uint32,address) + ++ changed-management-proxy + 0xab9c.9327.cffd.2acc.168f.afed.be06.139f. + 5f55.cb84.c761.df05.e051.1c25.1e2e.e9bf + :: + :: ChangedVotingProxy(uint32,address) + ++ changed-voting-proxy + 0xcbd6.269e.c714.57f2.c7b1.a227.74f2.46f6. + c5a2.eae3.795e.d730.0db5.1768.0c61.c805 + :: + :: ChangedDns(string,string,string) + ++ changed-dns + 0xfafd.04ad.e1da.ae2e.1fdb.0fc1.cc6a.899f. + d424.063e.d5c9.2120.e67e.0730.53b9.4898 + -- + -- +:: +:: logic +:: +|% +++ pass-from-eth + |= [enc=octs aut=octs sut=@ud] + ^- pass + %^ cat 3 'b' + ?. &(=(1 sut) =(p.enc 32) =(p.aut 32)) + (cat 8 0 0) + (cat 8 q.aut q.enc) +:: +++ point-from-eth + |= [who=@p point:eth-noun deed:eth-noun] + ^- point + :: + :: ownership + :: + :+ :* owner + management-proxy + voting-proxy + transfer-proxy + == + :: + :: network state + :: + ?. active ~ + :- ~ + :* key-revision + :: + (pass-from-eth encryption-key authentication-key crypto-suite) + :: + continuity-number + :: + [has-sponsor `@p`sponsor] + :: + ?. escape-requested ~ + ``@p`escape-to + == + :: + :: spawn state + :: + ?. ?=(?(%czar %king) (clan:title who)) ~ + :- ~ + :* spawn-proxy + ~ ::TODO call getSpawned to fill this + == +:: +++ event-log-to-point-diff + =, azimuth-events + =, abi:ethereum + |= log=event-log:rpc:ethereum + ^- (unit (pair ship diff-point)) + ~? ?=(~ mined.log) %processing-unmined-event + :: + ?: =(i.topics.log owner-changed) + =/ [who=@ wer=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %owner wer] + :: + ?: =(i.topics.log activated) + =/ who=@ + (decode-topics t.topics.log ~[%uint]) + `[who %activated who] + :: + ?: =(i.topics.log spawned) + =/ [pre=@ who=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[pre %spawned who] + :: + ?: =(i.topics.log escape-requested) + =/ [who=@ wer=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[who %escape `wer] + :: + ?: =(i.topics.log escape-canceled) + =/ who=@ (decode-topics t.topics.log ~[%uint]) + `[who %escape ~] + :: + ?: =(i.topics.log escape-accepted) + =/ [who=@ wer=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[who %sponsor & wer] + :: + ?: =(i.topics.log lost-sponsor) + =/ [who=@ pos=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[who %sponsor | pos] + :: + ?: =(i.topics.log changed-keys) + =/ who=@ (decode-topics t.topics.log ~[%uint]) + =/ [enc=octs aut=octs sut=@ud rev=@ud] + %+ decode-results data.log + ~[[%bytes-n 32] [%bytes-n 32] %uint %uint] + `[who %keys rev (pass-from-eth enc aut sut)] + :: + ?: =(i.topics.log broke-continuity) + =/ who=@ (decode-topics t.topics.log ~[%uint]) + =/ num=@ (decode-results data.log ~[%uint]) + `[who %continuity num] + :: + ?: =(i.topics.log changed-management-proxy) + =/ [who=@ sox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %management-proxy sox] + :: + ?: =(i.topics.log changed-voting-proxy) + =/ [who=@ tox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %voting-proxy tox] + :: + ?: =(i.topics.log changed-spawn-proxy) + =/ [who=@ sox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %spawn-proxy sox] + :: + ?: =(i.topics.log changed-transfer-proxy) + =/ [who=@ tox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %transfer-proxy tox] + :: + :: warn about unimplemented events, but ignore + :: the ones we know are harmless. + ~? ?! .= i.topics.log + :: OwnershipTransferred(address,address) + 0x8be0.079c.5316.5914.1344.cd1f.d0a4.f284. + 1949.7f97.22a3.daaf.e3b4.186f.6b64.57e0 + [%unimplemented-event i.topics.log] + ~ +:: +++ apply-point-diff + |= [pot=point dif=diff-point] + ^- point + ?- -.dif + %full new.dif + :: + %activated + %_ pot + net `[0 0 0 &^(^sein:title who.dif) ~] + kid ?. ?=(?(%czar %king) (clan:title who.dif)) ~ + `[0x0 ~] + == + :: + :: ownership + :: + %owner pot(owner.own new.dif) + %transfer-proxy pot(transfer-proxy.own new.dif) + %management-proxy pot(management-proxy.own new.dif) + %voting-proxy pot(voting-proxy.own new.dif) + :: + :: networking + :: + ?(%keys %continuity %sponsor %escape) + ?> ?=(^ net.pot) + ?- -.dif + %keys + pot(life.u.net life.dif, pass.u.net pass.dif) + :: + %sponsor + %= pot + sponsor.u.net new.dif + escape.u.net ?:(has.new.dif ~ escape.u.net.pot) + == + :: + %continuity pot(continuity-number.u.net new.dif) + %escape pot(escape.u.net new.dif) + == + :: + :: spawning + :: + ?(%spawned %spawn-proxy) + ?> ?=(^ kid.pot) + ?- -.dif + %spawned + =- pot(spawned.u.kid -) + (~(put in spawned.u.kid.pot) who.dif) + :: + %spawn-proxy pot(spawn-proxy.u.kid new.dif) + == + == +:: +++ parse-id + |= id=@t + ^- azimuth:function + |^ + ~| id + %+ rash id + ;~ pose + (function %points 'points' shipname) + (function %get-spawned 'getSpawned' shipname) + (function %dns-domains 'dnsDomains' dem:ag) + == + :: + ++ function + |* [tag=@tas fun=@t rul=rule] + ;~(plug (cold tag (jest fun)) (ifix [pal par] rul)) + :: + ++ shipname + ;~(pfix sig fed:ag) + -- +:: +++ function-to-call + |% + ++ azimuth + |= cal=azimuth:function + ^- [id=@t dat=call-data:rpc:ethereum] + ?- -.cal + %points + :- (crip "points({(scow %p who.cal)})") + ['points(uint32)' ~[uint+`@`who.cal]] + :: + %rights + :- (crip "rights({(scow %p who.cal)})") + ['rights(uint32)' ~[uint+`@`who.cal]] + :: + %get-spawned + :- (crip "getSpawned({(scow %p who.cal)})") + ['getSpawned(uint32)' ~[uint+`@`who.cal]] + :: + %dns-domains + :- (crip "dnsDomains({(scow %ud ind.cal)})") + ['dnsDomains(uint256)' ~[uint+ind.cal]] + == + -- +-- diff --git a/pkg/base-dev/lib/azimuthio.hoon b/pkg/base-dev/lib/azimuthio.hoon new file mode 100644 index 000000000..979c34704 --- /dev/null +++ b/pkg/base-dev/lib/azimuthio.hoon @@ -0,0 +1,146 @@ +/- rpc=json-rpc +/+ ethereum, azimuth, strandio +=, strand=strand:strandio +=, jael +|% +++ tract azimuth:contracts:azimuth +++ fetch-point + |= [url=@ta who=ship] + =/ m (strand ,point:azimuth) + ^- form:m + =/ =request:rpc:ethereum + :+ %eth-call + =- [from=~ to=tract gas=~ price=~ value=~ data=-] + (encode-call:rpc:ethereum 'points(uint32)' [%uint `@`who]~) + [%label %latest] + ;< jon=json bind:m (request-rpc url `'point' request) + =/ res=cord (so:dejs:format jon) + =/ =point:eth-noun:azimuth + (decode-results:abi:ethereum res point:eth-type:azimuth) + :: + =/ =request:rpc:ethereum + :+ %eth-call + =- [from=~ to=tract gas=~ price=~ value=~ data=-] + (encode-call:rpc:ethereum 'rights(uint32)' [%uint `@`who]~) + [%label %latest] + ;< jon=json bind:m (request-rpc url `'deed' request) + =/ res=cord (so:dejs:format jon) + =/ =deed:eth-noun:azimuth + (decode-results:abi:ethereum res deed:eth-type:azimuth) + :: + (pure:m (point-from-eth:azimuth who point deed)) +:: +++ request-rpc + |= [url=@ta id=(unit @t) req=request:rpc:ethereum] + =/ m (strand ,json) + ^- form:m + %+ (retry json) `10 + =/ m (strand ,(unit json)) + ^- form:m + |^ + =/ =request:http + :* method=%'POST' + url=url + header-list=['Content-Type'^'application/json' ~] + ^= body + %- some %- as-octt:mimes:html + %- en-json:html + (request-to-json:rpc:ethereum id req) + == + ;< ~ bind:m (send-request:strandio request) + ;< rep=(unit client-response:iris) bind:m + take-maybe-response:strandio + ?~ rep + (pure:m ~) + (parse-response u.rep) + :: + ++ parse-response + |= =client-response:iris + =/ m (strand ,(unit json)) + ^- form:m + ?> ?=(%finished -.client-response) + ?~ full-file.client-response + (pure:m ~) + =/ body=@t q.data.u.full-file.client-response + =/ jon=(unit json) (de-json:html body) + ?~ jon + (pure:m ~) + =, dejs-soft:format + =/ array=(unit (list response:rpc)) + ((ar parse-one-response) u.jon) + ?~ array + =/ res=(unit response:rpc) (parse-one-response u.jon) + ?~ res + (strand-fail:strandio %request-rpc-parse-error >id< ~) + ?: ?=(%error -.u.res) + (strand-fail:strandio %request-rpc-error >id< >+.res< ~) + ?. ?=(%result -.u.res) + (strand-fail:strandio %request-rpc-fail >u.res< ~) + (pure:m `res.u.res) + (strand-fail:strandio %request-rpc-batch >%not-implemented< ~) + :: (pure:m `[%batch u.array]) + :: + ++ parse-one-response + |= =json + ^- (unit response:rpc) + =/ res=(unit [@t ^json]) + %. json + =, dejs-soft:format + (ot id+so result+some ~) + ?^ res `[%result u.res] + ~| parse-one-response=json + :+ ~ %error %- need + %. json + =, dejs-soft:format + (ot id+so error+(ot code+no message+so ~) ~) + -- +:: +++ retry + |* result=mold + |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))] + =/ m (strand ,result) + =| try=@ud + |- ^- form:m + =* loop $ + ?: =(crash-after `try) + (strand-fail:strandio %retry-too-many ~) + ;< ~ bind:m (backoff:strandio try ~m1) + ;< res=(unit result) bind:m computation + ?^ res + (pure:m u.res) + loop(try +(try)) +:: +++ get-latest-block + |= url=@ta + =/ m (strand ,block) + ^- form:m + ;< =json bind:m (request-rpc url `'block number' %eth-block-number ~) + (get-block-by-number url (parse-eth-block-number:rpc:ethereum json)) +:: +++ get-block-by-number + |= [url=@ta =number:block] + =/ m (strand ,block) + ^- form:m + |^ + ;< =json bind:m + (request-rpc url `'block by number' %eth-get-block-by-number number |) + =/ =block (parse-block json) + ?. =(number number.id.block) + (strand-fail:strandio %reorg-detected >number< >block< ~) + (pure:m block) + :: + ++ parse-block + |= =json + ^- block + =< [[&1 &2] |2] + ^- [@ @ @] + ~| json + %. json + =, dejs:format + %- ot + :~ hash+parse-hex-result:rpc:ethereum + number+parse-hex-result:rpc:ethereum + 'parentHash'^parse-hex-result:rpc:ethereum + == + -- +-- diff --git a/pkg/base-dev/lib/bip/b158.hoon b/pkg/base-dev/lib/bip/b158.hoon new file mode 100644 index 000000000..eb0eb7f0f --- /dev/null +++ b/pkg/base-dev/lib/bip/b158.hoon @@ -0,0 +1,249 @@ +/- bc=bitcoin +/+ bcu=bitcoin-utils +|% +++ params + |% + ++ p 19 + ++ m 784.931 + -- +:: +++ siphash + |= [k=byts m=byts] + ^- byts + |^ + ?> =(wid.k 16) + ?> (lte (met 3 dat.k) wid.k) + ?> (lte (met 3 dat.m) wid.m) + =. k (flim:sha k) + =. m (flim:sha m) + (flim:sha (fin (comp m (init dat.k)))) + :: Initialise internal state + :: + ++ init + |= k=@ + ^- [@ @ @ @] + =/ k0=@ (end [6 1] k) + =/ k1=@ (cut 6 [1 1] k) + :^ (mix k0 0x736f.6d65.7073.6575) + (mix k1 0x646f.7261.6e64.6f6d) + (mix k0 0x6c79.6765.6e65.7261) + (mix k1 0x7465.6462.7974.6573) + :: + :: Compression rounds + ++ comp + |= [m=byts v=[v0=@ v1=@ v2=@ v3=@]] + ^- [@ @ @ @] + =/ len=@ud (div wid.m 8) + =/ last=@ (lsh [3 7] (mod wid.m 256)) + =| i=@ud + =| w=@ + |- + =. w (cut 6 [i 1] dat.m) + ?: =(i len) + =. v3.v (mix v3.v (mix last w)) + =. v (rnd (rnd v)) + =. v0.v (mix v0.v (mix last w)) + v + %= $ + v =. v3.v (mix v3.v w) + =. v (rnd (rnd v)) + =. v0.v (mix v0.v w) + v + i (add i 1) + == + :: + :: Finalisation rounds + ++ fin + |= v=[v0=@ v1=@ v2=@ v3=@] + ^- byts + =. v2.v (mix v2.v 0xff) + =. v (rnd (rnd (rnd (rnd v)))) + :- 8 + :(mix v0.v v1.v v2.v v3.v) + :: + :: Sipround + ++ rnd + |= [v0=@ v1=@ v2=@ v3=@] + ^- [@ @ @ @] + =. v0 (~(sum fe 6) v0 v1) + =. v2 (~(sum fe 6) v2 v3) + =. v1 (~(rol fe 6) 0 13 v1) + =. v3 (~(rol fe 6) 0 16 v3) + =. v1 (mix v1 v0) + =. v3 (mix v3 v2) + =. v0 (~(rol fe 6) 0 32 v0) + =. v2 (~(sum fe 6) v2 v1) + =. v0 (~(sum fe 6) v0 v3) + =. v1 (~(rol fe 6) 0 17 v1) + =. v3 (~(rol fe 6) 0 21 v3) + =. v1 (mix v1 v2) + =. v3 (mix v3 v0) + =. v2 (~(rol fe 6) 0 32 v2) + [v0 v1 v2 v3] + -- +:: +str: bit streams +:: read is from the front +:: write appends to the back +:: +++ str + |% + ++ read-bit + |= s=bits:bc + ^- [bit=@ub rest=bits:bc] + ?> (gth wid.s 0) + :* ?:((gth wid.s (met 0 dat.s)) 0b0 0b1) + [(dec wid.s) (end [0 (dec wid.s)] dat.s)] + == + :: + ++ read-bits + |= [n=@ s=bits:bc] + ^- [bits:bc rest=bits:bc] + =| bs=bits:bc + |- + ?: =(n 0) [bs s] + =^ b s (read-bit s) + $(n (dec n), bs (write-bits bs [1 b])) + :: + ++ write-bits + |= [s1=bits:bc s2=bits:bc] + ^- bits:bc + [(add wid.s1 wid.s2) (can 0 ~[s2 s1])] + -- +:: +gol: Golomb-Rice encoding/decoding +:: +++ gol + |% + :: +en: encode x and append to end of s + :: - s: bits stream + :: - x: number to add to the stream + :: - p: golomb-rice p param + :: + ++ en + |= [s=bits:bc x=@ p=@] + ^- bits:bc + =+ q=(rsh [0 p] x) + =+ unary=[+(q) (lsh [0 1] (dec (bex q)))] + =+ r=[p (end [0 p] x)] + %+ write-bits:str s + (write-bits:str unary r) + :: + ++ de + |= [s=bits:bc p=@] + ^- [delta=@ rest=bits:bc] + |^ ?> (gth wid.s 0) + =^ q s (get-q s) + =^ r s (read-bits:str p s) + [(add dat.r (lsh [0 p] q)) s] + :: + ++ get-q + |= s=bits:bc + =| q=@ + =^ first-bit s (read-bit:str s) + |- + ?: =(0 first-bit) [q s] + =^ b s (read-bit:str s) + $(first-bit b, q +(q)) + -- + -- +:: +hsh +:: +++ hsh + |% + :: +to-range + :: - item: scriptpubkey to hash + :: - f: N*M + :: - k: key for siphash (end of blockhash, reversed) + :: + ++ to-range + |= [item=byts f=@ k=byts] + ^- @ + (rsh [0 64] (mul f (swp 3 dat:(siphash k item)))) + :: +set-construct: return sorted hashes of scriptpubkeys + :: + ++ set-construct + |= [items=(list byts) k=byts f=@] + ^- (list @) + %+ sort + %+ turn items + |= item=byts + (to-range item f k) + lth + -- +:: +++ parse-filter + |= filter=hexb:bc + ^- [n=@ux gcs-set=bits:bc] + =/ n n:(de:csiz:bcu filter) + =/ lead=@ ?:(=(1 wid.n) 1 +(wid.n)) + :- dat.n + [(mul 8 (sub wid.filter lead)) `@ub`dat:(drop:byt:bcu lead filter)] +:: +to-key: blockhash (little endian) to key for siphash +:: +++ to-key + |= blockhash=tape + ^- byts + %+ take:byt:bcu 16 + %- flip:byt:bcu + (from-cord:hxb:bcu (crip blockhash)) +:: +match: whether block filter matches *any* target scriptpubkeys +:: - filter: full block filter, with leading N +:: - k: key for siphash (end of blockhash, reversed) +:: - targets: scriptpubkeys to match +:: +++ match + |= [filter=hexb:bc k=byts targets=(list byts)] + ^- ? + =/ [p=@ m=@] [p:params m:params] + =/ [n=@ux gcs-set=bits:bc] (parse-filter filter) + =+ target-hs=(set-construct:hsh targets k (mul n m)) + =+ last-val=0 + |- + ?~ target-hs %.n + ?: =(last-val i.target-hs) + %.y + ?: (gth last-val i.target-hs) + $(target-hs t.target-hs) + :: last-val is less than target: check next val in GCS, if any + :: + ?: (lth wid.gcs-set p) %.n + =^ delta gcs-set + (de:gol gcs-set p) + $(last-val (add delta last-val)) +:: +all-match: returns all target byts that match +:: - filter: full block filter, with leading N +:: - targets: scriptpubkeys to match +:: +++ all-match + |= [filter=hexb:bc blockhash=hexb:bc targets=(list [address:bc byts])] + ^- (set [address:bc hexb:bc]) + =/ k (to-key (trip (to-cord:hxb:bcu blockhash))) + %- ~(gas in *(set [address:bc hexb:bc])) + =/ [p=@ m=@] [p:params m:params] + =/ [n=@ux gcs-set=bits:bc] (parse-filter filter) + =/ target-map=(map @ [address:bc hexb:bc]) + %- ~(gas by *(map @ [address:bc hexb:bc])) + %+ turn targets + |= [a=address:bc t=hexb:bc] + [(to-range:hsh t (mul n m) k) a t] + =+ target-hs=(sort ~(tap in ~(key by target-map)) lth) + =+ last-val=0 + =| matches=(list @) + |- + ?~ target-hs + (murn matches ~(get by target-map)) + ?: =(last-val i.target-hs) + %= $ + target-hs t.target-hs + matches [last-val matches] + == + ?: (gth last-val i.target-hs) + $(target-hs t.target-hs) + :: last-val is less than target: get next val in GCS, if any + :: + ?: (lth wid.gcs-set p) + (murn matches ~(get by target-map)) + =^ delta gcs-set + (de:gol gcs-set p) + $(last-val (add delta last-val)) +:: +-- diff --git a/pkg/base-dev/lib/bip/b173.hoon b/pkg/base-dev/lib/bip/b173.hoon new file mode 100644 index 000000000..e2c46db1a --- /dev/null +++ b/pkg/base-dev/lib/bip/b173.hoon @@ -0,0 +1,144 @@ +:: BIP173: Bech32 Addresses +:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +:: +:: Heavily copies: +:: https://github.com/bitcoinjs/bech32/blob/master/index.js +:: +/- sur=bitcoin +/+ bcu=bitcoin-utils +=, sur +=, bcu +|% +++ prefixes + ^- (map network tape) + (my [[%main "bc"] [%testnet "tb"] ~]) +++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l" ++$ raw-decoded [hrp=tape data=(list @) checksum=(list @)] +:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js +:: +++ polymod + |= values=(list @) + |^ ^- @ + =/ gen=(list @ux) + ~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3] + =/ chk=@ 1 + |- ?~ values chk + =/ top (rsh [0 25] chk) + =. chk + (mix i.values (lsh [0 5] (dis chk 0x1ff.ffff))) + $(values t.values, chk (update-chk chk top gen)) +:: + ++ update-chk + |= [chk=@ top=@ gen=(list @ux)] + =/ is (gulf 0 4) + |- ?~ is chk + ?: =(1 (dis 1 (rsh [0 i.is] top))) + $(is t.is, chk (mix chk (snag i.is gen))) + $(is t.is) + -- +:: +++ expand-hrp + |= hrp=tape + ^- (list @) + =/ front (turn hrp |=(p=@tD (rsh [0 5] p))) + =/ back (turn hrp |=(p=@tD (dis 31 p))) + (zing ~[front ~[0] back]) +:: +++ verify-checksum + |= [hrp=tape data-and-checksum=(list @)] + ^- ? + %- |=(a=@ =(1 a)) + %- polymod + (weld (expand-hrp hrp) data-and-checksum) +:: +++ checksum + |= [hrp=tape data=(list @)] + ^- (list @) + :: xor 1 with the polymod + :: + =/ pmod=@ + %+ mix 1 + %- polymod + (zing ~[(expand-hrp hrp) data (reap 6 0)]) + %+ turn (gulf 0 5) + |=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod))) +:: +++ charset-to-value + |= c=@tD + ^- (unit @) + (find ~[c] charset) +++ value-to-charset + |= value=@ + ^- (unit @tD) + ?: (gth value 31) ~ + `(snag value charset) +:: +++ is-valid + |= [bech=tape last-1-pos=@] ^- ? + ?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech + (gte last-1-pos 1) + (lte (add last-1-pos 7) (lent bech)) + (lte (lent bech) 90) + (levy bech |=(c=@tD (gte c 33))) + (levy bech |=(c=@tD (lte c 126))) + == +:: data should be 5bit words +:: +++ encode-raw + |= [hrp=tape data=(list @)] + ^- cord + =/ combined=(list @) + (weld data (checksum hrp data)) + %- crip + (zing ~[hrp "1" (tape (murn combined value-to-charset))]) +++ decode-raw + |= body=cord + ^- (unit raw-decoded) + =/ bech (cass (trip body)) :: to lowercase + =/ pos (flop (fand "1" bech)) + ?~ pos ~ + =/ last-1=@ i.pos + ?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum) + ~ + =/ hrp (scag last-1 bech) + =/ encoded-data-and-checksum=(list @) + (slag +(last-1) bech) + =/ data-and-checksum=(list @) + %+ murn encoded-data-and-checksum + charset-to-value + ?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET + ~ + ?. (verify-checksum hrp data-and-checksum) + ~ + =/ checksum-pos (sub (lent data-and-checksum) 6) + `[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)] +:: +from-address: BIP173 bech32 address encoding to hex +:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +:: expects to drop a leading 5-bit 0 (the witness version) +:: +++ from-address + |= body=cord + ^- hexb + ~| "Invalid bech32 address" + =/ d=(unit raw-decoded) (decode-raw body) + ?> ?=(^ d) + =/ bs=bits (from-atoms:bit 5 data.u.d) + =/ byt-len=@ (div (sub wid.bs 5) 8) + ?> =(5^0b0 (take:bit 5 bs)) + ?> ?| =(20 byt-len) + =(32 byt-len) + == + [byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))] +:: pubkey is the 33 byte ECC compressed public key +:: +++ encode-pubkey + |= [=network pubkey=byts] + ^- (unit cord) + ?. =(33 wid.pubkey) + ~|('pubkey must be a 33 byte ECC compressed public key' !!) + =/ prefix (~(get by prefixes) network) + ?~ prefix ~ + :- ~ + %+ encode-raw u.prefix + [0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])] +-- diff --git a/pkg/base-dev/lib/bip/b174.hoon b/pkg/base-dev/lib/bip/b174.hoon new file mode 100644 index 000000000..3bae71d92 --- /dev/null +++ b/pkg/base-dev/lib/bip/b174.hoon @@ -0,0 +1,182 @@ +:: BIP174: PSBTs +:: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki +:: +/- sur=bitcoin +/+ bcu=bitcoin-utils +=, sur +=, bcu +|% +++ en + |% + ++ globals + |= rawtx=hexb + ^- map:psbt + :~ [[1 0x0] rawtx] + == + :: + ++ input + |= [only-witness=? i=in:psbt] + ^- map:psbt + %+ weld + ?: only-witness ~ + ~[[1^0x0 rawtx.i]] + :~ (witness-tx i) + (hdkey %input hdkey.i) + == + :: + ++ output + |= =out:psbt + ^- map:psbt + ?~ hk.out ~ + :~ (hdkey %output u.hk.out) + == + :: + ++ witness-tx + |= i=in:psbt + ^- keyval:psbt + :- [1 0x1] + %- cat:byt + :~ (flip:byt 8^value.utxo.i) + 1^0x16 + 2^0x14 + (hash-160 pubkey.hdkey.i) + == + :: + ++ hdkey + |= [=target:psbt h=^hdkey] + ^- keyval:psbt + =/ typ=@ux + ?- target + %input 0x6 + %output 0x2 + == + =/ coin-type=hexb + ?- network.h + %main + 1^0x0 + %testnet + 1^0x1 + == + :- (cat:byt ~[1^typ pubkey.h]) + %- cat:byt + :~ fprint.h + 1^`@ux`bipt.h 3^0x80 + coin-type 3^0x80 + 4^0x80 + 1^`@ux`chyg.h 3^0x0 + (flip:byt 4^idx.h) + == + :: + ++ keyval-byts + |= kv=keyval:psbt + ^- hexb + %- cat:byt + :~ 1^wid.key.kv + key.kv + 1^wid.val.kv + val.kv + == + :: + ++ map-byts + |= m=map:psbt + ^- (unit hexb) + ?~ m ~ + :- ~ + %- cat:byt + (turn m keyval-byts) + -- + ++ base64 + |= b=hexb + ^- base64:psbt + %- en:base64:mimes:html + (flip:byt b) +:: +encode: make base64 cord of PSBT +:: - only-witness: don't include non-witness UTXO +:: +++ encode + |= $: only-witness=? + rawtx=hexb + txid=hexb + inputs=(list in:psbt) + outputs=(list out:psbt) + == + ^- base64:psbt + =/ sep=(unit hexb) `1^0x0 + =/ final=(list (unit hexb)) + %+ join sep + %+ turn + %- zing + :~ ~[(globals:en rawtx)] + (turn inputs (cury input:en only-witness)) + (turn outputs output:en) + == + map-byts:en + %- base64:en + ^- byts + %- cat:byt + %+ weld ~[[5 0x70.7362.74ff]] + (murn (snoc final sep) same) +:: +++ parse + |= psbt-base64=cord + ^- (list map:psbt) + =/ todo=hexb + (drop:byt 5 (to-byts psbt-base64)) + =| acc=(list map:psbt) + =| m=map:psbt + |- + ?: =(wid.todo 0) + (snoc acc m) + :: 0x0: map separator + :: + ?: =(1^0x0 (take:byt 1 todo)) + $(acc (snoc acc m), m *map:psbt, todo (drop:byt 1 todo)) + =^ kv todo (next-keyval todo) + $(m (snoc m kv)) +:: +get-txid: extract txid from a valid PSBT +:: +++ get-txid + |= psbt-base64=cord + ^- hexb + =/ tx=hexb + %- raw-tx + %+ drop:byt 5 + (to-byts psbt-base64) + %- flip:byt + (dsha256 tx) +:: +raw-tx: extract hex transaction +:: looks for key 0x0 in global map +:: crashes if tx not in hex +:: +++ raw-tx + |= b=hexb + ^- hexb + |- + ?: =(wid.b 0) !! + ?: =(1^0x0 (take:byt 1 b)) !! + =/ nk (next-keyval b) + ?: =(0x0 dat.key.kv.nk) + val.kv.nk + $(b rest.nk) +:: +next-keyval: returns next key-val in a PSBT map +:: input first byte must be a map key length +:: +++ next-keyval + |= b=hexb + ^- [kv=keyval:psbt rest=hexb] + =/ klen dat:(take:byt 1 b) + =/ k (take:byt klen (drop:byt 1 b)) + =/ vlen dat:(take:byt 1 (drop:byt (add 1 klen) b)) + =/ v (take:byt vlen (drop:byt (add 2 klen) b)) + ?> ?&((gth wid.k 0) (gth wid.v 0)) + :- [k v] + (drop:byt ;:(add 2 klen vlen) b) +:: +++ to-byts + |= psbt-base64=cord + ^- hexb + ~| "Invalid PSBT" + =+ p=(de:base64:mimes:html psbt-base64) + ?~ p !! + (flip:byt u.p) +-- diff --git a/pkg/base-dev/lib/bip32.hoon b/pkg/base-dev/lib/bip32.hoon new file mode 100644 index 000000000..02187ad87 --- /dev/null +++ b/pkg/base-dev/lib/bip32.hoon @@ -0,0 +1,243 @@ +:: bip32 implementation in hoon +:: +:: to use, call one of the core initialization arms. +:: using the produced core, derive as needed and take out the data you want. +:: +::NOTE tested to be correct against +:: https://en.bitcoin.it/wiki/BIP_0032_TestVectors +:: +=, hmac:crypto +=, secp:crypto +=+ ecc=secp256k1 +:: +:: prv: private key +:: pub: public key +:: cad: chain code +:: dep: depth in chain +:: ind: index at depth +:: pif: parent fingerprint (4 bytes) +|_ [prv=@ pub=point.ecc cad=@ dep=@ud ind=@ud pif=@] +:: ++$ keyc [key=@ cai=@] :: prv/pub key + chain code +:: +:: elliptic curve operations and values +:: +++ point priv-to-pub.ecc +:: +++ ser-p compress-point.ecc +:: +++ n n:t.ecc +:: +:: core initialization +:: +++ from-seed + |= byts + ^+ +> + =+ der=(hmac-sha512l [12 'dees nioctiB'] [wid dat]) + =+ pri=(cut 3 [32 32] der) + +>.$(prv pri, pub (point pri), cad (cut 3 [0 32] der)) +:: +++ from-private + |= keyc + +>(prv key, pub (point key), cad cai) +:: +++ from-public + |= keyc + +>(pub (decompress-point.ecc key), cad cai) +:: +++ from-public-point + |= [pon=point.ecc cai=@] + +>(pub pon, cad cai) +:: +++ from-extended + |= t=tape + =+ x=(de-base58check 4 t) + => |% + ++ take + |= b=@ud + ^- [v=@ x=@] + :- (end [3 b] x) + (rsh [3 b] x) + -- + =^ k x (take 33) + =^ c x (take 32) + =^ i x (take 4) + =^ p x (take 4) + =^ d x (take 1) + ?> =(0 x) :: sanity check + %. [d i p] + =< set-metadata + =+ v=(swag [1 3] t) + ?: =("prv" v) (from-private k c) + ?: =("pub" v) (from-public k c) + !! +:: +++ set-metadata + |= [d=@ud i=@ud p=@] + +>(dep d, ind i, pif p) +:: +:: derivation +:: +++ derivation-path + ;~ pfix + ;~(pose (jest 'm/') (easy ~)) + %+ most fas + ;~ pose + %+ cook + |=(i=@ (add i (bex 31))) + ;~(sfix dem soq) + :: + dem + == == +:: +++ derive-path + |= t=tape + %- derive-sequence + (scan t derivation-path) +:: +++ derive-sequence + |= j=(list @u) + ?~ j +> + =. +> (derive i.j) + $(j t.j) +:: +++ derive + ?: =(0 prv) + derive-public + derive-private +:: +++ derive-private + |= i=@u + ^+ +> + :: we must have a private key to derive the next one + ?: =(0 prv) + ~| %know-no-private-key + !! + :: derive child at i + =/ [left=@ right=@] + =- [(cut 3 [32 32] -) (cut 3 [0 32] -)] + %+ hmac-sha512l [32 cad] + :- 37 + ?: (gte i (bex 31)) + :: hardened child + (can 3 ~[4^i 32^prv 1^0]) + :: normal child + (can 3 ~[4^i 33^(ser-p (point prv))]) + =+ key=(mod (add left prv) n) + :: rare exception, invalid key, go to the next one + ?: |(=(0 key) (gte left n)) $(i +(i)) + %_ +>.$ + prv key + pub (point key) + cad right + dep +(dep) + ind i + pif fingerprint + == +:: +++ derive-public + |= i=@u + ^+ +> + :: public keys can't be hardened + ?: (gte i (bex 31)) + ~| %cant-derive-hardened-public-key + !! + :: derive child at i + =/ [left=@ right=@] + =- [(cut 3 [32 32] -) (cut 3 [0 32] -)] + %+ hmac-sha512l [32 cad] + 37^(can 3 ~[4^i 33^(ser-p pub)]) + :: rare exception, invalid key, go to the next one + ?: (gte left n) $(i +(i)) ::TODO or child key is "point at infinity" + %_ +>.$ + pub (add-points.ecc (point left) pub) + cad right + dep +(dep) + ind i + pif fingerprint + == +:: +:: rendering +:: +++ private-key ?.(=(0 prv) prv ~|(%know-no-private-key !!)) +++ public-key (ser-p pub) +++ chain-code cad +++ private-chain [private-key cad] +++ public-chain [public-key cad] +:: +++ identity (hash160 public-key) +++ fingerprint (cut 3 [16 4] identity) +:: +++ address + |= network=?(%main %regtest %testnet) + ^- @uc + :: removes checksum + :: + %+ rsh [3 4] + %+ en-base58check + [4 (version-bytes network %pub %.n)] + [20 identity] +:: +++ prv-extended + |= network=?(%main %regtest %testnet) + %+ en-b58c-bip32 (version-bytes network %prv %.y) + (build-extended private-key) +:: +++ pub-extended + |= network=?(%main %regtest %testnet) + %+ en-b58c-bip32 (version-bytes network %pub %.y) + (build-extended public-key) +:: +++ build-extended + |= key=@ + %+ can 3 + :~ 33^key + 32^cad + 4^ind + 4^pif + 1^dep + == +:: +++ en-b58c-bip32 + |= [v=@ k=@] + %- en-base58:mimes:html + (en-base58check [4 v] [74 k]) +:: +:: base58check +:: +++ en-base58check + :: v: version bytes + :: d: data + |= [v=byts d=byts] + =+ p=[(add wid.v wid.d) (can 3 ~[d v])] + =- (can 3 ~[4^- p]) + %+ rsh [3 28] + (sha-256l:sha 32 (sha-256l:sha p)) +:: +++ de-base58check + :: vw: amount of version bytes + |= [vw=@u t=tape] + =+ x=(de-base58:mimes:html t) + =+ hash=(sha-256l:sha 32 (sha-256:sha (rsh [3 4] x))) + ?> =((end [3 4] x) (rsh [3 28] hash)) + (cut 3 [vw (sub (met 3 x) (add 4 vw))] x) +:: +++ hash160 + |= d=@ + (ripemd-160:ripemd:crypto 32 (sha-256:sha d)) +:: +++ version-bytes + |= [network=?(%main %regtest %testnet) type=?(%pub %prv) bip32=?] + ^- @ux + |^ + ?- type + %pub ?:(bip32 xpub-key pay-to-pubkey) + %prv ?:(bip32 xprv-key private-key) + == + :: + ++ pay-to-pubkey ?:(=(network %main) 0x0 0x6f) + ++ private-key ?:(=(network %main) 0x80 0xef) + ++ xpub-key ?:(=(network %main) 0x488.b21e 0x435.87cf) + ++ xprv-key ?:(=(network %main) 0x488.ade4 0x435.8394) + -- +-- diff --git a/pkg/base-dev/lib/bip39.hoon b/pkg/base-dev/lib/bip39.hoon new file mode 100644 index 000000000..cc33fe479 --- /dev/null +++ b/pkg/base-dev/lib/bip39.hoon @@ -0,0 +1,46 @@ +:: bip39 implementation in hoon +:: +/+ bip39-english +:: +|% +++ from-entropy + |= byts + ^- tape + =. wid (mul wid 8) + ~| [%unsupported-entropy-bit-length wid] + ?> &((gte wid 128) (lte wid 256)) + :: + =+ cs=(div wid 32) + =/ check=@ + %+ rsh [0 (sub 256 cs)] + (sha-256l:sha (div wid 8) dat) + =/ bits=byts + :- (add wid cs) + %+ can 0 + :~ cs^check + wid^dat + == + :: + =/ pieces + |- ^- (list @) + :- (end [0 11] dat.bits) + ?: (lte wid.bits 11) ~ + $(bits [(sub wid.bits 11) (rsh [0 11] dat.bits)]) + :: + =/ words=(list tape) + %+ turn pieces + |= ind=@ud + (snag ind `(list tape)`bip39-english) + :: + %+ roll (flop words) + |= [nex=tape all=tape] + ?~ all nex + :(weld all " " nex) +:: +::NOTE always produces a 512-bit result +++ to-seed + |= [mnem=tape pass=tape] + ^- @ + %- hmac-sha512t:pbkdf:crypto + [(crip mnem) (crip (weld "mnemonic" pass)) 2.048 64] +-- diff --git a/pkg/base-dev/lib/bip39/english.hoon b/pkg/base-dev/lib/bip39/english.hoon new file mode 100644 index 000000000..60de89317 --- /dev/null +++ b/pkg/base-dev/lib/bip39/english.hoon @@ -0,0 +1,2052 @@ +:: english wordlist for use in bip39 +^- (list tape) +:~ + "abandon" + "ability" + "able" + "about" + "above" + "absent" + "absorb" + "abstract" + "absurd" + "abuse" + "access" + "accident" + "account" + "accuse" + "achieve" + "acid" + "acoustic" + "acquire" + "across" + "act" + "action" + "actor" + "actress" + "actual" + "adapt" + "add" + "addict" + "address" + "adjust" + "admit" + "adult" + "advance" + "advice" + "aerobic" + "affair" + "afford" + "afraid" + "again" + "age" + "agent" + "agree" + "ahead" + "aim" + "air" + "airport" + "aisle" + "alarm" + "album" + "alcohol" + "alert" + "alien" + "all" + "alley" + "allow" + "almost" + "alone" + "alpha" + "already" + "also" + "alter" + "always" + "amateur" + "amazing" + "among" + "amount" + "amused" + "analyst" + "anchor" + "ancient" + "anger" + "angle" + "angry" + "animal" + "ankle" + "announce" + "annual" + "another" + "answer" + "antenna" + "antique" + "anxiety" + "any" + "apart" + "apology" + "appear" + "apple" + "approve" + "april" + "arch" + "arctic" + "area" + "arena" + "argue" + "arm" + "armed" + "armor" + "army" + "around" + "arrange" + "arrest" + "arrive" + "arrow" + "art" + "artefact" + "artist" + "artwork" + "ask" + "aspect" + "assault" + "asset" + "assist" + "assume" + "asthma" + "athlete" + "atom" + "attack" + "attend" + "attitude" + "attract" + "auction" + "audit" + "august" + "aunt" + "author" + "auto" + "autumn" + "average" + "avocado" + "avoid" + "awake" + "aware" + "away" + "awesome" + "awful" + "awkward" + "axis" + "baby" + "bachelor" + "bacon" + "badge" + "bag" + "balance" + "balcony" + "ball" + "bamboo" + "banana" + "banner" + "bar" + "barely" + "bargain" + "barrel" + "base" + "basic" + "basket" + "battle" + "beach" + "bean" + "beauty" + "because" + "become" + "beef" + "before" + "begin" + "behave" + "behind" + "believe" + "below" + "belt" + "bench" + "benefit" + "best" + "betray" + "better" + "between" + "beyond" + "bicycle" + "bid" + "bike" + "bind" + "biology" + "bird" + "birth" + "bitter" + "black" + "blade" + "blame" + "blanket" + "blast" + "bleak" + "bless" + "blind" + "blood" + "blossom" + "blouse" + "blue" + "blur" + "blush" + "board" + "boat" + "body" + "boil" + "bomb" + "bone" + "bonus" + "book" + "boost" + "border" + "boring" + "borrow" + "boss" + "bottom" + "bounce" + "box" + "boy" + "bracket" + "brain" + "brand" + "brass" + "brave" + "bread" + "breeze" + "brick" + "bridge" + "brief" + "bright" + "bring" + "brisk" + "broccoli" + "broken" + "bronze" + "broom" + "brother" + "brown" + "brush" + "bubble" + "buddy" + "budget" + "buffalo" + "build" + "bulb" + "bulk" + "bullet" + "bundle" + "bunker" + "burden" + "burger" + "burst" + "bus" + "business" + "busy" + "butter" + "buyer" + "buzz" + "cabbage" + "cabin" + "cable" + "cactus" + "cage" + "cake" + "call" + "calm" + "camera" + "camp" + "can" + "canal" + "cancel" + "candy" + "cannon" + "canoe" + "canvas" + "canyon" + "capable" + "capital" + "captain" + "car" + "carbon" + "card" + "cargo" + "carpet" + "carry" + "cart" + "case" + "cash" + "casino" + "castle" + "casual" + "cat" + "catalog" + "catch" + "category" + "cattle" + "caught" + "cause" + "caution" + "cave" + "ceiling" + "celery" + "cement" + "census" + "century" + "cereal" + "certain" + "chair" + "chalk" + "champion" + "change" + "chaos" + "chapter" + "charge" + "chase" + "chat" + "cheap" + "check" + "cheese" + "chef" + "cherry" + "chest" + "chicken" + "chief" + "child" + "chimney" + "choice" + "choose" + "chronic" + "chuckle" + "chunk" + "churn" + "cigar" + "cinnamon" + "circle" + "citizen" + "city" + "civil" + "claim" + "clap" + "clarify" + "claw" + "clay" + "clean" + "clerk" + "clever" + "click" + "client" + "cliff" + "climb" + "clinic" + "clip" + "clock" + "clog" + "close" + "cloth" + "cloud" + "clown" + "club" + "clump" + "cluster" + "clutch" + "coach" + "coast" + "coconut" + "code" + "coffee" + "coil" + "coin" + "collect" + "color" + "column" + "combine" + "come" + "comfort" + "comic" + "common" + "company" + "concert" + "conduct" + "confirm" + "congress" + "connect" + "consider" + "control" + "convince" + "cook" + "cool" + "copper" + "copy" + "coral" + "core" + "corn" + "correct" + "cost" + "cotton" + "couch" + "country" + "couple" + "course" + "cousin" + "cover" + "coyote" + "crack" + "cradle" + "craft" + "cram" + "crane" + "crash" + "crater" + "crawl" + "crazy" + "cream" + "credit" + "creek" + "crew" + "cricket" + "crime" + "crisp" + "critic" + "crop" + "cross" + "crouch" + "crowd" + "crucial" + "cruel" + "cruise" + "crumble" + "crunch" + "crush" + "cry" + "crystal" + "cube" + "culture" + "cup" + "cupboard" + "curious" + "current" + "curtain" + "curve" + "cushion" + "custom" + "cute" + "cycle" + "dad" + "damage" + "damp" + "dance" + "danger" + "daring" + "dash" + "daughter" + "dawn" + "day" + "deal" + "debate" + "debris" + "decade" + "december" + "decide" + "decline" + "decorate" + "decrease" + "deer" + "defense" + "define" + "defy" + "degree" + "delay" + "deliver" + "demand" + "demise" + "denial" + "dentist" + "deny" + "depart" + "depend" + "deposit" + "depth" + "deputy" + "derive" + "describe" + "desert" + "design" + "desk" + "despair" + "destroy" + "detail" + "detect" + "develop" + "device" + "devote" + "diagram" + "dial" + "diamond" + "diary" + "dice" + "diesel" + "diet" + "differ" + "digital" + "dignity" + "dilemma" + "dinner" + "dinosaur" + "direct" + "dirt" + "disagree" + "discover" + "disease" + "dish" + "dismiss" + "disorder" + "display" + "distance" + "divert" + "divide" + "divorce" + "dizzy" + "doctor" + "document" + "dog" + "doll" + "dolphin" + "domain" + "donate" + "donkey" + "donor" + "door" + "dose" + "double" + "dove" + "draft" + "dragon" + "drama" + "drastic" + "draw" + "dream" + "dress" + "drift" + "drill" + "drink" + "drip" + "drive" + "drop" + "drum" + "dry" + "duck" + "dumb" + "dune" + "during" + "dust" + "dutch" + "duty" + "dwarf" + "dynamic" + "eager" + "eagle" + "early" + "earn" + "earth" + "easily" + "east" + "easy" + "echo" + "ecology" + "economy" + "edge" + "edit" + "educate" + "effort" + "egg" + "eight" + "either" + "elbow" + "elder" + "electric" + "elegant" + "element" + "elephant" + "elevator" + "elite" + "else" + "embark" + "embody" + "embrace" + "emerge" + "emotion" + "employ" + "empower" + "empty" + "enable" + "enact" + "end" + "endless" + "endorse" + "enemy" + "energy" + "enforce" + "engage" + "engine" + "enhance" + "enjoy" + "enlist" + "enough" + "enrich" + "enroll" + "ensure" + "enter" + "entire" + "entry" + "envelope" + "episode" + "equal" + "equip" + "era" + "erase" + "erode" + "erosion" + "error" + "erupt" + "escape" + "essay" + "essence" + "estate" + "eternal" + "ethics" + "evidence" + "evil" + "evoke" + "evolve" + "exact" + "example" + "excess" + "exchange" + "excite" + "exclude" + "excuse" + "execute" + "exercise" + "exhaust" + "exhibit" + "exile" + "exist" + "exit" + "exotic" + "expand" + "expect" + "expire" + "explain" + "expose" + "express" + "extend" + "extra" + "eye" + "eyebrow" + "fabric" + "face" + "faculty" + "fade" + "faint" + "faith" + "fall" + "false" + "fame" + "family" + "famous" + "fan" + "fancy" + "fantasy" + "farm" + "fashion" + "fat" + "fatal" + "father" + "fatigue" + "fault" + "favorite" + "feature" + "february" + "federal" + "fee" + "feed" + "feel" + "female" + "fence" + "festival" + "fetch" + "fever" + "few" + "fiber" + "fiction" + "field" + "figure" + "file" + "film" + "filter" + "final" + "find" + "fine" + "finger" + "finish" + "fire" + "firm" + "first" + "fiscal" + "fish" + "fit" + "fitness" + "fix" + "flag" + "flame" + "flash" + "flat" + "flavor" + "flee" + "flight" + "flip" + "float" + "flock" + "floor" + "flower" + "fluid" + "flush" + "fly" + "foam" + "focus" + "fog" + "foil" + "fold" + "follow" + "food" + "foot" + "force" + "forest" + "forget" + "fork" + "fortune" + "forum" + "forward" + "fossil" + "foster" + "found" + "fox" + "fragile" + "frame" + "frequent" + "fresh" + "friend" + "fringe" + "frog" + "front" + "frost" + "frown" + "frozen" + "fruit" + "fuel" + "fun" + "funny" + "furnace" + "fury" + "future" + "gadget" + "gain" + "galaxy" + "gallery" + "game" + "gap" + "garage" + "garbage" + "garden" + "garlic" + "garment" + "gas" + "gasp" + "gate" + "gather" + "gauge" + "gaze" + "general" + "genius" + "genre" + "gentle" + "genuine" + "gesture" + "ghost" + "giant" + "gift" + "giggle" + "ginger" + "giraffe" + "girl" + "give" + "glad" + "glance" + "glare" + "glass" + "glide" + "glimpse" + "globe" + "gloom" + "glory" + "glove" + "glow" + "glue" + "goat" + "goddess" + "gold" + "good" + "goose" + "gorilla" + "gospel" + "gossip" + "govern" + "gown" + "grab" + "grace" + "grain" + "grant" + "grape" + "grass" + "gravity" + "great" + "green" + "grid" + "grief" + "grit" + "grocery" + "group" + "grow" + "grunt" + "guard" + "guess" + "guide" + "guilt" + "guitar" + "gun" + "gym" + "habit" + "hair" + "half" + "hammer" + "hamster" + "hand" + "happy" + "harbor" + "hard" + "harsh" + "harvest" + "hat" + "have" + "hawk" + "hazard" + "head" + "health" + "heart" + "heavy" + "hedgehog" + "height" + "hello" + "helmet" + "help" + "hen" + "hero" + "hidden" + "high" + "hill" + "hint" + "hip" + "hire" + "history" + "hobby" + "hockey" + "hold" + "hole" + "holiday" + "hollow" + "home" + "honey" + "hood" + "hope" + "horn" + "horror" + "horse" + "hospital" + "host" + "hotel" + "hour" + "hover" + "hub" + "huge" + "human" + "humble" + "humor" + "hundred" + "hungry" + "hunt" + "hurdle" + "hurry" + "hurt" + "husband" + "hybrid" + "ice" + "icon" + "idea" + "identify" + "idle" + "ignore" + "ill" + "illegal" + "illness" + "image" + "imitate" + "immense" + "immune" + "impact" + "impose" + "improve" + "impulse" + "inch" + "include" + "income" + "increase" + "index" + "indicate" + "indoor" + "industry" + "infant" + "inflict" + "inform" + "inhale" + "inherit" + "initial" + "inject" + "injury" + "inmate" + "inner" + "innocent" + "input" + "inquiry" + "insane" + "insect" + "inside" + "inspire" + "install" + "intact" + "interest" + "into" + "invest" + "invite" + "involve" + "iron" + "island" + "isolate" + "issue" + "item" + "ivory" + "jacket" + "jaguar" + "jar" + "jazz" + "jealous" + "jeans" + "jelly" + "jewel" + "job" + "join" + "joke" + "journey" + "joy" + "judge" + "juice" + "jump" + "jungle" + "junior" + "junk" + "just" + "kangaroo" + "keen" + "keep" + "ketchup" + "key" + "kick" + "kid" + "kidney" + "kind" + "kingdom" + "kiss" + "kit" + "kitchen" + "kite" + "kitten" + "kiwi" + "knee" + "knife" + "knock" + "know" + "lab" + "label" + "labor" + "ladder" + "lady" + "lake" + "lamp" + "language" + "laptop" + "large" + "later" + "latin" + "laugh" + "laundry" + "lava" + "law" + "lawn" + "lawsuit" + "layer" + "lazy" + "leader" + "leaf" + "learn" + "leave" + "lecture" + "left" + "leg" + "legal" + "legend" + "leisure" + "lemon" + "lend" + "length" + "lens" + "leopard" + "lesson" + "letter" + "level" + "liar" + "liberty" + "library" + "license" + "life" + "lift" + "light" + "like" + "limb" + "limit" + "link" + "lion" + "liquid" + "list" + "little" + "live" + "lizard" + "load" + "loan" + "lobster" + "local" + "lock" + "logic" + "lonely" + "long" + "loop" + "lottery" + "loud" + "lounge" + "love" + "loyal" + "lucky" + "luggage" + "lumber" + "lunar" + "lunch" + "luxury" + "lyrics" + "machine" + "mad" + "magic" + "magnet" + "maid" + "mail" + "main" + "major" + "make" + "mammal" + "man" + "manage" + "mandate" + "mango" + "mansion" + "manual" + "maple" + "marble" + "march" + "margin" + "marine" + "market" + "marriage" + "mask" + "mass" + "master" + "match" + "material" + "math" + "matrix" + "matter" + "maximum" + "maze" + "meadow" + "mean" + "measure" + "meat" + "mechanic" + "medal" + "media" + "melody" + "melt" + "member" + "memory" + "mention" + "menu" + "mercy" + "merge" + "merit" + "merry" + "mesh" + "message" + "metal" + "method" + "middle" + "midnight" + "milk" + "million" + "mimic" + "mind" + "minimum" + "minor" + "minute" + "miracle" + "mirror" + "misery" + "miss" + "mistake" + "mix" + "mixed" + "mixture" + "mobile" + "model" + "modify" + "mom" + "moment" + "monitor" + "monkey" + "monster" + "month" + "moon" + "moral" + "more" + "morning" + "mosquito" + "mother" + "motion" + "motor" + "mountain" + "mouse" + "move" + "movie" + "much" + "muffin" + "mule" + "multiply" + "muscle" + "museum" + "mushroom" + "music" + "must" + "mutual" + "myself" + "mystery" + "myth" + "naive" + "name" + "napkin" + "narrow" + "nasty" + "nation" + "nature" + "near" + "neck" + "need" + "negative" + "neglect" + "neither" + "nephew" + "nerve" + "nest" + "net" + "network" + "neutral" + "never" + "news" + "next" + "nice" + "night" + "noble" + "noise" + "nominee" + "noodle" + "normal" + "north" + "nose" + "notable" + "note" + "nothing" + "notice" + "novel" + "now" + "nuclear" + "number" + "nurse" + "nut" + "oak" + "obey" + "object" + "oblige" + "obscure" + "observe" + "obtain" + "obvious" + "occur" + "ocean" + "october" + "odor" + "off" + "offer" + "office" + "often" + "oil" + "okay" + "old" + "olive" + "olympic" + "omit" + "once" + "one" + "onion" + "online" + "only" + "open" + "opera" + "opinion" + "oppose" + "option" + "orange" + "orbit" + "orchard" + "order" + "ordinary" + "organ" + "orient" + "original" + "orphan" + "ostrich" + "other" + "outdoor" + "outer" + "output" + "outside" + "oval" + "oven" + "over" + "own" + "owner" + "oxygen" + "oyster" + "ozone" + "pact" + "paddle" + "page" + "pair" + "palace" + "palm" + "panda" + "panel" + "panic" + "panther" + "paper" + "parade" + "parent" + "park" + "parrot" + "party" + "pass" + "patch" + "path" + "patient" + "patrol" + "pattern" + "pause" + "pave" + "payment" + "peace" + "peanut" + "pear" + "peasant" + "pelican" + "pen" + "penalty" + "pencil" + "people" + "pepper" + "perfect" + "permit" + "person" + "pet" + "phone" + "photo" + "phrase" + "physical" + "piano" + "picnic" + "picture" + "piece" + "pig" + "pigeon" + "pill" + "pilot" + "pink" + "pioneer" + "pipe" + "pistol" + "pitch" + "pizza" + "place" + "planet" + "plastic" + "plate" + "play" + "please" + "pledge" + "pluck" + "plug" + "plunge" + "poem" + "poet" + "point" + "polar" + "pole" + "police" + "pond" + "pony" + "pool" + "popular" + "portion" + "position" + "possible" + "post" + "potato" + "pottery" + "poverty" + "powder" + "power" + "practice" + "praise" + "predict" + "prefer" + "prepare" + "present" + "pretty" + "prevent" + "price" + "pride" + "primary" + "print" + "priority" + "prison" + "private" + "prize" + "problem" + "process" + "produce" + "profit" + "program" + "project" + "promote" + "proof" + "property" + "prosper" + "protect" + "proud" + "provide" + "public" + "pudding" + "pull" + "pulp" + "pulse" + "pumpkin" + "punch" + "pupil" + "puppy" + "purchase" + "purity" + "purpose" + "purse" + "push" + "put" + "puzzle" + "pyramid" + "quality" + "quantum" + "quarter" + "question" + "quick" + "quit" + "quiz" + "quote" + "rabbit" + "raccoon" + "race" + "rack" + "radar" + "radio" + "rail" + "rain" + "raise" + "rally" + "ramp" + "ranch" + "random" + "range" + "rapid" + "rare" + "rate" + "rather" + "raven" + "raw" + "razor" + "ready" + "real" + "reason" + "rebel" + "rebuild" + "recall" + "receive" + "recipe" + "record" + "recycle" + "reduce" + "reflect" + "reform" + "refuse" + "region" + "regret" + "regular" + "reject" + "relax" + "release" + "relief" + "rely" + "remain" + "remember" + "remind" + "remove" + "render" + "renew" + "rent" + "reopen" + "repair" + "repeat" + "replace" + "report" + "require" + "rescue" + "resemble" + "resist" + "resource" + "response" + "result" + "retire" + "retreat" + "return" + "reunion" + "reveal" + "review" + "reward" + "rhythm" + "rib" + "ribbon" + "rice" + "rich" + "ride" + "ridge" + "rifle" + "right" + "rigid" + "ring" + "riot" + "ripple" + "risk" + "ritual" + "rival" + "river" + "road" + "roast" + "robot" + "robust" + "rocket" + "romance" + "roof" + "rookie" + "room" + "rose" + "rotate" + "rough" + "round" + "route" + "royal" + "rubber" + "rude" + "rug" + "rule" + "run" + "runway" + "rural" + "sad" + "saddle" + "sadness" + "safe" + "sail" + "salad" + "salmon" + "salon" + "salt" + "salute" + "same" + "sample" + "sand" + "satisfy" + "satoshi" + "sauce" + "sausage" + "save" + "say" + "scale" + "scan" + "scare" + "scatter" + "scene" + "scheme" + "school" + "science" + "scissors" + "scorpion" + "scout" + "scrap" + "screen" + "script" + "scrub" + "sea" + "search" + "season" + "seat" + "second" + "secret" + "section" + "security" + "seed" + "seek" + "segment" + "select" + "sell" + "seminar" + "senior" + "sense" + "sentence" + "series" + "service" + "session" + "settle" + "setup" + "seven" + "shadow" + "shaft" + "shallow" + "share" + "shed" + "shell" + "sheriff" + "shield" + "shift" + "shine" + "ship" + "shiver" + "shock" + "shoe" + "shoot" + "shop" + "short" + "shoulder" + "shove" + "shrimp" + "shrug" + "shuffle" + "shy" + "sibling" + "sick" + "side" + "siege" + "sight" + "sign" + "silent" + "silk" + "silly" + "silver" + "similar" + "simple" + "since" + "sing" + "siren" + "sister" + "situate" + "six" + "size" + "skate" + "sketch" + "ski" + "skill" + "skin" + "skirt" + "skull" + "slab" + "slam" + "sleep" + "slender" + "slice" + "slide" + "slight" + "slim" + "slogan" + "slot" + "slow" + "slush" + "small" + "smart" + "smile" + "smoke" + "smooth" + "snack" + "snake" + "snap" + "sniff" + "snow" + "soap" + "soccer" + "social" + "sock" + "soda" + "soft" + "solar" + "soldier" + "solid" + "solution" + "solve" + "someone" + "song" + "soon" + "sorry" + "sort" + "soul" + "sound" + "soup" + "source" + "south" + "space" + "spare" + "spatial" + "spawn" + "speak" + "special" + "speed" + "spell" + "spend" + "sphere" + "spice" + "spider" + "spike" + "spin" + "spirit" + "split" + "spoil" + "sponsor" + "spoon" + "sport" + "spot" + "spray" + "spread" + "spring" + "spy" + "square" + "squeeze" + "squirrel" + "stable" + "stadium" + "staff" + "stage" + "stairs" + "stamp" + "stand" + "start" + "state" + "stay" + "steak" + "steel" + "stem" + "step" + "stereo" + "stick" + "still" + "sting" + "stock" + "stomach" + "stone" + "stool" + "story" + "stove" + "strategy" + "street" + "strike" + "strong" + "struggle" + "student" + "stuff" + "stumble" + "style" + "subject" + "submit" + "subway" + "success" + "such" + "sudden" + "suffer" + "sugar" + "suggest" + "suit" + "summer" + "sun" + "sunny" + "sunset" + "super" + "supply" + "supreme" + "sure" + "surface" + "surge" + "surprise" + "surround" + "survey" + "suspect" + "sustain" + "swallow" + "swamp" + "swap" + "swarm" + "swear" + "sweet" + "swift" + "swim" + "swing" + "switch" + "sword" + "symbol" + "symptom" + "syrup" + "system" + "table" + "tackle" + "tag" + "tail" + "talent" + "talk" + "tank" + "tape" + "target" + "task" + "taste" + "tattoo" + "taxi" + "teach" + "team" + "tell" + "ten" + "tenant" + "tennis" + "tent" + "term" + "test" + "text" + "thank" + "that" + "theme" + "then" + "theory" + "there" + "they" + "thing" + "this" + "thought" + "three" + "thrive" + "throw" + "thumb" + "thunder" + "ticket" + "tide" + "tiger" + "tilt" + "timber" + "time" + "tiny" + "tip" + "tired" + "tissue" + "title" + "toast" + "tobacco" + "today" + "toddler" + "toe" + "together" + "toilet" + "token" + "tomato" + "tomorrow" + "tone" + "tongue" + "tonight" + "tool" + "tooth" + "top" + "topic" + "topple" + "torch" + "tornado" + "tortoise" + "toss" + "total" + "tourist" + "toward" + "tower" + "town" + "toy" + "track" + "trade" + "traffic" + "tragic" + "train" + "transfer" + "trap" + "trash" + "travel" + "tray" + "treat" + "tree" + "trend" + "trial" + "tribe" + "trick" + "trigger" + "trim" + "trip" + "trophy" + "trouble" + "truck" + "true" + "truly" + "trumpet" + "trust" + "truth" + "try" + "tube" + "tuition" + "tumble" + "tuna" + "tunnel" + "turkey" + "turn" + "turtle" + "twelve" + "twenty" + "twice" + "twin" + "twist" + "two" + "type" + "typical" + "ugly" + "umbrella" + "unable" + "unaware" + "uncle" + "uncover" + "under" + "undo" + "unfair" + "unfold" + "unhappy" + "uniform" + "unique" + "unit" + "universe" + "unknown" + "unlock" + "until" + "unusual" + "unveil" + "update" + "upgrade" + "uphold" + "upon" + "upper" + "upset" + "urban" + "urge" + "usage" + "use" + "used" + "useful" + "useless" + "usual" + "utility" + "vacant" + "vacuum" + "vague" + "valid" + "valley" + "valve" + "van" + "vanish" + "vapor" + "various" + "vast" + "vault" + "vehicle" + "velvet" + "vendor" + "venture" + "venue" + "verb" + "verify" + "version" + "very" + "vessel" + "veteran" + "viable" + "vibrant" + "vicious" + "victory" + "video" + "view" + "village" + "vintage" + "violin" + "virtual" + "virus" + "visa" + "visit" + "visual" + "vital" + "vivid" + "vocal" + "voice" + "void" + "volcano" + "volume" + "vote" + "voyage" + "wage" + "wagon" + "wait" + "walk" + "wall" + "walnut" + "want" + "warfare" + "warm" + "warrior" + "wash" + "wasp" + "waste" + "water" + "wave" + "way" + "wealth" + "weapon" + "wear" + "weasel" + "weather" + "web" + "wedding" + "weekend" + "weird" + "welcome" + "west" + "wet" + "whale" + "what" + "wheat" + "wheel" + "when" + "where" + "whip" + "whisper" + "wide" + "width" + "wife" + "wild" + "will" + "win" + "window" + "wine" + "wing" + "wink" + "winner" + "winter" + "wire" + "wisdom" + "wise" + "wish" + "witness" + "wolf" + "woman" + "wonder" + "wood" + "wool" + "word" + "work" + "world" + "worry" + "worth" + "wrap" + "wreck" + "wrestle" + "wrist" + "write" + "wrong" + "yard" + "year" + "yellow" + "you" + "young" + "youth" + "zebra" + "zero" + "zone" + "zoo" +== diff --git a/pkg/base-dev/lib/bitcoin-utils.hoon b/pkg/base-dev/lib/bitcoin-utils.hoon new file mode 100644 index 000000000..648fb781b --- /dev/null +++ b/pkg/base-dev/lib/bitcoin-utils.hoon @@ -0,0 +1,176 @@ +:: lib/bitcoin-utils.hoon +:: Utilities for working with BTC data types and transactions +:: +/- *bitcoin +~% %bitcoin-utils-lib ..part ~ +|% +:: +:: TODO: move this bit/byt stuff to zuse +:: bit/byte utilities +:: +:: +:: +blop: munge bit and byt sequences (cat, flip, take, drop) +:: +++ blop + ~/ %blop + |_ =bloq + +$ biyts [wid=@ud dat=@] + ++ cat + |= bs=(list biyts) + ^- biyts + :- (roll (turn bs |=(b=biyts -.b)) add) + (can bloq (flop bs)) + :: +flip: flip endianness while preserving lead/trail zeroes + :: + ++ flip + |= b=biyts + ^- biyts + [wid.b (rev bloq b)] + :: +take: take n bloqs from front + :: pads front with extra zeroes if n is longer than input + :: + ++ take + |= [n=@ b=biyts] + ^- biyts + ?: (gth n wid.b) + [n dat.b] + [n (rsh [bloq (sub wid.b n)] dat.b)] + :: +drop: drop n bloqs from front + :: returns 0^0 if n >= width + :: + ++ drop + |= [n=@ b=biyts] + ^- biyts + ?: (gte n wid.b) + 0^0x0 + =+ n-take=(sub wid.b n) + [n-take (end [bloq n-take] dat.b)] + -- +++ byt ~(. blop 3) +:: +++ bit + ~/ %bit + =/ bl ~(. blop 0) + |% + ++ cat cat:bl:bit + ++ flip flip:bl:bit + ++ take take:bl:bit + ++ drop drop:bl:bit + ++ from-atoms + |= [bitwidth=@ digits=(list @)] + ^- bits + %- cat:bit + %+ turn digits + |= a=@ + ?> (lte (met 0 a) bitwidth) + [bitwidth `@ub`a] + :: +to-atoms: convert bits to atoms of bitwidth + :: + ++ to-atoms + |= [bitwidth=@ bs=bits] + ^- (list @) + =| res=(list @) + ?> =(0 (mod wid.bs bitwidth)) + |- + ?: =(0 wid.bs) res + %= $ + res (snoc res dat:(take:bit bitwidth bs)) + bs (drop:bit bitwidth bs) + == + -- +:: big endian sha256: input and output are both MSB first (big endian) +:: +++ sha256 + ~/ %sha256 + |= =byts + ^- hexb + %- flip:byt + [32 (shay (flip:byt byts))] +:: +++ dsha256 + ~/ %dsha256 + |= =byts + (sha256 (sha256 byts)) +:: +++ hash-160 + ~/ %hash-160 + |= val=byts + ^- hexb + =, ripemd:crypto + :- 20 + %- ripemd-160 + (sha256 val) + +:: +:: hxb: hex parsing utilities +:: +++ hxb + ~% %hxb ..blop ~ + |% + ++ from-cord + ~/ %from-cord + |= h=@t + ^- hexb + ?: =('' h) 1^0x0 + :: Add leading 00 + :: + =+ (lsh [3 2] h) + :: Group by 4-size block + :: + =+ (rsh [3 2] -) + :: Parse hex to atom + :: + =/ a (need (de:base16:mimes:html -)) + [-.a `@ux`+.a] + :: + ++ to-cord + ~/ %to-cord + |= =hexb + ^- cord + (en:base16:mimes:html hexb) + -- +:: +:: +csiz: CompactSize integers (a Bitcoin-specific datatype) +:: https://btcinformation.org/en/developer-reference#compactsize-unsigned-integers +:: - encode: big endian to little endian +:: - decode: little endian to big endian +:: +++ csiz + ~% %csiz ..blop ~ + |% + ++ en + ~/ %en + |= a=@ + ^- hexb + =/ l=@ (met 3 a) + ?: =(l 1) 1^a + ?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)]) + ?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)]) + ?: (lte l 8) (cat:byt ~[1^0xff (flip:byt 8^a)]) + ~|("Cannot encode CompactSize longer than 8 bytes" !!) + :: + ++ de + ~/ %de + |= h=hexb + ^- [n=hexb rest=hexb] + =/ s=@ux dat:(take:byt 1 h) + ?: (lth s 0xfd) [1^s (drop:byt 1 h)] + ~| "Invalid compact-size at start of {}" + =/ len=bloq + ?+ s !! + %0xfd 1 + %0xfe 2 + %0xff 3 + == + :_ (drop:byt (add 1 len) h) + %- flip:byt + (take:byt (bex len) (drop:byt 1 h)) + :: +dea: atom instead of hexb for parsed CompactSize + :: + ++ dea + |= h=hexb + ^- [a=@ rest=hexb] + => (de h) + [dat.n rest] + -- +-- diff --git a/pkg/base-dev/lib/cram.hoon b/pkg/base-dev/lib/cram.hoon new file mode 100644 index 000000000..dbec8f7b4 --- /dev/null +++ b/pkg/base-dev/lib/cram.hoon @@ -0,0 +1,61 @@ +|% +++ static :: freeze .mdh hoon subset + |= gen=hoon ^- [inf=(map term dime) elm=manx] + ?+ -.gen + =/ gen ~(open ap gen) + ?: =(gen ^gen) ~|([%cram-dynamic -.gen] !!) + $(gen gen) + :: + %xray [~ (single (shut gen))] + ^ [(malt (frontmatter p.gen)) (single (shut q.gen))] + == +:: +++ single :: unwrap one-elem marl + |= xml=marl ^- manx + ?: ?=([* ~] xml) i.xml + ~|(%many-elems !!) +:: +++ shut-mart :: xml attrs + |=([n=mane v=(list beer:hoot)] [n (turn v |=(a=beer:hoot ?^(a !! a)))]) +:: +++ shut :: as xml constant + |= gen=hoon ^- marl + ?+ -.gen ~|([%bad-xml -.gen] !!) + %dbug $(gen q.gen) + :: + %xray + [[n.g.p.gen (turn a.g.p.gen shut-mart)] $(gen [%mcts c.p.gen])]~ + :: + %mcts + ?~ p.gen ~ + =- (weld - $(p.gen t.p.gen)) + ?^ -.i.p.gen $(gen [%xray i.p.gen]) + ~| [%shut-tuna -.i.p.gen] + ?+ -.i.p.gen !! + %manx ?>(?=(%xray -.p.i.p.gen) $(gen p.i.p.gen)) + %marl ?>(?=(%mcts -.p.i.p.gen) $(gen p.i.p.gen)) + == + == +:: +:: +++ frontmatter :: parse ~[[%foo 1] [%bar ~s2]] + |= gen=hoon ^- (list [term dime]) + ?: ?=([%bust %null] gen) ~ + ?: ?=(%dbug -.gen) $(gen q.gen) + ?. ?=(%clsg -.gen) ~|([%bad-frontmatter -.gen] !!) + %+ turn p.gen + |= gen=hoon + ?. ?=(^ -.gen) + =/ gen ~(open ap gen) + ?: =(gen ^gen) ~|([%bad-frontmatter-elem -.gen] !!) + $(gen gen) + =/ hed (as-dime p.gen) + ?. =(%tas p.hed) ~|([%bad-frontmatter-key-type p.hed] !!) + [q.hed (as-dime q.gen)] +:: +++ as-dime :: %foo ~.foo 0vbar etc + |= gen=hoon ^- dime + ?: ?=(%dbug -.gen) $(gen q.gen) + ?. ?=([?(%rock %sand) @ @] gen) ~|([%bad-literal gen] !!) + +.gen +-- diff --git a/pkg/base-dev/lib/dbug.hoon b/pkg/base-dev/lib/dbug.hoon new file mode 100644 index 000000000..ce98619e8 --- /dev/null +++ b/pkg/base-dev/lib/dbug.hoon @@ -0,0 +1,155 @@ +:: dbug: agent wrapper for generic debugging tools +:: +:: usage: %-(agent:dbug your-agent) +:: +|% ++$ poke + $% [%bowl ~] + [%state grab=cord] + [%incoming =about] + [%outgoing =about] + == +:: ++$ about + $@ ~ + $% [%ship =ship] + [%path =path] + [%wire =wire] + [%term =term] + == +:: +++ agent + |= =agent:gall + ^- agent:gall + !. + |_ =bowl:gall + +* this . + ag ~(. agent bowl) + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card:agent:gall agent:gall) + ?. ?=(%dbug mark) + =^ cards agent (on-poke:ag mark vase) + [cards this] + =/ dbug + !<(poke vase) + =; =tang + ((%*(. slog pri 1) tang) [~ this]) + ?- -.dbug + %bowl [(sell !>(bowl))]~ + :: + %state + =? grab.dbug =('' grab.dbug) '-' + =; product=^vase + [(sell product)]~ + =/ state=^vase + :: if the underlying app has implemented a /dbug/state scry endpoint, + :: use that vase in place of +on-save's. + :: + =/ result=(each ^vase tang) + (mule |.(q:(need (need (on-peek:ag /x/dbug/state))))) + ?:(?=(%& -.result) p.result on-save:ag) + %+ slap + (slop state !>([bowl=bowl ..zuse])) + (ream grab.dbug) + :: + %incoming + =; =tang + ?^ tang tang + [%leaf "no matching subscriptions"]~ + %+ murn + %+ sort ~(tap by sup.bowl) + |= [[* a=[=ship =path]] [* b=[=ship =path]]] + (aor [path ship]:a [path ship]:b) + |= [=duct [=ship =path]] + ^- (unit tank) + =; relevant=? + ?. relevant ~ + `>[path=path from=ship duct=duct]< + ?: ?=(~ about.dbug) & + ?- -.about.dbug + %ship =(ship ship.about.dbug) + %path ?=(^ (find path.about.dbug path)) + %wire %+ lien duct + |=(=wire ?=(^ (find wire.about.dbug wire))) + %term !! + == + :: + %outgoing + =; =tang + ?^ tang tang + [%leaf "no matching subscriptions"]~ + %+ murn + %+ sort ~(tap by wex.bowl) + |= [[[a=wire *] *] [[b=wire *] *]] + (aor a b) + |= [[=wire =ship =term] [acked=? =path]] + ^- (unit tank) + =; relevant=? + ?. relevant ~ + `>[wire=wire agnt=[ship term] path=path ackd=acked]< + ?: ?=(~ about.dbug) & + ?- -.about.dbug + %ship =(ship ship.about.dbug) + %path ?=(^ (find path.about.dbug path)) + %wire ?=(^ (find wire.about.dbug wire)) + %term =(term term.about.dbug) + == + == + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. ?=([@ %dbug *] path) + (on-peek:ag path) + ?+ path [~ ~] + [%u %dbug ~] ``noun+!>(&) + [%x %dbug %state ~] ``noun+!>(on-save:ag) + [%x %dbug %subscriptions ~] ``noun+!>([wex sup]:bowl) + == + :: + ++ on-init + ^- (quip card:agent:gall agent:gall) + =^ cards agent on-init:ag + [cards this] + :: + ++ on-save on-save:ag + :: + ++ on-load + |= old-state=vase + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-load:ag old-state) + [cards this] + :: + ++ on-watch + |= =path + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-watch:ag path) + [cards this] + :: + ++ on-leave + |= =path + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-leave:ag path) + [cards this] + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-agent:ag wire sign) + [cards this] + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-arvo:ag wire sign-arvo) + [cards this] + :: + ++ on-fail + |= [=term =tang] + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-fail:ag term tang) + [cards this] + -- +-- diff --git a/pkg/base-dev/lib/default-agent.hoon b/pkg/base-dev/lib/default-agent.hoon new file mode 100644 index 000000000..319bf9524 --- /dev/null +++ b/pkg/base-dev/lib/default-agent.hoon @@ -0,0 +1,69 @@ +/+ skeleton +|* [agent=* help=*] +?: ?=(%& help) + ~| %default-agent-helpfully-crashing + skeleton +|_ =bowl:gall +++ on-init + `agent +:: +++ on-save + !>(~) +:: +++ on-load + |= old-state=vase + `agent +:: +++ on-poke + |= =cage + ~| "unexpected poke to {} with mark {}" + !! +:: +++ on-watch + |= =path + ~| "unexpected subscription to {} on path {}" + !! +:: +++ on-leave + |= path + `agent +:: +++ on-peek + |= =path + ~| "unexpected scry into {} on path {}" + !! +:: +++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall _agent) + ?- -.sign + %poke-ack + ?~ p.sign + `agent + %- (slog leaf+"poke failed from {} on wire {}" u.p.sign) + `agent + :: + %watch-ack + ?~ p.sign + `agent + =/ =tank leaf+"subscribe failed from {} on wire {}" + %- (slog tank u.p.sign) + `agent + :: + %kick `agent + %fact + ~| "unexpected subscription update to {} on wire {}" + ~| "with mark {}" + !! + == +:: +++ on-arvo + |= [=wire =sign-arvo] + ~| "unexpected system response {<-.sign-arvo>} to {} on wire {}" + !! +:: +++ on-fail + |= [=term =tang] + %- (slog leaf+"error in {}" >term< tang) + `agent +-- diff --git a/pkg/base-dev/lib/der.hoon b/pkg/base-dev/lib/der.hoon new file mode 100644 index 000000000..c46acc87f --- /dev/null +++ b/pkg/base-dev/lib/der.hoon @@ -0,0 +1,210 @@ +/- asn1 +:: |der: distinguished encoding rules for ASN.1 +:: +:: DER is a tag-length-value binary encoding for ASN.1, designed +:: so that there is only one (distinguished) valid encoding for an +:: instance of a type. +:: +|% +:: +en:der: encode +spec:asn1 to +octs (kindof) +:: +++ en + =< |= a=spec:asn1 + ^- [len=@ud dat=@ux] + =/ b ~(ren raw a) + [(lent b) (rep 3 b)] + |% + :: +raw:en:der: door for encoding +spec:asn1 to list of bytes + :: + ++ raw + |_ pec=spec:asn1 + :: +ren:raw:en:der: render +spec:asn1 to tag-length-value bytes + :: + ++ ren + ^- (list @D) + =/ a lem + [tag (weld (len a) a)] + :: +tag:raw:en:der: tag byte + :: + ++ tag + ^- @D + ?- pec + [%int *] 2 + [%bit *] 3 + [%oct *] 4 + [%nul *] 5 + [%obj *] 6 + [%seq *] 48 :: constructed: (con 0x20 16) + [%set *] 49 :: constructed: (con 0x20 17) + [%con *] ;: con + 0x80 :: context-specifc + ?:(imp.bes.pec 0 0x20) :: implicit? + (dis 0x1f tag.bes.pec) :: 5 bits of custom tag + == + == + :: +lem:raw:en:der: element bytes + :: + ++ lem + ^- (list @D) + ?- pec + :: unsigned only, interpreted as positive-signed and + :: rendered in big-endian byte order. negative-signed would + :: be two's complement + :: + [%int *] =/ a (flop (rip 3 int.pec)) + ?~ a [0 ~] + ?:((lte i.a 127) a [0 a]) + :: padded to byte-width, must be already byte-aligned + :: + [%bit *] =/ a (rip 3 bit.pec) + =/ b ~| %der-invalid-bit + ?. =(0 (mod len.pec 8)) + ~|(%der-invalid-bit-alignment !!) + (sub (div len.pec 8) (lent a)) + [0 (weld a (reap b 0))] + :: padded to byte-width + :: + [%oct *] =/ a (rip 3 oct.pec) + =/ b ~| %der-invalid-oct + (sub len.pec (lent a)) + (weld a (reap b 0)) + :: + [%nul *] ~ + [%obj *] (rip 3 obj.pec) + :: + [%seq *] %- zing + |- ^- (list (list @)) + ?~ seq.pec ~ + :- ren(pec i.seq.pec) + $(seq.pec t.seq.pec) + :: presumed to be already deduplicated and sorted + :: + [%set *] %- zing + |- ^- (list (list @)) + ?~ set.pec ~ + :- ren(pec i.set.pec) + $(set.pec t.set.pec) + :: already constructed + :: + [%con *] con.pec + == + :: +len:raw:en:der: length bytes + :: + ++ len + |= a=(list @D) + ^- (list @D) + =/ b (lent a) + ?: (lte b 127) + [b ~] :: note: big-endian + [(con 0x80 (met 3 b)) (flop (rip 3 b))] + -- + -- +:: +de:der: decode atom to +spec:asn1 +:: +++ de + |= [len=@ud dat=@ux] + ^- (unit spec:asn1) + :: XX refactor into +parse + =/ a (rip 3 dat) + =/ b ~| %der-invalid-len + (sub len (lent a)) + (rust `(list @D)`(weld a (reap b 0)) parse) +:: +parse:der: DER parser combinator +:: +++ parse + =< ^- $-(nail (like spec:asn1)) + ;~ pose + (stag %int (bass 256 (sear int ;~(pfix (tag 2) till)))) + (stag %bit (sear bit (boss 256 ;~(pfix (tag 3) till)))) + (stag %oct (boss 256 ;~(pfix (tag 4) till))) + (stag %nul (cold ~ ;~(plug (tag 5) (tag 0)))) + (stag %obj (^boss 256 ;~(pfix (tag 6) till))) + (stag %seq (sear recur ;~(pfix (tag 48) till))) + (stag %set (sear recur ;~(pfix (tag 49) till))) + (stag %con ;~(plug (sear context next) till)) + == + |% + :: +tag:parse:der: parse tag byte + :: + ++ tag + |=(a=@D (just a)) + :: +int:parse:der: sear unsigned big-endian bytes + :: + ++ int + |= a=(list @D) + ^- (unit (list @D)) + ?~ a ~ + ?: ?=([@ ~] a) `a + ?. =(0 i.a) `a + ?.((gth i.t.a 127) ~ `t.a) + :: +bit:parse:der: convert bytewidth to bitwidth + :: + ++ bit + |= [len=@ud dat=@ux] + ^- (unit [len=@ud dat=@ux]) + ?. =(0 (end 3 dat)) ~ + :+ ~ + (mul 8 (dec len)) + (rsh 3 dat) + :: +recur:parse:der: parse bytes for a list of +spec:asn1 + :: + ++ recur + |=(a=(list @) (rust a (star parse))) + :: +context:parse:der: decode context-specific tag byte + :: + ++ context + |= a=@D + ^- (unit bespoke:asn1) + ?. =(1 (cut 0 [7 1] a)) ~ + :+ ~ + =(1 (cut 0 [5 1] a)) + (dis 0x1f a) + :: +boss:parse:der: shadowed to count as well + :: + :: Use for parsing +octs more broadly? + :: + ++ boss + |* [wuc=@ tyd=rule] + %+ cook + |= waq=(list @) + :- (lent waq) + (reel waq |=([p=@ q=@] (add p (mul wuc q)))) + tyd + :: +till:parse:der: parser combinator for len-prefixed bytes + :: + :: advance until + :: + ++ till + |= tub=nail + ^- (like (list @D)) + ?~ q.tub + (fail tub) + :: fuz: first byte - length, or length of the length + :: + =* fuz i.q.tub + :: nex: offset of value bytes from fuz + :: len: length of value bytes + :: + =/ [nex=@ len=@] + :: faz: meaningful bits in fuz + :: + =/ faz (end [0 7] fuz) + ?: =(0 (cut 0 [7 1] fuz)) + [0 faz] + [faz (rep 3 (flop (scag faz t.q.tub)))] + ?: ?& !=(0 nex) + !=(nex (met 3 len)) + == + (fail tub) + :: zuf: value bytes + :: + =/ zuf (swag [nex len] t.q.tub) + ?. =(len (lent zuf)) + (fail tub) + :: zaf: product nail + :: + =/ zaf [p.p.tub (add +(nex) q.p.tub)] + [zaf `[zuf zaf (slag (add nex len) t.q.tub)]] + -- +-- + diff --git a/pkg/base-dev/lib/ethereum.hoon b/pkg/base-dev/lib/ethereum.hoon new file mode 100644 index 000000000..c292eec3d --- /dev/null +++ b/pkg/base-dev/lib/ethereum.hoon @@ -0,0 +1,982 @@ +:: ethereum: utilities +:: +=, ethereum-types +|% +:: deriving and using ethereum keys +:: +++ key + |% + ++ address-from-pub + =, keccak:crypto + |= pub=@ + %+ end [3 20] + %+ keccak-256 64 + (rev 3 64 pub) + :: + ++ address-from-prv + (cork pub-from-prv address-from-pub) + :: + ++ pub-from-prv + =, secp256k1:secp:crypto + |= prv=@ + %- serialize-point + (priv-to-pub prv) + :: + ++ sign-typed-transaction + |= [tx=typed-transaction:rpc pk=@] + ^- @ux + =- (cat 3 - -.tx) + ?- -.tx + %0x0 (sign-transaction +.tx pk) + %0x2 (sign-transaction-1559 +.tx pk) + == + :: + ++ sign-transaction + =, crypto + |= [tx=transaction:rpc pk=@] + |^ ^- @ux + :: hash the raw transaction data + =/ hash=@ + %- keccak-256:keccak + =+ dat=(encode chain-id.tx 0 0) + =+ wid=(met 3 dat) + [wid (rev 3 wid dat)] + :: sign transaction hash with private key + =+ (ecdsa-raw-sign:secp256k1:secp hash pk) + :: complete transaction is raw data, with r and s + :: taken from the signature, and v as per eip-155 + (encode :(add (mul chain-id.tx 2) 35 v) r s) + :: + ++ encode + |= [v=@ r=@ s=@] + %+ encode:rlp %l + tx(to b+20^to.tx, chain-id [v r s ~]) + -- + :: + ++ sign-transaction-1559 + =, crypto + |= [tx=transaction-1559:rpc pk=@] + |^ ^- @ux + =; hash=@ + =+ (ecdsa-raw-sign:secp256k1:secp hash pk) + ::NOTE we retrieve y's parity from the v value + (encode-1559 ~ (end 0 v) r s) + :: hash the raw transaction data including leading 0x2 + %- keccak-256:keccak + =+ dat=(cat 3 (encode-1559 ~) 0x2) + =+ wid=(met 3 dat) + [wid (rev 3 wid dat)] + :: + ++ encode-1559 + |= sig=(unit [y=@ r=@ s=@]) + %+ encode:rlp %l + =, tx + :* chain-id + nonce + max-priority-gas-fee + max-gas-fee + gas + b+20^to + value + data + :: + :- %l + %+ turn ~(tap by access-list) + |= [a=address b=(list @ux)] + l+~[b+20^a l+(turn b |=(c=@ux b+32^c))] + :: + ?~ sig ~ + ~[y r s]:u.sig + == + -- + -- +:: +:: rlp en/decoding +::NOTE https://eth.wiki/en/fundamentals/rlp +:: +++ rlp + |% + ::NOTE rlp encoding doesn't really care about leading zeroes, + :: but because we need to disinguish between no-bytes zero + :: and one-byte zero (and also empty list) we end up with + :: this awful type... + +$ item + $@ @ + $% [%l l=(list item)] + [%b b=byts] + == + :: +encode-atoms: encode list of atoms as a %l of %b items + :: + ++ encode-atoms ::NOTE deprecated + |= l=(list @) + ^- @ + (encode l+l) + :: + ++ encode + |= in=item + |^ ^- @ + ?- in + @ + $(in [%b (met 3 in) in]) + :: + [%b *] + ?: &(=(1 wid.b.in) (lte dat.b.in 0x7f)) + dat.b.in + =- (can 3 ~[b.in [(met 3 -) -]]) + (encode-length wid.b.in 0x80) + :: + [%l *] + :: we +can because b+1^0x0 encodes to 0x00 + :: + =/ l=(list byts) + %+ turn l.in + |= ni=item + =+ (encode ni) + [(max 1 (met 3 -)) -] + %+ can 3 + %- flop + =- [(met 3 -)^- l] + (encode-length (roll (turn l head) add) 0xc0) + == + :: + ++ encode-length + |= [len=@ off=@] + ?: (lth len 56) (add len off) + =- (cat 3 len -) + :(add (met 3 len) off 55) + -- + :: +decode-atoms: decode expecting a %l of %b items, producing atoms within + :: + ++ decode-atoms + |= dat=@ + ^- (list @) + =/ i=item (decode dat) + ~| [%unexpected-data i] + ?> ?=(%l -.i) + %+ turn l.i + |= i=item + ~| [%unexpected-list i] + ?> ?=(%b -.i) + dat.b.i + :: + ++ decode + |= dat=@ + ^- item + =/ bytes=(list @) (flop (rip 3 dat)) + =? bytes ?=(~ bytes) ~[0] + |^ item:decode-head + :: + ++ decode-head + ^- [done=@ud =item] + ?~ bytes + ~| %rlp-unexpected-end + !! + =* byt i.bytes + :: byte in 0x00-0x79 range encodes itself + :: + ?: (lte byt 0x79) + :- 1 + [%b 1^byt] + :: byte in 0x80-0xb7 range encodes string length + :: + ?: (lte byt 0xb7) + =+ len=(sub byt 0x80) + :- +(len) + :- %b + len^(get-value 1 len) + :: byte in 0xb8-0xbf range encodes string length length + :: + ?: (lte byt 0xbf) + =+ led=(sub byt 0xb7) + =+ len=(get-value 1 led) + :- (add +(led) len) + :- %b + len^(get-value +(led) len) + :: byte in 0xc0-f7 range encodes list length + :: + ?: (lte byt 0xf7) + =+ len=(sub byt 0xc0) + :- +(len) + :- %l + %. len + decode-list(bytes (slag 1 `(list @)`bytes)) + :: byte in 0xf8-ff range encodes list length length + :: + ?: (lte byt 0xff) + =+ led=(sub byt 0xf7) + =+ len=(get-value 1 led) + :- (add +(led) len) + :- %l + %. len + decode-list(bytes (slag +(led) `(list @)`bytes)) + ~| [%rip-not-bloq-3 `@ux`byt] + !! + :: + ++ decode-list + |= rem=@ud + ^- (list item) + ?: =(0 rem) ~ + =+ ^- [don=@ud =item] ::TODO =/ + decode-head + :- item + %= $ + rem (sub rem don) + bytes (slag don bytes) + == + :: + ++ get-value + |= [at=@ud to=@ud] + ^- @ + (rep 3 (flop (swag [at to] bytes))) + -- + -- +:: +:: abi en/decoding +::NOTE https://solidity.readthedocs.io/en/develop/abi-spec.html +:: +++ abi + => |% + :: solidity types. integer bitsizes ignored + ++ etyp + $@ $? :: static + %address %bool + %int %uint + %real %ureal + :: dynamic + %bytes %string + == + $% :: static + [%bytes-n n=@ud] + :: dynamic + [%array-n t=etyp n=@ud] + [%array t=etyp] + == + :: + :: solidity-style typed data. integer bitsizes ignored + ++ data + $% [%address p=address] + [%string p=tape] + [%bool p=?] + [%int p=@sd] + [%uint p=@ud] + [%real p=@rs] + [%ureal p=@urs] + [%array-n p=(list data)] + [%array p=(list data)] + [%bytes-n p=octs] ::TODO just @, because context knows length? + [%bytes p=octs] + == + -- + =, mimes:html + |% + :: encoding + :: + ++ encode-args + :: encode list of arguments. + :: + |= das=(list data) + ^- tape + (encode-data [%array-n das]) + :: + ++ encode-data + :: encode typed data into ABI bytestring. + :: + |= dat=data + ^- tape + ?+ -.dat + ~| [%unsupported-type -.dat] + !! + :: + %array-n + :: enc(X) = head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[k-1]) + :: where head and tail are defined for X[i] being of a static type as + :: head(X[i]) = enc(X[i]) and tail(X[i]) = "" (the empty string), or as + :: head(X[i]) = enc(len( head(X[0])..head(X[k-1]) + :: tail(X[0])..tail(X[i-1]) )) + :: and tail(X[i]) = enc(X[i]) otherwise. + :: + :: so: if it's a static type, data goes in the head. if it's a dynamic + :: type, a reference goes into the head and data goes into the tail. + :: + :: in the head, we first put a placeholder where references need to go. + =+ hol=(reap 64 'x') + =/ hes=(list tape) + %+ turn p.dat + |= d=data + ?. (is-dynamic-type d) ^$(dat d) + hol + =/ tas=(list tape) + %+ turn p.dat + |= d=data + ?. (is-dynamic-type d) "" + ^$(dat d) + :: once we know the head and tail, we can fill in the references in head. + =- (weld nes `tape`(zing tas)) + ^- [@ud nes=tape] + =+ led=(lent (zing hes)) + %+ roll hes + |= [t=tape i=@ud nes=tape] + :- +(i) + :: if no reference needed, just put the data. + ?. =(t hol) (weld nes t) + :: calculate byte offset of data we need to reference. + =/ ofs=@ud + =- (div - 2) :: two hex digits per byte. + %+ add led :: count head, and + %- lent %- zing :: count all tail data + (scag i tas) :: preceding ours. + =+ ref=^$(dat [%uint ofs]) + :: shouldn't hit this unless we're sending over 2gb of data? + ~| [%weird-ref-lent (lent ref)] + ?> =((lent ref) (lent hol)) + (weld nes ref) + :: + %array :: where X has k elements (k is assumed to be of type uint256): + :: enc(X) = enc(k) enc([X[1], ..., X[k]]) + :: i.e. it is encoded as if it were an array of static size k, prefixed + :: with the number of elements. + %+ weld $(dat [%uint (lent p.dat)]) + $(dat [%array-n p.dat]) + :: + %bytes-n + :: enc(X) is the sequence of bytes in X padded with zero-bytes to a + :: length of 32. + :: Note that for any X, len(enc(X)) is a multiple of 32. + ~| [%bytes-n-too-long max=32 actual=p.p.dat] + ?> (lte p.p.dat 32) + (pad-to-multiple (render-hex-bytes p.dat) 64 %right) + :: + %bytes :: of length k (which is assumed to be of type uint256) + :: enc(X) = enc(k) pad_right(X), i.e. the number of bytes is encoded as a + :: uint256 followed by the actual value of X as a byte sequence, followed + :: by the minimum number of zero-bytes such that len(enc(X)) is a + :: multiple of 32. + %+ weld $(dat [%uint p.p.dat]) + (pad-to-multiple (render-hex-bytes p.dat) 64 %right) + :: + %string + :: enc(X) = enc(enc_utf8(X)), i.e. X is utf-8 encoded and this value is + :: interpreted as of bytes type and encoded further. Note that the length + :: used in this subsequent encoding is the number of bytes of the utf-8 + :: encoded string, not its number of characters. + $(dat [%bytes (lent p.dat) (swp 3 (crip p.dat))]) + :: + %uint + :: enc(X) is the big-endian encoding of X, padded on the higher-order + :: (left) side with zero-bytes such that the length is a multiple of 32 + :: bytes. + (pad-to-multiple (render-hex-bytes (as-octs p.dat)) 64 %left) + :: + %bool + :: as in the uint8 case, where 1 is used for true and 0 for false + $(dat [%uint ?:(p.dat 1 0)]) + :: + %address + :: as in the uint160 case + $(dat [%uint `@ud`p.dat]) + == + :: + ++ is-dynamic-type + |= a=data + ?. ?=(%array-n -.a) + ?=(?(%string %bytes %array) -.a) + &(!=((lent p.a) 0) (lien p.a is-dynamic-type)) + :: + :: decoding + :: + ++ decode-topics decode-arguments + :: + ++ decode-results + :: rex: string of hex bytes with leading 0x. + |* [rex=@t tys=(list etyp)] + =- (decode-arguments - tys) + %^ rut 9 + (rsh [3 2] rex) + (curr rash hex) + :: + ++ decode-arguments + |* [wos=(list @) tys=(list etyp)] + =/ wos=(list @) wos :: get rid of tmi + =| win=@ud + =< (decode-from 0 tys) + |% + ++ decode-from + |* [win=@ud tys=(list etyp)] + ?~ tys !! + =- ?~ t.tys dat + [dat $(win nin, tys t.tys)] + (decode-one win ~[i.tys]) + :: + ++ decode-one + ::NOTE we take (list etyp) even though we only operate on + :: a single etyp as a workaround for urbit/arvo#673 + |* [win=@ud tys=(list etyp)] + =- [nin dat]=- ::NOTE ^= regular form broken + ?~ tys !! + =* typ i.tys + =+ wor=(snag win wos) + ?+ typ + ~| [%unsupported-type typ] + !! + :: + ?(%address %bool %uint) :: %int %real %ureal + :- +(win) + ?- typ + %address `@ux`wor + %uint `@ud`wor + %bool =(1 wor) + == + :: + %string + =+ $(tys ~[%bytes]) + [nin (trip (swp 3 q.dat))] + :: + %bytes + :- +(win) + :: find the word index of the actual data. + =/ lic=@ud (div wor 32) + :: learn the bytelength of the data. + =/ len=@ud (snag lic wos) + (decode-bytes-n +(lic) len) + :: + [%bytes-n *] + :- (add win +((div (dec n.typ) 32))) + (decode-bytes-n win n.typ) + :: + [%array *] + :- +(win) + :: find the word index of the actual data. + =. win (div wor 32) + :: read the elements from their location. + %- tail + %^ decode-array-n ~[t.typ] +(win) + (snag win wos) + :: + [%array-n *] + (decode-array-n ~[t.typ] win n.typ) + == + :: + ++ decode-bytes-n + |= [fro=@ud bys=@ud] + ^- octs + :: parse {bys} bytes from {fro}. + :- bys + %+ rsh + :- 3 + =+ (mod bys 32) + ?:(=(0 -) - (sub 32 -)) + %+ rep 8 + %- flop + =- (swag [fro -] wos) + +((div (dec bys) 32)) + :: + ++ decode-array-n + ::NOTE we take (list etyp) even though we only operate on + :: a single etyp as a workaround for urbit/arvo#673 + ::NOTE careful! produces lists without type info + =| res=(list) + |* [tys=(list etyp) fro=@ud len=@ud] + ^- [@ud (list)] + ?~ tys !! + ?: =(len 0) [fro (flop `(list)`res)] + =+ (decode-one fro ~[i.tys]) :: [nin=@ud dat=*] + $(res ^+(res [dat res]), fro nin, len (dec len)) + -- + -- +:: +:: communicating with rpc nodes +::NOTE https://github.com/ethereum/wiki/wiki/JSON-RPC +:: +++ rpc + :: types + :: + => =, abi + =, format + |% + :: raw call data + ++ call-data + $: function=@t + arguments=(list data) + == + :: + :: raw transaction data + +$ typed-transaction + $% [%0x0 transaction] + [%0x2 transaction-1559] + == + :: + +$ transaction + $: nonce=@ud + gas-price=@ud + gas=@ud + to=address + value=@ud + data=@ux + chain-id=@ux + == + :: + +$ transaction-1559 + $: chain-id=@ux + nonce=@ud + max-priority-gas-fee=@ud + max-gas-fee=@ud + gas=@ud + to=address + value=@ud + data=@ux + access-list=(jar address @ux) + == + :: + :: ethereum json rpc api + :: + :: supported requests. + ++ request + $% [%eth-block-number ~] + [%eth-call cal=call deb=block] + $: %eth-new-filter + fro=(unit block) + tob=(unit block) + adr=(list address) + top=(list ?(@ux (list @ux))) + == + [%eth-get-block-by-number bon=@ud txs=?] + [%eth-get-filter-logs fid=@ud] + $: %eth-get-logs + fro=(unit block) + tob=(unit block) + adr=(list address) + top=(list ?(@ux (list @ux))) + == + $: %eth-get-logs-by-hash + has=@ + adr=(list address) + top=(list ?(@ux (list @ux))) + == + [%eth-get-filter-changes fid=@ud] + [%eth-get-transaction-by-hash txh=@ux] + [%eth-get-transaction-count adr=address =block] + [%eth-get-balance adr=address =block] + [%eth-get-transaction-receipt txh=@ux] + [%eth-send-raw-transaction dat=@ux] + == + :: + ::TODO clean up & actually use + ++ response + $% ::TODO + [%eth-new-filter fid=@ud] + [%eth-get-filter-logs los=(list event-log)] + [%eth-get-logs los=(list event-log)] + [%eth-get-logs-by-hash los=(list event-log)] + [%eth-got-filter-changes los=(list event-log)] + [%eth-transaction-hash haz=@ux] + == + :: + ++ transaction-result + $: block-hash=(unit @ux) + block-number=(unit @ud) + transaction-index=(unit @ud) + from=@ux + to=(unit @ux) + input=@t + == + :: + ++ event-log + $: :: null for pending logs + $= mined %- unit + $: input=(unit @ux) + log-index=@ud + transaction-index=@ud + transaction-hash=@ux + block-number=@ud + block-hash=@ux + removed=? + == + :: + address=@ux + data=@t + :: event data + :: + :: For standard events, the first topic is the event signature + :: hash. For anonymous events, the first topic is the first + :: indexed argument. + :: Note that this does not support the "anonymous event with + :: zero topics" case. This has dubious usability, and using + :: +lest instead of +list saves a lot of ?~ checks. + :: + topics=(lest @ux) + == + :: + :: data for eth_call. + ++ call + $: from=(unit address) + to=address + gas=(unit @ud) + gas-price=(unit @ud) + value=(unit @ud) + data=tape + == + :: + :: minimum data needed to construct a read call + ++ proto-read-request + $: id=(unit @t) + to=address + call-data + == + :: + :: block to operate on. + ++ block + $% [%number n=@ud] + [%label l=?(%earliest %latest %pending)] + == + -- + :: + :: logic + :: + |% + ++ encode-call + |= call-data + ^- tape + ::TODO should this check to see if the data matches the function signature? + =- :(weld "0x" - (encode-args arguments)) + %+ scag 8 + %+ render-hex-bytes 32 + %- keccak-256:keccak:crypto + (as-octs:mimes:html function) + :: + :: building requests + :: + ++ json-request + =, eyre + |= [url=purl jon=json] + ^- hiss + :^ url %post + %- ~(gas in *math) + ~['Content-Type'^['application/json']~] + (some (as-octt (en-json:html jon))) + :: +light-json-request: like json-request, but for %l + :: + :: TODO: Exorcising +purl from our system is a much longer term effort; + :: get the current output types for now. + :: + ++ light-json-request + |= [url=purl:eyre jon=json] + ^- request:http + :: + :* %'POST' + (crip (en-purl:html url)) + ~[['content-type' 'application/json']] + (some (as-octt (en-json:html jon))) + == + :: + ++ batch-read-request + |= req=(list proto-read-request) + ^- json + a+(turn req read-request) + :: + ++ read-request + |= proto-read-request + ^- json + %+ request-to-json id + :+ %eth-call + ^- call + [~ to ~ ~ ~ `tape`(encode-call function arguments)] + [%label %latest] + :: + ++ request-to-json + =, enjs:format + |= [riq=(unit @t) req=request] + ^- json + %- pairs + =; r=[met=@t pas=(list json)] + ::TODO should use request-to-json:rpc:jstd, + :: and probably (fall riq -.req) + :* jsonrpc+s+'2.0' + method+s+met.r + params+a+pas.r + ::TODO would just jamming the req noun for id be a bad idea? + ?~ riq ~ + [id+s+u.riq]~ + == + ?- -.req + %eth-block-number + ['eth_blockNumber' ~] + :: + %eth-call + :- 'eth_call' + :~ (eth-call-to-json cal.req) + (block-to-json deb.req) + == + :: + %eth-new-filter + :- 'eth_newFilter' + :_ ~ + :- %o %- ~(gas by *(map @t json)) + =- (murn - same) + ^- (list (unit (pair @t json))) + :~ ?~ fro.req ~ + `['fromBlock' (block-to-json u.fro.req)] + :: + ?~ tob.req ~ + `['toBlock' (block-to-json u.tob.req)] + :: + ::NOTE tmi + ?: =(0 (lent adr.req)) ~ + :+ ~ 'address' + ?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req))) + :- %a + (turn adr.req (cork address-to-hex tape)) + :: + ?~ top.req ~ + :+ ~ 'topics' + (topics-to-json top.req) + == + :: + %eth-get-block-by-number + :- 'eth_getBlockByNumber' + :~ (tape (num-to-hex bon.req)) + b+txs.req + == + :: + %eth-get-filter-logs + ['eth_getFilterLogs' (tape (num-to-hex fid.req)) ~] + :: + %eth-get-logs + :- 'eth_getLogs' + :_ ~ + :- %o %- ~(gas by *(map @t json)) + =- (murn - same) + ^- (list (unit (pair @t json))) + :~ ?~ fro.req ~ + `['fromBlock' (block-to-json u.fro.req)] + :: + ?~ tob.req ~ + `['toBlock' (block-to-json u.tob.req)] + :: + ?: =(0 (lent adr.req)) ~ + :+ ~ 'address' + ?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req))) + :- %a + (turn adr.req (cork address-to-hex tape)) + :: + ?~ top.req ~ + :+ ~ 'topics' + (topics-to-json top.req) + == + :: + %eth-get-logs-by-hash + :- 'eth_getLogs' + :_ ~ :- %o + %- ~(gas by *(map @t json)) + =- (murn - same) + ^- (list (unit (pair @t json))) + :~ `['blockHash' (tape (transaction-to-hex has.req))] + :: + ?: =(0 (lent adr.req)) ~ + :+ ~ 'address' + ?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req))) + :- %a + (turn adr.req (cork address-to-hex tape)) + :: + ?~ top.req ~ + :+ ~ 'topics' + (topics-to-json top.req) + == + :: + %eth-get-filter-changes + ['eth_getFilterChanges' (tape (num-to-hex fid.req)) ~] + :: + %eth-get-transaction-count + :- 'eth_getTransactionCount' + :~ (tape (address-to-hex adr.req)) + (block-to-json block.req) + == + :: + %eth-get-balance + :- 'eth_getBalance' + :~ (tape (address-to-hex adr.req)) + (block-to-json block.req) + == + :: + %eth-get-transaction-by-hash + ['eth_getTransactionByHash' (tape (transaction-to-hex txh.req)) ~] + :: + %eth-get-transaction-receipt + ['eth_getTransactionReceipt' (tape (transaction-to-hex txh.req)) ~] + :: + %eth-send-raw-transaction + ['eth_sendRawTransaction' (tape (num-to-hex dat.req)) ~] + == + :: + ++ eth-call-to-json + =, enjs:format + |= cal=call + ^- json + :- %o %- ~(gas by *(map @t json)) + =- (murn - same) + ^- (list (unit (pair @t json))) + :~ ?~ from.cal ~ + `['from' (tape (address-to-hex u.from.cal))] + :: + `['to' (tape (address-to-hex to.cal))] + :: + ?~ gas.cal ~ + `['gas' (tape (num-to-hex u.gas.cal))] + :: + ?~ gas-price.cal ~ + `['gasPrice' (tape (num-to-hex u.gas-price.cal))] + :: + ?~ value.cal ~ + `['value' (tape (num-to-hex u.value.cal))] + :: + ?~ data.cal ~ + `['data' (tape data.cal)] + == + :: + ++ block-to-json + |= dob=block + ^- json + ?- -.dob + %number s+(crip '0' 'x' ((x-co:co 1) n.dob)) + %label s+l.dob + == + :: + ++ topics-to-json + |= tos=(list ?(@ux (list @ux))) + ^- json + :- %a + =/ ttj + ;: cork + (cury render-hex-bytes 32) + prefix-hex + tape:enjs:format + == + %+ turn tos + |= t=?(@ (list @)) + ?@ t + ?: =(0 t) ~ + (ttj `@`t) + a+(turn t ttj) + :: + :: parsing responses + :: + ::TODO ++ parse-response |= json ^- response + :: + ++ parse-hex-result + |= j=json + ^- @ + ?> ?=(%s -.j) + (hex-to-num p.j) + :: + ++ parse-eth-new-filter-res parse-hex-result + :: + ++ parse-eth-block-number parse-hex-result + :: + ++ parse-transaction-hash parse-hex-result + :: + ++ parse-eth-get-transaction-count parse-hex-result + :: + ++ parse-eth-get-balance parse-hex-result + :: + ++ parse-event-logs + (ar:dejs:format parse-event-log) + :: + ++ parse-event-log + =, dejs:format + |= log=json + ^- event-log + =- ((ot -) log) + :~ =- ['logIndex'^(cu - (mu so))] + |= li=(unit @t) + ?~ li ~ + =- ``((ou -) log) ::TODO not sure if elegant or hacky. + :~ 'logIndex'^(un (cu hex-to-num so)) + 'transactionIndex'^(un (cu hex-to-num so)) + 'transactionHash'^(un (cu hex-to-num so)) + 'blockNumber'^(un (cu hex-to-num so)) + 'blockHash'^(un (cu hex-to-num so)) + 'removed'^(uf | bo) + == + :: + address+(cu hex-to-num so) + data+so + :: + =- topics+(cu - (ar so)) + |= r=(list @t) + ^- (lest @ux) + ?> ?=([@t *] r) + :- (hex-to-num i.r) + (turn t.r hex-to-num) + == + :: + ++ parse-transaction-result + =, dejs:format + |= jon=json + ~| jon=jon + ^- transaction-result + =- ((ot -) jon) + :~ 'blockHash'^_~ :: TODO: fails if maybe-num? + 'blockNumber'^maybe-num + 'transactionIndex'^maybe-num + from+(cu hex-to-num so) + to+maybe-num + input+so + == + :: + ++ maybe-num + =, dejs:format + =- (cu - (mu so)) + |= r=(unit @t) + ?~ r ~ + `(hex-to-num u.r) + -- +:: +:: utilities +::TODO give them better homes! +:: +++ num-to-hex + |= n=@ + ^- tape + %- prefix-hex + ?: =(0 n) + "0" + %- render-hex-bytes + (as-octs:mimes:html n) +:: +++ address-to-hex + |= a=address + ^- tape + %- prefix-hex + (render-hex-bytes 20 `@`a) +:: +++ transaction-to-hex + |= h=@ + ^- tape + %- prefix-hex + (render-hex-bytes 32 h) +:: +++ prefix-hex + |= a=tape + ^- tape + ['0' 'x' a] +:: +++ render-hex-bytes + :: atom to string of hex bytes without 0x prefix and dots. + |= a=octs + ^- tape + ((x-co:co (mul 2 p.a)) q.a) +:: +++ pad-to-multiple + |= [wat=tape mof=@ud wer=?(%left %right)] + ^- tape + =+ len=(lent wat) + ?: =(0 len) (reap mof '0') + =+ mad=(mod len mof) + ?: =(0 mad) wat + =+ tad=(reap (sub mof mad) '0') + %- weld + ?:(?=(%left wer) [tad wat] [wat tad]) +:: +++ hex-to-num + |= a=@t + (rash (rsh [3 2] a) hex) +-- diff --git a/pkg/base-dev/lib/ethio.hoon b/pkg/base-dev/lib/ethio.hoon new file mode 100644 index 000000000..0e4c7793e --- /dev/null +++ b/pkg/base-dev/lib/ethio.hoon @@ -0,0 +1,289 @@ +:: ethio: Asynchronous Ethereum input/output functions. +:: +/- rpc=json-rpc +/+ ethereum, strandio +=, ethereum-types +=, jael +:: +=> |% + +$ topics (list ?(@ux (list @ux))) + -- +|% +:: +request-rpc: send rpc request, with retry +:: +++ request-rpc + |= [url=@ta id=(unit @t) req=request:rpc:ethereum] + =/ m (strand:strandio ,json) + ^- form:m + ;< res=(list [id=@t =json]) bind:m + (request-batch-rpc-strict url [id req]~) + ?: ?=([* ~] res) + (pure:m json.i.res) + %+ strand-fail:strandio + %unexpected-multiple-results + [>(lent res)< ~] +:: +request-batch-rpc-strict: send rpc requests, with retry +:: +:: sends a batch request. produces results for all requests in the batch, +:: but only if all of them are successful. +:: +++ request-batch-rpc-strict + |= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])] + |^ %+ (retry:strandio results) + `10 + attempt-request + :: + +$ results (list [id=@t =json]) + :: + ++ attempt-request + =/ m (strand:strandio ,(unit results)) + ^- form:m + ;< responses=(list response:rpc) bind:m + (request-batch-rpc-loose url reqs) + =- ?~ err + (pure:m `res) + (pure:m ~) + %+ roll responses + |= $: rpc=response:rpc + [res=results err=(list [id=@t code=@t message=@t])] + == + ?: ?=(%error -.rpc) + [res [+.rpc err]] + ?. ?=(%result -.rpc) + [res [['' 'ethio-rpc-fail' (crip )] err]] + [[+.rpc res] err] + -- +:: +request-batch-rpc-loose: send rpc requests, with retry +:: +:: sends a batch request. produces results for all requests in the batch, +:: including the ones that are unsuccessful. +:: +++ request-batch-rpc-loose + |= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])] + |^ %+ (retry:strandio results) + `10 + attempt-request + :: + +$ result response:rpc + +$ results (list response:rpc) + :: + ++ attempt-request + =/ m (strand:strandio ,(unit results)) + ^- form:m + =/ =request:http + :* method=%'POST' + url=url + header-list=['Content-Type'^'application/json' ~] + :: + ^= body + %- some %- as-octt:mimes:html + %- en-json:html + a+(turn reqs request-to-json:rpc:ethereum) + == + ;< ~ bind:m + (send-request:strandio request) + ;< rep=(unit client-response:iris) bind:m + take-maybe-response:strandio + ?~ rep + (pure:m ~) + (parse-responses u.rep) + :: + ++ parse-responses + |= =client-response:iris + =/ m (strand:strandio ,(unit results)) + ^- form:m + ?> ?=(%finished -.client-response) + ?~ full-file.client-response + (pure:m ~) + =/ body=@t q.data.u.full-file.client-response + =/ jon=(unit json) (de-json:html body) + ?~ jon + (pure:m ~) + =/ array=(unit (list response:rpc)) + ((ar:dejs-soft:format parse-one-response) u.jon) + ?~ array + (strand-fail:strandio %rpc-result-incomplete-batch >u.jon< ~) + (pure:m array) + :: + ++ parse-one-response + |= =json + ^- (unit response:rpc) + ?. &(?=([%o *] json) (~(has by p.json) 'error')) + =/ res=(unit [@t ^json]) + %. json + =, dejs-soft:format + (ot id+so result+some ~) + ?~ res ~ + `[%result u.res] + ~| parse-one-response=json + =/ error=(unit [id=@t ^json code=@ta mssg=@t]) + %. json + =, dejs-soft:format + :: A 'result' member is present in the error + :: response when using ganache, even though + :: that goes against the JSON-RPC spec + :: + (ot id+so result+some error+(ot code+no message+so ~) ~) + ?~ error ~ + =* err u.error + `[%error id.err code.err mssg.err] + -- +:: +:: +read-contract: calls a read function on a contract, produces result hex +:: +++ read-contract + |= [url=@t req=proto-read-request:rpc:ethereum] + =/ m (strand:strandio ,@t) + ;< res=(list [id=@t res=@t]) bind:m + (batch-read-contract-strict url [req]~) + ?: ?=([* ~] res) + (pure:m res.i.res) + %+ strand-fail:strandio + %unexpected-multiple-results + [>(lent res)< ~] +:: +batch-read-contract-strict: calls read functions on contracts +:: +:: sends a batch request. produces results for all requests in the batch, +:: but only if all of them are successful. +:: +++ batch-read-contract-strict + |= [url=@t reqs=(list proto-read-request:rpc:ethereum)] + |^ =/ m (strand:strandio ,results) + ^- form:m + ;< res=(list [id=@t =json]) bind:m + %+ request-batch-rpc-strict url + (turn reqs proto-to-rpc) + =+ ^- [=results =failures] + (roll res response-to-result) + ?~ failures (pure:m results) + (strand-fail:strandio %batch-read-failed-for >failures< ~) + :: + +$ results (list [id=@t res=@t]) + +$ failures (list [id=@t =json]) + :: + ++ proto-to-rpc + |= proto-read-request:rpc:ethereum + ^- [(unit @t) request:rpc:ethereum] + :- id + :+ %eth-call + ^- call:rpc:ethereum + [~ to ~ ~ ~ `tape`(encode-call:rpc:ethereum function arguments)] + [%label %latest] + :: + ++ response-to-result + |= [[id=@t =json] =results =failures] + ^+ [results failures] + ?: ?=(%s -.json) + [[id^p.json results] failures] + [results [id^json failures]] + -- +:: +:: +++ get-latest-block + |= url=@ta + =/ m (strand:strandio ,block) + ^- form:m + ;< =json bind:m + (request-rpc url `'block number' %eth-block-number ~) + (get-block-by-number url (parse-eth-block-number:rpc:ethereum json)) +:: +++ get-block-by-number + |= [url=@ta =number:block] + =/ m (strand:strandio ,block) + ^- form:m + |^ + %+ (retry:strandio ,block) `10 + =/ m (strand:strandio ,(unit block)) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :- `'block by number' + [%eth-get-block-by-number number |] + (pure:m (parse-block json)) + :: + ++ parse-block + |= =json + ^- (unit block) + =< ?~(. ~ `[[&1 &2] |2]:u) + ^- (unit [@ @ @]) + ~| json + %. json + =, dejs-soft:format + %- ot + :~ hash+parse-hex + number+parse-hex + 'parentHash'^parse-hex + == + :: + ++ parse-hex |=(=json `(unit @)`(some (parse-hex-result:rpc:ethereum json))) + -- +:: +++ get-tx-by-hash + |= [url=@ta tx-hash=@ux] + =/ m (strand:strandio transaction-result:rpc:ethereum) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :* `'tx by hash' + %eth-get-transaction-by-hash + tx-hash + == + %- pure:m + (parse-transaction-result:rpc:ethereum json) +:: +++ get-logs-by-hash + |= [url=@ta =hash:block contracts=(list address) =topics] + =/ m (strand:strandio (list event-log:rpc:ethereum)) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :* `'logs by hash' + %eth-get-logs-by-hash + hash + contracts + topics + == + %- pure:m + (parse-event-logs:rpc:ethereum json) +:: +++ get-logs-by-range + |= $: url=@ta + contracts=(list address) + =topics + =from=number:block + =to=number:block + == + =/ m (strand:strandio (list event-log:rpc:ethereum)) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :* `'logs by range' + %eth-get-logs + `number+from-number + `number+to-number + contracts + topics + == + %- pure:m + (parse-event-logs:rpc:ethereum json) +:: +++ get-next-nonce + |= [url=@ta =address] + =/ m (strand:strandio ,@ud) + ^- form:m + ;< =json bind:m + %^ request-rpc url `'nonce' + [%eth-get-transaction-count address [%label %latest]] + %- pure:m + (parse-eth-get-transaction-count:rpc:ethereum json) +:: +++ get-balance + |= [url=@ta =address] + =/ m (strand:strandio ,@ud) + ^- form:m + ;< =json bind:m + %^ request-rpc url `'balance' + [%eth-get-balance address [%label %latest]] + %- pure:m + (parse-eth-get-balance:rpc:ethereum json) +-- diff --git a/pkg/base-dev/lib/jose.hoon b/pkg/base-dev/lib/jose.hoon new file mode 100644 index 000000000..e2f77e8c5 --- /dev/null +++ b/pkg/base-dev/lib/jose.hoon @@ -0,0 +1,214 @@ +/+ primitive-rsa, *pkcs +=* rsa primitive-rsa +|% +:: +en-base64url: url-safe base64 encoding, without padding +:: +++ en-base64url + ~(en base64:mimes:html | &) +:: +de-base64url: url-safe base64 decoding, without padding +:: +++ de-base64url + ~(de base64:mimes:html | &) +:: |octn: encode/decode unsigned atoms as big-endian octet stream +:: +++ octn + |% + ++ en |=(a=@u `octs`[(met 3 a) (swp 3 a)]) + ++ de |=(a=octs `@u`(rev 3 p.a q.a)) + -- +:: +eor: explicit sort order comparator +:: +:: Lookup :a and :b in :lit, and pass their indices to :com. +:: +++ eor + |= [com=$-([@ @] ?) lit=(list)] + |= [a=* b=*] + ^- ? + (fall (bind (both (find ~[a] lit) (find ~[b] lit)) com) |) +:: +en-json-sort: json encoding with sorted object keys +:: +:: XX move %zuse with sorting optional? +:: +++ en-json-sort :: XX rename + |^ |=([sor=$-(^ ?) val=json] (apex val sor "")) + :: :: ++apex:en-json:html + ++ apex + =, en-json:html + |= [val=json sor=$-(^ ?) rez=tape] + ^- tape + ?~ val (weld "null" rez) + ?- -.val + %a + :- '[' + =. rez [']' rez] + !. + ?~ p.val rez + |- + ?~ t.p.val ^$(val i.p.val) + ^$(val i.p.val, rez [',' $(p.val t.p.val)]) + :: + %b (weld ?:(p.val "true" "false") rez) + %n (weld (trip p.val) rez) + %s + :- '"' + =. rez ['"' rez] + =+ viz=(trip p.val) + !. + |- ^- tape + ?~ viz rez + =+ hed=(jesc i.viz) + ?: ?=([@ ~] hed) + [i.hed $(viz t.viz)] + (weld hed $(viz t.viz)) + :: + %o + :- '{' + =. rez ['}' rez] + =/ viz + %+ sort ~(tap by p.val) + |=((pair) (sor (head p) (head q))) + ?~ viz rez + !. + |- ^+ rez + ?~ t.viz ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)]) + =. rez [',' $(viz t.viz)] + ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)]) + == + -- +:: %/lib/jose +:: +:: |jwk: json representations of cryptographic keys (rfc7517) +:: +:: Url-safe base64 encoding of key parameters in big-endian byte order. +:: RSA-only for now +:: +++ jwk + |% + :: |en:jwk: encoding of json cryptographic keys + :: + ++ en + => |% + :: +numb:en:jwk: base64-url encode big-endian number + :: + ++ numb (corl en-base64url en:octn) + -- + |% + :: +pass:en:jwk: json encode public key + :: + ++ pass + |= k=key:rsa + ^- json + [%o (my kty+s+'RSA' n+s+(numb n.pub.k) e+s+(numb e.pub.k) ~)] + :: +ring:en:jwk: json encode private key + :: + ++ ring + |= k=key:rsa + ^- json + ~| %rsa-need-ring + ?> ?=(^ sek.k) + :- %o %- my :~ + kty+s+'RSA' + n+s+(numb n.pub.k) + e+s+(numb e.pub.k) + d+s+(numb d.u.sek.k) + p+s+(numb p.u.sek.k) + q+s+(numb q.u.sek.k) + == + -- + :: |de:jwk: decoding of json cryptographic keys + :: + ++ de + =, dejs-soft:format + => |% + :: +numb:de:jwk: parse base64-url big-endian number + :: + ++ numb (cu (cork de-base64url (lift de:octn)) so) + -- + |% + :: +pass:de:jwk: decode json public key + :: + ++ pass + %+ ci + =/ a (unit @ux) + |= [kty=@t n=a e=a] + ^- (unit key:rsa) + =/ pub (both n e) + ?~(pub ~ `[u.pub ~]) + (ot kty+(su (jest 'RSA')) n+numb e+numb ~) + :: +ring:de:jwk: decode json private key + :: + ++ ring + %+ ci + =/ a (unit @ux) + |= [kty=@t n=a e=a d=a p=a q=a] + ^- (unit key:rsa) + =/ pub (both n e) + =/ sek :(both d p q) + ?:(|(?=(~ pub) ?=(~ sek)) ~ `[u.pub sek]) + (ot kty+(su (jest 'RSA')) n+numb e+numb d+numb p+numb q+numb ~) + -- + :: |thumb:jwk: "thumbprint" json-encoded key (rfc7638) + :: + ++ thumb + |% + :: +pass:thumb:jwk: thumbprint json-encoded public key + :: + ++ pass + |= k=key:rsa + (en-base64url 32 (shax (crip (en-json-sort aor (pass:en k))))) + :: +ring:thumb:jwk: thumbprint json-encoded private key + :: + ++ ring !! + -- + -- +:: |jws: json web signatures (rfc7515) +:: +:: Note: flattened signature form only. +:: +++ jws + |% + :: +sign:jws: sign json value + :: + ++ sign + |= [k=key:rsa pro=json lod=json] + |^ ^- json + =. pro header + =/ protect=cord (encode pro) + =/ payload=cord (encode lod) + :- %o %- my :~ + protected+s+protect + payload+s+payload + signature+s+(sign protect payload) + == + :: +header:sign:jws: set signature algorithm in header + :: + ++ header + ?> ?=([%o *] pro) + ^- json + [%o (~(put by p.pro) %alg s+'RS256')] + :: +encode:sign:jws: encode json for signing + :: + :: Alphabetically sort object keys, url-safe base64 encode + :: the serialized json. + :: + ++ encode + |= jon=json + %- en-base64url + %- as-octt:mimes:html + (en-json-sort aor jon) + :: +sign:sign:jws: compute signature + :: + :: Url-safe base64 encode in big-endian byte order. + :: + ++ sign + |= [protect=cord payload=cord] + =/ msg=@t (rap 3 ~[protect '.' payload]) + =/ sig=@ud (~(sign rs256 k) (met 3 msg) msg) + =/ len=@ud (met 3 n.pub.k) + (en-base64url len (rev 3 len sig)) + -- + :: +verify:jws: verify signature + :: + ++ verify !! + -- +-- diff --git a/pkg/base-dev/lib/keygen.hoon b/pkg/base-dev/lib/keygen.hoon new file mode 100644 index 000000000..b4c0a6e20 --- /dev/null +++ b/pkg/base-dev/lib/keygen.hoon @@ -0,0 +1,112 @@ +:: urbit-style key generation and derivation functions +:: +/- keygen +:: +/+ ethereum, bip32, bip39 +:: +=, keygen +:: +|% +++ argon2u + |= [who=ship tic=byts] + ^- @ + ~| [%who who (met 3 who)] + :: ?> (lte (met 3 who) 4) + %- (argon2-urbit:argon2:crypto 32) + :- tic + =- [(met 3 -) (swp 3 -)] + %- crip + (weld "urbitkeygen" (a-co:co who)) +:: +++ child-node-from-seed + |= [seed=@ typ=tape pass=(unit @t)] + ^- node + =+ sed=(seed:ds 32^seed typ) + =+ nom=(from-entropy:bip39 32^sed) + :+ typ nom + %- wallet:ds + %+ to-seed:bip39 nom + (trip (fall pass '')) +:: +++ derive-network-seed + |= [mngs=@ rev=@ud] + ^- @ux + =+ (seed:ds 64^mngs (weld "network" (a-co:co rev))) + ?: =(0 rev) - + :: hash again to prevent length extension attacks + (sha-256l:sha 32 -) +:: +++ ownership-wallet-from-ticket + |= [who=ship ticket=byts pass=(unit @t)] + ^- node + =+ master-seed=(argon2u who ticket) + (child-node-from-seed master-seed "ownership" pass) +:: +++ full-wallet-from-ticket + :: who: username + :: ticket: password + :: rev: network key revision + :: pass: optional passphrase + :: + |= [who=ship ticket=byts rev=@ud pass=(unit @t)] + ^- vault + =+ master-seed=(argon2u who ticket) + =/ cn :: child node + |= typ=nodetype + (child-node-from-seed master-seed typ pass) + :: + :- ^= ownership ^- node + (cn "ownership") + :: + :- ^= voting ^- node + (cn "voting") + :: + =/ management=node + (cn "management") + :- management=management + :: + :- ^= transfer ^- node + (cn "transfer") + :: + :- ^= spawn ^- node + (cn "spawn") + :: + ^= network ^- uode + =/ mad :: management seed + %+ to-seed:bip39 + seed:management + (trip (fall pass '')) + =+ sed=(derive-network-seed mad rev) + [rev sed (urbit:ds sed)] +:: +++ ds :: derive from raw seed + |% + ++ wallet + |= seed=@ + ^- ^wallet + =+ => (from-seed:bip32 64^seed) + (derive-path "m/44'/60'/0'/0/0") + :+ [public-key private-key] + (address-from-prv:key:ethereum private-key) + chain-code + :: + ++ urbit + |= seed=@ + ^- edkeys + =+ =< [pub=pub:ex sec=sec:ex] + (pit:nu:crub:crypto 256 seed) + :- ^= auth + :- (rsh 3 (end [3 33] pub)) + (rsh 3 (end [3 33] sec)) + ^= crypt + :- (rsh [3 33] pub) + (rsh [3 33] sec) + :: + ++ seed + |= [seed=byts salt=tape] + ^- @ux + %- sha-256l:sha + :- (add wid.seed (lent salt)) + (cat 3 (crip (flop salt)) dat.seed) + -- +-- diff --git a/pkg/base-dev/lib/language-server/build.hoon b/pkg/base-dev/lib/language-server/build.hoon new file mode 100644 index 000000000..015f37b88 --- /dev/null +++ b/pkg/base-dev/lib/language-server/build.hoon @@ -0,0 +1,61 @@ +/- *language-server +:: +|% +++ parse-error + |= =tape + ^- (unit [=path =range]) + =/ parse-pair + %+ cook + |=([row=@ud col=@ud] [(dec row) col]) + (ifix [sel ser] ;~((glue ace) dem dem)) + =/ parse-path + %+ cook + |=(p=path (slag 3 p)) + (ifix [fas (jest '::')] (more fas urs:ab)) + =/ parse-full + ;~(plug parse-path ;~(sfix ;~((glue dot) parse-pair parse-pair) gar)) + (rust tape parse-full) +:: +++ get-errors-from-tang + |= [uri=@t =tang] + ^- (list range) + =/ =path + (uri-to-path uri) + %+ murn tang + |= =tank + ^- (unit range) + ?. ?=([%leaf *] tank) + ~ + =/ error + (parse-error p.tank) + ?~ error + ~ + ?: =(path path.u.error) + `range.u.error + ~ +:: +++ uri-to-path + |= uri=@t + ^- path + =/ pier-root=(set cord) + %- sy + ['app' 'gen' 'lib' 'mar' 'ren' 'sur' 'sys' 'test' ~] + =/ path=(list cord) + (parse-uri uri) + |- + ?< ?=(~ path) + ?: (~(has in pier-root) i.path) + `^path`path + $(path t.path) +:: +++ parse-uri + |= uri=@t + =- (fall - /fail) + %+ rush uri + %+ more + ;~(pose (plus fas) dot) + %+ cook + crip + (star ;~(pose col hep alf)) +:: +-- diff --git a/pkg/base-dev/lib/language-server/complete.hoon b/pkg/base-dev/lib/language-server/complete.hoon new file mode 100644 index 000000000..56b3ca498 --- /dev/null +++ b/pkg/base-dev/lib/language-server/complete.hoon @@ -0,0 +1,386 @@ +/+ language-server-parser +:: Autocomplete for hoon. +:: +=/ debug | +|% ++* option [item] + [term=cord detail=item] +:: +:: Like +rose except also produces line number +:: +++ lily + |* [los=tape sab=rule] + =+ vex=(sab [[1 1] los]) + ?~ q.vex + [%| p=p.vex(q (dec q.p.vex))] + ?. =(~ q.q.u.q.vex) + [%| p=p.vex(q (dec q.p.vex))] + [%& p=p.u.q.vex] +:: +:: Get all the identifiers accessible if this type is your subject. +:: +++ get-identifiers + |= ty=type + %- flop + |- ^- (list (option type)) + ?- ty + %noun ~ + %void ~ + [%atom *] ~ + [%cell *] + %+ weld + $(ty p.ty) + $(ty q.ty) + :: + [%core *] + %- weld + :_ ?. ?=(%gold r.p.q.ty) + ~ + $(ty p.ty) + ^- (list (option type)) + %- zing + %+ turn ~(tap by q.r.q.ty) + |= [term =tome] + %+ turn + ~(tap by q.tome) + |= [name=term =hoon] + ^- (pair term type) + ~| term=term + [name ~(play ~(et ut ty) ~[name] ~)] + :: + [%face *] + ?^ p.ty + ~ + [p.ty q.ty]~ + :: + [%fork *] + %= $ + ty + =/ tines ~(tap in p.ty) + ?~ tines + %void + |- ^- type + ?~ t.tines + i.tines + (~(fuse ut $(tines t.tines)) i.tines) + == + :: + [%hint *] $(ty q.ty) + [%hold *] $(ty ~(repo ut ty)) + == +:: +++ search-exact + |* [sid=term options=(list (option))] + =/ match + %+ skim options + |= [id=cord *] + =(sid id) + ?~ match + ~ + [~ i.match] +:: +:: Get all the identifiers that start with sid. +:: +++ search-prefix + |* [sid=cord ids=(list (option))] + ^+ ids + %+ skim ids + |= [id=cord *] + ^- ?(%.y %.n) + =(sid (end [3 (met 3 sid)] id)) +:: +:: Get the longest prefix of a list of identifiers. +:: +++ longest-match + |= matches=(list (option)) + ^- cord + ?~ matches + '' + =/ n 1 + =/ last (met 3 term.i.matches) + |- ^- term + ?: (gth n last) + term.i.matches + =/ prefix (end [3 n] term.i.matches) + ?: |- ^- ? + ?| ?=(~ t.matches) + ?& =(prefix (end [3 n] term.i.t.matches)) + $(t.matches t.t.matches) + == == + $(n +(n)) + (end [3 (dec n)] term.i.matches) +:: +:: Run +find-type safely, printing the first line of the stack trace on +:: error. +:: +++ find-type-mule + |= [sut=type gen=hoon] + ^- (unit [term type]) + =/ res (mule |.((find-type sut gen))) + ?- -.res + %& p.res + %| ((slog (flop (scag 10 p.res))) ~) + == +:: +:: Get the subject type of the wing where you've put the "magic-spoon". +:: +++ find-type + |= [sut=type gen=hoon] + =* loop $ + |^ + ^- (unit [term type]) + ?- gen + [%cnts [%magic-spoon ~] *] `['' sut] + [%cnts [%magic-spoon @ ~] *] `[i.t.p.gen sut] + [%cnts [%magic-spoon @ *] *] + %= $ + sut (~(play ut sut) wing+t.t.p.gen) + t.p.gen t.p.gen(t ~) + == + :: + [%cnts [%magic-fork @ ~] *] + `['' (~(play ut sut) wing+t.p.gen)] + :: + [^ *] (both p.gen q.gen) + [%brcn *] (grow q.gen) + [%brpt *] (grow q.gen) + [%cnts *] + |- ^- (unit [term type]) + =* inner-loop $ + ?~ q.gen + ~ + %+ replace + loop(gen q.i.q.gen) + |. inner-loop(q.gen t.q.gen) + :: + [%dtkt *] (spec-and-hoon p.gen q.gen) + [%dtls *] loop(gen p.gen) + [%rock *] ~ + [%sand *] ~ + [%tune *] ~ + [%dttr *] (both p.gen q.gen) + [%dtts *] (both p.gen q.gen) + [%dtwt *] loop(gen p.gen) + [%hand *] ~ + [%ktbr *] loop(gen p.gen) + [%ktls *] (both p.gen q.gen) + [%ktpm *] loop(gen p.gen) + [%ktsg *] loop(gen p.gen) + [%ktwt *] loop(gen p.gen) + [%note *] loop(gen q.gen) + [%sgzp *] (both p.gen q.gen) + [%sggr *] loop(gen q.gen) :: should check for hoon in p.gen + [%tsgr *] (change p.gen q.gen) + [%tscm *] + %+ replace + loop(gen p.gen) + |.(loop(gen q.gen, sut (~(busk ut sut) p.gen))) + :: + [%wtcl *] (bell p.gen q.gen r.gen) + [%fits *] (both p.gen wing+q.gen) + [%wthx *] loop(gen wing+q.gen) + [%dbug *] loop(gen q.gen) + [%zpcm *] (both p.gen q.gen) + [%lost *] loop(gen p.gen) + [%zpmc *] (both p.gen q.gen) + [%zpts *] loop(gen p.gen) + [%zppt *] (both q.gen r.gen) + [%zpgl *] (spec-and-hoon p.gen q.gen) + [%zpzp *] ~ + * + =+ doz=~(open ap gen) + ?: =(doz gen) + ~_ (show [%c 'hoon'] [%q gen]) + ~> %mean.'play-open' + !! + loop(gen doz) + == + :: + ++ replace + |= [a=(unit [term type]) b=(trap (unit [term type]))] + ^- (unit [term type]) + ?~(a $:b a) + :: + ++ both + |= [a=hoon b=hoon] + (replace loop(gen a) |.(loop(gen b))) + :: + ++ bell + |= [a=hoon b=hoon c=hoon] + %+ replace loop(gen a) + |. %+ replace loop(gen b, sut (~(gain ut sut) a)) + |. loop(gen c, sut (~(lose ut sut) a)) + :: + ++ spec-and-hoon + |= [a=spec b=hoon] + (replace (find-type-in-spec sut a) |.(loop(gen b))) + :: + ++ change + |= [a=hoon b=hoon] + (replace loop(gen a) |.(loop(gen b, sut (~(play ut sut) a)))) + :: + ++ grow + |= m=(map term tome) + =/ tomes ~(tap by m) + |- ^- (unit [term type]) + =* outer-loop $ + ?~ tomes + ~ + =/ arms ~(tap by q.q.i.tomes) + |- ^- (unit [term type]) + =* inner-loop $ + ?~ arms + outer-loop(tomes t.tomes) + %+ replace + loop(gen q.i.arms, sut (~(play ut sut) gen)) + |. inner-loop(arms t.arms) + -- +:: +:: Not implemented yet. I wonder whether we should modify types found +:: in spec mode such that if it's a mold that produces a type, it +:: should just display the type and not that it's technically a +:: function. +:: +++ find-type-in-spec + |= [sut=type pec=spec] + ^- (unit [term type]) + ~ +:: +++ get-id-sym + |= [pos=@ud =tape] + %^ get-id pos tape + ^- $-(nail (like (unit @t))) + ;~(sfix (punt sym) (star ;~(pose prn (just `@`10)))) +:: +++ get-id-cord + |= [pos=@ud =tape] + %^ get-id pos tape + ^- $-(nail (like (unit @t))) + ;~(sfix (punt (cook crip (star prn))) (star ;~(pose prn (just `@`10)))) +:: +++ get-id + |= [pos=@ud txt=tape seek=$-(nail (like (unit @t)))] + ^- [forward=(unit @t) backward=(unit @t) id=(unit @t)] + =/ forward=(unit @t) + (scan (slag pos txt) seek) + =/ backward=(unit @t) + %- (lift |=(t=@t (swp 3 t))) + (scan (flop (scag pos txt)) seek) + =/ id=(unit @t) + ?~ forward + ?~ backward + ~ + `u.backward + ?~ backward + `u.forward + `(cat 3 u.backward u.forward) + [forward backward id] +:: +:: Insert magic marker in hoon source at the given position. +:: +++ insert-magic + |= [pos=@ud txt=tape] + ^- [back-pos=@ud fore-pos=@ud txt=tape] + :: Find beg-pos by searching backward to where the current term + :: begins + =+ (get-id-sym pos txt) + =/ back-pos + ?~ backward + pos + (sub pos (met 3 u.backward)) + =/ fore-pos + ?~ forward + pos + (add pos (met 3 u.forward)) + :+ back-pos fore-pos + :: Insert "magic-spoon" marker so +find-type can identify where to + :: stop. + :: + ;: weld + (scag back-pos txt) + ?: &(?=(~ id) ?=([%'.' *] (slag pos txt))) + "magic-fork" + "magic-spoon" + ?~ id + "" + "." + (slag back-pos txt) + "\0a" + == +:: +:: Produce the longest possible advance without choosing between +:: matches. +:: +:: Takes a +hoon which has already has a magic-spoon marker. Useful if +:: you want to handle your own parsing. +:: +++ advance-hoon + |= [sut=type gen=hoon] + %+ bind (find-type-mule sut gen) + |= [id=term typ=type] + =/ matches=(list (option type)) + (search-prefix id (get-identifiers typ)) + (longest-match matches) +:: +:: Same as +advance-hoon, but takes a position and text directly. +:: +++ advance-tape + |= [sut=type pos=@ud code=tape] + (advance-hoon sut (scan txt:(insert-magic pos code) vest)) +:: +:: Produce a list of matches. +:: +:: Takes a +hoon which has already has a magic-spoon marker. Useful if +:: you want to handle your own parsing. +:: +++ tab-list-hoon + |= [sut=type gen=hoon] + ^- (unit (list (option type))) + %+ bind (find-type-mule sut gen) + |= [id=term typ=type] + (search-prefix id (get-identifiers typ)) +:: +:: Same as +advance-hoon, but takes a position and text directly. +:: +++ tab-list-tape + |= [sut=type pos=@ud code=tape] + ^- (each (unit (list (option type))) [row=@ col=@]) + ~? > debug %start-magick + =/ magicked txt:(insert-magic pos code) + ~? > debug %start-parsing + =/ res (lily magicked (language-server-parser *path)) + ?: ?=(%| -.res) + ~? > debug [%parsing-error p.res] + [%| p.res] + :- %& + ~? > debug %parsed-good + ((cury tab-list-hoon sut) hoon:`pile:clay`p.res) +:: +:: Generators +++ tab-generators + |= [pfix=path app=(unit term) gens=(list term)] + ^- (list (option tank)) + %+ turn gens + |= gen=term + ^- (option tank) + =/ pax=path + (weld pfix ~[gen %hoon]) + =/ file + .^(@t %cx pax) + :_ (render-help file) + ?~ app + (cat 3 '+' gen) + ?: =(%hood u.app) + (cat 3 '|' gen) + :((cury cat 3) ':' u.app '|' gen) +:: Stolen from +help +++ render-help + |= a=@t + ^- tank + :- %leaf + =/ c (to-wain:format a) + ?~ c "~" + ?. =(':: ' (end [3 4] i.c)) + "" + (trip i.c) +-- diff --git a/pkg/base-dev/lib/language-server/easy-print.hoon b/pkg/base-dev/lib/language-server/easy-print.hoon new file mode 100644 index 000000000..12558c8a5 --- /dev/null +++ b/pkg/base-dev/lib/language-server/easy-print.hoon @@ -0,0 +1,484 @@ +:: Fast type printing that's easy on the eyes or your money back +:: +=> |% + +$ cape [p=(map @ud wine) q=wine] + +$ wine + $@ $? %noun + %path + %type + %void + %wall + %wool + %yarn + == + $% [%mato p=term] + [%gate p=hoon q=type r=wine] + [%core p=(list @ta) q=wine] + [%face p=term q=wine] + [%list p=term q=wine] + [%pear p=term q=@] + [%bcwt p=(list wine)] + [%plot p=(list wine)] + [%stop p=@ud] + [%tree p=term q=wine] + [%unit p=term q=wine] + == + -- +|_ sut=type +++ dash + |= [mil=tape lim=char lam=tape] + ^- tape + =/ esc (~(gas in *(set @tD)) lam) + :- lim + |- ^- tape + ?~ mil [lim ~] + ?: ?| =(lim i.mil) + =('\\' i.mil) + (~(has in esc) i.mil) + == + ['\\' i.mil $(mil t.mil)] + ?: (lte ' ' i.mil) + [i.mil $(mil t.mil)] + ['\\' ~(x ne (rsh 2 i.mil)) ~(x ne (end 2 i.mil)) $(mil t.mil)] +:: +++ deal |=(lum=* (dish dole lum)) +++ dial + |= ham=cape + =+ gid=*(set @ud) + =| top-level=? :: don't need circumfix punctuation + =< `tank`-:$ + |% + ++ many + |= haz=(list wine) + ^- [(list tank) (set @ud)] + ?~ haz [~ gid] + =^ mor gid $(haz t.haz) + =^ dis gid ^$(q.ham i.haz) + [[dis mor] gid] + :: + ++ $ + ^- [tank (set @ud)] + ?- q.ham + %noun :_(gid [%leaf '*' ~]) + %path :_(gid [%leaf '/' ~]) + %type :_(gid [%leaf '#' 't' ~]) + %void :_(gid [%leaf '#' '!' ~]) + %wool :_(gid [%leaf '*' '"' '"' ~]) + %wall :_(gid [%leaf '*' '\'' '\'' ~]) + %yarn :_(gid [%leaf '"' '"' ~]) + [%mato *] :_(gid [%leaf '@' (trip p.q.ham)]) + [%gate *] + =^ sam gid + ?. ?=([%plot * * *] r.q.ham) + ?: ?=(%plot -.r.q.ham) + %- (slog -:$(q.ham r.q.ham) ~) + `gid + `gid + [`u=- +]:$(q.ham i.p.r.q.ham, top-level |) + :_ gid + :+ %rose + :- ?> ?=(%core -.q.q.ham) + ?: ?=(%dry q.p.q.q.q.ham) + " -> " + " ~> " + ?: top-level + ["" ""] + ["(" ")"] + :+ ?~(sam leaf+"_" u.sam) + =/ res (mule |.((~(play ut q.q.ham) p.q.ham))) + ?- -.res + %& duck(sut p.res) + %| leaf+"###" + == + ~ + :: + [%core *] + =^ sam gid + ?. ?=([%plot * * ~] q.q.ham) + `gid + [`u=- +]:$(q.ham i.p.q.q.ham) + :_ gid + ?~ sam + :+ %rose + [[' ' ~] ['<' ~] ['>' ~]] + |- ^- (list tank) + ?~ p.q.ham ~ + [[%leaf (rip 3 i.p.q.ham)] $(p.q.ham t.p.q.ham)] + :+ %rose + [" -> " "" ""] + :+ u.sam + :+ %rose + [[' ' ~] ['<' ~] ['>' ~]] + |- ^- (list tank) + ?~ p.q.ham ~ + [[%leaf (rip 3 i.p.q.ham)] $(p.q.ham t.p.q.ham)] + ~ + :: + [%face *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%palm [['=' ~] ~ ~ ~] [%leaf (trip p.q.ham)] cox ~]) + :: + [%list *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) + :: + [%bcwt *] + =^ coz gid (many p.q.ham) + :_(gid [%rose [[' ' ~] ['?' '(' ~] [')' ~]] coz]) + :: + [%plot *] + =^ coz gid (many p.q.ham) + :_(gid [%rose [[' ' ~] ['[' ~] [']' ~]] coz]) + :: + [%pear *] + :_(gid [%leaf '$' ~(rend co [%$ p.q.ham q.q.ham])]) + :: + [%stop *] + =+ num=~(rend co [%$ %ud p.q.ham]) + ?: (~(has in gid) p.q.ham) + :_(gid [%leaf '#' num]) + =^ cox gid + %= $ + gid (~(put in gid) p.q.ham) + q.ham (~(got by p.ham) p.q.ham) + == + :_(gid [%palm [['.' ~] ~ ~ ~] [%leaf ['^' '#' num]] cox ~]) + :: + [%tree *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) + :: + [%unit *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) + == + -- +:: +++ dish !: + |= [ham=cape lum=*] ^- tank + ~| [%dish-h ?@(q.ham q.ham -.q.ham)] + ~| [%lump lum] + ~| [%ham ham] + %- need + =| gil=(set [@ud *]) + |- ^- (unit tank) + ?- q.ham + %noun + %= $ + q.ham + ?: ?=(@ lum) + [%mato %$] + :- %plot + |- ^- (list wine) + [%noun ?:(?=(@ +.lum) [[%mato %$] ~] $(lum +.lum))] + == + :: + %path + :- ~ + :+ %rose + [['/' ~] ['/' ~] ~] + |- ^- (list tank) + ?~ lum ~ + ?@ lum !! + ?> ?=(@ -.lum) + [[%leaf (rip 3 -.lum)] $(lum +.lum)] + :: + %type + =+ tyr=|.((dial dole)) + =+ vol=tyr(sut lum) + =+ cis=;;(tank .*(vol [%9 2 %0 1])) + :^ ~ %palm + [~ ~ ~ ~] + [[%leaf '#' 't' '/' ~] cis ~] + :: + %wall + :- ~ + :+ %rose + [[' ' ~] ['<' '|' ~] ['|' '>' ~]] + |- ^- (list tank) + ?~ lum ~ + ?@ lum !! + [[%leaf (trip ;;(@ -.lum))] $(lum +.lum)] + :: + %wool + :- ~ + :+ %rose + [[' ' ~] ['<' '<' ~] ['>' '>' ~]] + |- ^- (list tank) + ?~ lum ~ + ?@ lum !! + [(need ^$(q.ham %yarn, lum -.lum)) $(lum +.lum)] + :: + %yarn + [~ %leaf (dash (tape lum) '"' "\{")] + :: + %void + ~ + :: + [%mato *] + ?. ?=(@ lum) + ~ + :+ ~ + %leaf + ?+ (rash p.q.ham ;~(sfix (cook crip (star low)) (star hig))) + ~(rend co [%$ p.q.ham lum]) + %$ ~(rend co [%$ %ud lum]) + %t (dash (rip 3 lum) '\'' ~) + %tas ['%' ?.(=(0 lum) (rip 3 lum) ['$' ~])] + == + :: + [%gate *] + !! + :: + [%core *] + :: XX needs rethinking for core metal + :: ?. ?=(^ lum) ~ + :: => .(lum `*`lum) + :: =- ?~(tok ~ [~ %rose [[' ' ~] ['<' ~] ['>' ~]] u.tok]) + :: ^= tok + :: |- ^- (unit (list tank)) + :: ?~ p.q.ham + :: =+ den=^$(q.ham q.q.ham) + :: ?~(den ~ [~ u.den ~]) + :: =+ mur=$(p.q.ham t.p.q.ham, lum +.lum) + :: ?~(mur ~ [~ [[%leaf (rip 3 i.p.q.ham)] u.mur]]) + [~ (dial ham)] + :: + [%face *] + =+ wal=$(q.ham q.q.ham) + ?~ wal + ~ + [~ %palm [['=' ~] ~ ~ ~] [%leaf (trip p.q.ham)] u.wal ~] + :: + [%list *] + ?: =(~ lum) + [~ %leaf '~' ~] + =- ?~ tok + ~ + [~ %rose [[' ' ~] ['~' '[' ~] [']' ~]] u.tok] + ^= tok + |- ^- (unit (list tank)) + ?: ?=(@ lum) + ?.(=(~ lum) ~ [~ ~]) + =+ [for=^$(q.ham q.q.ham, lum -.lum) aft=$(lum +.lum)] + ?. &(?=(^ for) ?=(^ aft)) + ~ + [~ u.for u.aft] + :: + [%bcwt *] + |- ^- (unit tank) + ?~ p.q.ham + ~ + =+ wal=^$(q.ham i.p.q.ham) + ?~ wal + $(p.q.ham t.p.q.ham) + wal + :: + [%plot *] + =- ?~ tok + ~ + [~ %rose [[' ' ~] ['[' ~] [']' ~]] u.tok] + ^= tok + |- ^- (unit (list tank)) + ?~ p.q.ham + ~ + ?: ?=([* ~] p.q.ham) + =+ wal=^$(q.ham i.p.q.ham) + ?~(wal ~ [~ [u.wal ~]]) + ?@ lum + ~ + =+ gim=^$(q.ham i.p.q.ham, lum -.lum) + ?~ gim + ~ + =+ myd=$(p.q.ham t.p.q.ham, lum +.lum) + ?~ myd + ~ + [~ u.gim u.myd] + :: + [%pear *] + ?. =(lum q.q.ham) + ~ + =. p.q.ham + (rash p.q.ham ;~(sfix (cook crip (star low)) (star hig))) + =+ fox=$(q.ham [%mato p.q.ham]) + ?> ?=([~ %leaf ^] fox) + ?: ?=(?(%n %tas) p.q.ham) + fox + [~ %leaf '%' p.u.fox] + :: + [%stop *] + ?: (~(has in gil) [p.q.ham lum]) ~ + =+ kep=(~(get by p.ham) p.q.ham) + ?~ kep + ~|([%stop-loss p.q.ham] !!) + $(gil (~(put in gil) [p.q.ham lum]), q.ham u.kep) + :: + [%tree *] + =- ?~ tok + ~ + [~ %rose [[' ' ~] ['{' ~] ['}' ~]] u.tok] + ^= tok + =+ tuk=*(list tank) + |- ^- (unit (list tank)) + ?: =(~ lum) + [~ tuk] + ?. ?=([n=* l=* r=*] lum) + ~ + =+ rol=$(lum r.lum) + ?~ rol + ~ + =+ tim=^$(q.ham q.q.ham, lum n.lum) + ?~ tim + ~ + $(lum l.lum, tuk [u.tim u.rol]) + :: + [%unit *] + ?@ lum + ?.(=(~ lum) ~ [~ %leaf '~' ~]) + ?. =(~ -.lum) + ~ + =+ wal=$(q.ham q.q.ham, lum +.lum) + ?~ wal + ~ + [~ %rose [[' ' ~] ['[' ~] [']' ~]] [%leaf '~' ~] u.wal ~] + == +:: +++ doge + |= ham=cape + =- ?+ woz woz + [%list * [%mato %'ta']] %path + [%list * [%mato %'t']] %wall + [%list * [%mato %'tD']] %yarn + [%list * %yarn] %wool + == + ^= woz + ^- wine + ?. ?=([%stop *] q.ham) + ?: ?& ?= [%bcwt [%pear %n %0] [%plot [%pear %n %0] [%face *] ~] ~] + q.ham + =(1 (met 3 p.i.t.p.i.t.p.q.ham)) + == + [%unit =<([p q] i.t.p.i.t.p.q.ham)] + q.ham + =+ may=(~(get by p.ham) p.q.ham) + ?~ may + q.ham + =+ nul=[%pear %n 0] + ?. ?& ?=([%bcwt *] u.may) + ?=([* * ~] p.u.may) + |(=(nul i.p.u.may) =(nul i.t.p.u.may)) + == + q.ham + =+ din=?:(=(nul i.p.u.may) i.t.p.u.may i.p.u.may) + ?: ?& ?=([%plot [%face *] [%face * %stop *] ~] din) + =(p.q.ham p.q.i.t.p.din) + =(1 (met 3 p.i.p.din)) + =(1 (met 3 p.i.t.p.din)) + == + :+ %list + (cat 3 p.i.p.din p.i.t.p.din) + q.i.p.din + ?: ?& ?= $: %plot + [%face *] + [%face * %stop *] + [[%face * %stop *] ~] + == + din + =(p.q.ham p.q.i.t.p.din) + =(p.q.ham p.q.i.t.t.p.din) + =(1 (met 3 p.i.p.din)) + =(1 (met 3 p.i.t.p.din)) + =(1 (met 3 p.i.t.t.p.din)) + == + :+ %tree + %^ cat + 3 + p.i.p.din + (cat 3 p.i.t.p.din p.i.t.t.p.din) + q.i.p.din + q.ham +:: +++ dole + ^- cape + =+ gil=*(set type) + =+ dex=[p=*(map type @) q=*(map @ wine)] + =< [q.p q] + |- ^- [p=[p=(map type @) q=(map @ wine)] q=wine] + =- [p.tez (doge q.p.tez q.tez)] + ^= tez + ^- [p=[p=(map type @) q=(map @ wine)] q=wine] + ?: (~(meet ut sut) -:!>(*type)) + [dex %type] + ?- sut + %noun [dex sut] + %void [dex sut] + [%atom *] [dex ?~(q.sut [%mato p.sut] [%pear p.sut u.q.sut])] + [%cell *] + =+ hin=$(sut p.sut) + =+ yon=$(dex p.hin, sut q.sut) + :- p.yon + :- %plot + ?:(?=([%plot *] q.yon) [q.hin p.q.yon] [q.hin q.yon ~]) + :: + [%core *] + ?: ?=([[%$ * [[%$ @ *] ~ ~]] ~ ~] q.r.q.sut) + =/ dad $(sut p.sut) + :- p.dad + ~! q.r.q.sut + [%gate q.n.q.q.n.q.r.q.sut sut(r.p.q %gold) q.dad] + =+ yad=$(sut p.sut) + :- p.yad + =+ ^= doy ^- [p=(list @ta) q=wine] + ?: ?=([%core *] q.yad) + [p.q.yad q.q.yad] + [~ q.yad] + :- %core + :_ q.doy + :_ p.doy + %^ cat 3 + %~ rent co + :+ %$ %ud + %- ~(rep by (~(run by q.r.q.sut) |=(tome ~(wyt by q.+<)))) + |=([[@ a=@u] b=@u] (add a b)) + %^ cat 3 + ?-(r.p.q.sut %gold '.', %iron '|', %lead '?', %zinc '&') + =+ gum=(mug q.r.q.sut) + %+ can 3 + :~ [1 (add 'a' (mod gum 26))] + [1 (add 'a' (mod (div gum 26) 26))] + [1 (add 'a' (mod (div gum 676) 26))] + == + :: + [%hint *] + $(sut q.sut) + :: + [%face *] + =+ yad=$(sut q.sut) + ?^(p.sut yad [p.yad [%face p.sut q.yad]]) + :: + [%fork *] + =+ yed=(sort ~(tap in p.sut) aor) + =- [p [%bcwt q]] + |- ^- [p=[p=(map type @) q=(map @ wine)] q=(list wine)] + ?~ yed + [dex ~] + =+ mor=$(yed t.yed) + =+ dis=^$(dex p.mor, sut i.yed) + [p.dis q.dis q.mor] + :: + [%hold *] + =+ hey=(~(get by p.dex) sut) + ?^ hey + [dex [%stop u.hey]] + ?: (~(has in gil) sut) + =+ dyr=+(~(wyt by p.dex)) + [[(~(put by p.dex) sut dyr) q.dex] [%stop dyr]] + =+ rom=$(gil (~(put in gil) sut), sut ~(repo ut sut)) + =+ rey=(~(get by p.p.rom) sut) + ?~ rey + rom + [[p.p.rom (~(put by q.p.rom) u.rey q.rom)] [%stop u.rey]] + == +:: +++ duck (dial dole) +-- diff --git a/pkg/base-dev/lib/language-server/json.hoon b/pkg/base-dev/lib/language-server/json.hoon new file mode 100644 index 000000000..a817766df --- /dev/null +++ b/pkg/base-dev/lib/language-server/json.hoon @@ -0,0 +1,301 @@ +/- lsp=language-server +|% +:: +++ util + |% + ++ get-json-string + |= [jon=(map @t json) key=@t] + ^- (unit cord) + =/ cord-jon=(unit json) + (~(get by jon) key) + ?~ cord-jon + ~ + ?> ?=([%s *] u.cord-jon) + `p.u.cord-jon + -- +:: +:: +++ dejs + =, dejs:format + |% + ++ request + |= jon=json + ?> ?=([%o *] jon) + =/ method=cord + %- method + (trip (need (get-json-string:util p.jon 'method'))) + =/ id=cord + (need (get-json-string:util p.jon 'id')) + =/ params=json + (~(got by p.jon) 'params') + ^- all:request:lsp + |^ + ?+ method [%unknown jon] + %text-document--hover (text-document--hover params id) + %text-document--completion (text-document--completion params id) + == + :: + ++ text-document--hover + |= [params=json id=cord] + ^- text-document--hover:request:lsp + :+ %text-document--hover + id + %. params + %: ot + position+position + 'textDocument'^text-document-id + ~ + == + :: + ++ text-document--completion + |= [params=json id=cord] + :+ %text-document--completion id + %. params + %: ot + position+position + 'textDocument'^text-document-id + ~ + == + -- + :: + ++ notification + |= jon=json + ?> ?=([%o *] jon) + =/ method=cord + %- method + (trip (need (get-json-string:util p.jon 'method'))) + =/ params=json + (~(got by p.jon) 'params') + ^- all:notification:lsp + |^ + ?+ method [%unknown jon] + %text-document--did-change + (text-document--did-change params) + %text-document--did-open + (text-document--did-open params) + %text-document--did-save + (text-document--did-save params) + %text-document--did-close + (text-document--did-close params) + == + :: + ++ text-document--did-save + |= jon=json + ^- text-document--did-save:notification:lsp + ?> ?=([%o *] jon) + =/ doc-id + (~(got by p.jon) 'textDocument') + :- %text-document--did-save + (text-document-id doc-id) + :: + ++ text-document--did-close + |= jon=json + ^- text-document--did-close:notification:lsp + ?> ?=([%o *] jon) + =/ doc-id + (~(got by p.jon) 'textDocument') + :- %text-document--did-close + (text-document-id doc-id) + :: + ++ text-document--did-change + |= jon=json + ^- text-document--did-change:notification:lsp + :- %text-document--did-change + %. jon + %: ot + 'textDocument'^text-document-id + 'contentChanges'^text-document-changes + ~ + == + :: + ++ text-document--did-open + |= jon=json + ^- text-document--did-open:notification:lsp + ?> ?=([%o *] jon) + :- %text-document--did-open + (text-document-item (~(got by p.jon) 'textDocument')) + -- + :: Utilities + :: + ++ text-document-item + |= jon=json + ^- text-document-item:lsp + %. jon + %: ot + uri+so + version+(mu ni) + text+so + ~ + == + :: + ++ text-document-id + %: ou + uri+(un so) + version+(uf ~ (pe ~ ni)) + ~ + == + :: + ++ text-document-changes + %- ar + %: ou + range+(uf ~ (pe ~ range)) + 'rangeLength'^(uf ~ (pe ~ ni)) + text+(un so) + ~ + == + :: + ++ method + |= =tape + ^- cord + %- crip %- zing + %+ join "--" + ^- (list ^tape) + %+ turn + ^- (list (list ^tape)) + %+ scan + tape + %+ more + fas + ;~ plug + (star low) + (star ;~(plug (cook |=(a=@ (add a 32)) hig) (star low))) + == + |= words=(list ^tape) + ^- ^tape + (zing (join "-" words)) + :: + ++ range + %: ot + start+position + end+position + ~ + == + :: + ++ position + %: ot + line+ni + character+ni + ~ + == + -- +:: +++ enjs + =, enjs:format + |% + ++ text-document--publish-diagnostics + |= pub=text-document--publish-diagnostics:notification:lsp + ^- json + %: pairs + uri+s+uri.pub + diagnostics+a+(turn diagnostics.pub diagnostic) + ~ + == + ++ notification + |= notification=all:notification:lsp + ^- json + =/ params=json + ?+ -.notification !! + %text-document--publish-diagnostics + (text-document--publish-diagnostics notification) + == + ~! -.notification + =/ method=cord (crip (unparse-method -.notification)) + %: pairs + method+s+method + params+params + ~ + == + :: + ++ response + |= res=all:response:lsp + ^- json + |^ + ?- -.res + %text-document--hover (text-document--hover res) + %text-document--completion (text-document--completion res) + == + :: + ++ wrap-in-id + |= [id=cord res=json] + %: pairs + id+s+id + result+res + ~ + == + ++ text-document--hover + |= hov=text-document--hover:response:lsp + %+ wrap-in-id id.hov + %+ frond 'contents' + ?~ contents.hov + ~ + s+u.contents.hov + :: + ++ text-document--completion + |= com=text-document--completion:response:lsp + %+ wrap-in-id id.com + [%a (turn completion.com completion-item)] + -- + ++ unparse-method + |= =cord + ^- ^tape + %+ rash cord + %+ cook |=(l=(list ^tape) (zing (join "/" l))) + %+ more (jest '--') + %+ cook + |= tapes=(list ^tape) + ^- ^tape + ?~ tapes ~ + %- zing + :- i.tapes + %+ turn t.tapes + |= t=^tape + ^- ^tape + ?~ t ~ + [`@tD`(sub i.t 32) t.t] + %+ more + ;~(less (jest '--') hep) + (star alf) + :: + ++ completion-item + |= com=completion-item:lsp + ^- json + %: pairs + label+s+label.com + detail+s+detail.com + kind+(numb kind.com) + 'documentation'^s+doc.com + 'insertText'^s+insert-text.com + 'insertTextFormat'^(numb insert-text-format.com) + ~ + == + :: + ++ position + |= =position:lsp + ^- json + %: pairs + line+(numb row.position) + character+(numb col.position) + ~ + == + :: + ++ range + |= =range:lsp + ^- json + %: pairs + start+(position start.range) + end+(position end.range) + ~ + == + :: + ++ diagnostic + |= diag=diagnostic:lsp + ^- json + %: pairs + range+(range range.diag) + severity+(numb severity.diag) + message+s+message.diag + ~ + == + :: + -- +-- diff --git a/pkg/base-dev/lib/language-server/parser.hoon b/pkg/base-dev/lib/language-server/parser.hoon new file mode 100644 index 000000000..cf5779092 --- /dev/null +++ b/pkg/base-dev/lib/language-server/parser.hoon @@ -0,0 +1,72 @@ +:: lifted directly from ford, should probably be in zuse +=, clay +=< pile-rule +|% +++ pile-rule + |= pax=path + %- full + %+ ifix + :_ gay + :: parse optional /? and ignore + :: + ;~(plug gay (punt ;~(plug fas wut gap dem gap))) + |^ + ;~ plug + %+ cook (bake zing (list (list taut))) + %+ rune hep + (most ;~(plug com gaw) taut-rule) + :: + %+ cook (bake zing (list (list taut))) + %+ rune lus + (most ;~(plug com gaw) taut-rule) + :: + %+ rune tis + ;~(plug sym ;~(pfix gap stap)) + :: + %+ rune sig + ;~((glue gap) sym wyde:vast stap) + :: + %+ rune cen + ;~(plug sym ;~(pfix gap ;~(pfix cen sym))) + :: + %+ rune buc + ;~ (glue gap) + sym + ;~(pfix cen sym) + ;~(pfix cen sym) + == + :: + %+ rune tar + ;~ (glue gap) + sym + ;~(pfix cen sym) + stap + == + :: + %+ stag %tssg + (most gap tall:(vang & pax)) + == + :: + ++ pant + |* fel=^rule + ;~(pose fel (easy ~)) + :: + ++ mast + |* [bus=^rule fel=^rule] + ;~(sfix (more bus fel) bus) + :: + ++ rune + |* [bus=^rule fel=^rule] + %- pant + %+ mast gap + ;~(pfix fas bus gap fel) + -- +:: +++ taut-rule + %+ cook |=(taut +<) + ;~ pose + (stag ~ ;~(pfix tar sym)) + ;~(plug (stag ~ sym) ;~(pfix tis sym)) + (cook |=(a=term [`a a]) sym) + == +-- diff --git a/pkg/base-dev/lib/language-server/rune-snippet.hoon b/pkg/base-dev/lib/language-server/rune-snippet.hoon new file mode 100644 index 000000000..b25e306be --- /dev/null +++ b/pkg/base-dev/lib/language-server/rune-snippet.hoon @@ -0,0 +1,532 @@ +/- lsp-sur=language-server +/+ auto=language-server-complete +=> +|% +++ snippet + |= [rune=tape text=tape] + ^- json + =, enjs:format + %- pairs + :~ 'label'^(tape rune) + 'insertTextFormat'^(numb 2) + 'insertText'^(tape text) + == +:: +++ runes + ^- (list (option:auto tape)) + :~ :- '|$' + """ + $\{1:sample} + $\{2:body} + """ + :- '|_' + """ + $\{1:sample} + ++ $\{2:arm} + $\{3:body} + -- + """ + :- '|:' + """ + $\{1:sample} + $\{2:body} + """ + :- '|%' + """ + + ++ $\{1:arm} + $\{2:body} + -- + """ + :- '|.' + """ + $\{1:body} + """ + :- '|^' + """ + + $\{1:body} + :: + ++ $\{2:arm} + $\{3:body} + -- + """ + :- '|-' + """ + $\{1:body} + """ + :- '|~' + """ + $\{1:sample} + $\{2:body} + """ + :- '|*' + """ + $\{1:sample} + $\{2:body} + """ + :- '|=' + """ + $\{1:sample} + $\{2:body} + """ + :- '|@' + """ + ++ $\{1:arm} + $\{2:body} + -- + """ + :- '|?' + """ + $\{1:sample} + """ + :: + :- ':_' + """ + $\{1:tail} + $\{2:head} + """ + :- ':^' + """ + $\{1:car} + $\{2:cadr} + $\{3:caddr} + $\{4:cddr} + """ + :- ':-' + """ + $\{1:tail} + $\{2:head} + """ + :- ':+' + """ + $\{1:car} + $\{2:cadr} + $\{3:cddr} + """ + :- ':~' + """ + $\{1:item} + == + """ + :- ':*' + """ + $\{1:item} + == + """ + :: + :- '%_' + """ + $\{1:target} + $\{2:wing} $\{3:new-value} + == + """ + :- '%.' + """ + $\{1:arg} + $\{2:gate} + """ + :- '%-' + """ + $\{1:gate} + $\{2:arg} + """ + :- '%:' + """ + $\{1:gate} + $\{2:args} + == + """ + :- '%*' + """ + $\{1:target-wing} $\{2:from} + $\{3:wing} $\{4:new-value} + == + """ + :- '%^' + """ + $\{1:gate} + $\{2:arg1} + $\{3:arg2} + $\{4:arg3} + """ + :- '%+' + """ + $\{1:gate} + $\{2:arg1} + $\{3:arg2} + """ + :- '%~' + """ + $\{1:arm} + $\{2:core} + $\{3:arg} + """ + :- '%=' + """ + $\{1:target} + $\{2:wing} $\{3:new-value} + == + """ + :: + :- '.^' + """ + $\{1:mold} + $\{2:path} + """ + :- '.+' + """ + $\{1:atom} + """ + :- '.*' + """ + $\{1:subject} + $\{2:formula} + """ + :- '.=' + """ + $\{1:a} + $\{2:b} + """ + :- '.?' + """ + $\{1:noun} + """ + :: + :- '^|' + """ + $\{1:iron-core} + """ + :- '^.' + """ + $\{1:a} + $\{2:b} + """ + :- '^+' + """ + $\{1:like} + $\{2:body} + """ + :- '^-' + """ + $\{1:type} + $\{2:body} + """ + :- '^&' + """ + $\{1:zinc-core} + """ + :- '^~' + """ + $\{1:constant} + """ + :- '^=' + """ + $\{1:face} + $\{2:body} + """ + :- '^?' + """ + $\{1:lead-core} + """ + :- '^*' + """ + $\{1:type} + """ + :- '^:' + """ + $\{1:type} + """ + :: + :- '~|' + """ + $\{1:trace} + $\{2:body} + """ + :- '~_' + """ + $\{1:tank} + $\{2:body} + """ + :- '~%' + """ + $\{1:name} + $\{2:parent} + ~ + $\{3:body} + """ + :- '~/' + """ + $\{1:name} + $\{2:body} + """ + :- '~<' + """ + $\{1:hint} + $\{2:body} + """ + :- '~>' + """ + $\{1:hint} + $\{2:body} + """ + :- '~$' + """ + $\{1:name} + $\{2:body} + """ + :- '~+' + """ + + $\{1:body} + """ + :- '~&' + """ + $\{1:printf} + $\{2:body} + """ + :- '~=' + """ + $\{1:a} + $\{2:b} + """ + :- '~?' + """ + $\{1:condition} + $\{2:printf} + $\{3:body} + """ + :- '~!' + """ + $\{1:type} + $\{2:body} + """ + :: + :- ';=' + """ + $\{1:manx} + == + """ + :- ';:' + """ + $\{1:gate} + $\{2:args} + == + """ + :- ';/' + """ + $\{1:tape} + """ + :- ';<' + """ + $\{1:type} bind:m $\{2:body1} + $\{3:body2} + """ + :- ';~' + """ + $\{1:gate} + $\{2:args} + == + """ + :- ';;' + """ + $\{1:type} + $\{2:body} + """ + :: + :- '=|' + """ + $\{1:type} + $\{2:body} + """ + :- '=:' + """ + $\{1:wing} $\{2:value} + == + $\{3:body} + """ + :- '=/' + """ + $\{1:face} + $\{2:value} + $\{3:body} + """ + :- '=;' + """ + $\{1:face} + $\{2:body} + $\{3:value} + """ + :- '=.' + """ + $\{1:wing} + $\{2:value} + $\{3:body} + """ + :- '=?' + """ + $\{1:wing} $\{2:condition} + $\{3:value} + $\{4:body} + """ + :- '=<' + """ + $\{1:formula} + $\{2:subject} + """ + :- '=-' + """ + $\{1:body} + $\{2:value} + """ + :- '=>' + """ + $\{1:subject} + $\{2:formula} + """ + :- '=^' + """ + $\{1:face} $\{2:wing} + $\{3:computation} + $\{4:body} + """ + :- '=+' + """ + $\{1:value} + $\{2:body} + """ + :- '=~' + """ + + $\{1:body} + """ + :- '=*' + """ + $\{1:alias} $\{2:value} + $\{3:body} + """ + :- '=,' + """ + $\{1:alias} + $\{3:body} + """ + :: + :- '?|' + """ + $\{1:condition} + == + """ + :- '?-' + """ + $\{1:case} + $\{2:type} $\{3:value} + == + """ + :- '?:' + """ + $\{1:if} + $\{2:then} + $\{3:else} + """ + :- '?.' + """ + $\{1:if} + $\{2:else} + $\{3:then} + """ + :- '?^' + """ + $\{1:value} + $\{2:if-cell} + $\{3:if-atom} + """ + :- '?<' + """ + $\{1:assertion} + $\{2:body} + """ + :- '?>' + """ + $\{1:assertion} + $\{2:body} + """ + :- '?+' + """ + $\{1:case} $\{2:else} + $\{3:type} $\{4:value} + == + """ + :- '?&' + """ + $\{1:condition} + == + """ + :- '?@' + """ + $\{1:value} + $\{2:if-atom} + $\{3:if-cell} + """ + :- '?~' + """ + $\{1:value} + $\{2:if-null} + $\{3:if-nonnull} + """ + :- '?#' + """ + $\{1:skin} + $\{2:wing} + """ + :- '?=' + """ + $\{1:type} + $\{2:wing} + """ + :- '?!' + """ + $\{1:loobean} + """ + :: + :- '!,' + """ + *hoon + $\{1:ast} + """ + :- '!>' + """ + $\{1:value} + """ + :- '!;' + """ + $\{1:type} + $\{2:body} + """ + :- '!=' + """ + $\{1:body} + """ + :- '!@' + """ + $\{1:wing} + $\{2:if-exists} + $\{3:if-not-exists} + """ + :- '!?' + """ + $\{1:version} + $\{2:body} + """ + :- '!!' + "" + == +-- +|= rune=tape +^- (list completion-item:lsp-sur) +=? rune =(' ' (snag 0 rune)) + (slag 1 rune) +~& rune +%+ turn (search-prefix:auto (crip rune) runes) +|= [name=cord snippet=tape] +^- completion-item:lsp-sur +[name 1 '' '' (crip snippet) 2] diff --git a/pkg/base-dev/lib/ph/io.hoon b/pkg/base-dev/lib/ph/io.hoon new file mode 100644 index 000000000..d6cbed8d7 --- /dev/null +++ b/pkg/base-dev/lib/ph/io.hoon @@ -0,0 +1,297 @@ +/- *aquarium, spider +/+ libstrand=strand, *strandio, util=ph-util +=, strand=strand:libstrand +|% +++ send-events + |= events=(list aqua-event) + =/ m (strand ,~) + ^- form:m + (poke-our %aqua %aqua-events !>(events)) +:: +++ send-azimuth-action + |= =azimuth-action + =/ m (strand ,~) + ^- form:m + (poke-our %aqua %azimuth-action !>(azimuth-action)) +:: +++ take-unix-effect + =/ m (strand ,[ship unix-effect]) + ^- form:m + ;< [=path =cage] bind:m (take-fact-prefix /effect) + ?> ?=(%aqua-effect p.cage) + (pure:m !<([aqua-effect] q.cage)) +:: +++ start-simple + (start-test %aqua-ames %aqua-behn %aqua-dill %aqua-eyre ~) +:: +++ start-azimuth + =/ m (strand ,~) + ^- form:m + ;<(~ bind:m start-simple init) +:: +++ end + (end-test %aqua-ames %aqua-behn %aqua-dill %aqua-eyre ~) +:: +++ start-test + |= vane-threads=(list term) + =/ m (strand ,~) + ^- form:m + ~& > "starting" + ;< tids=(map term tid:spider) bind:m (start-threads vane-threads) + ;< ~ bind:m (watch-our /effect %aqua /effect) + :: Get our very own event with no mistakes in it... yet. + :: + :: We want to wait for the vane threads to actually start and get + :: their subscriptions started. Other ways to do this are delaying + :: the ack from spider until the build is finished (does that + :: guarantee the subscriptions have started?) or subscribe to the + :: threads themselves for a notification when they're done. This is + :: probably the best option because the thread can delay until it + :: gets a positive ack on the subscription. + :: + :: Threads might not get built until a %writ is dripped back to + :: spider. Drips are at +(now), so we sleep until two clicks in the + :: future. + :: + ;< ~ bind:m (sleep `@dr`2) + (pure:m ~) +:: +++ end-test + |= vane-threads=(list term) + =/ m (strand ,~) + ^- form:m + ~& > "done" + ;< ~ bind:m (stop-threads vane-threads) + ;< ~ bind:m (leave-our /effect %aqua) + (pure:m ~) +:: +++ start-threads + |= threads=(list term) + =/ m (strand ,(map term tid:spider)) + ^- form:m + ;< =bowl:spider bind:m get-bowl + =| tids=(map term tid:spider) + |- ^- form:m + =* loop $ + ?~ threads + (pure:m tids) + =/ tid + %+ scot %ta + (cat 3 (cat 3 'strand_' i.threads) (scot %uv (sham i.threads eny.bowl))) + =/ poke-vase !>([`tid.bowl ~ byk.bowl i.threads *vase]) + ;< ~ bind:m (poke-our %spider %spider-start poke-vase) + loop(threads t.threads, tids (~(put by tids) i.threads tid)) +:: +++ stop-threads + |= threads=(list term) + =/ m (strand ,~) + ^- form:m + (pure:m ~) +:: +:: +++ init + =/ m (strand ,~) + ^- form:m + (send-azimuth-action %init-azimuth ~) +:: +++ spawn + |= =ship + ~& > "spawning {}" + =/ m (strand ,~) + ^- form:m + (send-azimuth-action %spawn ship) +:: +++ breach + |= =ship + ~& > "breaching {}" + =/ m (strand ,~) + ^- form:m + (send-azimuth-action %breach ship) +:: +:: who: breachee +:: her: wait until hears about breach +:: +++ breach-and-hear + |= [who=ship her=ship] + ~& > "breaching {} for {}" + =/ m (strand ,~) + ;< =bowl:spider bind:m get-bowl + =/ aqua-pax + :- %i + /(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun + =/ old-rut ;;((unit @) (scry-aqua:util noun our.bowl now.bowl aqua-pax)) + =/ new-rut + ?~ old-rut + 1 + +(+.old-rut) + ;< ~ bind:m (send-azimuth-action %breach who) + |- ^- form:m + =* loop $ + ;< ~ bind:m (sleep ~s1) + ;< =bowl:spider bind:m get-bowl + =/ aqua-pax + :- %i + /(scot %p her)/j/(scot %p her)/rift/(scot %da now.bowl)/(scot %p who)/noun + =/ rut (scry-aqua:util noun our.bowl now.bowl aqua-pax) + ?: =([~ new-rut] rut) + (pure:m ~) + loop +:: +++ init-ship + |= [=ship fake=?] + =/ m (strand ,~) + ^- form:m + ~& > "starting {}" + ;< ~ bind:m (send-events (init:util ship fake)) + (check-ship-booted ship) +:: +++ check-ship-booted + |= =ship + =/ m (strand ,~) + ^- form:m + =* loop $ + ;< [her=^ship =unix-effect] bind:m take-unix-effect + =/ f |=(=tape (is-dojo-output:util ship her unix-effect tape)) + :: This is a pretty bad heuristic, but in general galaxies will + :: hit the first of these cases, and other ships will hit the + :: second. + :: + ?: ?| (f ":dojo>") + (f "is your neighbor") + == + (pure:m ~) + loop +:: +++ dojo + |= [=ship =tape] + =/ m (strand ,~) + ^- form:m + ~& > "dojo: {tape}" + (send-events (dojo:util ship tape)) +:: +++ wait-for-output + |= [=ship =tape] + =/ m (strand ,~) + ^- form:m + ~& > "waiting for output: {tape}" + |- ^- form:m + =* loop $ + ;< [her=^ship =unix-effect] bind:m take-unix-effect + ?: (is-dojo-output:util ship her unix-effect tape) + (pure:m ~) + loop +:: +:: Send "|hi" from one ship to another +:: +++ send-hi + |= [from=@p to=@p] + =/ m (strand ,~) + ^- form:m + ;< ~ bind:m (dojo from "|hi {(scow %p to)}") + (wait-for-output from "hi {(scow %p to)} successful") +:: +:: Send "|hi" and wait for "not responding" message +:: +++ send-hi-not-responding + |= [from=@p to=@p] + ~& > 'sending hi not responding' + =/ m (strand ,~) + ;< ~ bind:m (dojo from "|hi {(scow %p to)}") + (wait-for-output from "{(scow %p to)} not responding still trying") +:: +:: Mount a desk. +:: +++ mount + |= [=ship =desk] + =/ m (strand ,~) + ^- form:m + ;< ~ bind:m (dojo ship "|mount /={(trip desk)}=") + |- ^- form:m + =* loop $ + ;< [her=^ship =unix-effect] bind:m take-unix-effect + ?: (is-ergo:util ship her unix-effect) + (pure:m ~) + loop +:: +:: Modify /sur/aquarium/hoon on the given ship +:: +++ touch-file + |= [her=ship =desk extra=@t] + =/ m (strand ,@t) + ^- form:m + (touch her desk /sur/aquarium/hoon extra) +:: +:: Modify path on the given ship +:: +++ touch + |= [her=ship =desk pax=path extra=@t] + =/ m (strand ,@t) + ^- form:m + ~& > "touching file on {}/{}" + ;< ~ bind:m (mount her desk) + ;< our=@p bind:m get-our + ;< now=@da bind:m get-time + =/ aqua-pax + ;: weld + /i/(scot %p her)/cx/(scot %p her)/[desk]/(scot %da now) + pax + /noun + == + =/ warped + %^ cat 3 '=> . ' + %^ cat 3 extra + (need (scry-aqua:util (unit @) our now aqua-pax)) + ;< ~ bind:m (send-events (insert-files:util her desk [pax warped] ~)) + (pure:m warped) +:: +:: Check /sur/aquarium/hoon on the given has the given contents. +:: +++ check-file-touched + |= [=ship =desk warped=@t] + =/ m (strand ,~) + (check-touched ship desk /sur/aquarium/hoon warped) +:: +:: Check path on the given desk has the given contents. +:: +++ check-touched + |= [=ship =desk pax=path warped=@t] + =/ m (strand ,~) + ~& > "checking file touched on {}/{}" + ;< ~ bind:m (mount ship desk) + ^- form:m + |- ^- form:m + =* loop $ + ;< [her=^ship =unix-effect] bind:m take-unix-effect + ;< our=@p bind:m get-our + ;< now=@da bind:m get-time + :: %ergo is no longer sufficient because .^ is pinned to beginning of + :: the event. So we hope somebody sets a timer for something. + :: + ?. &(=(ship her) ?=(?(%init %ergo %doze) -.q.unix-effect)) + loop + =/ aqua-pax + ;: weld + /i/(scot %p ship)/cx/(scot %p ship)/[desk]/(scot %da now) + pax + /noun + == + ?: =(warped (need (scry-aqua:util (unit @) our now aqua-pax))) + (pure:m ~) + loop +:: +:: Turns poke into a dojo command +:: +++ poke-app + |= [=ship app=term =mark data=*] + =/ m (strand ,~) + ^- form:m + =/ command=tape ":{(trip app)} &{(trip mark)} {}" + (send-events (dojo:util ship command)) +:: +++ dojo-thread + |= [=ship ted=term =mark data=*] + =/ m (strand ,~) + ^- form:m + =/ command=tape "-{(trip ted)} &{(trip mark)} {}" + (send-events (dojo:util ship command)) +-- diff --git a/pkg/base-dev/lib/ph/util.hoon b/pkg/base-dev/lib/ph/util.hoon new file mode 100644 index 000000000..53979b425 --- /dev/null +++ b/pkg/base-dev/lib/ph/util.hoon @@ -0,0 +1,112 @@ +:: Utility functions for constructing tests +:: +/- aquarium +=, aquarium +|% +:: +:: Turn [ship (list unix-event)] into (list ph-event) +:: +++ send-events-to + |= [who=ship what=(list unix-event)] + ^- (list aqua-event) + %+ turn what + |= ue=unix-event + [%event who ue] +:: +:: Start a ship (low-level; prefer +raw-ship) +:: +++ init + |= [who=ship fake=?] + ^- (list aqua-event) + [%init-ship who fake]~ +:: +:: Send dojo command +:: +++ dojo + |= [who=ship what=tape] + ^- (list aqua-event) + %+ send-events-to who + ^- (list unix-event) + :~ + [/d/term/1 %belt %ctl `@c`%e] + [/d/term/1 %belt %ctl `@c`%u] + [/d/term/1 %belt %txt ((list @c) what)] + [/d/term/1 %belt %ret ~] + == +:: +:: Control character +:: +++ ctrl + |= [who=ship what=term] + ^- (list ph-event) + %+ send-events-to who + :~ [/d/term/1 %belt %ctl (,@c what)] + == +:: +:: Inject a file into a ship +:: +++ insert-files + |= [who=ship des=desk files=(list [=path txt=@t])] + ^- (list aqua-event) + =/ input + %+ turn files + |= [=path txt=@t] + [path ~ /text/plain (as-octs:mimes:html txt)] + %+ send-events-to who + :~ + [/c/sync/0v1n.2m9vh %into des | input] + == +:: +:: Checks whether the given event is a dojo output blit containing the +:: given tape +:: +++ is-dojo-output + |= [who=ship her=ship uf=unix-effect what=tape] + ?& =(who her) + ?=(%blit -.q.uf) + :: + %+ lien p.q.uf + |= =blit:dill + ?. ?=(%lin -.blit) + | + !=(~ (find what p.blit)) + == +:: +:: Test is successful if +is-dojo-output +:: +++ expect-dojo-output + |= [who=ship her=ship uf=unix-effect what=tape] + ^- (list ph-event) + ?. (is-dojo-output who her uf what) + ~ + [%test-done &]~ +:: +:: Check whether the given event is an ergo +:: +++ is-ergo + |= [who=ship her=ship uf=unix-effect] + ?& =(who her) + ?=(%ergo -.q.uf) + == +:: +:: Check if given effect is an http request; extract +:: +++ extract-request + |= [uf=unix-effect dest=@t] + ^- (unit [num=@ud =request:http]) + ?. ?=(%request -.q.uf) ~ + ?. =(dest url.request.q.uf) ~ + `[id.q.uf request.q.uf] +:: +:: Scry into a running aqua ship +:: +++ scry-aqua + |* [a=mold our=@p now=@da pax=path] + .^ a + %gx + (scot %p our) + %aqua + (scot %da now) + pax + == +-- diff --git a/pkg/base-dev/lib/pill.hoon b/pkg/base-dev/lib/pill.hoon new file mode 100644 index 000000000..95e49b8b5 --- /dev/null +++ b/pkg/base-dev/lib/pill.hoon @@ -0,0 +1,131 @@ +:: |pill: helper functions for making pills +:: +^? +|% +:: ++$ pill + $% [%ivory p=(list)] + $: %pill + nam=term + boot-ova=(list) + kernel-ova=(list unix-event) + userspace-ova=(list unix-event) + == == +:: ++$ unix-event + %+ pair wire + $% [%wack p=@] + [%what p=(list (pair path (cask)))] + [%whom p=ship] + [%boot ? $%($>(%fake task:jael) $>(%dawn task:jael))] + [%wyrd p=vere] + [%verb p=(unit ?)] + unix-task + == +:: +boot-ovum: boostrap kernel filesystem load +:: +++ boot-ovum + |= [hoon=cord arvo=cord] + :~ //arvo + %what + [/sys/hoon hoon/hoon] + [/sys/arvo hoon/arvo] + == +:: +file-ovum: userspace filesystem load +:: +:: bas: full path to / directory +:: +++ file-ovum + =/ directories=(list path) + :~ /app :: %gall applications + /gen :: :dojo generators + /lib :: libraries + /mar :: mark definitions + /sur :: structures + /sys :: system files + /ted :: :spider strands + /web :: %eyre web content + /desk :: desk manifest + == + |= [des=desk bas=path] + ^- unix-event + %. directories + |= :: sal: all spurs to load from + :: + sal=(list spur) + ^- unix-event + :: + :: hav: all user files + :: + =; hav ~& user-files+(lent hav) + =/ =yuki:clay + :- *(list tako:clay) + %- ~(gas by *(map path (each page:clay lobe:clay))) + (turn hav |=([=path =page:clay] [path &+page])) + [/c/sync [%park des &+yuki *rang:clay]] + =| hav=(list [path page:clay]) + |- ^+ hav + ?~ sal ~ + =. hav $(sal t.sal) + :: + :: tyl: spur + :: + =/ tyl i.sal + |- ^+ hav + :: + :: pax: full path at `tyl` + :: lon: directory at `tyl` + :: + =/ lyt (flop tyl) + =/ pax (weld bas lyt) + =/ lon .^(arch %cy pax) + =? hav ?=(^ fil.lon) + :_(hav [lyt mark=;;(@tas (head tyl)) noun=.^(* %cx pax)]) + =/ all ~(tap by dir.lon) + |- ^+ hav + ?~ all hav + $(all t.all, hav ^$(tyl [p.i.all tyl])) +:: +:: +file-ovum2: electric boogaloo +:: +++ file-ovum2 |=(p=path `unix-event`[//arvo what/(user-files p)]) +:: +:: +user-files: all userspace hoon files +:: +++ user-files + |= bas=path + %. directories:file-ovum + |= sal=(list spur) + ^- (list (pair path (cask))) + :: + :: hav: all user files + :: + =| hav=(list (pair path (cask))) + |- ^+ hav + ?~ sal ~ + =. hav $(sal t.sal) + :: + :: tyl: spur + :: + =/ tyl i.sal + |- ^+ hav + :: + :: pax: full path at `tyl` + :: lon: directory at `tyl` + :: + =/ pax (weld bas (flop tyl)) + =/ lon .^(arch %cy pax) + =? hav ?=(^ fil.lon) + :: + :: install only hoon files for now + :: + ?. ?=([%hoon *] tyl) + hav + :_ hav + [(flop `path`t.tyl) hoon/.^(@t %cx pax)] + :: + =/ all ~(tap by dir.lon) + |- ^+ hav + ?~ all hav + $(all t.all, hav ^$(tyl [p.i.all tyl])) +-- diff --git a/pkg/base-dev/lib/pkcs.hoon b/pkg/base-dev/lib/pkcs.hoon new file mode 100644 index 000000000..d94356174 --- /dev/null +++ b/pkg/base-dev/lib/pkcs.hoon @@ -0,0 +1,378 @@ +/- asn1 +/+ primitive-rsa, der +=* rsa primitive-rsa +:::: %/lib/pkcs +|% +:: +rs256: RSA signatures over a sha-256 digest +:: +++ rs256 + |_ k=key:rsa + :: +emsa:rs256: message digest + :: + :: Padded, DER encoded sha-256 hash (EMSA-PKCS1-v1_5). + :: + ++ emsa + |= m=byts + =/ emlen (met 3 n.pub.k) + =/ pec=spec:asn1 + :~ %seq + [%seq [%obj sha-256:obj:asn1] [%nul ~] ~] + [%oct 32 (shay wid.m dat.m)] + == + :: note: this asn.1 digest is rendered raw here, as we require + :: big-endian bytes, and the product of +en:der is little-endian + :: + =/ t=(list @D) ~(ren raw:en:der pec) + =/ tlen=@ud (lent t) + ?: (lth emlen (add 11 tlen)) + ~|(%emsa-too-short !!) + =/ ps=(list @D) + (reap (sub emlen (add 3 tlen)) 0xff) + (rep 3 (flop (weld [0x0 0x1 ps] [0x0 t]))) + :: +sign:rs256: sign message + :: + :: An RSA signature is the primitive decryption of the message hash. + :: + ++ sign + |=(m=byts (de:rsa (emsa m) k)) + :: +verify:rs256: verify signature + :: + :: RSA signature verification confirms that the primitive encryption + :: of the signature matches the message hash. + :: + ++ verify + |= [s=@ m=byts] + =((emsa m) (en:rsa s k)) + -- +:: |pem: generic PEM implementation (rfc7468) +:: +:: PEM is the base64 encoding of DER encoded data, with BEGIN and +:: END labels indicating some type. +:: +++ pem + |% + :: +en:pem: PEM encode + :: + ++ en + |= [lab=@t len=@ud der=@ux] + ^- wain + :: XX validate label? + :- (rap 3 ['-----BEGIN ' lab '-----' ~]) + =/ a (en:base64:mimes:html len `@`der) + |- ^- wain + ?~ a + [(rap 3 ['-----END ' lab '-----' ~]) ~] + [(end [3 64] a) $(a (rsh [3 64] a))] + :: +de:pem: PEM decode + :: + ++ de + |= [lab=@t mep=wain] + ^- (unit [len=@ud der=@ux]) + =/ a (sub (lent mep) 2) + ?~ mep ~ + :: XX validate label? + ?. =((rap 3 ['-----BEGIN ' lab '-----' ~]) i.mep) ~ + ?. =((rap 3 ['-----END ' lab '-----' ~]) (snag a t.mep)) ~ + ^- (unit [@ @]) + (de:base64:mimes:html (rap 3 (scag a t.mep))) + -- +:: |pkcs1: RSA asymmetric cryptography (rfc3447) +:: +++ pkcs1 + |% + :: |spec:pkcs1: ASN.1 specs for RSA keys + :: + ++ spec + |% + :: |en:spec:pkcs1: ASN.1 encoding for RSA keys + :: + ++ en + |% + :: +pass:en:spec:pkcs1: encode public key to ASN.1 + :: + ++ pass + |= k=key:rsa + ^- spec:asn1 + [%seq [%int n.pub.k] [%int e.pub.k] ~] + :: +ring:en:spec:pkcs1: encode private key to ASN.1 + :: + ++ ring + |= k=key:rsa + ^- spec:asn1 + ~| %rsa-need-ring + ?> ?=(^ sek.k) + :~ %seq + [%int 0] + [%int n.pub.k] + [%int e.pub.k] + [%int d.u.sek.k] + [%int p.u.sek.k] + [%int q.u.sek.k] + [%int (mod d.u.sek.k (dec p.u.sek.k))] + [%int (mod d.u.sek.k (dec q.u.sek.k))] + [%int (~(inv fo p.u.sek.k) q.u.sek.k)] + == + -- + :: |de:spec:pkcs1: ASN.1 decoding for RSA keys + :: + ++ de + |% + :: +pass:de:spec:pkcs1: decode ASN.1 public key + :: + ++ pass + |= a=spec:asn1 + ^- (unit key:rsa) + ?. ?=([%seq [%int *] [%int *] ~] a) + ~ + =* n int.i.seq.a + =* e int.i.t.seq.a + `[[n e] ~] + :: +ring:de:spec:pkcs1: decode ASN.1 private key + :: + ++ ring + |= a=spec:asn1 + ^- (unit key:rsa) + ?. ?=([%seq *] a) ~ + ?. ?= $: [%int %0] + [%int *] + [%int *] + [%int *] + [%int *] + [%int *] + * + == + seq.a + ~ + =* n int.i.t.seq.a + =* e int.i.t.t.seq.a + =* d int.i.t.t.t.seq.a + =* p int.i.t.t.t.t.seq.a + =* q int.i.t.t.t.t.t.seq.a + `[[n e] `[d p q]] + -- + -- + :: |der:pkcs1: DER encoding for RSA keys + :: + :: En(coding) and de(coding) for public (pass) and private (ring) keys. + :: + ++ der + |% + ++ en + |% + ++ pass |=(k=key:rsa (en:^der (pass:en:spec k))) + ++ ring |=(k=key:rsa (en:^der (ring:en:spec k))) + -- + ++ de + |% + ++ pass |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) pass:de:spec)) + ++ ring |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) ring:de:spec)) + -- + -- + :: |pem:pkcs1: PEM encoding for RSA keys + :: + :: En(coding) and de(coding) for public (pass) and private (ring) keys. + :: + ++ pem + |% + ++ en + |% + ++ pass |=(k=key:rsa (en:^pem 'RSA PUBLIC KEY' (pass:en:der k))) + ++ ring |=(k=key:rsa (en:^pem 'RSA PRIVATE KEY' (ring:en:der k))) + -- + ++ de + |% + ++ pass |=(mep=wain (biff (de:^pem 'RSA PUBLIC KEY' mep) pass:de:der)) + ++ ring |=(mep=wain (biff (de:^pem 'RSA PRIVATE KEY' mep) ring:de:der)) + -- + -- + -- +:: |pkcs8: asymmetric cryptography (rfc5208, rfc5958) +:: +:: RSA-only for now. +:: +++ pkcs8 + |% + :: |spec:pkcs8: ASN.1 specs for asymmetric keys + :: + ++ spec + |% + ++ en + |% + :: +pass:spec:pkcs8: public key ASN.1 + :: + :: Technically not part of pkcs8, but standardized later in + :: the superseding RFC. Included here for symmetry. + :: + ++ pass + |= k=key:rsa + ^- spec:asn1 + :~ %seq + [%seq [[%obj rsa:obj:asn1] [%nul ~] ~]] + =/ a=[len=@ud dat=@ux] + (pass:en:der:pkcs1 k) + [%bit (mul 8 len.a) dat.a] + == + :: +ring:spec:pkcs8: private key ASN.1 + :: + ++ ring + |= k=key:rsa + ^- spec:asn1 + :~ %seq + [%int 0] + [%seq [[%obj rsa:obj:asn1] [%nul ~] ~]] + [%oct (ring:en:der:pkcs1 k)] + == + -- + :: |de:spec:pkcs8: ASN.1 decoding for asymmetric keys + :: + ++ de + |% + :: +pass:de:spec:pkcs8: decode public key ASN.1 + :: + ++ pass + |= a=spec:asn1 + ^- (unit key:rsa) + ?. ?=([%seq [%seq *] [%bit *] ~] a) + ~ + ?. ?& ?=([[%obj *] [%nul ~] ~] seq.i.seq.a) + =(rsa:obj:asn1 obj.i.seq.i.seq.a) + == + ~ + (pass:de:der:pkcs1 (div len.i.t.seq.a 8) bit.i.t.seq.a) + :: +ring:de:spec:pkcs8: decode private key ASN.1 + :: + ++ ring + |= a=spec:asn1 + ^- (unit key:rsa) + ?. ?=([%seq [%int %0] [%seq *] [%oct *] ~] a) + ~ + ?. ?& ?=([[%obj *] [%nul ~] ~] seq.i.t.seq.a) + =(rsa:obj:asn1 obj.i.seq.i.t.seq.a) + == + ~ + (ring:de:der:pkcs1 [len oct]:i.t.t.seq.a) + -- + -- + :: |der:pkcs8: DER encoding for asymmetric keys + :: + :: En(coding) and de(coding) for public (pass) and private (ring) keys. + :: RSA-only for now. + :: + ++ der + |% + ++ en + |% + ++ pass |=(k=key:rsa `[len=@ud dat=@ux]`(en:^der (pass:en:spec k))) + ++ ring |=(k=key:rsa `[len=@ud dat=@ux]`(en:^der (ring:en:spec k))) + -- + ++ de + |% + ++ pass |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) pass:de:spec)) + ++ ring |=([len=@ud dat=@ux] `(unit key:rsa)`(biff (de:^der len dat) ring:de:spec)) + -- + -- + :: |pem:pkcs8: PEM encoding for asymmetric keys + :: + :: En(coding) and de(coding) for public (pass) and private (ring) keys. + :: RSA-only for now. + :: + ++ pem + |% + ++ en + |% + ++ pass |=(k=key:rsa (en:^pem 'PUBLIC KEY' (pass:en:der k))) + ++ ring |=(k=key:rsa (en:^pem 'PRIVATE KEY' (ring:en:der k))) + -- + ++ de + |% + ++ pass |=(mep=wain (biff (de:^pem 'PUBLIC KEY' mep) pass:de:der)) + ++ ring |=(mep=wain (biff (de:^pem 'PRIVATE KEY' mep) ring:de:der)) + -- + -- + -- +:: |pkcs10: certificate signing requests (rfc2986) +:: +:: Only implemented for RSA keys with subject-alternate names. +:: +++ pkcs10 + => |% + :: +csr:pkcs10: certificate request + :: + +$ csr [key=key:rsa hot=(list turf)] + -- + |% + :: |spec:pkcs10: ASN.1 specs for certificate signing requests + :: + ++ spec + |% + :: +en:spec:pkcs10: ASN.1 encoding for certificate signing requests + :: + ++ en + |= csr + ^- spec:asn1 + |^ =/ dat=spec:asn1 (info key hot) + :~ %seq + dat + [%seq [[%obj rsa-sha-256:obj:asn1] [%nul ~] ~]] + :: big-endian signature bits + :: + :: the signature bitwidth is definitionally the key length + :: + :+ %bit + (met 0 n.pub.key) + (swp 3 (~(sign rs256 key) (en:^der dat))) + == + :: +info:en:spec:pkcs10: certificate request info + :: + ++ info + |= csr + ^- spec:asn1 + :~ %seq + [%int 0] + [%seq ~] + (pass:en:spec:pkcs8 key) + :: explicit, context-specific tag #0 (extensions) + :: + :+ %con + `bespoke:asn1`[| 0] + %~ ren + raw:en:^der + :~ %seq + [%obj csr-ext:obj:asn1] + :~ %set + :~ %seq + :~ %seq + [%obj sub-alt:obj:asn1] + [%oct (en:^der (san hot))] + == == == == == + :: +san:en:spec:pkcs10: subject-alternate-names + :: + ++ san + |= hot=(list turf) + ^- spec:asn1 + :- %seq + %+ turn hot + :: implicit, context-specific tag #2 (IA5String) + :: XX sanitize string? + |=(=turf [%con `bespoke:asn1`[& 2] (trip (en-turf:html turf))]) + -- + :: |de:spec:pkcs10: ASN.1 decoding for certificate signing requests + ++ de !! + -- + :: |der:pkcs10: DER encoding for certificate signing requests + :: + ++ der + |% + ++ en |=(a=csr `[len=@ud der=@ux]`(en:^der (en:spec a))) + ++ de !! ::|=(a=@ `(unit csr)`(biff (de:^der a) de:spec)) + -- + :: |pem:pkcs10: PEM encoding for certificate signing requests + :: + ++ pem + |% + ++ en |=(a=csr (en:^pem 'CERTIFICATE REQUEST' (en:der a))) + ++ de !! ::|=(mep=wain (biff (de:^pem 'CERTIFICATE REQUEST' mep) de:der)) + -- + -- +-- + diff --git a/pkg/base-dev/lib/primitive-rsa.hoon b/pkg/base-dev/lib/primitive-rsa.hoon new file mode 100644 index 000000000..b843e2545 --- /dev/null +++ b/pkg/base-dev/lib/primitive-rsa.hoon @@ -0,0 +1,84 @@ +:: |rsa: primitive, textbook RSA +:: +:: Unpadded, unsafe, unsuitable for encryption! +:: +|% +:: +key:rsa: rsa public or private key +:: ++$ key + $: :: pub: public parameters (n=modulus, e=pub-exponent) + :: + pub=[n=@ux e=@ux] + :: sek: secret parameters (d=private-exponent, p/q=primes) + :: + sek=(unit [d=@ux p=@ux q=@ux]) + == +:: +ramp: make rabin-miller probabilistic prime +:: +:: XX replace +ramp:number? +:: a: bitwidth +:: b: snags (XX small primes to check divisibility?) +:: c: entropy +:: +++ ramp + |= [a=@ b=(list @) c=@] + =. c (shas %ramp c) + :: XX what is this value? + :: + =| d=@ + |- ^- @ux + :: XX what is this condition? + :: + ?: =((mul 100 a) d) + ~|(%ar-ramp !!) + :: e: prime candidate + :: + :: Sets low bit, as prime must be odd. + :: Sets high bit, as +raw:og only gives up to :a bits. + :: + =/ e :(con 1 (lsh [0 (dec a)] 1) (~(raw og c) a)) + :: XX what algorithm is this modular remainder check? + :: + ?: ?& (levy b |=(f=@ !=(1 (mod e f)))) + (pram:number e) + == + e + $(c +(c), d (shax d)) +:: +elcm:rsa: carmichael totient +:: +++ elcm + |= [a=@ b=@] + (div (mul a b) d:(egcd a b)) +:: +new-key:rsa: write somethingXXX +:: +++ new-key + =/ e `@ux`65.537 + |= [wid=@ eny=@] + ^- key + =/ diw (rsh 0 wid) + =/ p=@ux (ramp diw [3 5 ~] eny) + =/ q=@ux (ramp diw [3 5 ~] +(eny)) + =/ n=@ux (mul p q) + =/ d=@ux (~(inv fo (elcm (dec p) (dec q))) e) + [[n e] `[d p q]] +:: +en:rsa: primitive RSA encryption +:: +:: ciphertext = message^e (mod n) +:: +++ en + |= [m=@ k=key] + ~| %rsa-len + ?> (lte (met 0 m) (met 0 n.pub.k)) + (~(exp fo n.pub.k) e.pub.k m) +:: +de:rsa: primitive RSA decryption +:: +:: message = ciphertext^d (mod e) +:: +++ de + |= [m=@ k=key] + :: XX assert rsa-len here too? + ~| %rsa-need-ring + ?> ?=(^ sek.k) + =/ fu (fu:number p.u.sek.k q.u.sek.k) + (out.fu (exp.fu d.u.sek.k (sit.fu m))) +-- diff --git a/pkg/base-dev/lib/ring.hoon b/pkg/base-dev/lib/ring.hoon new file mode 100644 index 000000000..a7be742b7 --- /dev/null +++ b/pkg/base-dev/lib/ring.hoon @@ -0,0 +1,477 @@ +/- *ring +:: ring signatures over the edwards curve +:: +|% +:: +raw is the raw internal ring signature implementation. +raw does not deal +:: with urbit ship identities or urbit nouns and is low level. It only deals +:: with ed25519 keys and message digests. +:: +:: This raw interface is vaguely modeled on the haskell aos-signature package, +:: but is written in terms of ed25519 primitives instead of general ECC and +:: changes how linkage tags are computed so that how linkage occurs is a +:: client decision instead of hard coding the set of public keys as the +:: linkage scope. +:: +++ raw + |% + :: +generate-public-linkage: generate public linkage information + :: + ++ generate-public-linkage + |= link-scope=@ + ^- [data=@ h=@udpoint] + :: + =/ data=@ (mod link-scope l:ed:crypto) + =/ h=@udpoint (scalarmult-base:ed:crypto data) + [data h] + :: +generate-linkage: linkage information from scope and private key + :: + :: data: deterministically picked data point based off scope + :: h: h = [data] * g + :: y: y = [x] * h + ++ generate-linkage + |= [link-scope=(unit @) my-private-key=@] + ^- (unit [data=@ h=@udpoint y=@udpoint]) + :: + ?~ link-scope + ~ + :: + =+ [data=@ h=@udpoint]=(generate-public-linkage u.link-scope) + =/ y=@udpoint (scalarmult:ed:crypto my-private-key h) + [~ data h y] + :: +generate-challenge: generate challenge from a given message + :: + :: When :link-scope is ~ (ie, we're not building a linked ring signature), + :: calculates just the hash of `[message g]`. Otherwise, weaves the + :: linkage state into the challenge. + :: + ++ generate-challenge + |= $: :: common to both linked and unlinked + message=@ + g=@udpoint + :: high level universal state + :: + link-state=(unit [data=@ h=@udpoint y=@udpoint]) + :: point to include in challenge when link-state isn't ~ + :: + h=(unit @udpoint) + == + ^- @ + :: concatenate and reduce our message down to a 512-bit hash + =/ concatenated + ?~ link-state + (shal 96 (can 3 ~[[64 message] [32 g]])) + :: + %+ shal 192 + %+ can 3 + :~ [64 message] + [32 g] + [32 data.u.link-state] + [32 y.u.link-state] + [32 (need h)] + == + :: + (mod concatenated l:ed:crypto) + :: +generate-challenges: generates the full list of challenges + :: + ++ generate-challenges + |= $: link-state=(unit [data=@ h=@udpoint y=@udpoint]) + message=@ + public-keys=(list @udpoint) + ss=(list @) + :: + prev-k=@u + prev-s=@ + prev-ch=@ + challenges=(list @) + == + ^- (list @) + :: + =/ gs=@udpoint + %- add-scalarmult-scalarmult-base:ed:crypto :* + prev-ch + (snag prev-k public-keys) + prev-s + == + :: + =/ hs=(unit @udpoint) + ?~ link-state + ~ + :: + :- ~ + %- add-double-scalarmult:ed:crypto :* + prev-s + h.u.link-state + prev-ch + y.u.link-state + == + :: + =/ ch=@ + (generate-challenge message gs link-state hs) + :: + ?~ ss + [ch challenges] + :: + %_ $ + prev-k (mod (add prev-k 1) (lent public-keys)) + prev-s i.ss + prev-ch ch + ss t.ss + challenges [ch challenges] + == + :: +scalarmult-h: maybe multiply u by h in linkage + :: + :: Since linkage tags are optional, we need to be able to just do the math + :: in case :linkage is set and fall through otherwise. +scalarmult-h is + :: used to generate the (unit point) consumed by +generate-challenge. + :: + ++ scalarmult-h + |= [u=@ linkage=(unit [data=@ h=@udpoint y=@udpoint])] + ^- (unit @udpoint) + ?~ linkage + ~ + [~ (scalarmult:ed:crypto u h.u.linkage)] + :: +reorder: reorders a list so the ith element is first + :: + ++ reorder + |* [i=@ l=(list)] + %+ weld + (slag i l) + (scag i l) + :: +sign: creates a ring signature on an ed25519 curve + :: + ++ sign + |= $: message=@ + link-scope=(unit @) + :: + anonymity-set=(set @udpoint) + my-public-key=@udpoint + my-private-key=@udscalar + :: + eny=@uvJ + == + ^- raw-ring-signature + |^ :: k: our public-key's position in :anonymity-list + :: + =/ k=@u + ~| [%couldnt-find my-public-key in=anonymity-list] + (need (find [my-public-key ~] anonymity-list)) + :: Generate linkage information if given + :: + =/ linkage=(unit [data=@ h=@udpoint y=@udpoint]) + (generate-linkage link-scope my-private-key) + :: initialize our random number generator from entropy + :: + =+ rand=~(. og eny) + :: generate the random s values used in the ring + :: + =^ random-s-values=(list @) rand + =| count=@ + =| random-s-values=(list @) + |- + ?: =(count (sub participants 1)) + [random-s-values rand] + :: + =^ v=@ rand (rads:rand l:ed:crypto) + $(count (add 1 count), random-s-values [v random-s-values]) + :: + ?> ?=(^ random-s-values) + =/ sk1=@ i.random-s-values + =/ sk2-to-prev-sk=(list @) t.random-s-values + :: Pick a random :u + :: + =^ u=@ rand + (rads:rand l:ed:crypto) + :: Compute challenge at k + 1 + :: + =/ chk1=@ + %- generate-challenge :* + message + (scalarmult-base:ed:crypto u) + linkage + (scalarmult-h u linkage) + == + :: Generate challenges for [ck, ..., c1, c0, ... ck + 2, ck + 1] + :: + =/ reversed-chk-to-chk1=(list @) + %- generate-challenges :* + linkage + message + anonymity-list + sk2-to-prev-sk + :: + (mod (add k 1) participants) + sk1 + chk1 + [chk1 ~] + == + =/ chk=@ (head reversed-chk-to-chk1) + :: Compute s = u - x * c mod n + :: + =/ sk=@ (~(dif fo l:ed:crypto) u (mul my-private-key chk)) + :: + =/ ordered-challenges=(list @) + (order-challenges k (flop reversed-chk-to-chk1)) + :: + =/ ordered-ss=(list @) (order-ss k [sk sk1 sk2-to-prev-sk]) + =/ ch0 (head ordered-challenges) + :: + [ch0 ordered-ss ?~(linkage ~ `y.u.linkage)] + :: + ++ anonymity-list + ~(tap in anonymity-set) + :: + ++ participants + (lent anonymity-list) + :: + ++ order-challenges + |= [k=@ ch=(list @)] + (reorder (sub participants (add k 1)) ch) + :: + ++ order-ss + |= [k=@ sk-to-prev-sk=(list @)] + (reorder (sub participants k) sk-to-prev-sk) + -- + :: +verify: verify signature + :: + ++ verify + |= $: message=@ + link-scope=(unit @) + :: + anonymity-set=(set @udpoint) + signature=raw-ring-signature + == + ^- ? + :: if there's a linkage scope but no tag, fail + :: + ?: &(?=(^ link-scope) ?=(~ y.signature)) + %.n + :: if there's no linkage scope but a tag, fail + :: + ?: &(?=(~ link-scope) ?=(^ y.signature)) + %.n + :: vice versa. + :: + :: decompose the signature into [s0 s1 s2....] + :: + ?> ?=([@ @ *] s.signature) + =/ s0=@ i.s.signature + =/ s1=@ i.t.s.signature + =/ s2-to-end=(list @) t.t.s.signature + :: anonymity-list: set of public keys listified in ring order + :: + =/ anonymity-list=(list @udpoint) + ~(tap in anonymity-set) + :: participants: length of :anonymity-list + :: + =/ participants=@u + (lent anonymity-list) + :: + =/ z0p=@udpoint + %- add-scalarmult-scalarmult-base:ed:crypto :* + ch0.signature + (head anonymity-list) + s0 + == + :: generate the linkage using public data, and the y point from the + :: signature + :: + =/ linkage=(unit [data=@ h=@udpoint y=@udpoint]) + ?~ link-scope + ~ + =+ [data=@ h=@udpoint]=(generate-public-linkage u.link-scope) + :- ~ + [data h (need y.signature)] + :: + =/ z0pp=(unit @udpoint) + ?~ linkage + ~ + :- ~ + %- add-double-scalarmult:ed:crypto :* + s0 + h.u.linkage + ch0.signature + y.u.linkage + == + :: initial challenge + :: + =/ ch1=@ + (generate-challenge message z0p linkage z0pp) + :: + =/ challenges + %- generate-challenges :* + linkage + message + anonymity-list + s2-to-end + :: + (mod 1 participants) + s1 + ch1 + [ch1 ~] + == + :: + =(ch0.signature (head challenges)) + -- +:: +detail: details about getting keys from Azimuth +:: +++ detail + |% + :: +seed-to-private-key-scalar: keyfile form to scalar we can multiply with + :: + ++ seed-to-private-key-scalar + |= sk=@I ^- @udscalar + ?: (gth (met 3 sk) 32) !! + =+ h=(shal (rsh [0 3] b:ed:crypto) sk) + %+ add + (bex (sub b:ed:crypto 2)) + (lsh [0 3] (cut 0 [3 (sub b:ed:crypto 5)] h)) + :: +get-public-key-from-pass: decode the raw @ public key structure + :: + ++ get-public-key-from-pass + |= a=pass + ^- [@ @] + =+ [mag=(end 3 a) bod=(rsh 3 a)] + ~| %not-crub-pubkey ?> =('b' mag) + [cry=(rsh 8 bod) sgn=(end 8 bod)] + :: + :: + ++ get-private-key-from-ring + |= a=ring + ^- [@ @] + =+ [mag=(end 3 a) bod=(rsh 3 a)] + ~| %not-crub-seckey ?> =('B' mag) + =+ [c=(rsh 8 bod) s=(end 8 bod)] + :: todo: do we puck here? + [c s] + :: +ship-life-to-pubid: fetches public key information from jael + :: + ++ ship-life-to-pubid + |= [our=@p now=@da ship=@p =life] + ^- @udpoint + :: + =/ d=[=^life =pass] + =/ scry-path=path + :~ %k + (scot %p our) + (scot %da now) + (scot %p ship) + (scot %ud life) + == + .^([^life pass] scry-path) + :: we have the deed which has pass, which is several numbers +cat-ed + :: together; pull out the keys + :: + =/ x=[crypt=@ auth=@] (get-public-key-from-pass pass.d) + :: + `@udpoint`auth.x + :: + ++ build-signing-participants + |= [our=@p now=@da invited=(list @p)] + ^- [(set [@p life]) (set @udpoint)] + :: + =| participants=(set [@p life]) + =| keys=(set @udpoint) + :: + |- + ?~ invited + [participants keys] + :: + =/ =life + .^(life k+/(scot %p our)/life/(scot %da now)/(scot %p i.invited)) + :: + ?: =(life 0) + $(invited t.invited) + :: + =/ pubkey=@udpoint (ship-life-to-pubid our now i.invited life) + :: + =. participants (~(put in participants) [i.invited life]) + =. keys (~(put in keys) pubkey) + :: + $(invited t.invited) + :: + :: + ++ build-verifying-participants + |= [our=@p now=@da invited=(list [ship=@p =life])] + ^- (set @udpoint) + :: + =| keys=(set @udpoint) + :: + |- + ?~ invited + keys + :: + =/ pubkey=@udpoint + (ship-life-to-pubid our now ship.i.invited life.i.invited) + =. keys + (~(put in keys) pubkey) + :: + $(invited t.invited) + -- +-- +:: public interface +:: +|% +:: +sign: ring-signs a message using the current ship +:: +++ sign + |= $: our=@p + now=@da + eny=@uvJ + :: + message=* + link-scope=(unit *) + anonymity-set=(set @p) + == + ^- ring-signature + :: if our is not in @p, we must be in @p. + :: + =. anonymity-set (~(put in anonymity-set) our) + :: + =/ msg-hash=@ (shaz (jam message)) + =/ link-hash=(unit @) (bind link-scope |=(a=* (shaz (jam a)))) + :: get everyone's public keys + :: + =/ p=[participants=(set [ship=@p =life]) keys=(set @udpoint)] + (build-signing-participants:detail our now ~(tap in anonymity-set)) + :: get our ships' current life + :: + =/ our-life=life + .^(life %k /(scot %p our)/life/(scot %da now)/(scot %p our)) + :: get our ships' secret keyfile ring + :: + =/ secret-ring=ring + .^(ring %k /(scot %p our)/vein/(scot %da now)/(scot %ud our-life)) + :: fetch the encoded auth seed from the ring + :: + =/ secret-auth-seed=@ + +:(get-private-key-from-ring:detail secret-ring) + :: get our ships' public key + :: + =/ public-key=@udpoint + (ship-life-to-pubid:detail our now our our-life) + :: + :- participants.p + :- link-scope + %- sign:raw :* + msg-hash + link-hash + keys.p + public-key + (seed-to-private-key-scalar:detail secret-auth-seed) + eny + == +:: +verify: verifies a message against a ring signature +:: +++ verify + |= [our=@p now=@da message=* =ring-signature] + ^- ? + :: + =/ keys=(set @udpoint) + %^ build-verifying-participants:detail our now + ~(tap in participants.ring-signature) + :: + =/ msg-hash=@ (shaz (jam message)) + =/ link-hash=(unit @) (bind link-scope.ring-signature |=(a=* (shaz (jam a)))) + :: + (verify:raw msg-hash link-hash keys raw.ring-signature) +-- diff --git a/pkg/base-dev/lib/server.hoon b/pkg/base-dev/lib/server.hoon new file mode 100644 index 000000000..431b5db8a --- /dev/null +++ b/pkg/base-dev/lib/server.hoon @@ -0,0 +1,159 @@ +=, eyre +|% ++$ request-line + $: [ext=(unit @ta) site=(list @t)] + args=(list [key=@t value=@t]) + == +:: +parse-request-line: take a cord and parse out a url +:: +++ parse-request-line + |= url=@t + ^- request-line + (fall (rush url ;~(plug apat:de-purl:html yque:de-purl:html)) [[~ ~] ~]) +:: +++ manx-to-octs + |= man=manx + ^- octs + (as-octt:mimes:html (en-xml:html man)) +:: +++ json-to-octs + |= jon=json + ^- octs + (as-octt:mimes:html (en-json:html jon)) +:: +++ app + |% + :: + :: +require-authorization: + :: redirect to the login page when unauthenticated + :: otherwise call handler on inbound request + :: + ++ require-authorization + |= $: =inbound-request:eyre + handler=$-(inbound-request:eyre simple-payload:http) + == + ^- simple-payload:http + :: + ?: authenticated.inbound-request + ~! this + ~! +:*handler + (handler inbound-request) + :: + =- [[307 ['location' -]~] ~] + %^ cat 3 + '/~/login?redirect=' + url.request.inbound-request + :: + :: +require-authorization-simple: + :: redirect to the login page when unauthenticated + :: otherwise pass through simple-paylod + :: + ++ require-authorization-simple + |= [=inbound-request:eyre =simple-payload:http] + ^- simple-payload:http + :: + ?: authenticated.inbound-request + ~! this + simple-payload + :: + =- [[307 ['location' -]~] ~] + %^ cat 3 + '/~/login?redirect=' + url.request.inbound-request + :: + ++ give-simple-payload + |= [eyre-id=@ta =simple-payload:http] + ^- (list card:agent:gall) + =/ header-cage + [%http-response-header !>(response-header.simple-payload)] + =/ data-cage + [%http-response-data !>(data.simple-payload)] + :~ [%give %fact ~[/http-response/[eyre-id]] header-cage] + [%give %fact ~[/http-response/[eyre-id]] data-cage] + [%give %kick ~[/http-response/[eyre-id]] ~] + == + -- +++ gen + |% + :: + ++ max-1-da ['cache-control' 'max-age=86400'] + ++ max-1-wk ['cache-control' 'max-age=604800'] + :: + ++ html-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'text/html'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ css-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'text/css'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ js-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'text/javascript'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ png-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'image/png'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ svg-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'image/svg+xml'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ ico-response + |= =octs + ^- simple-payload:http + [[200 [['content-type' 'image/x-icon'] max-1-wk ~]] `octs] + :: + ++ woff2-response + =| cache=? + |= =octs + ^- simple-payload:http + [[200 [['content-type' 'font/woff2'] max-1-wk ~]] `octs] + :: + ++ json-response + =| cache=_| + |= =json + ^- simple-payload:http + :_ `(json-to-octs json) + [200 [['content-type' 'application/json'] ?:(cache [max-1-da ~] ~)]] + :: + ++ manx-response + =| cache=_| + |= man=manx + ^- simple-payload:http + :_ `(manx-to-octs man) + [200 [['content-type' 'text/html'] ?:(cache [max-1-da ~] ~)]] + :: + ++ not-found + ^- simple-payload:http + [[404 ~] ~] + :: + ++ login-redirect + |= =request:http + ^- simple-payload:http + =- [[307 ['location' -]~] ~] + %^ cat 3 + '/~/login?redirect=' + url.request + :: + ++ redirect + |= redirect=cord + ^- simple-payload:http + [[307 ['location' redirect]~] ~] + -- +-- diff --git a/pkg/base-dev/lib/shoe.hoon b/pkg/base-dev/lib/shoe.hoon new file mode 100644 index 000000000..0348e10e5 --- /dev/null +++ b/pkg/base-dev/lib/shoe.hoon @@ -0,0 +1,532 @@ +:: shoe: console application library +:: +:: /lib/sole: draw some characters +:: /lib/shoe: draw the rest of the fscking app +:: +:: call +agent with a type, then call the resulting function with a core +:: of the shape described in +shoe. +:: you may produce classic gall cards and "shoe-effects", shorthands for +:: sending cli events to connected clients. +:: default implementations for the shoe-specific arms are in +default. +:: for a simple usage example, see /app/shoe. +:: +/- *sole +/+ sole, auto=language-server-complete +|% ++$ state-0 + $: %0 + soles=(map @ta sole-share) + == +:: $card: standard gall cards plus shoe effects +:: ++$ card + $% card:agent:gall + [%shoe sole-ids=(list @ta) effect=shoe-effect] :: ~ sends to all soles + == +:: $shoe-effect: easier sole-effects +:: ++$ shoe-effect + $% :: %sole: raw sole-effect + :: + [%sole effect=sole-effect] + :: %table: sortable, filterable data, with suggested column char widths + :: + [%table head=(list dime) wide=(list @ud) rows=(list (list dime))] + :: %row: line sections with suggested char widths + :: + [%row wide=(list @ud) cols=(list dime)] + == +:: +shoe: gall agent core with extra arms +:: +++ shoe + |* command-type=mold + $_ ^| + |_ bowl:gall + :: +command-parser: input parser for a specific session + :: + :: if the head of the result is true, instantly run the command + :: + ++ command-parser + |~ sole-id=@ta + |~(nail *(like [? command-type])) + :: +tab-list: autocomplete options for the session (to match +command-parser) + :: + ++ tab-list + |~ sole-id=@ta + :: (list [@t tank]) + *(list (option:auto tank)) + :: +on-command: called when a valid command is run + :: + ++ on-command + |~ [sole-id=@ta command=command-type] + *(quip card _^|(..on-init)) + :: + ++ can-connect + |~ sole-id=@ta + *? + :: + ++ on-connect + |~ sole-id=@ta + *(quip card _^|(..on-init)) + :: + ++ on-disconnect + |~ sole-id=@ta + *(quip card _^|(..on-init)) + :: + ::NOTE standard gall agent arms below, though they may produce %shoe cards + :: + ++ on-init + *(quip card _^|(..on-init)) + :: + ++ on-save + *vase + :: + ++ on-load + |~ vase + *(quip card _^|(..on-init)) + :: + ++ on-poke + |~ [mark vase] + *(quip card _^|(..on-init)) + :: + ++ on-watch + |~ path + *(quip card _^|(..on-init)) + :: + ++ on-leave + |~ path + *(quip card _^|(..on-init)) + :: + ++ on-peek + |~ path + *(unit (unit cage)) + :: + ++ on-agent + |~ [wire sign:agent:gall] + *(quip card _^|(..on-init)) + :: + ++ on-arvo + |~ [wire sign-arvo] + *(quip card _^|(..on-init)) + :: + ++ on-fail + |~ [term tang] + *(quip card _^|(..on-init)) + -- +:: +default: bare-minimum implementations of shoe arms +:: +++ default + |* [shoe=* command-type=mold] + |_ =bowl:gall + ++ command-parser + |= sole-id=@ta + (easy *[? command-type]) + :: + ++ tab-list + |= sole-id=@ta + ~ + :: + ++ on-command + |= [sole-id=@ta command=command-type] + [~ shoe] + :: + ++ can-connect + |= sole-id=@ta + (team:title [our src]:bowl) + :: + ++ on-connect + |= sole-id=@ta + [~ shoe] + :: + ++ on-disconnect + |= sole-id=@ta + [~ shoe] + -- +:: +agent: creates wrapper core that handles sole events and calls shoe arms +:: +++ agent + |* command-type=mold + |= =(shoe command-type) + =| state-0 + =* state - + ^- agent:gall + => + |% + ++ deal + |= cards=(list card) + %+ turn cards + |= =card + ^- card:agent:gall + ?. ?=(%shoe -.card) card + ?- -.effect.card + %sole + =- [%give %fact - %sole-effect !>(effect.effect.card)] + %+ turn + ?^ sole-ids.card sole-ids.card + ~(tap in ~(key by soles)) + |= sole-id=@ta + /sole/[sole-id] + :: + %table + =; fez=(list sole-effect) + $(effect.card [%sole %mor fez]) + =, +.effect.card + :- (row:draw & wide head) + %+ turn rows + (cury (cury row:draw |) wide) + :: + %row + $(effect.card [%sole (row:draw | +.effect.card)]) + == + -- + :: + |_ =bowl:gall + +* this . + og ~(. shoe bowl) + :: + ++ on-init + ^- (quip card:agent:gall agent:gall) + =^ cards shoe on-init:og + [(deal cards) this] + :: + ++ on-save !>([%shoe-app on-save:og state]) + :: + ++ on-load + |= old-state=vase + ^- (quip card:agent:gall agent:gall) + :: we could be upgrading from a shoe-less app, in which case the vase + :: contains inner application state instead of our +on-save. + :: to distinguish between the two, we check for the presence of our own + :: +on-save tag in the vase. + :: + ?. ?=([%shoe-app ^] q.old-state) + =^ cards shoe (on-load:og old-state) + [(deal cards) this] + =^ old-inner state +:!<([%shoe-app vase state-0] old-state) + =^ cards shoe (on-load:og old-inner) + [(deal cards) this] + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card:agent:gall agent:gall) + ?. ?=(%sole-action mark) + =^ cards shoe (on-poke:og mark vase) + [(deal cards) this] + :: + =/ act !<(sole-action vase) + =* sole-id id.act + =/ cli-state=sole-share + (~(gut by soles) sole-id *sole-share) + |^ =^ [cards=(list card) =_cli-state] shoe + ?- -.dat.act + %det (apply-edit +.dat.act) + %clr [[~ cli-state] shoe] + %ret try-command + %tab [(tab +.dat.act) shoe] + == + :- (deal cards) + this(soles (~(put by soles) sole-id cli-state)) + :: + ++ effect + |= =sole-effect + ^- card + [%shoe [sole-id]~ %sole sole-effect] + :: + ++ apply-edit + |= =sole-change + ^+ [[*(list card) cli-state] shoe] + =^ inverse cli-state + (~(transceive sole cli-state) sole-change) + :: res: & for fully parsed, | for parsing failure at location + :: + =/ res=(each (unit [run=? cmd=command-type]) @ud) + %+ rose (tufa buf.cli-state) + (command-parser:og sole-id) + ?: ?=(%& -.res) + :: only auto-run eligible commands if they were typed out + :: (that is, not retrieved from command history) + :: + ?. &(?=(^ p.res) run.u.p.res !?=(%set -.ted.sole-change)) + [[~ cli-state] shoe] + (run-command cmd.u.p.res) + :_ shoe + :: parsing failed + :: + ?. &(?=(%del -.inverse) =(+(p.inverse) (lent buf.cli-state))) + :: if edit was somewhere in the middle, let it happen anyway + :: + [~ cli-state] + :: if edit was insertion at buffer tail, revert it + :: + =^ undo cli-state + (~(transmit sole cli-state) inverse) + :_ cli-state + :_ ~ + %+ effect %mor + :~ [%det undo] :: undo edit + [%err p.res] :: cursor to error location + == + :: + ++ try-command + ^+ [[*(list card) cli-state] shoe] + =/ res=(unit [? cmd=command-type]) + %+ rust (tufa buf.cli-state) + (command-parser:og sole-id) + ?^ res (run-command cmd.u.res) + [[[(effect %bel ~)]~ cli-state] shoe] + :: + ++ run-command + |= cmd=command-type + ^+ [[*(list card) cli-state] shoe] + =^ cards shoe (on-command:og sole-id cmd) + :: clear buffer + :: + =^ clear cli-state (~(transmit sole cli-state) [%set ~]) + =- [[[- cards] cli-state] shoe] + %+ effect %mor + :~ [%nex ~] + [%det clear] + == + :: + ++ tab + |= pos=@ud + ^- (quip card _cli-state) + =+ (get-id-cord:auto pos (tufa buf.cli-state)) + =/ needle=term + (fall id %$) + :: autocomplete empty command iff user at start of command + :: + =/ options=(list (option:auto tank)) + (search-prefix:auto needle (tab-list:og sole-id)) + =/ advance=term + (longest-match:auto options) + =/ to-send=tape + %- trip + (rsh [3 (met 3 needle)] advance) + =/ send-pos=@ud + %+ add pos + (met 3 (fall forward '')) + =| cards=(list card) + :: only render the option list if we couldn't complete anything + :: + =? cards &(?=(~ to-send) ?=(^ options)) + [(effect %tab options) cards] + |- ^- (quip card _cli-state) + ?~ to-send + [(flop cards) cli-state] + =^ char cli-state + (~(transmit sole cli-state) [%ins send-pos `@c`i.to-send]) + %_ $ + cards [(effect %det char) cards] + send-pos +(send-pos) + to-send t.to-send + == + -- + :: + ++ on-watch + |= =path + ^- (quip card:agent:gall agent:gall) + ?. ?=([%sole @ ~] path) + =^ cards shoe + (on-watch:og path) + [(deal cards) this] + =* sole-id i.t.path + ?> (can-connect:og sole-id) + =. soles (~(put by soles) sole-id *sole-share) + =^ cards shoe + (on-connect:og sole-id) + :_ this + %- deal + :_ cards + [%shoe [sole-id]~ %sole %pro & dap.bowl "> "] + :: + ++ on-leave + |= =path + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-leave:og path) + [(deal cards) this] + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. =(/x/dbug/state path) ~ + ``noun+(slop on-save:og !>(shoe=state)) + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-agent:og wire sign) + [(deal cards) this] + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-arvo:og wire sign-arvo) + [(deal cards) this] + :: + ++ on-fail + |= [=term =tang] + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-fail:og term tang) + [(deal cards) this] + -- +:: +++ draw + |% + ++ row + |= [bold=? wide=(list @ud) cols=(list dime)] + ^- sole-effect + :- %mor + ^- (list sole-effect) + =/ cows=(list [wid=@ud col=dime]) + %- head + %^ spin cols wide + |= [col=dime wiz=(list @ud)] + ~| [%too-few-wide col] + ?> ?=(^ wiz) + [[i.wiz col] t.wiz] + =/ cobs=(list [wid=@ud (list tape)]) + (turn cows col-as-lines) + =+ [lin=0 any=|] + =| fez=(list sole-effect) + |- ^+ fez + =; out=tape + :: done when we're past the end of all columns + :: + ?: (levy out (cury test ' ')) + (flop fez) + =; fec=sole-effect + $(lin +(lin), fez [fec fez]) + ?. bold txt+out + klr+[[`%br ~ ~]^[(crip out)]~]~ + %+ roll cobs + |= [[wid=@ud lines=(list tape)] out=tape] + %+ weld out + %+ weld ?~(out "" " ") + =+ l=(swag [lin 1] lines) + ?^(l i.l (reap wid ' ')) + :: + ++ col-as-lines + |= [wid=@ud col=dime] + ^- [@ud (list tape)] + :- wid + %+ turn + (break wid (col-as-text col) (break-sets -.col)) + (cury (cury pad wid) (alignment -.col)) + :: + ++ col-as-text + |= col=dime + ^- tape + ?+ p.col (scow col) + %t (trip q.col) + %tas ['%' (scow col)] + == + :: + ++ alignment + |= wut=@ta + ^- ?(%left %right) + ?: ?=(?(%t %ta %tas %da) wut) + %left + %right + :: + ++ break-sets + |= wut=@ta + :: for: may break directly before these characters + :: aft: may break directly after these characters + :: new: always break on these characters, consuming them + :: + ^- [for=(set @t) aft=(set @t) new=(set @t)] + ?+ wut [(sy " ") (sy ".:-/") (sy "\0a")] + ?(%p %q) [(sy "-") (sy "-") ~] + %ux [(sy ".") ~ ~] + == + :: + ++ break + |= [wid=@ud cot=tape brs=_*break-sets] + ^- (list tape) + ~| [wid cot] + ?: =("" cot) ~ + =; [lin=tape rem=tape] + [lin $(cot rem)] + :: take snip of max width+1, search for breakpoint on that. + :: we grab one char extra, to look-ahead for for.brs. + :: later on, we always transfer _at least_ the extra char. + :: + =^ lin=tape cot + [(scag +(wid) cot) (slag +(wid) cot)] + =+ len=(lent lin) + :: find the first newline character + :: + =/ new=(unit @ud) + =+ new=~(tap in new.brs) + =| las=(unit @ud) + |- + ?~ new las + $(new t.new, las (hunt lth las (find [i.new]~ lin))) + :: if we found a newline, break on it + :: + ?^ new + :- (scag u.new lin) + (weld (slag +(u.new) lin) cot) + :: if it fits, we're done + :: + ?: (lte len wid) + [lin cot] + =+ nil=(flop lin) + :: search for latest aft match + :: + =/ aft=(unit @ud) + :: exclude the look-ahead character from search + :: + =. len (dec len) + =. nil (slag 1 nil) + =- ?~(- ~ `+(u.-)) + ^- (unit @ud) + =+ aft=~(tap in aft.brs) + =| las=(unit @ud) + |- + ?~ aft (bind las (cury sub (dec len))) + $(aft t.aft, las (hunt lth las (find [i.aft]~ nil))) + :: search for latest for match + :: + =/ for=(unit @ud) + =+ for=~(tap in for.brs) + =| las=(unit @ud) + |- + ?~ for (bind las (cury sub (dec len))) + =- $(for t.for, las (hunt lth las -)) + =+ (find [i.for]~ nil) + :: don't break before the first character + :: + ?:(=(`(dec len) -) ~ -) + :: if any result, break as late as possible + :: + =+ brk=(hunt gth aft for) + ?~ brk + :: lin can't break, produce it in its entirety + :: (after moving the look-ahead character back) + :: + :- (scag wid lin) + (weld (slag wid lin) cot) + :- (scag u.brk lin) + =. cot (weld (slag u.brk lin) cot) + :: eat any leading whitespace the next line might have, "clean break" + :: + |- ^+ cot + ?~ cot ~ + ?. ?=(?(%' ' %'\09') i.cot) + cot + $(cot t.cot) + :: + ++ pad + |= [wid=@ud lyn=?(%left %right) lin=tape] + ^+ lin + =+ l=(lent lin) + ?: (gte l wid) lin + =+ p=(reap (sub wid l) ' ') + ?- lyn + %left (weld lin p) + %right (weld p lin) + == + -- +-- diff --git a/pkg/base-dev/lib/skeleton.hoon b/pkg/base-dev/lib/skeleton.hoon new file mode 100644 index 000000000..982c371b8 --- /dev/null +++ b/pkg/base-dev/lib/skeleton.hoon @@ -0,0 +1,51 @@ +:: Similar to default-agent except crashes everywhere +^- agent:gall +|_ bowl:gall +++ on-init + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-save + ^- vase + !! +:: +++ on-load + |~ old-state=vase + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-poke + |~ in-poke-data=cage + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-watch + |~ path + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-leave + |~ path + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-peek + |~ path + ^- (unit (unit cage)) + !! +:: +++ on-agent + |~ [wire sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-arvo + |~ [wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + !! +:: +++ on-fail + |~ [term tang] + ^- (quip card:agent:gall agent:gall) + !! +-- diff --git a/pkg/base-dev/lib/sole.hoon b/pkg/base-dev/lib/sole.hoon new file mode 100644 index 000000000..66684668a --- /dev/null +++ b/pkg/base-dev/lib/sole.hoon @@ -0,0 +1,139 @@ +:: +:::: /hoon/sole/lib + :: +/? 310 +/- *sole +:::: + :: +|_ sole-share :: shared-state engine +++ abet +< +++ apply + |= ted=sole-edit + ^+ +> + ?- -.ted + %del +>.$(buf (weld (scag p.ted buf) (slag +(p.ted) buf))) + %ins +>.$(buf (weld (scag p.ted buf) `_buf`[q.ted (slag p.ted buf)])) + %mor |- ^+ +>.^$ + ?~ p.ted + +>.^$ + $(p.ted t.p.ted, +>.^$ ^$(ted i.p.ted)) + %nop +>.$ + %set +>.$(buf p.ted) + == +:: +:::: +:: ++transmute: symmetric operational transformation. +:: +:: for any sole state +>, obeys +:: +:: =+ [x=(transmute a b) y=(transmute b a)] +:: .= (apply:(apply a) x) +:: (apply:(apply b) y) +:: +++ transmute :: dex as after sin + |= [sin=sole-edit dex=sole-edit] + ~| [%transmute sin dex] + ^- sole-edit + ?: ?=(%mor -.sin) + |- ^- sole-edit + ?~ p.sin dex + $(p.sin t.p.sin, dex ^$(sin i.p.sin)) + :: + ?: ?=(%mor -.dex) + :- %mor + |- ^- (list sole-edit) + ?~ p.dex ~ + [^$(dex i.p.dex) $(p.dex t.p.dex)] + :: + ?: |(?=(%nop -.sin) ?=(%nop -.dex)) dex + ?: ?=(%set -.sin) [%nop ~] + ?: ?=(%set -.dex) dex + :: + ?- -.sin + %del + ?- -.dex + %del ?: =(p.sin p.dex) [%nop ~] + ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex) + %ins ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex) + == + :: + %ins + ?- -.dex + %del ?:((lte p.sin p.dex) dex(p +(p.dex)) dex) + %ins ?: =(p.sin p.dex) + ?:((lth q.sin q.dex) dex dex(p +(p.dex))) + ?:((lte p.sin p.dex) dex(p +(p.dex)) dex) + == + == +:: +++ commit :: local change + |= ted=sole-edit + ^- sole-share + abet:(apply(own.ven +(own.ven), leg [ted leg]) ted) +:: +:::: +:: ++inverse: inverse of change in context. +:: +:: for any sole state +>, obeys +:: +:: =(+> (apply:(apply a) (inverse a))) +:: +++ inverse :: relative inverse + |= ted=sole-edit + ^- sole-edit + =. ted ?.(?=([%mor * ~] ted) ted i.p.ted) + ?- -.ted + %del [%ins p.ted (snag p.ted buf)] + %ins [%del p.ted] + %mor :- %mor + %- flop + |- ^- (list sole-edit) + ?~ p.ted ~ + :- ^$(ted i.p.ted) + $(p.ted t.p.ted, +>.^$ (apply i.p.ted)) + %nop [%nop ~] + %set [%set buf] + == +:: +++ receive :: naturalize event + |= sole-change + ^- [sole-edit sole-share] + ?. &(=(his.ler his.ven) (lte own.ler own.ven)) + ~| [%receive-sync his+[his.ler his.ven] own+[own.ler own.ven]] + !! + ?> &(=(his.ler his.ven) (lte own.ler own.ven)) + ?> |(!=(own.ler own.ven) =(`@`0 haw) =(haw (sham buf))) + =. leg (scag (sub own.ven own.ler) leg) + :: ~? !=(own.ler own.ven) [%miss-leg leg] + =+ dat=(transmute [%mor leg] ted) + :: ~? !=(~ leg) [%transmute from+ted to+dat ~] + [dat abet:(apply(his.ven +(his.ven)) dat)] +:: +++ remit :: conditional accept + |= [cal=sole-change ask=$-((list @c) ?)] + ^- [(unit sole-change) sole-share] + =+ old=buf + =^ dat +>+<.$ (receive cal) + ?: (ask buf) + [~ +>+<.$] + =^ lic +>+<.$ (transmit (inverse(buf old) dat)) + [`lic +>+<.$] +:: +++ transmit :: outgoing change + |= ted=sole-edit + ^- [sole-change sole-share] + [[[his.ven own.ven] (sham buf) ted] (commit ted)] +:: +++ transceive :: receive and invert + |= sole-change + ^- [sole-edit sole-share] + =+ old=buf + =^ dat +>+<.$ (receive +<.$) + [(inverse(buf old) dat) +>+<.$] +:: +++ transpose :: adjust position + |= pos=@ud + =+ dat=(transmute [%mor leg] [%ins pos `@c`0]) + ?> ?=(%ins -.dat) + p.dat +-- diff --git a/pkg/base-dev/lib/strand.hoon b/pkg/base-dev/lib/strand.hoon new file mode 100644 index 000000000..d49260225 --- /dev/null +++ b/pkg/base-dev/lib/strand.hoon @@ -0,0 +1,188 @@ +|% ++$ card card:agent:gall ++$ input + $% [%poke =cage] + [%sign =wire =sign-arvo] + [%agent =wire =sign:agent:gall] + [%watch =path] + == ++$ strand-input [=bowl in=(unit input)] ++$ tid @tatid ++$ bowl + $: our=ship + src=ship + tid=tid + mom=(unit tid) + wex=boat:gall + sup=bitt:gall + eny=@uvJ + now=@da + byk=beak + == +:: +:: cards: cards to send immediately. These will go out even if a +:: later stage of the computation fails, so they shouldn't have +:: any semantic effect on the rest of the system. +:: Alternately, they may record an entry in contracts with +:: enough information to undo the effect if the computation +:: fails. +:: wait: don't move on, stay here. The next sign should come back +:: to this same callback. +:: skip: didn't expect this input; drop it down to be handled +:: elsewhere +:: cont: continue computation with new callback. +:: fail: abort computation; don't send effects +:: done: finish computation; send effects +:: +++ strand-output-raw + |* a=mold + $~ [~ %done *a] + $: cards=(list card) + $= next + $% [%wait ~] + [%skip ~] + [%cont self=(strand-form-raw a)] + [%fail err=(pair term tang)] + [%done value=a] + == + == +:: +++ strand-form-raw + |* a=mold + $-(strand-input (strand-output-raw a)) +:: +:: Abort strand computation with error message +:: +++ strand-fail + |= err=(pair term tang) + |= strand-input + [~ %fail err] +:: +:: Asynchronous transcaction monad. +:: +:: Combo of four monads: +:: - Reader on input +:: - Writer on card +:: - Continuation +:: - Exception +:: +++ strand + |* a=mold + |% + ++ output (strand-output-raw a) + :: + :: Type of an strand computation. + :: + ++ form (strand-form-raw a) + :: + :: Monadic pure. Identity computation for bind. + :: + ++ pure + |= arg=a + ^- form + |= strand-input + [~ %done arg] + :: + :: Monadic bind. Combines two computations, associatively. + :: + ++ bind + |* b=mold + |= [m-b=(strand-form-raw b) fun=$-(b form)] + ^- form + |= input=strand-input + =/ b-res=(strand-output-raw b) + (m-b input) + ^- output + :- cards.b-res + ?- -.next.b-res + %wait [%wait ~] + %skip [%skip ~] + %cont [%cont ..$(m-b self.next.b-res)] + %fail [%fail err.next.b-res] + %done [%cont (fun value.next.b-res)] + == + :: + :: The strand monad must be evaluted in a particular way to maintain + :: its monadic character. +take:eval implements this. + :: + ++ eval + |% + :: Indelible state of a strand + :: + +$ eval-form + $: =form + == + :: + :: Convert initial form to eval-form + :: + ++ from-form + |= =form + ^- eval-form + form + :: + :: The cases of results of +take + :: + +$ eval-result + $% [%next ~] + [%fail err=(pair term tang)] + [%done value=a] + == + :: + ++ validate-mark + |= [in=* =mark =bowl] + ^- cage + =+ .^ =dais:clay %cb + /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[mark] + == + =/ res (mule |.((vale.dais in))) + ?: ?=(%| -.res) + ~|(%spider-mark-fail (mean leaf+"spider: ames vale fail {}" p.res)) + [mark p.res] + :: + :: Take a new sign and run the strand against it + :: + ++ take + :: cards: accumulate throughout recursion the cards to be + :: produced now + =| cards=(list card) + |= [=eval-form =strand-input] + ^- [[(list card) =eval-result] _eval-form] + =* take-loop $ + =. in.strand-input + ?~ in.strand-input ~ + =/ in u.in.strand-input + ?. ?=(%agent -.in) `in + ?. ?=(%fact -.sign.in) `in + :: + :- ~ + :+ %agent wire.in + [%fact (validate-mark q.q.cage.sign.in p.cage.sign.in bowl.strand-input)] + :: run the strand callback + :: + =/ =output (form.eval-form strand-input) + :: add cards to cards + :: + =. cards + %+ welp + cards + :: XX add tag to wires? + cards.output + :: case-wise handle next steps + :: + ?- -.next.output + %wait [[cards %next ~] eval-form] + %skip [[cards %next ~] eval-form] + %fail [[cards %fail err.next.output] eval-form] + %done [[cards %done value.next.output] eval-form] + %cont + :: recurse to run continuation with initialization input + :: + %_ take-loop + form.eval-form self.next.output + strand-input [bowl.strand-input ~] + == + == + -- + -- +-- +:: diff --git a/pkg/base-dev/lib/strandio.hoon b/pkg/base-dev/lib/strandio.hoon new file mode 100644 index 000000000..a83d5ae0e --- /dev/null +++ b/pkg/base-dev/lib/strandio.hoon @@ -0,0 +1,761 @@ +/- spider +/+ libstrand=strand +=, strand=strand:libstrand +=, strand-fail=strand-fail:libstrand +|% +++ send-raw-cards + |= cards=(list =card:agent:gall) + =/ m (strand ,~) + ^- form:m + |= strand-input:strand + [cards %done ~] +:: +++ send-raw-card + |= =card:agent:gall + =/ m (strand ,~) + ^- form:m + (send-raw-cards card ~) +:: +++ ignore + |= tin=strand-input:strand + `[%fail %ignore ~] +:: +++ get-bowl + =/ m (strand ,bowl:strand) + ^- form:m + |= tin=strand-input:strand + `[%done bowl.tin] +:: +++ get-beak + =/ m (strand ,beak) + ^- form:m + |= tin=strand-input:strand + `[%done [our q.byk da+now]:bowl.tin] +:: +++ get-time + =/ m (strand ,@da) + ^- form:m + |= tin=strand-input:strand + `[%done now.bowl.tin] +:: +++ get-our + =/ m (strand ,ship) + ^- form:m + |= tin=strand-input:strand + `[%done our.bowl.tin] +:: +++ get-entropy + =/ m (strand ,@uvJ) + ^- form:m + |= tin=strand-input:strand + `[%done eny.bowl.tin] +:: +:: Convert skips to %ignore failures. +:: +:: This tells the main loop to try the next handler. +:: +++ handle + |* a=mold + =/ m (strand ,a) + |= =form:m + ^- form:m + |= tin=strand-input:strand + =/ res (form tin) + =? next.res ?=(%skip -.next.res) + [%fail %ignore ~] + res +:: +:: Wait for a poke with a particular mark +:: +++ take-poke + |= =mark + =/ m (strand ,vase) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %poke @ *] + ?. =(mark p.cage.u.in.tin) + `[%skip ~] + `[%done q.cage.u.in.tin] + == +:: +:: +:: +++ take-sign-arvo + =/ m (strand ,[wire sign-arvo]) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign *] + `[%done [wire sign-arvo]:u.in.tin] + == +:: +:: Wait for a subscription update on a wire +:: +++ take-fact-prefix + |= =wire + =/ m (strand ,[path cage]) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %fact *] + ?. =(watch+wire (scag +((lent wire)) wire.u.in.tin)) + `[%skip ~] + `[%done (slag (lent wire) wire.u.in.tin) cage.sign.u.in.tin] + == +:: +:: Wait for a subscription update on a wire +:: +++ take-fact + |= =wire + =/ m (strand ,cage) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %fact *] + ?. =(watch+wire wire.u.in.tin) + `[%skip ~] + `[%done cage.sign.u.in.tin] + == +:: +:: Wait for a subscription close +:: +++ take-kick + |= =wire + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %kick *] + ?. =(watch+wire wire.u.in.tin) + `[%skip ~] + `[%done ~] + == +:: +++ echo + =/ m (strand ,~) + ^- form:m + %- (main-loop ,~) + :~ |= ~ + ^- form:m + ;< =vase bind:m ((handle ,vase) (take-poke %echo)) + =/ message=tape !<(tape vase) + %- (slog leaf+"{message}..." ~) + ;< ~ bind:m (sleep ~s2) + %- (slog leaf+"{message}.." ~) + (pure:m ~) + :: + |= ~ + ^- form:m + ;< =vase bind:m ((handle ,vase) (take-poke %over)) + %- (slog leaf+"over..." ~) + (pure:m ~) + == +:: +++ take-watch + =/ m (strand ,path) + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %watch *] + `[%done path.u.in.tin] + == +:: +++ take-wake + |= until=(unit @da) + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign [%wait @ ~] %behn %wake *] + ?. |(?=(~ until) =(`u.until (slaw %da i.t.wire.u.in.tin))) + `[%skip ~] + ?~ error.sign-arvo.u.in.tin + `[%done ~] + `[%fail %timer-error u.error.sign-arvo.u.in.tin] + == +:: +++ take-poke-ack + |= =wire + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %poke-ack *] + ?. =(wire wire.u.in.tin) + `[%skip ~] + ?~ p.sign.u.in.tin + `[%done ~] + `[%fail %poke-fail u.p.sign.u.in.tin] + == +:: +++ take-watch-ack + |= =wire + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %watch-ack *] + ?. =(watch+wire wire.u.in.tin) + `[%skip ~] + ?~ p.sign.u.in.tin + `[%done ~] + `[%fail %watch-ack-fail u.p.sign.u.in.tin] + == +:: +++ poke + |= [=dock =cage] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass /poke %agent dock %poke cage] + ;< ~ bind:m (send-raw-card card) + (take-poke-ack /poke) +:: +++ raw-poke + |= [=dock =cage] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass /poke %agent dock %poke cage] + ;< ~ bind:m (send-raw-card card) + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ + `[%wait ~] + :: + [~ %agent * %poke-ack *] + ?. =(/poke wire.u.in.tin) + `[%skip ~] + `[%done ~] + == +:: +++ raw-poke-our + |= [app=term =cage] + =/ m (strand ,~) + ^- form:m + ;< =bowl:spider bind:m get-bowl + (raw-poke [our.bowl app] cage) +:: +++ poke-our + |= [=term =cage] + =/ m (strand ,~) + ^- form:m + ;< our=@p bind:m get-our + (poke [our term] cage) +:: +++ watch + |= [=wire =dock =path] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass watch+wire %agent dock %watch path] + ;< ~ bind:m (send-raw-card card) + (take-watch-ack wire) +:: +++ watch-one + |= [=wire =dock =path] + =/ m (strand ,cage) + ^- form:m + ;< ~ bind:m (watch wire dock path) + ;< =cage bind:m (take-fact wire) + ;< ~ bind:m (take-kick wire) + (pure:m cage) +:: +++ watch-our + |= [=wire =term =path] + =/ m (strand ,~) + ^- form:m + ;< our=@p bind:m get-our + (watch wire [our term] path) +:: +++ scry + |* [=mold =path] + =/ m (strand ,mold) + ^- form:m + ?> ?=(^ path) + ?> ?=(^ t.path) + ;< =bowl:spider bind:m get-bowl + %- pure:m + .^(mold i.path (scot %p our.bowl) i.t.path (scot %da now.bowl) t.t.path) +:: +++ leave + |= [=wire =dock] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass watch+wire %agent dock %leave ~] + (send-raw-card card) +:: +++ leave-our + |= [=wire =term] + =/ m (strand ,~) + ^- form:m + ;< our=@p bind:m get-our + (leave wire [our term]) +:: +++ rewatch + |= [=wire =dock =path] + =/ m (strand ,~) + ;< ~ bind:m ((handle ,~) (take-kick wire)) + ;< ~ bind:m (flog-text "rewatching {} {}") + ;< ~ bind:m (watch wire dock path) + (pure:m ~) +:: +++ wait + |= until=@da + =/ m (strand ,~) + ^- form:m + ;< ~ bind:m (send-wait until) + (take-wake `until) +:: +++ sleep + |= for=@dr + =/ m (strand ,~) + ^- form:m + ;< now=@da bind:m get-time + (wait (add now for)) +:: +++ send-wait + |= until=@da + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall + [%pass /wait/(scot %da until) %arvo %b %wait until] + (send-raw-card card) +:: +++ map-err + |* computation-result=mold + =/ m (strand ,computation-result) + |= [f=$-([term tang] [term tang]) computation=form:m] + ^- form:m + |= tin=strand-input:strand + =* loop $ + =/ c-res (computation tin) + ?: ?=(%cont -.next.c-res) + c-res(self.next ..loop(computation self.next.c-res)) + ?. ?=(%fail -.next.c-res) + c-res + c-res(err.next (f err.next.c-res)) +:: +++ set-timeout + |* computation-result=mold + =/ m (strand ,computation-result) + |= [time=@dr computation=form:m] + ^- form:m + ;< now=@da bind:m get-time + =/ when (add now time) + =/ =card:agent:gall + [%pass /timeout/(scot %da when) %arvo %b %wait when] + ;< ~ bind:m (send-raw-card card) + |= tin=strand-input:strand + =* loop $ + ?: ?& ?=([~ %sign [%timeout @ ~] %behn %wake *] in.tin) + =((scot %da when) i.t.wire.u.in.tin) + == + `[%fail %timeout ~] + =/ c-res (computation tin) + ?: ?=(%cont -.next.c-res) + c-res(self.next ..loop(computation self.next.c-res)) + ?: ?=(%done -.next.c-res) + =/ =card:agent:gall + [%pass /timeout/(scot %da when) %arvo %b %rest when] + c-res(cards [card cards.c-res]) + c-res +:: +++ send-request + |= =request:http + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass /request %arvo %i %request request *outbound-config:iris) +:: +++ send-cancel-request + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass /request %arvo %i %cancel-request ~) +:: +++ take-client-response + =/ m (strand ,client-response:iris) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + :: + [~ %sign [%request ~] %iris %http-response %cancel *] + ::NOTE iris does not (yet?) retry after cancel, so it means failure + :- ~ + :+ %fail + %http-request-cancelled + ['http request was cancelled by the runtime']~ + :: + [~ %sign [%request ~] %iris %http-response %finished *] + `[%done client-response.sign-arvo.u.in.tin] + == +:: +:: Wait until we get an HTTP response or cancelation and unset contract +:: +++ take-maybe-sigh + =/ m (strand ,(unit httr:eyre)) + ^- form:m + ;< rep=(unit client-response:iris) bind:m + take-maybe-response + ?~ rep + (pure:m ~) + :: XX s/b impossible + :: + ?. ?=(%finished -.u.rep) + (pure:m ~) + (pure:m (some (to-httr:iris +.u.rep))) +:: +++ take-maybe-response + =/ m (strand ,(unit client-response:iris)) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign [%request ~] %iris %http-response %cancel *] + `[%done ~] + [~ %sign [%request ~] %iris %http-response %finished *] + `[%done `client-response.sign-arvo.u.in.tin] + == +:: +++ extract-body + |= =client-response:iris + =/ m (strand ,cord) + ^- form:m + ?> ?=(%finished -.client-response) + %- pure:m + ?~ full-file.client-response '' + q.data.u.full-file.client-response + +:: +++ fetch-cord + |= url=tape + =/ m (strand ,cord) + ^- form:m + =/ =request:http [%'GET' (crip url) ~ ~] + ;< ~ bind:m (send-request request) + ;< =client-response:iris bind:m take-client-response + (extract-body client-response) +:: +++ fetch-json + |= url=tape + =/ m (strand ,json) + ^- form:m + ;< =cord bind:m (fetch-cord url) + =/ json=(unit json) (de-json:html cord) + ?~ json + (strand-fail %json-parse-error ~) + (pure:m u.json) +:: +++ hiss-request + |= =hiss:eyre + =/ m (strand ,(unit httr:eyre)) + ^- form:m + ;< ~ bind:m (send-request (hiss-to-request:html hiss)) + take-maybe-sigh +:: +:: +build-file: build the source file at the specified $beam +:: +++ build-file + |= [[=ship =desk =case] =spur] + =* arg +< + =/ m (strand ,(unit vase)) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %a case spur) + ?~ riot + (pure:m ~) + ?> =(%vase p.r.u.riot) + (pure:m (some !<(vase q.r.u.riot))) +:: +build-mark: build a mark definition to a $dais +:: +++ build-mark + |= [[=ship =desk =case] mak=mark] + =* arg +< + =/ m (strand ,dais:clay) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %b case /[mak]) + ?~ riot + (strand-fail %build-mark >arg< ~) + ?> =(%dais p.r.u.riot) + (pure:m !<(dais:clay q.r.u.riot)) +:: +build-tube: build a mark conversion gate ($tube) +:: +++ build-tube + |= [[=ship =desk =case] =mars:clay] + =* arg +< + =/ m (strand ,tube:clay) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %c case /[a.mars]/[b.mars]) + ?~ riot + (strand-fail %build-tube >arg< ~) + ?> =(%tube p.r.u.riot) + (pure:m !<(tube:clay q.r.u.riot)) +:: +:: +build-nave: build a mark definition to a $nave +:: +++ build-nave + |= [[=ship =desk =case] mak=mark] + =* arg +< + =/ m (strand ,vase) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %e case /[mak]) + ?~ riot + (strand-fail %build-nave >arg< ~) + ?> =(%nave p.r.u.riot) + (pure:m q.r.u.riot) +:: +build-cast: build a mark conversion gate (static) +:: +++ build-cast + |= [[=ship =desk =case] =mars:clay] + =* arg +< + =/ m (strand ,vase) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %f case /[a.mars]/[b.mars]) + ?~ riot + (strand-fail %build-cast >arg< ~) + ?> =(%cast p.r.u.riot) + (pure:m q.r.u.riot) +:: +:: Read from Clay +:: +++ warp + |= [=ship =riff:clay] + =/ m (strand ,riot:clay) + ;< ~ bind:m (send-raw-card %pass /warp %arvo %c %warp ship riff) + (take-writ /warp) +:: +++ read-file + |= [[=ship =desk =case:clay] =spur] + =* arg +< + =/ m (strand ,cage) + ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur) + ?~ riot + (strand-fail %read-file >arg< ~) + (pure:m r.u.riot) +:: +++ check-for-file + |= [[=ship =desk =case:clay] =spur] + =/ m (strand ,?) + ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur) + (pure:m ?=(^ riot)) +:: +++ list-tree + |= [[=ship =desk =case:clay] =spur] + =* arg +< + =/ m (strand ,(list path)) + ;< =riot:clay bind:m (warp ship desk ~ %sing %t case spur) + ?~ riot + (strand-fail %list-tree >arg< ~) + (pure:m !<((list path) q.r.u.riot)) +:: +:: Take Clay read result +:: +++ take-writ + |= =wire + =/ m (strand ,riot:clay) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign * ?(%behn %clay) %writ *] + ?. =(wire wire.u.in.tin) + `[%skip ~] + `[%done +>.sign-arvo.u.in.tin] + == +:: +check-online: require that peer respond before timeout +:: +++ check-online + |= [who=ship lag=@dr] + =/ m (strand ,~) + ^- form:m + %+ (map-err ,~) |=(* [%offline *tang]) + %+ (set-timeout ,~) lag + ;< ~ bind:m + (poke [who %hood] %helm-hi !>(~)) + (pure:m ~) +:: +:: Queue on skip, try next on fail %ignore +:: +++ main-loop + |* a=mold + =/ m (strand ,~) + =/ m-a (strand ,a) + =| queue=(qeu (unit input:strand)) + =| active=(unit [in=(unit input:strand) =form:m-a forms=(list $-(a form:m-a))]) + =| state=a + |= forms=(lest $-(a form:m-a)) + ^- form:m + |= tin=strand-input:strand + =* top `form:m`..$ + =. queue (~(put to queue) in.tin) + |^ (continue bowl.tin) + :: + ++ continue + |= =bowl:strand + ^- output:m + ?> =(~ active) + ?: =(~ queue) + `[%cont top] + =^ in=(unit input:strand) queue ~(get to queue) + ^- output:m + =. active `[in (i.forms state) t.forms] + ^- output:m + (run bowl in) + :: + ++ run + ^- form:m + |= tin=strand-input:strand + ^- output:m + ?> ?=(^ active) + =/ res (form.u.active tin) + =/ =output:m + ?- -.next.res + %wait `[%wait ~] + %skip `[%cont ..$(queue (~(put to queue) in.tin))] + %cont `[%cont ..$(active `[in.u.active self.next.res forms.u.active])] + %done (continue(active ~, state value.next.res) bowl.tin) + %fail + ?: &(?=(^ forms.u.active) ?=(%ignore p.err.next.res)) + %= $ + active `[in.u.active (i.forms.u.active state) t.forms.u.active] + in.tin in.u.active + == + `[%fail err.next.res] + == + [(weld cards.res cards.output) next.output] + -- +:: +++ retry + |* result=mold + |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))] + =/ m (strand ,result) + =| try=@ud + |- ^- form:m + =* loop $ + ?: =(crash-after `try) + (strand-fail %retry-too-many ~) + ;< ~ bind:m (backoff try ~m1) + ;< res=(unit result) bind:m computation + ?^ res + (pure:m u.res) + loop(try +(try)) +:: +++ backoff + |= [try=@ud limit=@dr] + =/ m (strand ,~) + ^- form:m + ;< eny=@uvJ bind:m get-entropy + %- sleep + %+ min limit + ?: =(0 try) ~s0 + %+ add + (mul ~s1 (bex (dec try))) + (mul ~s0..0001 (~(rad og eny) 1.000)) +:: +:: ---- +:: +:: Output +:: +++ flog + |= =flog:dill + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass / %arvo %d %flog flog) +:: +++ flog-text + |= =tape + =/ m (strand ,~) + ^- form:m + (flog %text tape) +:: +++ flog-tang + |= =tang + =/ m (strand ,~) + ^- form:m + =/ =wall + (zing (turn (flop tang) (cury wash [0 80]))) + |- ^- form:m + =* loop $ + ?~ wall + (pure:m ~) + ;< ~ bind:m (flog-text i.wall) + loop(wall t.wall) +:: +++ trace + |= =tang + =/ m (strand ,~) + ^- form:m + (pure:m ((slog tang) ~)) +:: +++ app-message + |= [app=term =cord =tang] + =/ m (strand ,~) + ^- form:m + =/ msg=tape :(weld (trip app) ": " (trip cord)) + ;< ~ bind:m (flog-text msg) + (flog-tang tang) +:: +:: ---- +:: +:: Handle domains +:: +++ install-domain + |= =turf + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass / %arvo %e %rule %turf %put turf) +:: +:: ---- +:: +:: Threads +:: +++ start-thread + |= file=term + =/ m (strand ,tid:spider) + ;< =bowl:spider bind:m get-bowl + (start-thread-with-args byk.bowl file *vase) +:: +++ start-thread-with-args + |= [=beak file=term args=vase] + =/ m (strand ,tid:spider) + ^- form:m + ;< =bowl:spider bind:m get-bowl + =/ tid + (scot %ta (cat 3 (cat 3 'strand_' file) (scot %uv (sham file eny.bowl)))) + =/ poke-vase !>([`tid.bowl `tid beak file args]) + ;< ~ bind:m (poke-our %spider %spider-start poke-vase) + ;< ~ bind:m (sleep ~s0) :: wait for thread to start + (pure:m tid) +:: ++$ thread-result + (each vase [term tang]) +:: +++ await-thread + |= [file=term args=vase] + =/ m (strand ,thread-result) + ^- form:m + ;< =bowl:spider bind:m get-bowl + =/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl)))) + =/ poke-vase !>([`tid.bowl `tid file args]) + ;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid]) + ;< ~ bind:m (poke-our %spider %spider-start poke-vase) + ;< ~ bind:m (sleep ~s0) :: wait for thread to start + ;< =cage bind:m (take-fact /awaiting/[tid]) + ;< ~ bind:m (take-kick /awaiting/[tid]) + ?+ p.cage ~|([%strange-thread-result p.cage file tid] !!) + %thread-done (pure:m %& q.cage) + %thread-fail (pure:m %| !<([term tang] q.cage)) + == +-- diff --git a/pkg/base-dev/lib/test.hoon b/pkg/base-dev/lib/test.hoon new file mode 100644 index 000000000..7e4eca44a --- /dev/null +++ b/pkg/base-dev/lib/test.hoon @@ -0,0 +1,50 @@ +:: testing utilities meant to be directly used from files in %/tests +:: +|% +:: +expect-eq: compares :expected and :actual and pretty-prints the result +:: +++ expect-eq + |= [expected=vase actual=vase] + ^- tang + :: + =| result=tang + :: + =? result !=(q.expected q.actual) + %+ weld result + ^- tang + :~ [%palm [": " ~ ~ ~] [leaf+"expected" (sell expected) ~]] + [%palm [": " ~ ~ ~] [leaf+"actual" (sell actual) ~]] + == + :: + =? result !(~(nest ut p.actual) | p.expected) + %+ weld result + ^- tang + :~ :+ %palm [": " ~ ~ ~] + :~ [%leaf "failed to nest"] + (~(dunk ut p.actual) %actual) + (~(dunk ut p.expected) %expected) + == == + result +:: +expect: compares :actual to %.y and pretty-prints anything else +:: +++ expect + |= actual=vase + (expect-eq !>(%.y) actual) +:: +expect-fail: kicks a trap, expecting crash. pretty-prints if succeeds +:: +++ expect-fail + |= a=(trap) + ^- tang + =/ b (mule a) + ?- -.b + %| ~ + %& [leaf+"expected failure - succeeded" ~] + == +:: +category: prepends a name to an error result; passes successes unchanged +:: +++ category + |= [a=tape b=tang] ^- tang + ?: =(~ b) ~ :: test OK + :- leaf+"in: '{a}'" + (turn b |=(c=tank rose+[~ " " ~]^~[c])) +-- diff --git a/pkg/base-dev/lib/verb.hoon b/pkg/base-dev/lib/verb.hoon new file mode 100644 index 000000000..2737addfc --- /dev/null +++ b/pkg/base-dev/lib/verb.hoon @@ -0,0 +1,105 @@ +:: Print what your agent is doing. +:: +/- verb +:: +|= [loud=? =agent:gall] +=| bowl-print=_| +^- agent:gall +|^ !. +|_ =bowl:gall ++* this . + ag ~(. agent bowl) +:: +++ on-init + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-init")) + =^ cards agent on-init:ag + [[(emit-event %on-init ~) cards] this] +:: +++ on-save + ^- vase + %- (print bowl |.("{}: on-save")) + on-save:ag +:: +++ on-load + |= old-state=vase + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-load")) + =^ cards agent (on-load:ag old-state) + [[(emit-event %on-load ~) cards] this] +:: +++ on-poke + |= [=mark =vase] + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-poke with mark {}")) + ?: ?=(%verb mark) + ?- !<(?(%loud %bowl) vase) + %loud `this(loud !loud) + %bowl `this(bowl-print !bowl-print) + == + =^ cards agent (on-poke:ag mark vase) + [[(emit-event %on-poke mark) cards] this] +:: +++ on-watch + |= =path + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-watch on path {}")) + =^ cards agent + ?: ?=([%verb %events ~] path) + [~ agent] + (on-watch:ag path) + [[(emit-event %on-watch path) cards] this] +:: +++ on-leave + |= =path + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-leave on path {}")) + ?: ?=([%verb %event ~] path) + [~ this] + =^ cards agent (on-leave:ag path) + [[(emit-event %on-leave path) cards] this] +:: +++ on-peek + |= =path + ^- (unit (unit cage)) + %- (print bowl |.("{}: on-peek on path {}")) + (on-peek:ag path) +:: +++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-agent on wire {}, {<-.sign>}")) + =^ cards agent (on-agent:ag wire sign) + [[(emit-event %on-agent wire -.sign) cards] this] +:: +++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + %- %+ print bowl |. + "{}: on-arvo on wire {}, {<[- +<]:sign-arvo>}" + =^ cards agent (on-arvo:ag wire sign-arvo) + [[(emit-event %on-arvo wire [- +<]:sign-arvo) cards] this] +:: +++ on-fail + |= [=term =tang] + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-fail with term {}")) + =^ cards agent (on-fail:ag term tang) + [[(emit-event %on-fail term) cards] this] +-- +:: +++ print + |= [=bowl:gall render=(trap tape)] + ^+ same + =? . bowl-print + %- (slog >bowl< ~) + . + ?. loud same + %- (slog [%leaf $:render] ~) + same +:: +++ emit-event + |= =event:verb + ^- card:agent:gall + [%give %fact ~[/verb/events] %verb-event !>(event)] +-- diff --git a/pkg/base-dev/mar/belt.hoon b/pkg/base-dev/mar/belt.hoon new file mode 100644 index 000000000..1c5a6e1ea --- /dev/null +++ b/pkg/base-dev/mar/belt.hoon @@ -0,0 +1,29 @@ +:: belt: runtime belt structure +:: +|_ =belt:dill +++ grad %noun +:: +grab: convert from +:: +++ grab + |% + ++ noun belt:dill + ++ json + ^- $-(^json belt:dill) + =, dejs:format + %- of + :~ aro+(su (perk %d %l %r %u ~)) + bac+ul + ctl+(cu taft so) + del+ul + met+(cu taft so) + ret+ul + txt+(ar (cu taft so)) + == + -- +:: +grow: convert to +:: +++ grow + |% + ++ noun belt + -- +-- diff --git a/pkg/base-dev/mar/bill.hoon b/pkg/base-dev/mar/bill.hoon new file mode 100644 index 000000000..76cef343a --- /dev/null +++ b/pkg/base-dev/mar/bill.hoon @@ -0,0 +1,34 @@ +|_ bil=(list dude:gall) +++ grow + |% + ++ mime `^mime`[/text/x-bill (as-octs:mimes:html hoon)] + ++ noun bil + ++ hoon + ^- @t + |^ (crip (of-wall:format (wrap-lines (spit-duz bil)))) + :: + ++ wrap-lines + |= taz=wall + ^- wall + ?~ taz ["~"]~ + :- (weld ":~ " i.taz) + %- snoc :_ "==" + (turn t.taz |=(t=tape (weld " " t))) + :: + ++ spit-duz + |= duz=(list dude:gall) + ^- wall + (turn duz |=(=dude:gall ['%' (trip dude)])) + -- + ++ txt (to-wain:format hoon) + -- +++ grab + |% + ++ noun (list dude:gall) + ++ mime + |= [=mite len=@ud tex=@] + ~_ tex + !<((list dude:gall) (slap !>(~) (ream tex))) + -- +++ grad %noun +-- diff --git a/pkg/base-dev/mar/blit.hoon b/pkg/base-dev/mar/blit.hoon new file mode 100644 index 000000000..4c23c5705 --- /dev/null +++ b/pkg/base-dev/mar/blit.hoon @@ -0,0 +1,61 @@ +:: blit: runtime blit structure +:: +|_ =blit:dill +++ grad %noun +:: +grab: convert from +:: +++ grab + |% + ++ noun blit:dill + -- +:: +grow: convert to +:: +++ grow + |% + ++ noun blit + ++ json + ^- ^json + =, enjs:format + %+ frond -.blit + ?- -.blit + %bel b+& + %clr b+& + %hop (numb p.blit) + %lin a+(turn p.blit |=(c=@c s+(tuft c))) + %mor b+& + %url s+p.blit + :: + %sag + %- pairs + :~ 'path'^(path p.blit) + 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit))) + == + :: + %sav + %- pairs + :~ 'path'^(path p.blit) + 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit)) + == + :: + %klr + :- %a + %+ turn p.blit + |= [=stye text=(list @c)] + %- pairs + :~ 'text'^a+(turn text |=(c=@c s+(tuft c))) + :: + :- 'stye' + %- pairs + |^ :~ 'back'^(color p.q.stye) + 'fore'^(color q.q.stye) + 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d))) + == + ++ color + |= =tint + ?@ tint ?~(tint ~ s+tint) + s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint))) + -- + == + == + -- +-- diff --git a/pkg/base-dev/mar/hoon.hoon b/pkg/base-dev/mar/hoon.hoon new file mode 100644 index 000000000..b6f590649 --- /dev/null +++ b/pkg/base-dev/mar/hoon.hoon @@ -0,0 +1,49 @@ +:::: /hoon/hoon/mar + :: +/? 310 +:: +=, eyre +|_ own=@t +:: +++ grow :: convert to + |% + ++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime + ++ elem :: convert to %html + ;div:pre(urb_codemirror "", mode "hoon"):"{(trip own)}" + :: =+ gen-id="src-{<`@ui`(mug own)>}" + :: ;div + :: ;textarea(id "{gen-id}"):"{(trip own)}" + :: ;script:""" + :: CodeMirror.fromTextArea( + :: window[{}], + :: \{lineNumbers:true, readOnly:true} + :: ) + :: """ + :: == + ++ hymn + :: ;html:(head:title:"Source" "+{elem}") + ;html + ;head + ;title:"Source" + ;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js"; + ;script@"/lib/syntax/hoon.js"; + ;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/". + "codemirror/4.3.0/codemirror.min.css"); + ;link/"/lib/syntax/codemirror.css"(rel "stylesheet"); + == + ;body + ;textarea#src:"{(trip own)}" + ;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})' + == + == + ++ txt + (to-wain:format own) + -- +++ grab + |% :: convert from + ++ mime |=([p=mite q=octs] q.q) + ++ noun @t :: clam from %noun + ++ txt of-wain:format + -- +++ grad %txt +-- diff --git a/pkg/base-dev/mar/htm.hoon b/pkg/base-dev/mar/htm.hoon new file mode 100644 index 000000000..a40a432dd --- /dev/null +++ b/pkg/base-dev/mar/htm.hoon @@ -0,0 +1,15 @@ +:: +:::: /hoon/htm/mar + :: +/? 310 +|_ own=manx +:: +++ grad %noun +++ grow :: convert to + |% + ++ noun own + ++ hymn own + -- +++ grab |% :: convert from + ++ noun manx :: clam from %noun +-- -- diff --git a/pkg/base-dev/mar/html.hoon b/pkg/base-dev/mar/html.hoon new file mode 100644 index 000000000..203d75f61 --- /dev/null +++ b/pkg/base-dev/mar/html.hoon @@ -0,0 +1,22 @@ +:: +:::: /hoon/html/mar + :: +/? 310 + :: +:::: compute + :: +=, html +|_ htm=@t +++ grow :: convert to + ^? + |% :: + ++ mime [/text/html (met 3 htm) htm] :: to %mime + ++ hymn (need (de-xml htm)) :: to %hymn + -- :: +++ grab ^? + |% :: convert from + ++ noun @t :: clam from %noun + ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/httr.hoon b/pkg/base-dev/mar/httr.hoon new file mode 100644 index 000000000..bbac8f990 --- /dev/null +++ b/pkg/base-dev/mar/httr.hoon @@ -0,0 +1,25 @@ +:: +:::: /hoon/httr/mar + :: +/? 310 +:: +=, eyre +=, format +=, html +|_ hit=httr +++ grad %noun +++ grow |% ++ wall (turn wain trip) + ++ wain (to-wain cord) + ++ json (need (de-json cord)) + ++ cord q:octs + ++ noun hit + ++ octs + ~| hit + ?> =(2 (div p.hit 100)) + (need r.hit) + -- +++ grab :: convert from + |% + ++ noun httr :: clam from %noun + -- +-- diff --git a/pkg/base-dev/mar/hymn.hoon b/pkg/base-dev/mar/hymn.hoon new file mode 100644 index 000000000..cf01508ea --- /dev/null +++ b/pkg/base-dev/mar/hymn.hoon @@ -0,0 +1,17 @@ +:: +:::: /hoon/hymn/mar + :: +/? 310 +=, mimes:html +=, html +|_ own=manx +:: +++ grad %noun +++ grow :: convert to + |% + ++ html (crip (en-xml own)) :: convert to %html + ++ mime [/text/html (as-octs html)] :: convert to %mime + -- +++ grab |% :: convert from + ++ noun manx :: clam from %noun +-- -- diff --git a/pkg/base-dev/mar/js.hoon b/pkg/base-dev/mar/js.hoon new file mode 100644 index 000000000..e8fbe7701 --- /dev/null +++ b/pkg/base-dev/mar/js.hoon @@ -0,0 +1,22 @@ +:: +:::: /hoon/js/mar + :: +/? 310 +:: +=, eyre +|_ mud=@ +++ grow + |% + ++ mime [/application/javascript (as-octs:mimes:html (@t mud))] + ++ elem ;script + ;- (trip (@t mud)) + == + ++ hymn ;html:(head:"+{elem}" body) + -- +++ grab + |% :: convert from + ++ mime |=([p=mite q=octs] (@t q.q)) + ++ noun cord :: clam from %noun + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/json.hoon b/pkg/base-dev/mar/json.hoon new file mode 100644 index 000000000..506b70835 --- /dev/null +++ b/pkg/base-dev/mar/json.hoon @@ -0,0 +1,26 @@ +:: +:::: /hoon/json/mar + :: +/? 310 + :: +:::: compute + :: +=, eyre +=, format +=, html +|_ jon=json +:: +++ grow :: convert to + |% + ++ mime [/application/json (as-octs:mimes -:txt)] :: convert to %mime + ++ txt [(crip (en-json jon))]~ + -- +++ grab + |% :: convert from + ++ mime |=([p=mite q=octs] (fall (rush (@t q.q) apex:de-json) *json)) + ++ noun json :: clam from %noun + ++ numb numb:enjs + ++ time time:enjs + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/json/rpc/response.hoon b/pkg/base-dev/mar/json/rpc/response.hoon new file mode 100644 index 000000000..91ea2f670 --- /dev/null +++ b/pkg/base-dev/mar/json/rpc/response.hoon @@ -0,0 +1,43 @@ +:: +/- *json-rpc +:: +|_ res=response +:: +++ grad %noun +++ grow + |% + ++ noun res + -- +++ grab :: convert from + |% + ++ noun response :: from noun + ++ httr :: from httr + |= hit=httr:eyre + ^- response + ~| hit + ?: ?=(%2 (div p.hit 100)) + =, html + %- json + ?~ r.hit + a+~ + (need (de-json q:u.r.hit)) + fail+hit + ++ json :: from json + =, dejs-soft:format + |= a=json + ^- response + =; dere + =+ res=((ar dere) a) + ?~ res (need (dere a)) + [%batch u.res] + |= a=json + ^- (unit response) + =/ res=(unit [@t json]) + ::TODO breaks when no id present + ((ot id+so result+some ~) a) + ?^ res `[%result u.res] + ~| a + :+ ~ %error %- need + ((ot id+so error+(ot code+no message+so ~) ~) a) + -- +-- diff --git a/pkg/base-dev/mar/kelvin.hoon b/pkg/base-dev/mar/kelvin.hoon new file mode 100644 index 000000000..f64063d18 --- /dev/null +++ b/pkg/base-dev/mar/kelvin.hoon @@ -0,0 +1,18 @@ +=/ weft ,[lal=@tas num=@ud] :: TODO remove after merge +|_ kel=weft +++ grow + |% + ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)] + ++ noun kel + ++ hoon (crip "{<[lal num]:kel>}\0a") + ++ txt (to-wain:format hoon) + -- +++ grab + |% + ++ noun weft + ++ mime + |= [=mite len=@ud tex=@] + !<(weft (slap !>(~) (ream tex))) + -- +++ grad %noun +-- diff --git a/pkg/base-dev/mar/language-server/rpc/notification.hoon b/pkg/base-dev/mar/language-server/rpc/notification.hoon new file mode 100644 index 000000000..d464da489 --- /dev/null +++ b/pkg/base-dev/mar/language-server/rpc/notification.hoon @@ -0,0 +1,18 @@ +/- *language-server +/+ lsp-json=language-server-json +|_ not=all:notification +++ grad %noun +++ grab + |% + ++ noun all:notification + ++ json + |= jon=^json + (notification:dejs:lsp-json jon) + -- +++ grow + |% + ++ noun not + ++ json + (notification:enjs:lsp-json not) + -- +-- diff --git a/pkg/base-dev/mar/language-server/rpc/request.hoon b/pkg/base-dev/mar/language-server/rpc/request.hoon new file mode 100644 index 000000000..989a6f41c --- /dev/null +++ b/pkg/base-dev/mar/language-server/rpc/request.hoon @@ -0,0 +1,16 @@ +/- *language-server +/+ lsp-json=language-server-json +|_ req=all:request +++ grad %noun +++ grow + |% + ++ noun req + -- +++ grab + |% + ++ noun all:request + ++ json + |= jon=^json + (request:dejs:lsp-json jon) + -- +-- diff --git a/pkg/base-dev/mar/language-server/rpc/response.hoon b/pkg/base-dev/mar/language-server/rpc/response.hoon new file mode 100644 index 000000000..f82408b87 --- /dev/null +++ b/pkg/base-dev/mar/language-server/rpc/response.hoon @@ -0,0 +1,17 @@ +/- *language-server +/+ lsp=language-server-json +|_ res=all:response +:: +++ grad %noun +++ grow + |% + ++ noun res + ++ json (response:enjs:lsp res) + -- +:: +++ grab + |% + ++ noun all:response + -- +:: +-- diff --git a/pkg/base-dev/mar/mime.hoon b/pkg/base-dev/mar/mime.hoon new file mode 100644 index 000000000..83b4daeb5 --- /dev/null +++ b/pkg/base-dev/mar/mime.hoon @@ -0,0 +1,32 @@ +:: +:::: /hoon/mime/mar + :: +/? 310 +:: +|_ own=mime +++ grow + ^? + |% + ++ jam `@`q.q.own + -- +:: +++ grab :: convert from + ^? + |% + ++ noun mime :: clam from %noun + ++ tape + |=(a=_"" [/application/x-urb-unknown (as-octt:mimes:html a)]) + -- +++ grad + ^? + |% + ++ form %mime + ++ diff |=(mime +<) + ++ pact |=(mime +<) + ++ join |=([mime mime] `(unit mime)`~) + ++ mash + |= [[ship desk mime] [ship desk mime]] + ^- mime + ~|(%mime-mash !!) + -- +-- diff --git a/pkg/base-dev/mar/noun.hoon b/pkg/base-dev/mar/noun.hoon new file mode 100644 index 000000000..5c798d3c2 --- /dev/null +++ b/pkg/base-dev/mar/noun.hoon @@ -0,0 +1,19 @@ +:: +:::: /hoon/noun/mar + :: +/? 310 +!: +:::: A minimal noun mark +|_ non=* +++ grab |% + ++ noun * + -- +++ grad + |% + ++ form %noun + ++ diff |=(* +<) + ++ pact |=(* +<) + ++ join |=([* *] *(unit *)) + ++ mash |=([[ship desk *] [ship desk *]] `*`~|(%noun-mash !!)) + -- +-- diff --git a/pkg/base-dev/mar/path.hoon b/pkg/base-dev/mar/path.hoon new file mode 100644 index 000000000..2196ba95a --- /dev/null +++ b/pkg/base-dev/mar/path.hoon @@ -0,0 +1,11 @@ +|_ pax=path +++ grad %noun +++ grow + |% + ++ noun pax + -- +++ grab + |% + ++ noun path + -- +-- diff --git a/pkg/base-dev/mar/png.hoon b/pkg/base-dev/mar/png.hoon new file mode 100644 index 000000000..6a60a6a27 --- /dev/null +++ b/pkg/base-dev/mar/png.hoon @@ -0,0 +1,12 @@ +|_ dat=@ +++ grow + |% + ++ mime [/image/png (as-octs:mimes:html dat)] + -- +++ grab + |% + ++ mime |=([p=mite q=octs] q.q) + ++ noun @ + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/purl.hoon b/pkg/base-dev/mar/purl.hoon new file mode 100644 index 000000000..3fb39fa69 --- /dev/null +++ b/pkg/base-dev/mar/purl.hoon @@ -0,0 +1,18 @@ +:: +:::: /hoon/purl/mar + :: +/? 310 +=, eyre +|_ url=purl +++ grad %noun +:: +++ grow + |% + ++ noun url + ++ hiss [url %get ~ ~] + -- +++ grab :: convert from + |% + ++ noun purl :: clam from %noun + -- +-- diff --git a/pkg/base-dev/mar/ship.hoon b/pkg/base-dev/mar/ship.hoon new file mode 100644 index 000000000..176bcaded --- /dev/null +++ b/pkg/base-dev/mar/ship.hoon @@ -0,0 +1,20 @@ +|_ s=ship +++ grad %noun +++ grow + |% + ++ noun s + ++ json s+(scot %p s) + ++ mime + ^- ^mime + [/text/x-ship (as-octt:mimes:html (scow %p s))] + + -- +++ grab + |% + ++ noun ship + ++ json (su:dejs:format ;~(pfix sig fed:ag)) + ++ mime + |= [=mite len=@ tex=@] + (slav %p (snag 0 (to-wain:format tex))) + -- +-- diff --git a/pkg/base-dev/mar/sole/action.hoon b/pkg/base-dev/mar/sole/action.hoon new file mode 100644 index 000000000..149ef5ef1 --- /dev/null +++ b/pkg/base-dev/mar/sole/action.hoon @@ -0,0 +1,50 @@ +:: +:::: /hoon/action/sole/mar + :: +/? 310 +/- sole +:: +:::: + :: +=, sole +|_ sole-action +:: +++ grad %noun +++ grow + |% + ++ noun +<.grad + -- +++ grab :: convert from + |% + ++ json + |= jon=^json ^- sole-action + %- need %. jon + => [dejs-soft:format ..sole-action] + |^ (ot id+so dat+(fo %ret (of det+change tab+ni ~)) ~) + ++ fo + |* [a=term b=fist] + |=(c=json ?.(=([%s a] c) (b c) (some [a ~]))) + :: + ++ ra + |* [a=[term fist] b=fist] + |= c=json %. c + ?.(=(%a -.c) b (pe -.a (ar +.a))) + :: + ++ ke :: callbacks + |* [gar=* sef=(trap fist)] + |= jon=json ^- (unit _gar) + =- ~! gar ~! (need -) - + ((sef) jon) + :: + ++ change (ot ler+(at ni ni ~) ted+(pe 0v0 edit) ~) + ++ char (cu taft so) + ++ edit + %+ ke *sole-edit |. ~+ + %+ fo %nop + %+ ra mor+edit + (of del+ni set+(cu tuba sa) ins+(ot at+ni cha+char ~) ~) + -- + :: + ++ noun sole-action :: clam from %noun + -- +-- diff --git a/pkg/base-dev/mar/sole/effect.hoon b/pkg/base-dev/mar/sole/effect.hoon new file mode 100644 index 000000000..7b1f7477b --- /dev/null +++ b/pkg/base-dev/mar/sole/effect.hoon @@ -0,0 +1,82 @@ +:: +:::: /hoon/effect/sole/mar + :: +/? 310 +/- sole +!: +:: +:::: + :: +=, sole +=, format +|% +++ mar-sole-change :: XX dependency + |_ cha=sole-change + ++ grow + |% ++ json + ^- ^json + =, enjs + =; edi + =,(cha (pairs ted+(edi ted) ler+a+~[(numb own.ler) (numb his.ler)] ~)) + |= det=sole-edit + ?- -.det + %nop [%s 'nop'] + %mor [%a (turn p.det ..$)] + %del (frond %del (numb p.det)) + %set (frond %set (tape (tufa p.det))) + %ins (frond %ins (pairs at+(numb p.det) cha+s+(tuft q.det) ~)) + == + -- + -- +++ wush + |= [wid=@u tan=tang] + ^- tape + (of-wall (turn (flop tan) |=(a=tank (of-wall (wash 0^wid a))))) +:: +++ purge :: discard ++styx style + |= a=styx ^- tape + %- zing %+ turn a + |= a=_?>(?=(^ a) i.a) + ?@(a (trip a) ^$(a q.a)) +-- +:: +|_ sef=sole-effect +:: +++ grad %noun +++ grab :: convert from + |% + ++ noun sole-effect :: clam from %noun + -- +++ grow + =, enjs + |% + ++ noun sef + ++ json + ^- ^json + ?+ -.sef + ~|(unsupported-effect+-.sef !!) + %mor [%a (turn p.sef |=(a=sole-effect json(sef a)))] + %err (frond %hop (numb p.sef)) + %txt (frond %txt (tape p.sef)) + %tan (frond %tan (tape (wush 160 p.sef))) + %det (frond %det json:~(grow mar-sole-change +.sef)) + :: + %pro + %+ frond %pro + (pairs vis+b+vis.sef tag+s+tag.sef cad+(tape (purge cad.sef)) ~) + :: + %tab + :- %a + %+ turn p.sef + |= [=cord =^tank] + %+ frond %tab + %- pairs + :~ match+s+cord + info+(tape ~(ram re tank)) + == + :: + ?(%bel %clr %nex %bye) + (frond %act %s -.sef) + == + -- +-- diff --git a/pkg/base-dev/mar/svg.hoon b/pkg/base-dev/mar/svg.hoon new file mode 100644 index 000000000..2911e4900 --- /dev/null +++ b/pkg/base-dev/mar/svg.hoon @@ -0,0 +1,12 @@ +|_ dat=@ +++ grow + |% + ++ mime [/image/'svg+xml' (as-octs:mimes:html dat)] + -- +++ grab + |% + ++ mime |=([p=mite q=octs] q.q) + ++ noun @ + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/tang.hoon b/pkg/base-dev/mar/tang.hoon new file mode 100644 index 000000000..681e939fb --- /dev/null +++ b/pkg/base-dev/mar/tang.hoon @@ -0,0 +1,30 @@ +:: +:::: /hoon/tang/mar + :: +/? 310 +:: +=, format +|_ tan=(list tank) +++ grad %noun +++ grow + |% + ++ noun tan + ++ json + =/ result=(each (list ^json) tang) + (mule |.((turn tan tank:enjs:format))) + ?- -.result + %& a+p.result + %| a+[a+[%s '[[output rendering error]]']~]~ + == + :: + ++ elem + =- ;pre:code:"{(of-wall -)}" + ^- wall %- zing ^- (list wall) + (turn (flop tan) |=(a=tank (wash 0^160 a))) + -- +++ grab :: convert from + |% + ++ noun (list ^tank) :: clam from %noun + ++ tank |=(a=^tank [a]~) + -- +-- diff --git a/pkg/base-dev/mar/tape.hoon b/pkg/base-dev/mar/tape.hoon new file mode 100644 index 000000000..a30176421 --- /dev/null +++ b/pkg/base-dev/mar/tape.hoon @@ -0,0 +1,12 @@ +|_ tap=tape +++ grad %noun +++ grow + |% + ++ noun tap + ++ json s+(crip tap) + -- +++ grab + |% + ++ noun tape + -- +-- diff --git a/pkg/base-dev/mar/txt-diff.hoon b/pkg/base-dev/mar/txt-diff.hoon new file mode 100644 index 000000000..2c9a500dc --- /dev/null +++ b/pkg/base-dev/mar/txt-diff.hoon @@ -0,0 +1,16 @@ +:: +:::: /hoon/txt-diff/mar + :: +/? 310 +|_ txt-diff=(urge:clay cord) +:: +++ grad %noun +++ grow + |% + ++ noun txt-diff + -- +++ grab :: convert from + |% + ++ noun (urge:clay cord) :: make from %noun + -- +-- diff --git a/pkg/base-dev/mar/txt.hoon b/pkg/base-dev/mar/txt.hoon new file mode 100644 index 000000000..1c349b182 --- /dev/null +++ b/pkg/base-dev/mar/txt.hoon @@ -0,0 +1,275 @@ +:: +:::: /hoon/txt/mar + :: +/? 310 +:: +=, clay +=, differ +=, format +=, mimes:html +|_ txt=wain +:: +++ grab :: convert from + |% + ++ mime |=((pair mite octs) (to-wain q.q)) + ++ noun wain :: clam from %noun + -- +++ grow + => v=. + |% + ++ mime => v [/text/plain (as-octs (of-wain txt))] + ++ elem => v ;pre: {(trip (of-wain txt))} + -- +++ grad + |% + ++ form %txt-diff + ++ diff + |= tyt=wain + ^- (urge cord) + (lusk txt tyt (loss txt tyt)) + :: + ++ pact + |= dif=(urge cord) + ~| [%pacting dif] + ^- wain + (lurk txt dif) + :: + ++ join + |= [ali=(urge cord) bob=(urge cord)] + ^- (unit (urge cord)) + |^ + =. ali (clean ali) + =. bob (clean bob) + |- ^- (unit (urge cord)) + ?~ ali `bob + ?~ bob `ali + ?- -.i.ali + %& + ?- -.i.bob + %& + ?: =(p.i.ali p.i.bob) + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.ali cud]) + ?: (gth p.i.ali p.i.bob) + %+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob) + |=(cud=(urge cord) [i.bob cud]) + %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali)) + |=(cud=(urge cord) [i.ali cud]) + :: + %| + ?: =(p.i.ali (lent p.i.bob)) + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.bob cud]) + ?: (gth p.i.ali (lent p.i.bob)) + %+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob) + |=(cud=(urge cord) [i.bob cud]) + ~ + == + :: + %| + ?- -.i.bob + %| + ?. =(i.ali i.bob) + ~ + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.ali cud]) + :: + %& + ?: =(p.i.bob (lent p.i.ali)) + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.ali cud]) + ?: (gth p.i.bob (lent p.i.ali)) + %+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali))) + |=(cud=(urge cord) [i.ali cud]) + ~ + == + == + ++ clean :: clean + |= wig=(urge cord) + ^- (urge cord) + ?~ wig ~ + ?~ t.wig wig + ?: ?=(%& -.i.wig) + ?: ?=(%& -.i.t.wig) + $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + ?: ?=(%| -.i.t.wig) + $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + -- + :: + ++ mash + |= $: [als=ship ald=desk ali=(urge cord)] + [bos=ship bod=desk bob=(urge cord)] + == + ^- (urge cord) + |^ + =. ali (clean ali) + =. bob (clean bob) + |- ^- (urge cord) + ?~ ali bob + ?~ bob ali + ?- -.i.ali + %& + ?- -.i.bob + %& + ?: =(p.i.ali p.i.bob) + [i.ali $(ali t.ali, bob t.bob)] + ?: (gth p.i.ali p.i.bob) + [i.bob $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)] + [i.ali $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))] + :: + %| + ?: =(p.i.ali (lent p.i.bob)) + [i.bob $(ali t.ali, bob t.bob)] + ?: (gth p.i.ali (lent p.i.bob)) + [i.bob $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)] + =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] + (resolve ali bob) + [fic $(ali ali, bob bob)] + :: ~ :: here, alice is good for a while, but not for the whole + == :: length of bob's changes + :: + %| + ?- -.i.bob + %| + =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] + (resolve ali bob) + [fic $(ali ali, bob bob)] + :: + %& + ?: =(p.i.bob (lent p.i.ali)) + [i.ali $(ali t.ali, bob t.bob)] + ?: (gth p.i.bob (lent p.i.ali)) + [i.ali $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))] + =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] + (resolve ali bob) + [fic $(ali ali, bob bob)] + == + == + :: + ++ annotate :: annotate conflict + |= $: ali=(list @t) + bob=(list @t) + bas=(list @t) + == + ^- (list @t) + %- zing + ^- (list (list @t)) + %- flop + ^- (list (list @t)) + :- :_ ~ + %^ cat 3 '<<<<<<<<<<<<' + %^ cat 3 ' ' + %^ cat 3 `@t`(scot %p bos) + %^ cat 3 '/' + bod + + :- bob + :- ~['------------'] + :- bas + :- ~['++++++++++++'] + :- ali + :- :_ ~ + %^ cat 3 '>>>>>>>>>>>>' + %^ cat 3 ' ' + %^ cat 3 `@t`(scot %p als) + %^ cat 3 '/' + ald + ~ + :: + ++ clean :: clean + |= wig=(urge cord) + ^- (urge cord) + ?~ wig ~ + ?~ t.wig wig + ?: ?=(%& -.i.wig) + ?: ?=(%& -.i.t.wig) + $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + ?: ?=(%| -.i.t.wig) + $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + :: + ++ resolve + |= [ali=(urge cord) bob=(urge cord)] + ^- [fic=[%| p=(list cord) q=(list cord)] ali=(urge cord) bob=(urge cord)] + =- [[%| bac (annotate alc boc bac)] ali bob] + |- ^- $: $: bac=(list cord) + alc=(list cord) + boc=(list cord) + == + ali=(urge cord) + bob=(urge cord) + == + ?~ ali [[~ ~ ~] ali bob] + ?~ bob [[~ ~ ~] ali bob] + ?- -.i.ali + %& + ?- -.i.bob + %& [[~ ~ ~] ali bob] :: no conflict + %| + =+ lob=(lent p.i.bob) + ?: =(lob p.i.ali) + [[p.i.bob p.i.bob q.i.bob] t.ali t.bob] + ?: (lth lob p.i.ali) + [[p.i.bob p.i.bob q.i.bob] [[%& (sub p.i.ali lob)] t.ali] t.bob] + =+ wat=(scag (sub lob p.i.ali) p.i.bob) + =+ ^= res + %= $ + ali t.ali + bob [[%| (scag (sub lob p.i.ali) p.i.bob) ~] t.bob] + == + :* :* (welp bac.res wat) + (welp alc.res wat) + (welp boc.res q.i.bob) + == + ali.res + bob.res + == + == + :: + %| + ?- -.i.bob + %& + =+ loa=(lent p.i.ali) + ?: =(loa p.i.bob) + [[p.i.ali q.i.ali p.i.ali] t.ali t.bob] + ?: (lth loa p.i.bob) + [[p.i.ali q.i.ali p.i.ali] t.ali [[%& (sub p.i.bob loa)] t.bob]] + =+ wat=(slag (sub loa p.i.bob) p.i.ali) + =+ ^= res + %= $ + ali [[%| (scag (sub loa p.i.bob) p.i.ali) ~] t.ali] + bob t.bob + == + :* :* (welp bac.res wat) + (welp alc.res q.i.ali) + (welp boc.res wat) + == + ali.res + bob.res + == + :: + %| + =+ loa=(lent p.i.ali) + =+ lob=(lent p.i.bob) + ?: =(loa lob) + [[p.i.ali q.i.ali q.i.bob] t.ali t.bob] + =+ ^= res + ?: (gth loa lob) + $(ali [[%| (scag (sub loa lob) p.i.ali) ~] t.ali], bob t.bob) + ~& [%scagging loa=loa pibob=p.i.bob slag=(scag loa p.i.bob)] + $(ali t.ali, bob [[%| (scag (sub lob loa) p.i.bob) ~] t.bob]) + :* :* (welp bac.res ?:((gth loa lob) p.i.bob p.i.ali)) + (welp alc.res q.i.ali) + (welp boc.res q.i.bob) + == + ali.res + bob.res + == + == + == + -- + -- +-- diff --git a/pkg/base-dev/mar/udon.hoon b/pkg/base-dev/mar/udon.hoon new file mode 100644 index 000000000..72c9e6f5c --- /dev/null +++ b/pkg/base-dev/mar/udon.hoon @@ -0,0 +1,32 @@ +:: +:::: /hoon/udon/mar + :: +/+ cram +:: +|_ mud=@t +++ grow + |% + ++ mime [/text/x-unmark (as-octs:mimes:html mud)] + ++ txt + (to-wain:format mud) + ++ elem + ^- manx + =, cram + elm:(static (ream mud)) + ++ front :: XX performance, types + ^- (map term knot) + %- ~(run by inf:(static:cram (ream mud))) + |= a=dime ^- cord + ?+ (end 3 p.a) (scot a) + %t q.a + == + -- +++ grab + |% + ++ mime |=((pair mite octs) q.q) + ++ noun @t + ++ txt of-wain:format + -- +++ grad %txt +++ garb /down +-- diff --git a/pkg/base-dev/mar/umd.hoon b/pkg/base-dev/mar/umd.hoon new file mode 100644 index 000000000..d249bcff8 --- /dev/null +++ b/pkg/base-dev/mar/umd.hoon @@ -0,0 +1,32 @@ +:: +:::: /hoon/umd/mar + :: +/+ cram +:: +|_ mud=@t +++ grow + |% + ++ mime [/text/x-unmark (as-octs:mimes:html mud)] + ++ txt + (to-wain:format mud) + ++ elem + ^- manx + =, cram + elm:(static (ream mud)) + ++ front :: XX performance, types + ^- (map term knot) + %- ~(run by inf:(static:cram (ream mud))) + |= a=dime ^- cord + ?+ (end 3 p.a) (scot a) + %t q.a + == + -- +++ grab + |% + ++ mime |=((pair mite octs) q.q) + ++ noun @t + ++ txt of-wain:format + -- +++ grad %txt +++ garb /down +-- diff --git a/pkg/base-dev/mar/urb.hoon b/pkg/base-dev/mar/urb.hoon new file mode 100644 index 000000000..49545e73f --- /dev/null +++ b/pkg/base-dev/mar/urb.hoon @@ -0,0 +1,18 @@ +:: +:::: /hoon/elem/urb/mar + :: +/? 310 +=, mimes:html +=, html +|_ own=manx +:: +++ grad %noun +++ grow :: convert to + |% + ++ hymn ;html:(head body:"+{own}") :: convert to %hymn + ++ html (crip (en-xml hymn)) :: convert to %html + ++ mime [/text/html (as-octs html)] :: convert to %mime + -- +++ grab |% :: convert from + ++ noun manx :: clam from %noun +-- -- diff --git a/pkg/base-dev/mar/urbit.hoon b/pkg/base-dev/mar/urbit.hoon new file mode 100644 index 000000000..8d2c3c658 --- /dev/null +++ b/pkg/base-dev/mar/urbit.hoon @@ -0,0 +1,17 @@ +:: +:::: /hoon/urbit/mar + :: +/? 310 +:::: A minimal urbit mark +:: +|_ her=@p +++ grab + |% + ++ noun @p + -- +++ grow + |% + ++ noun her + -- +++ grad %noun +-- diff --git a/pkg/base-dev/mar/woff2.hoon b/pkg/base-dev/mar/woff2.hoon new file mode 100644 index 000000000..7e7242908 --- /dev/null +++ b/pkg/base-dev/mar/woff2.hoon @@ -0,0 +1,12 @@ +|_ dat=octs +++ grow + |% + ++ mime [/font/woff2 dat] + -- +++ grab + |% + ++ mime |=([=mite =octs] octs) + ++ noun octs + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/xml.hoon b/pkg/base-dev/mar/xml.hoon new file mode 100644 index 000000000..6d52d8024 --- /dev/null +++ b/pkg/base-dev/mar/xml.hoon @@ -0,0 +1,21 @@ +:: +:::: /hoon/xml/mar + :: +/? 310 + :: +:::: compute + :: +=, mimes:html +=, html +|_ xml=@t +:: +++ grad %mime +++ grow :: convert to + |% :: + ++ mime [/application/xml (as-octs xml)] :: to %mime + ++ hymn (need (de-xml xml)) :: to %hymn + -- :: +++ grab |% :: convert from + ++ noun @t :: clam from %noun + ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime +-- -- diff --git a/pkg/base-dev/sur/aquarium.hoon b/pkg/base-dev/sur/aquarium.hoon new file mode 100644 index 000000000..d71d9f519 --- /dev/null +++ b/pkg/base-dev/sur/aquarium.hoon @@ -0,0 +1,76 @@ +:: Traditionally, ovo refers to an ovum -- (pair wire card) -- and ova +:: refers to a list of them. We have several versions of each of these +:: depending on context, so we do away with that naming scheme and use +:: the following naming scheme. +:: +:: Every card is either an `event` or an `effect`. Prepended to this +:: is `unix` if it has no ship associated with it, or `aqua` if it +:: does. `timed` is added if it includes the time of the event. +:: +:: Short names are simply the first letter of each word plus `s` if +:: it's a list. +:: +/+ pill +=, pill-lib=pill +|% ++$ az-log [topics=(lest @) data=@t] ++$ az-state + $: logs=(list az-log) + lives=(map ship [lyfe=life rut=rift]) + tym=@da + == +++ ph-event + $% [%test-done p=?] + aqua-event + == +:: ++$ unix-event unix-event:pill-lib ++$ pill pill:pill-lib +:: ++$ aqua-event + $% [%init-ship who=ship fake=?] + [%pause-events who=ship] + [%snap-ships lab=term hers=(list ship)] + [%restore-snap lab=term] + [%event who=ship ue=unix-event] + == +:: ++$ azimuth-action + $% [%init-azimuth ~] + [%spawn who=ship] + [%breach who=ship] + == +:: ++$ aqua-effects + [who=ship ufs=(list unix-effect)] +:: ++$ aqua-effect + [who=ship ufs=unix-effect] +:: ++$ aqua-events + [who=ship utes=(list unix-timed-event)] +:: ++$ aqua-boths + [who=ship ub=(list unix-both)] +:: ++$ unix-both + $% [%event unix-timed-event] + [%effect unix-effect] + == +:: ++$ unix-timed-event [tym=@da ue=unix-event] +:: ++$ unix-effect + %+ pair wire + $% [%blit p=(list blit:dill)] + [%send p=lane:ames q=@] + [%doze p=(unit @da)] + [%thus p=@ud q=(unit hiss:eyre)] + [%ergo p=@tas q=mode:clay] + [%sleep ~] + [%restore ~] + [%kill ~] + [%init ~] + [%request id=@ud request=request:http] + == +-- diff --git a/pkg/base-dev/sur/asn1.hoon b/pkg/base-dev/sur/asn1.hoon new file mode 100644 index 000000000..348c07ebe --- /dev/null +++ b/pkg/base-dev/sur/asn1.hoon @@ -0,0 +1,80 @@ +:: |asn1: small selection of types and constants for ASN.1 +:: +:: A minimal representation of some basic ASN.1 types, +:: created to support PKCS keys, digests, and cert requests. +:: +^? +|% +:: +bespoke:asn1: context-specific, generic ASN.1 tag type +:: +:: Note that *explicit* implies *constructed* (ie, bit 5 is set in DER). +:: ++$ bespoke + :: imp: & is implicit, | is explicit + :: tag: 5 bits for the custom tag number + :: + [imp=? tag=@ud] +:: +spec:asn1: minimal representations of basic ASN.1 types +:: ++$ spec + $% :: %int: arbitrary-sized, unsigned integers + :: + :: Unsigned integers, represented as having a positive sign. + :: Negative integers would be two's complement in DER, + :: but we don't need them. + :: + [%int int=@u] + :: %bit: very minimal support for bit strings + :: + :: Specifically, values must already be padded and byte-aligned. + :: len: bitwidth + :: bit: data + :: + [%bit len=@ud bit=@ux] + :: %oct: octets in little-endian byte order + :: + :: len: bytewidth + :: bit: data + :: + [%oct len=@ud oct=@ux] + :: %nul: fully supported! + :: + [%nul ~] + :: %obj: object identifiers, pre-packed + :: + :: Object identifiers are technically a sequence of integers, + :: represented here in their already-encoded form. + :: + [%obj obj=@ux] + :: %seq: a list of specs + :: + [%seq seq=(list spec)] + :: %set: a logical set of specs + :: + :: Implemented here as a list for the sake of simplicity. + :: must be already deduplicated and sorted! + :: + [%set set=(list spec)] + :: %con: context-specific + :: + :: General support for context-specific tags. + :: bes: custom tag number, implicit or explicit + :: con: already-encoded bytes + :: + [%con bes=bespoke con=(list @D)] + == +:: |obj:asn1: constant object ids, pre-encoded +:: +++ obj + ^? + |% :: rfc4055 + ++ sha-256 0x1.0204.0365.0148.8660 :: 2.16.840.1.101.3.4.2.1 + ++ rsa 0x1.0101.0df7.8648.862a :: 1.2.840.113549.1.1.1 + ++ rsa-sha-256 0xb.0101.0df7.8648.862a :: 1.2.840.113549.1.1.11 + :: rfc2985 + ++ csr-ext 0xe.0901.0df7.8648.862a :: 1.2.840.113549.1.9.14 + :: rfc3280 + ++ sub-alt 0x11.1d55 :: 2.5.29.17 + -- +-- + diff --git a/pkg/base-dev/sur/bitcoin.hoon b/pkg/base-dev/sur/bitcoin.hoon new file mode 100644 index 000000000..06aee8178 --- /dev/null +++ b/pkg/base-dev/sur/bitcoin.hoon @@ -0,0 +1,84 @@ +:: sur/btc.hoon +:: Utilities for working with BTC data types and transactions +:: +:: chyg: whether account is (non-)change. 0 or 1 +:: bytc: "btc-byts" with dat cast to @ux +|% ++$ network ?(%main %testnet) ++$ hexb [wid=@ dat=@ux] :: hex byts ++$ bits [wid=@ dat=@ub] ++$ xpub @ta ++$ address + $% [%base58 @uc] + [%bech32 cord] + == ++$ fprint hexb ++$ bipt $?(%44 %49 %84) ++$ chyg $?(%0 %1) ++$ idx @ud ++$ hdkey [=fprint pubkey=hexb =network =bipt =chyg =idx] ++$ sats @ud ++$ vbytes @ud ++$ txid hexb ++$ utxo [pos=@ =txid height=@ value=sats recvd=(unit @da)] +++ address-info + $: =address + confirmed-value=sats + unconfirmed-value=sats + utxos=(set utxo) + == +++ tx + |% + +$ data + $: is=(list input) + os=(list output) + locktime=@ud + nversion=@ud + segwit=(unit @ud) + == + +$ val + $: =txid + pos=@ud + =address + value=sats + == + :: included: whether tx is in the mempool or blockchain + :: + +$ info + $: included=? + =txid + confs=@ud + recvd=(unit @da) + inputs=(list val) + outputs=(list val) + == + +$ input + $: =txid + pos=@ud + sequence=hexb + script-sig=(unit hexb) + pubkey=(unit hexb) + value=sats + == + +$ output + $: script-pubkey=hexb + value=sats + == + -- +++ psbt + |% + +$ base64 cord + +$ in [=utxo rawtx=hexb =hdkey] + +$ out [=address hk=(unit hdkey)] + +$ target $?(%input %output) + +$ keyval [key=hexb val=hexb] + +$ map (list keyval) + -- +++ ops + |% + ++ op-dup 118 + ++ op-equalverify 136 + ++ op-hash160 169 + ++ op-checksig 172 + -- +-- diff --git a/pkg/base-dev/sur/hood.hoon b/pkg/base-dev/sur/hood.hoon new file mode 100644 index 000000000..420276243 --- /dev/null +++ b/pkg/base-dev/sur/hood.hoon @@ -0,0 +1,313 @@ +=, clay +=* dude dude:gall +|% +:: $snap: kiln snapshot +:: ++$ snap (map desk arak) +:: $diff: subscription update +:: ++$ diff + $% [%block =desk =arak =weft blockers=(set desk)] + [%reset =desk =arak] + [%commit =desk =arak] + [%merge-sunk =desk =arak =tang] + [%merge-fail =desk =arak =tang] + [%suspend =desk =arak] + [%revive =desk =arak] + == +:: $arak: foreign vat tracker +:: +:: .rail: upstream tracking state, if any +:: .rein: configuration for agents +:: ++$ arak + $: rail=(unit rail) + =rein + == +:: $rail: upstream tracking state +:: +:: .publisher: Ship that originally published desk, if available +:: .paused: is tracking paused? or live +:: .ship: upstream ship (could be .our) +:: .desk: name of upstream desk +:: .aeon: next aeon to pull from upstream +:: .next: list of pending commits with future kelvins +:: ++$ rail + $: publisher=(unit ship) + paused=? + =ship + =desk + =aeon + next=(list rung) + == +:: $rung: reference to upstream commit +:: ++$ rung [=aeon =weft] +:: $rein: diff from desk manifest +:: +:: .liv: suspended? if suspended, no agents should run +:: .add: agents not in manifest that should be running +:: .sub: agents in manifest that should not be running +:: ++$ rein + $: liv=_& + add=(set dude) + sub=(set dude) + == +:: ++$ vat [=desk hash=@uv =cass =arak] +:: +report-vats: report on all desk installations +:: +++ report-vats + |= [our=@p now=@da] + ^- tang + =+ .^ raz=(list vat) + %gx /(scot %p our)/hood/(scot %da now)/kiln/vats/noun + == + :- (report-kids our now) + (turn raz |=(v=vat (report-vat our now v))) +:: +report-vat: report on a single desk installation +:: +++ report-vat + |= [our=ship now=@da vat] + ^- tank + ?: =(ud.cass 0) + leaf+"desk does not yet exist: {}" + =/ kel-path + /(scot %p our)/[desk]/(scot %da now)/sys/kelvin + ?. .^(? %cu kel-path) + leaf+"bad desk: {}" + =+ .^(=weft %cx kel-path) + :+ %rose ["" "{}" "::"] + ^- tang + =/ meb (mergebase-hashes our desk now arak) + =/ poz + ?~ rail.arak "local" + ?:(paused.u.rail.arak "paused" "tracking") + =/ sat ?:(liv.rein.arak "running" "suspended") + =/ pen + ?~ rail.arak "~" + <(turn next.u.rail.arak |=([@ lal=@tas num=@] [lal num]))> + :~ leaf/"/sys/kelvin: {<[lal num]:weft>}" + leaf/"base hash: {?.(=(1 (lent meb)) <(head meb)>)}" + leaf/"%cz hash: {}" + :: + leaf/"app status: {sat}" + leaf/"force on: {?:(=(~ add.rein.arak) "~" )}" + leaf/"force off: {?:(=(~ sub.rein.arak) "~" )}" + :: + leaf/"publishing ship: {?~(rail.arak <~> )}" + leaf/"updates: {poz}" + leaf/"source ship: {?~(rail.arak <~> )}" + leaf/"source desk: {?~(rail.arak <~> )}" + leaf/"source aeon: {?~(rail.arak <~> )}" + leaf/"pending updates: {pen}" + == +:: +report-kids: non-vat cz hash report for kids desk +:: +++ report-kids + |= [our=ship now=@da] + ^- tank + =/ dek %kids + =/ ego (scot %p our) + =/ wen (scot %da now) + ?. (~(has in .^((set desk) %cd /[ego]//[wen])) dek) + leaf/"no %kids desk" + =+ .^(hash=@uv %cz /[ego]/[dek]/[wen]) + leaf/"%kids %cz hash: {}" +:: +read-kelvin-foreign: read /sys/kelvin from a foreign desk +:: +++ read-kelvin-foreign + |= [=ship =desk =aeon] + ^- weft + ~| read-foreign-kelvin/+< + =/ her (scot %p ship) + =/ syd (scot %tas desk) + =/ yon (scot %ud aeon) + :: + =/ dom .^(dome cv/~[her syd yon]) + =/ tak (scot %uv (~(got by hit.dom) let.dom)) + =/ yak .^(yaki cs/~[her syd yon %yaki tak]) + =/ lob (scot %uv (~(got by q.yak) /sys/kelvin)) + =/ bob .^(blob cs/~[her syd yon %blob lob]) + :: + ;; weft + ?- -.bob + %direct q.q.bob + %delta q.r.bob + == +:: +read-kelvin-local: read /sys/kelvin from a local desk +:: +++ read-kelvin-local + |= [our=ship =desk now=@da] + ^- (unit weft) + ~| read-kelvin-local+desk + =/ pax (en-beam [our desk da+now] /sys/kelvin) + ?. .^(? cu/pax) + ~ + [~ .^(weft cx/pax)] +:: +read-bill-foreign: read /desk/bill from a foreign desk +:: +++ read-bill-foreign + |= [=ship =desk =aeon] + ^- (list dude) + ~| +< + =/ her (scot %p ship) + =/ syd (scot %tas desk) + =/ yon (scot %ud aeon) + :: + =/ dom .^(dome cv/~[her syd yon]) + =/ tak ~| aeons=~(key by hit.dom) + (scot %uv (~(got by hit.dom) aeon)) + =/ yak .^(yaki cs/~[her syd yon %yaki tak]) + =/ fil (~(get by q.yak) /desk/bill) + ?~ fil ~ + =/ lob (scot %uv u.fil) + =/ bob .^(blob cs/~[her syd yon %blob lob]) + :: + ;; (list dude) + ?- -.bob + %direct q.q.bob + %delta q.r.bob + == +:: +read-bill: read contents of /desk/bill manifest +:: +++ read-bill + |= [our=ship =desk now=@da] + =/ pax (en-beam [our desk da+now] /desk/bill) + ?. .^(? cu/pax) + *(list dude) + .^((list dude) cx/pax) +:: +adjust-dudes: which agents should be started and stopped +:: +:: Will ask Gall to start agents that it's already running +:: but that should be ok, and might be safer in case other +:: unprocessed moves would have turned them off. +:: +++ adjust-dudes + |= $: local=[our=ship =desk now=@da] + =rein + == + ^- [jolt=(list dude) idle=(list dude)] + =/ all=(list dude) (read-bill local) + =/ want (get-apps-want all rein) + =/ have (get-apps-live local) + [want (skip have ~(has in (sy want)))] +:: +++ get-remote-diff + |= [our=ship here=desk now=@da her=ship there=desk when=aeon] + =+ .^(our-hash=@uv cz/[(scot %p our) here (scot %da now) ~]) + =+ .^(her-hash=@uv cz/[(scot %p her) there (scot %ud when) ~]) + !=(our-hash her-hash) +:: +++ get-publisher + |= [our=ship =desk now=@da] + ^- (unit ship) + =/ pax /(scot %p our)/[desk]/(scot %da now)/desk/ship + ?. .^(? %cu pax) ~ + `.^(ship %cx pax) +:: +++ get-apps-live + |= [our=ship =desk now=@da] + ^- (list dude) + %+ murn (get-apps-have our desk now) + |=([=dude live=?] ?.(live ~ `dude)) +:: +get-apps-have: find which apps Gall is running on a desk +:: +++ get-apps-have + |= [our=ship =desk now=@da] + ^- (list [=dude live=?]) + %~ tap in + .^((set [=dude live=?]) ge+/(scot %p our)/[desk]/(scot %da now)) +:: +get-apps-want: find which apps should be running on a desk +:: +++ get-apps-want + |= [duz=(list dude) =rein] + ^- (list dude) + =. duz (skip duz ~(has in sub.rein)) + =. duz (weld duz (skip ~(tap in add.rein) ~(has in (sy duz)))) + duz +:: +++ mergebase-hashes + |= [our=@p =desk now=@da =arak] + ?~ rail.arak + ~ + =/ her (scot %p ship.u.rail.arak) + =/ ego (scot %p our) + =/ wen (scot %da now) + %+ turn .^((list tako) %cs ~[ego desk wen %base her desk.u.rail.arak]) + |=(=tako .^(@uv %cs ~[ego desk wen %hash (scot %uv tako)])) +:: +++ enjs + =, enjs:format + |% + ++ vats + |= v=(list ^vat) + ^- json + %- pairs + %+ turn v + |= va=^vat + [desk.va (vat va)] + :: + ++ tim + |= t=@ + ^- json + (numb (fall (mole |.((unm:chrono:userlib t))) 0)) + :: + ++ cass + |= c=^cass + %- pairs + :~ ud+(numb ud.c) + da+(tim da.c) + == + :: + ++ vat + |= v=^vat + %- pairs + :~ desk+s+desk.v + hash+s+(scot %uv hash.v) + cass+(cass cass.v) + arak+(arak arak.v) + == + :: + ++ weft + |= w=^weft + %- pairs + :~ name+s+lal.w + kelvin+(numb num.w) + == + :: + ++ rung + |= r=^rung + %- pairs + :~ aeon+(numb aeon.r) + weft+(weft weft.r) + == + :: + ++ rein + |= r=^rein + %- pairs + :~ add+a+(turn ~(tap in add.r) (lead %s)) + sub+a+(turn ~(tap in sub.r) (lead %s)) + == + :: + ++ arak + |= a=^arak + %- pairs + :~ rail+?~(rail.a ~ (rail u.rail.a)) + rein+(rein rein.a) + == + :: + ++ rail + |= r=^rail + %- pairs + :~ ship+s+(scot %p ship.r) + publisher+?~(publisher.r ~ s+(scot %p u.publisher.r)) + desk+s+desk.r + paused+b+paused.r + aeon+(numb aeon.r) + next+a+(turn next.r rung) + == + -- +-- diff --git a/pkg/base-dev/sur/json/rpc.hoon b/pkg/base-dev/sur/json/rpc.hoon new file mode 100644 index 000000000..1c99b0f0a --- /dev/null +++ b/pkg/base-dev/sur/json/rpc.hoon @@ -0,0 +1,28 @@ +:: json-rpc: protocol types +:: +|% ++$ batch-request + $% [%a p=(list request)] + [%o p=request] + == +:: ++$ request + $: id=@t + jsonrpc=@t + method=@t + params=request-params + == +:: ++$ request-params + $% [%list (list json)] + [%map (map @t json)] + [%object (list (pair @t json))] + == ++$ response + $~ [%fail *httr:eyre] + $% [%result id=@t res=json] + [%error id=@t code=@t message=@t] ::TODO data? + [%fail hit=httr:eyre] + [%batch bas=(list response)] + == +-- diff --git a/pkg/base-dev/sur/keygen.hoon b/pkg/base-dev/sur/keygen.hoon new file mode 100644 index 000000000..f897eee4a --- /dev/null +++ b/pkg/base-dev/sur/keygen.hoon @@ -0,0 +1,23 @@ +|% ++$ revision @ud ++$ nodetype tape ++$ mnemonic tape +:: ++$ vault + $: ownership=node + voting=node + management=node + transfer=node + spawn=node + network=uode + == +:: ++$ node [type=nodetype seed=mnemonic keys=wallet] ++$ uode [revi=revision seed=@ux keys=edkeys] +:: ++$ wallet [keys=[public=@ux private=@ux] addr=@ux chain=@ux] +:: ++$ edkeys [auth=keypair crypt=keypair] +:: ++$ keypair [public=@ux secret=@ux] +-- diff --git a/pkg/base-dev/sur/language-server.hoon b/pkg/base-dev/sur/language-server.hoon new file mode 100644 index 000000000..f781588c3 --- /dev/null +++ b/pkg/base-dev/sur/language-server.hoon @@ -0,0 +1,114 @@ +|% +:: ++$ versioned-doc-id + [uri=@t version=(unit @)] +:: +++ request + |% + +$ all + $% + text-document--hover + text-document--completion + unknown + == + +$ text-document--hover + [%text-document--hover id=cord position versioned-doc-id] + +$ text-document--completion + [%text-document--completion id=cord position versioned-doc-id] + +$ unknown + [%unknown json] + -- +++ response + |% + +$ all + $% + text-document--hover + text-document--completion + == + +$ text-document--hover + [%text-document--hover id=cord contents=(unit @t)] + +$ text-document--completion + [%text-document--completion id=cord completion=(list completion-item)] + -- +:: ++$ completion-item + $: + label=cord + kind=@ud + detail=cord + doc=cord + insert-text=cord + insert-text-format=@ud + == + + + +:: ++$ diagnostic + [=range severity=@ud message=@t] +:: ++$ position + [row=@ud col=@ud] +:: ++$ text-document-item + [uri=@t version=(unit @) text=@t] +:: +++ notification + |% + :: + +$ in + $% + text-document--did-change + text-document--did-open + text-document--did-save + text-document--did-close + exit + unknown + == + :: + +$ out + $% + text-document--publish-diagnostics + == + :: + +$ all + $% + out + in + == + :: + +$ text-document--did-change + [%text-document--did-change versioned-doc-id changes=(list change)] + :: + +$ text-document--did-open + [%text-document--did-open text-document-item] + :: + +$ text-document--did-save + [%text-document--did-save versioned-doc-id] + :: + +$ text-document--did-close + [%text-document--did-close versioned-doc-id] + :: + +$ exit + [%exit ~] + :: + +$ unknown + [%unknown =json] + :: + +$ text-document--publish-diagnostics + [%text-document--publish-diagnostics uri=@t diagnostics=(list diagnostic)] + :: + -- +:: ++$ change + $: range=(unit range) + range-length=(unit @ud) + text=@t + == +:: ++$ range + $: start=position + end=position + == +:: +-- diff --git a/pkg/base-dev/sur/ring.hoon b/pkg/base-dev/sur/ring.hoon new file mode 100644 index 000000000..f25cec06b --- /dev/null +++ b/pkg/base-dev/sur/ring.hoon @@ -0,0 +1,47 @@ +|% +:: +raw-ring-signature: low level ring signature type +:: +:: The :s field of a ring signature grows O(n) with the number of +:: participants in the ring. +:: +++ raw-ring-signature + $: ch0=@ + :: + s=(list @) + :: linked ring signature tag + :: + :: Two linked ring signatures with the same link scope can be shown to + :: have been made by the same private key, leading to Sybil + :: resistance...but if your private keys are compromised, your + :: adversary can determine which signatures you made. + :: + y=(unit @udpoint) + == +:: +ring-signature: higher level ring signature type +:: +:: This contains all the identifying information to verify a ring signature +:: in an urbit context. +:: +++ ring-signature + $: :: a ring signature is computed over a set of public keys. the + :: participants set is not those keys, but static references to them. + :: + participants=(set [ship=@p =life]) + :: the linkage scope this signature was made on + :: + link-scope=(unit *) + :: the rest of the low level ring signature is appended + :: + raw=raw-ring-signature + == +:: ++$ ring-group + $: :: a ring signature is computed over a set of public keys. the + :: participants set is not those keys, but static references to them. + :: + participants=(set [ship=@p =life]) + :: the linkage scope this signature was made on + :: + link-scope=(unit *) + == +-- diff --git a/pkg/base-dev/sur/sole.hoon b/pkg/base-dev/sur/sole.hoon new file mode 100644 index 000000000..e942bccb8 --- /dev/null +++ b/pkg/base-dev/sur/sole.hoon @@ -0,0 +1,87 @@ +:: +:::: /hoon/sole/sur + :: +^? +|% ++$ sole-action :: sole to app + $: id=@ta :: duct id + $= dat + $% :: [%abo ~] :: reset interaction + [%det sole-change] :: command line edit + [%ret ~] :: submit and clear + [%clr ~] :: exit context + [%tab pos=@ud] :: tab complete + == :: + == ++$ sole-buffer (list @c) :: command state ++$ sole-change :: network change + $: ler=sole-clock :: destination clock + haw=@uvH :: source hash + ted=sole-edit :: state change + == :: ++$ sole-clock [own=@ud his=@ud] :: vector clock ++$ sole-edit :: shared state change + $% [%del p=@ud] :: delete one at + [%ins p=@ud q=@c] :: insert at + [%mor p=(list sole-edit)] :: combination + [%nop ~] :: no-op + [%set p=sole-buffer] :: discontinuity + == :: ++$ sole-effect :: app to sole + $% [%bel ~] :: beep + [%blk p=@ud q=@c] :: blink+match char at + [%bye ~] :: close session + [%clr ~] :: clear screen + [%det sole-change] :: edit command + [%err p=@ud] :: error point + [%klr p=styx] :: styled text line + [%mor p=(list sole-effect)] :: multiple effects + [%nex ~] :: save clear command + [%pro sole-prompt] :: set prompt + [%sag p=path q=*] :: save to jamfile + [%sav p=path q=@] :: save to file + [%tab p=(list [=cord =tank])] :: tab-complete list + [%tan p=(list tank)] :: classic tank + :: [%taq p=tanq] :: modern tank + [%txt p=tape] :: text line + [%url p=@t] :: activate url + == :: ++$ sole-command :: command state + $: pos=@ud :: cursor position + say=sole-share :: cursor + == :: ++$ sole-prompt :: prompt definition + $: vis=? :: command visible + tag=term :: history mode + cad=styx :: caption + == :: ++$ sole-share :: symmetric state + $: ven=sole-clock :: our vector clock + leg=(list sole-edit) :: unmerged edits + buf=sole-buffer :: sole state + == :: +:: :: +:: :: +++ sole-dialog :: standard dialog + |* out=$-(* *) :: output structure + $-(sole-input (sole-result out)) :: output function +:: :: ++$ sole-input tape :: prompt input +++ sole-result :: conditional result + |* out=$-(* *) :: output structure + $@(@ud (sole-product out)) :: error position +:: :: +++ sole-product :: success result + |* out=$-(* *) :: + %+ pair (list tank) :: + %+ each (unit out) :: ~ is abort + (pair sole-prompt (sole-dialog out)) :: ask and continue +:: :: ++$ sole-gen :: XX virtual type + $% [%say $-((sole-args) (cask))] :: direct noun + [%ask $-((sole-args) (sole-product (cask)))] :: dialog + == :: +++ sole-args :: generator arguments + |* _[* *] :: + ,[[now=@da eny=@uvJ bek=beak] [,+<- ,+<+]] :: +-- diff --git a/pkg/base-dev/sur/spider.hoon b/pkg/base-dev/sur/spider.hoon new file mode 100644 index 000000000..5fe7a7626 --- /dev/null +++ b/pkg/base-dev/sur/spider.hoon @@ -0,0 +1,14 @@ +/+ libstrand=strand +=, strand=strand:libstrand +|% ++$ thread $-(vase _*form:(strand ,vase)) ++$ input [=tid =cage] ++$ tid tid:strand ++$ bowl bowl:strand ++$ http-error + $? %bad-request :: 400 + %forbidden :: 403 + %nonexistent :: 404 + %offline :: 504 + == +-- diff --git a/pkg/base-dev/sur/verb.hoon b/pkg/base-dev/sur/verb.hoon new file mode 100644 index 000000000..f7d19f658 --- /dev/null +++ b/pkg/base-dev/sur/verb.hoon @@ -0,0 +1,12 @@ +|% ++$ event + $% [%on-init ~] + [%on-load ~] + [%on-poke =mark] + [%on-watch =path] + [%on-leave =path] + [%on-agent =wire sign=term] + [%on-arvo =wire vane=term sign=term] + [%on-fail =term] + == +-- \ No newline at end of file diff --git a/pkg/base-dev/sys.kelvin b/pkg/base-dev/sys.kelvin new file mode 100644 index 000000000..b7464903a --- /dev/null +++ b/pkg/base-dev/sys.kelvin @@ -0,0 +1 @@ +[%zuse 420] diff --git a/pkg/bitcoin/app/btc-provider.hoon b/pkg/bitcoin/app/btc-provider.hoon new file mode 100644 index 000000000..af4a69488 --- /dev/null +++ b/pkg/bitcoin/app/btc-provider.hoon @@ -0,0 +1,400 @@ +:: btc-provider.hoon +:: Proxy that serves a BTC full node and ElectRS address indexer +:: +:: Subscriptions: none +:: To Subscribers: /clients +:: current connection state +:: results/errors of RPC calls +:: +:: Scrys +:: x/is-whitelisted/SHIP: bool, whether ship is whitelisted +:: +/- *bitcoin, json-rpc, *btc-provider +/+ dbug, default-agent, bl=btc, groupl=group, resource +~% %btc-provider-top ..part ~ +|% ++$ card card:agent:gall ++$ versioned-state + $% state-0 + state-1 + state-2 + == +:: ++$ state-0 [%0 =host-info =whitelist] ++$ state-1 [%1 =host-info =whitelist timer=(unit @da)] ++$ state-2 [%2 =host-info =whitelist timer=(unit @da) interval=@dr] +-- +%- agent:dbug +=| state-2 +=* state - +^- agent:gall +=< +~% %btc-provider-agent ..send-status ~ +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) + hc ~(. +> bowl) +:: +++ on-init + ^- (quip card _this) + =| wl=^whitelist + :- ~ + %_ this + host-info ['' connected=%.n %main block=0 clients=*(set ship)] + whitelist wl(public %.n, kids %.n) + timer ~ + interval ~m1 + == +:: +++ on-save + ^- vase + !>(state) +:: +++ on-load + |= old-state=vase + ^- (quip card _this) + =/ old !<(versioned-state old-state) + ?- -.old + %2 + [~ this(state old)] + :: + %1 + `this(state [%2 host-info.old whitelist.old timer.old ~m1]) + :: + %0 + :_ this(state [%2 host-info.old whitelist.old ~ ~m1]) + ?: =('' api-url.host-info.old) ~ + ~[(start-ping-timer:hc ~s0)] + == +:: +++ on-poke + ~/ %on-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + ?> ?|((team:title our.bowl src.bowl) (is-client:hc src.bowl)) + =^ cards state + ?+ mark (on-poke:def mark vase) + %btc-provider-command + ?> (team:title our.bowl src.bowl) + (handle-command !<(command vase)) + :: + %btc-provider-action + (handle-action !<(action vase)) + :: + %noun + ?. =(q.vase %kick-timer) `state + :_ state(timer `now.bowl) + :* (start-ping-timer ~s0) + ?~ timer ~ + [[%pass /block-time %arvo %b %rest u.timer] ~] + == + == + [cards this] + :: + ++ handle-command + |= comm=command + ^- (quip card _state) + ?- -.comm + %set-credentials + :_ %_ state + host-info [api-url.comm %.n network.comm 0 *(set ship)] + timer `now.bowl + == + :* (start-ping-timer:hc ~s0) + ?~ timer ~ + [[%pass /block-time %arvo %b %rest u.timer] ~] + == + :: + %add-whitelist + :- ~ + ?- -.wt.comm + %public + state(public.whitelist %.y) + :: + %kids + state(kids.whitelist %.y) + :: + %users + state(users.whitelist (~(uni in users.whitelist) users.wt.comm)) + :: + %groups + state(groups.whitelist (~(uni in groups.whitelist) groups.wt.comm)) + == + :: + %remove-whitelist + =. state + ?- -.wt.comm + %public + state(public.whitelist %.n) + :: + %kids + state(kids.whitelist %.n) + :: + %users + state(users.whitelist (~(dif in users.whitelist) users.wt.comm)) + :: + %groups + state(groups.whitelist (~(dif in groups.whitelist) groups.wt.comm)) + == + clean-client-list + :: + %set-interval + `state(interval inte.comm) + == + :: + :: +clean-client-list: remove clients who are no longer whitelisted + :: called after a whitelist change + :: + ++ clean-client-list + ^- (quip card _state) + =/ to-kick=(set ship) + %- silt + %+ murn ~(tap in clients.host-info) + |= c=ship ^- (unit ship) + ?:((is-whitelisted:hc c) ~ `c) + :_ state(clients.host-info (~(dif in clients.host-info) to-kick)) + %+ turn ~(tap in to-kick) + |=(c=ship [%give %kick ~[/clients] `c]) + :: + :: if not connected, only %ping action is allowed + :: + ++ handle-action + |= act=action + ^- (quip card _state) + :_ state + ?. ?|(connected.host-info ?=(%ping -.act)) + ~[(send-update:hc [%| %not-connected 500] ~)] + :_ ~ + %+ req-card act + ^- action:rpc-types + ?- -.act + %address-info [%get-address-info address.act] + %tx-info [%get-tx-vals txid.act] + %raw-tx [%get-raw-tx txid.act] + %broadcast-tx [%broadcast-tx rawtx.act] + %ping [%get-block-info ~] + %block-info [%get-block-info block.act] + == + :: + ++ req-card + |= [act=action ract=action:rpc-types] + =/ req=request:http + (gen-request:bl host-info ract) + [%pass (rpc-wire act) %arvo %i %request req *outbound-config:iris] + :: + ++ rpc-wire + |= act=action + ^- wire + /[-.act]/(scot %p src.bowl)/(scot %ux (cut 3 [0 20] eny.bowl)) + -- +:: +++ on-watch + ~/ %on-watch + |= pax=path + ^- (quip card _this) + :: checking provider permissions before trying to subscribe + :: terrible hack until we have cross-ship scries + :: + ?: ?=([%permitted @ ~] pax) + :_ this + =/ jon=json + %+ frond:enjs:format + %'providerStatus' + %- pairs:enjs:format + :~ provider+s+(scot %p our.bowl) + permitted+b+(is-whitelisted:hc src.bowl) + == + [%give %fact ~ %json !>(jon)]~ + :: + ?> ?| ?=([%clients ~] pax) + ?& ?=([%clients @ ~] pax) + =(src.bowl (slav %p i.t.pax)) + == + == + ?. (is-whitelisted:hc src.bowl) + ~|("btc-provider: blocked client {}" !!) + ~& > "btc-provider: accepted client {}" + `this(clients.host-info (~(put in clients.host-info) src.bowl)) +:: +++ on-arvo + ~/ %on-arvo + |= [wir=wire =sign-arvo] + |^ + ^- (quip card _this) + :: check for connectivity every 30 seconds + :: + ?: ?=([%ping-timer *] wir) + `this + ?: ?=([%block-ping *] wir) + :_ this(timer `(add now.bowl interval)) + :~ do-ping + (start-ping-timer:hc interval) + == + =^ cards state + ?+ +<.sign-arvo (on-arvo:def wir sign-arvo) + %http-response + (handle-rpc-response wir client-response.sign-arvo) + == + [cards this] + :: + ++ do-ping + ^- card + =/ act=action [%ping ~] + :* %pass /ping/[(scot %da now.bowl)] %agent + [our.bowl %btc-provider] %poke + %btc-provider-action !>(act) + == + :: + :: Handles HTTP responses from RPC servers. Parses for errors, + :: then handles response. For actions that require collating multiple + :: RPC calls, uses req-card to call out to RPC again if more + :: information is required. + ++ handle-rpc-response + |= [=wire response=client-response:iris] + ^- (quip card _state) + ?. ?=(%finished -.response) `state + =* status status-code.response-header.response + :: handle error types: connection errors, RPC errors (in order) + :: + =^ conn-err state + (connection-error status) + ?^ conn-err + :_ state(connected.host-info %.n) + :~ (send-status:hc [%disconnected ~] ~) + (send-update:hc [%| u.conn-err] ~) + == + :: + %+ handle-rpc-result wire + %- parse-result:rpc:bl + (get-rpc-response:bl response) + :: + ++ handle-rpc-result + |= [=wire r=result:rpc-types] + ^- (quip card _state) + =/ ship=(unit ship) + (slaw %p (snag 1 wire)) + ?+ -.wire ~|("Unexpected HTTP response" !!) + %address-info + ?> ?=([%get-address-info *] r) + :_ state + ~[(send-update:hc [%.y %address-info +.r] ship)] + :: + %tx-info + ?> ?=([%get-tx-vals *] r) + :_ state + ~[(send-update:hc [%.y %tx-info +.r] ship)] + :: + %raw-tx + ?> ?=([%get-raw-tx *] r) + :_ state + ~[(send-update:hc [%.y %raw-tx +.r] ship)] + :: + %broadcast-tx + ?> ?=([%broadcast-tx *] r) + :_ state + ~[(send-update:hc [%.y %broadcast-tx +.r] ship)] + :: + %ping + ?> ?=([%get-block-info *] r) + :_ state(connected.host-info %.y, block.host-info block.r) + :_ ~ + %- send-status:hc + :_ ~ + ?: =(block.host-info block.r) + [%connected network.host-info block.r fee.r] + [%new-block network.host-info block.r fee.r blockhash.r blockfilter.r] + :: + %block-info + ?> ?=([%get-block-info *] r) + :_ state + ~[(send-update:hc [%.y %block-info network.host-info +.r] ship)] + == + :: + ++ connection-error + |= status=@ud + ^- [(unit error) _state] + ?+ status [`[%rpc-error ~] state] + %200 [~ state] + %400 [`[%bad-request status] state] + %401 [`[%no-auth status] state(connected.host-info %.n)] + %502 [`[%not-connected status] state(connected.host-info %.n)] + %504 [`[%not-connected status] state(connected.host-info %.n)] + == + -- +:: +++ on-peek + ~/ %on-peek + |= pax=path + ^- (unit (unit cage)) + ?+ pax (on-peek:def pax) + [%x %is-whitelisted @t ~] + ``noun+!>((is-whitelisted:hc (ship (slav %p +>-.pax)))) + :: + [%x %is-client @t ~] + ``noun+!>((is-client:hc (ship (slav %p +>-.pax)))) +== +:: +++ on-leave on-leave:def +++ on-agent on-agent:def +++ on-fail on-fail:def +-- +:: helper core +~% %btc-provider-helper ..card ~ +|_ =bowl:gall ++* grp ~(. groupl bowl) +++ send-status + |= [=status ship=(unit ship)] + ^- card + %- ?: ?=(%new-block -.status) + ~&(>> "%new-block: {}" same) + same + =- [%give %fact ~[-] %btc-provider-status !>(status)] + ?~ ship /clients + /clients/(scot %p u.ship) +:: +++ send-update + |= [=update ship=(unit ship)] + ^- card + %- ?: ?=(%.y -.update) + same + ~&(>> "prov. err: {}" same) + =- [%give %fact ~[-] %btc-provider-update !>(update)] + ?~ ship /clients + /clients/(scot %p u.ship) +:: +++ is-whitelisted + ~/ %is-whitelisted + |= user=ship + ^- ? + |^ + ?| public.whitelist + =(our.bowl user) + ?&(kids.whitelist is-kid) + (~(has in users.whitelist) user) + in-group + == + :: + ++ is-kid + =(our.bowl (sein:title our.bowl now.bowl user)) + :: + ++ in-group + =/ gs ~(tap in groups.whitelist) + ?. is-running:grp %.n + |- + ?~ gs %.n + ?: (is-member:grp user i.gs) + %.y + $(gs t.gs) + -- +:: +++ is-client + |= user=ship + ^- ? + (~(has in clients.host-info) user) +:: +++ start-ping-timer + |= interval=@dr + ^- card + [%pass /block-ping %arvo %b %wait (add now.bowl interval)] +-- diff --git a/pkg/bitcoin/app/btc-wallet.hoon b/pkg/bitcoin/app/btc-wallet.hoon new file mode 100644 index 000000000..d2fc5ac70 --- /dev/null +++ b/pkg/bitcoin/app/btc-wallet.hoon @@ -0,0 +1,1383 @@ +:: btc-wallet +:: +:: Scrys +:: x/scanned: (list xpub) of all scanned wallets +:: x/balance/xpub: balance (in sats) of wallet +/- *btc-wallet, bp=btc-provider, settings +/+ dbug, default-agent, bl=btc, bc=bitcoin, bcu=bitcoin-utils, bip32, agentio +~% %btc-wallet-top ..part ~ +|% ++$ card card:agent:gall +:: +++ defaults + |% + ++ params + :* batch-size=20 + fam-limit=10 + piym-limit=3 + == + ++ confs 6 + ++ fee 100 + -- +:: ++$ versioned-state + $% state-0 + state-1 + state-2 + state-3 + == +:: ++$ state-0 + $: %0 + prov=(unit provider) + walts=(map xpub:bc walt-0) + =btc-state + =history + curr-xpub=(unit xpub:bc) + =scans + =params + feybs=(map ship sats) + =piym + =poym + ahistorical-txs=(set txid) + == +:: ++$ base-state + $: prov=(unit provider) + walts=(map xpub:bc walt) + =btc-state + =history + curr-xpub=(unit xpub:bc) + =scans + =params + feybs=(map ship sats) + =piym + =poym + ahistorical-txs=(set txid) + == +:: ++$ state-1 [%1 base-state] ++$ state-2 [%2 base-state] ++$ state-3 [%3 base-state] +-- +=| state-3 +=* state - +%- agent:dbug +^- agent:gall +=< +~% %btc-wallet-agent ..retry-filtered-addrs ~ +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) + hc ~(. +> bowl) + io ~(. agentio bowl) + pass pass:io +:: +++ on-init +^- (quip card _this) + ~& > '%btc-wallet initialized' + :: + =/ warning=event:settings [%put-entry q.byk.bowl %btc-wallet %warning %b %.y] + =/ currency=event:settings [%put-entry q.byk.bowl %btc-wallet %currency %s 'USD'] + =/ cards=(list card) + :~ (poke-our:hc %settings-store %settings-event !>(warning)) + (poke-our:hc %settings-store %settings-event !>(currency)) + == + :: + :- cards + %_ this + state + :* %3 + ~ + *(map xpub:bc walt) + *^btc-state + *^history + ~ + *^scans + params:defaults + *(map ship sats) + *^piym + *^poym + ~ + == + == +:: +++ on-save + ^- vase + !>(state) +:: +++ on-load + |= old-state=vase + ^- (quip card _this) + ~& > '%btc-wallet recompiled' + =/ ver !<(versioned-state old-state) + =| cards=(list card) + |- + ?- -.ver + %3 + [(flop cards) this(state ver)] + :: + %2 + %_ $ + -.ver %3 + cards :_(cards (~(wait pass /migrate-settings) (add now.bowl ~s1))) + == + :: + %1 + =? cards ?=(^ prov.ver) + :_ cards + =/ =dock [host.u.prov.ver %btc-provider] + =/ wir=wire /set-provider/(scot %p host.u.prov.ver) + =/ priv-wire=^wire (welp wir [%priv ~]) + [%pass priv-wire %agent dock %watch /clients/(scot %p our.bowl)] + $(-.ver %2) + :: + %0 + =/ new-walts=(map xpub:bc walt) + %- ~(run by walts.ver) + |= old-walt=walt-0 + ^- walt + old-walt(wilt +6:wilt.old-walt) + $(ver [%1 +.ver(walts new-walts)]) + == +:: +++ on-poke + ~/ %on-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + =^ cards state + ?+ mark (on-poke:def mark vase) + :: + %noun + ?> =(our.bowl src.bowl) + (handle-noun q.vase) + :: + %btc-wallet-command + ?> =(our.bowl src.bowl) + (handle-command !<(command vase)) + :: + %btc-wallet-action + ?< =(our.bowl src.bowl) + (handle-action !<(action vase)) + :: + %btc-wallet-internal + ?> =(our.bowl src.bowl) + (handle-internal !<(internal vase)) + == + [cards this] + :: + ++ handle-noun + |= non=* + ?> ?=(%migrate-settings non) + :_ state + ^- (list card) + =/ bas=path /(scot %p our.bowl)/settings-store/(scot %da now.bowl) + ?. .^(? %gu bas) + ~& [dap.bowl %settings-store-mia] + ~ + ?. .^(? %gx (weld bas /has-bucket/landscape/btc-wallet/noun)) + ~ + =/ dat + .^(data:settings %gx (weld bas /bucket/landscape/btc-wallet/noun)) + ?> ?=(%bucket -.dat) + |^ :- =/ del=event:settings [%del-bucket %landscape %btc-wallet] + (poke-our:hc %settings-store %settings-event !>(del)) + (murn ~(tap by bucket.dat) copy-if-missing) + :: + ++ copy-if-missing + |= [=key:settings =val:settings] + ^- (unit card) + =/ hav=? + .^(? %gx (weld bas /has-entry/[q.byk.bowl]/btc-wallet/[key]/noun)) + ?: hav ~ + ~& [dap.bowl %importing-previous-setting key] + =/ put=event:settings [%put-entry q.byk.bowl %btc-wallet key val] + `(poke-our:hc %settings-store %settings-event !>(put)) + -- + :: + ++ handle-command + |= comm=command + ^- (quip card _state) + ?> (team:title our.bowl src.bowl) + ?- -.comm + %set-provider + |^ + ?~ provider.comm + ?~ prov `state + :_ state(prov ~) + %- zing + :~ (leave-provider host.u.prov) + (give-update:hc %change-provider ~)^~ + == + :_ state(prov `[u.provider.comm %.n]) + ?~ prov + (watch-provider:hc u.provider.comm) + %- zing + :~ (leave-provider host.u.prov) + (watch-provider:hc u.provider.comm) + (give-update:hc %change-provider `[u.provider.comm %.n])^~ + == + :: + ++ leave-provider + |= who=@p + ^- (list card) + =/ wir=wire /set-provider/(scot %p who) + =/ priv-wir=wire (welp wir %priv^~) + :+ [%pass wir %agent who^%btc-provider %leave ~] + [%pass priv-wir %agent who^%btc-provider %leave ~] + ~ + -- + :: + %check-provider + =/ pax /permitted/(scot %p provider.comm) + :_ state + [%pass pax %agent [provider.comm %btc-provider] %watch pax]~ + :: + %check-payee + =/ pax /check-payee/(scot %p payee.comm) + :_ state + [%pass pax %agent [payee.comm %btc-wallet] %watch pax]~ + :: + %set-current-wallet + (set-curr-xpub:hc xpub.comm) + :: + %add-wallet + |^ + ?~ (~(has by walts) xpub.comm) + ((slog ~[leaf+"xpub already in wallet"]) `state) + =/ w=walt (from-xpub:bl +.comm) + =. walts (~(put by walts) xpub.comm w) + =^ c1 state (init-batches xpub.comm (dec max-gap.w)) + =^ c2 state (set-curr-xpub:hc xpub.comm) + [(weld c1 c2) state] + :: + ++ init-batches + |= [=xpub:bc endpoint=idx] + ^- (quip card _state) + =/ b=batch + [(silt (gulf 0 endpoint)) endpoint %.n] + =^ cards0 state (req-scan:hc b xpub %0) + =^ cards1 state (req-scan:hc b xpub %1) + :_ state + [(scan-progress:hc xpub) (weld cards0 cards1)] + -- + :: + %delete-wallet + =* cw curr-xpub.state + =? cw ?&(?=(^ cw) =(u.cw xpub.comm)) + ~ + =. scans (~(del by scans) [xpub.comm %0]) + =: scans (~(del by scans) [xpub.comm %1]) + walts (~(del by walts) xpub.comm) + history + %- ~(rep by history) + |= [[=txid =hest] out=_history] + ?: =(xpub.hest xpub.comm) + (~(del by out) txid) + out + == + [[give-initial:hc]~ state] + :: + %init-payment-external + ?: is-broadcasting:hc + %- (slog ~[leaf+"broadcasting a transaction"]) + [[(give-update:hc %error %tx-being-signed)]~ state] + ?~ curr-xpub + ~|("btc-wallet: no curr-xpub set" !!) + ?: (is-dust:hc value.comm address.comm) + %- (slog ~[leaf+"sending dust"]) + [[(give-update:hc %error %no-dust)]~ state] + :: + ~| "no wallet with xpub" + =/ wal (~(got by walts) u.curr-xpub) + ~| "wallet not scanned yet" + ?> scanned.wal + =/ [tb=(unit txbu) chng=(unit sats)] + %~ with-change sut:bl + :* wal eny.bowl + block.btc-state ~ + feyb.comm ~[[address.comm value.comm ~]] + == + ?~ tb + %- %- slog + ~[leaf+"insufficient balance or not enough confirmed balance"] + [[(give-update:hc %error %insufficient-balance)]~ state] + =^ tb=(unit txbu) state + ?~ chng `state + =/ [addr=address =idx w=walt] + ~(nixt-address wad:bl wal %1) + :_ state(walts (~(put by walts) u.curr-xpub w)) + `(~(add-output txb:bl u.tb) addr u.chng `(~(hdkey wad:bl w %1) idx)) + =/ po=^poym + ?~(tb [~ ~] [tb note.comm]) + :_ state(poym po) + ?~ tb ~ + %+ turn txis.u.tb + |=(=txi (poke-provider:hc %raw-tx txid.utxo.txi)) + :: + :: overwrites any payment being built in poym + :: + %init-payment + ?: =(src.bowl payee.comm) + %- (slog ~[leaf+"can't pay ourselves"]) + [[(give-update:hc %error %cant-pay-ourselves)]~ state] + ?: ?=(%pawn (clan:title payee.comm)) + %- (slog ~[leaf+"no comets"]) + [[(give-update:hc %error %no-comets)]~ state] + ?: is-broadcasting:hc + %- (slog ~[leaf+"broadcasting a transaction"]) + [[(give-update:hc %error %tx-being-signed)]~ state] + =: poym `note.comm + feybs (~(put by feybs) payee.comm feyb.comm) + == + :_ state + ~[(poke-peer:hc payee.comm [%gen-pay-address value.comm note.comm])] + :: + %broadcast-tx + ?~ prov ~|("Provider not connected" !!) + =+ signed=(from-cord:hxb:bcu txhex.comm) + =/ tx-match=? + ?~ txbu.poym %.n + =((get-id:txu:bc (decode:txu:bc signed)) ~(get-txid txb:bl u.txbu.poym)) + :- ?. tx-match + %- (slog leaf+"txid didn't match txid in wallet") + [(give-update:hc %error %broadcast-fail)]~ + ~[(poke-provider:hc [%broadcast-tx signed])] + ?. tx-match state + ?~ txbu.poym state + state(signed-tx.u.txbu.poym `signed) + :: + %gen-new-address + ?~ curr-xpub + ~|("btc-wallet: no curr-xpub set" !!) + ~| "no wallet with xpub" + =/ wal (~(got by walts) u.curr-xpub) + ~| "wallet not scanned yet" + ?> scanned.wal + =/ [addr=address =idx w=walt] + ~(gen-address wad:bl wal %0) + :_ state(walts (~(put by walts) u.curr-xpub w)) + [(give-update:hc %new-address addr)]~ + == + :: + ++ handle-action + |= act=action + ^- (quip card _state) + ?- -.act + :: comets can't pay (could spam address requests) + :: reuses payment address for ship if ship in piym already + :: + %gen-pay-address + ~| "no comets" + ?< ?=(%pawn (clan:title src.bowl)) + ?~ curr-xpub + ~|("btc-wallet: no curr-xpub set" !!) + |^ + =^ cards state reuse-address + ?^ cards + :: if cards returned, means we already have an address + [cards state] + =+ f=(fam:bl our.bowl now.bowl src.bowl) + =+ n=(~(gut by num-fam.piym) f 0) + ?: (gte n fam-limit.params) + ~|("More than {} addresses for moons + planet" !!) + =. num-fam.piym (~(put by num-fam.piym) f +(n)) + =^ a=address state + (generate-address u.curr-xpub %0) + :- ~[(poke-peer:hc src.bowl [%give-pay-address a value.act])] + %_ state + ps.piym + %+ ~(put by ps.piym) src.bowl + `[u.curr-xpub a src.bowl value.act note.act] + == + :: + ++ generate-address + |= [=xpub:bc =chyg] + ~| "no wallet with xpub" + =/ wal=walt (~(got by walts) xpub) + ~| "wallet not scanned yet" + ?> scanned.wal + =/ [addr=address =idx w=walt] + ~(gen-address wad:bl wal chyg) + [addr state(walts (~(put by walts) xpub w))] + :: + ++ reuse-address + ^- (quip card _state) + =* payer src.bowl + =+ p=(~(get by ps.piym) payer) + ?~ p `state + ?^ pend.u.p + ~|("%gen-address: {} already has pending payment to us" !!) + =+ newp=u.p(value value.act) + :_ state(ps.piym (~(put by ps.piym) payer newp)) + ~[(poke-peer:hc payer [%give-pay-address address.newp value.act])] + -- + :: + %give-pay-address + ~| "Can't pay ourselves" + ?< =(src.bowl our.bowl) + ~| "Broadcasting a transaction" + ?< is-broadcasting:hc + ?~ curr-xpub + ~|("btc-wallet-hook: no curr-xpub set" !!) + ?: (is-dust:hc value.act address.act) + %- (slog ~[leaf+"sending dust"]) + [[(give-update:hc %error %no-dust)]~ state] + :: + =/ feyb + %+ ~(gut by feybs) + src.bowl + ?~(fee.btc-state fee:defaults u.fee.btc-state) + |^ + =^ tb=(unit txbu) state + (generate-txbu u.curr-xpub `src.bowl feyb ~[[address.act value.act ~]]) + =/ po=^poym + ?~(tb [~ ~] [tb note.poym]) + :_ state(poym po) + ?~ tb [(give-update:hc %error %insufficient-balance)]~ + %+ turn txis.u.tb + |=(=txi (poke-provider:hc [%raw-tx txid.utxo.txi])) + :: + ++ generate-txbu + |= [=xpub:bc payee=(unit ship) feyb=sats txos=(list txo)] + ^- [(unit txbu) _state] + ~| "no wallet with xpub" + =/ wal (~(got by walts) xpub) + ~| "wallet not scanned yet" + ?> scanned.wal + =/ [tb=(unit txbu) chng=(unit sats)] + %~ with-change sut:bl + [wal eny.bowl block.btc-state payee feyb txos] + ?~ tb + %- %- slog + ~[leaf+"insufficient balance or not enough confirmed balance"] + [tb state] + :: if no change, return txbu; else add change output to txbu + :: + ?~ chng [tb state] + =/ [addr=address =idx w=walt] + ~(nixt-address wad:bl wal %1) + :_ state(walts (~(put by walts) xpub w)) + `(~(add-output txb:bl u.tb) addr u.chng `(~(hdkey wad:bl w %1) idx)) + -- + :: + :: %expect-payment + :: - check that payment is in piym + :: - replace pend.payment with incoming txid (lock) + :: - add txid to pend.piym + :: - request tx-info from provider + :: + %expect-payment + |^ + ~| "%expect-payment: matching payment not in piym" + =/ pay (~(got by ps.piym) src.bowl) + ?> (piym-matches pay) + :_ (update-pend-piym txid.act pay(pend `txid.act)) + ?~ prov ~ + ~[(poke-provider:hc [%tx-info txid.act])] + :: + ++ piym-matches + |= p=payment + ?& =(payer.p src.bowl) + =(value.p value.act) + == + :: + ++ update-pend-piym + |= [txid=hexb p=payment] + ^- _state + ?~ pend.p ~|("update-pend-piym: no pending payment" !!) + %= state + ps.piym (~(put by ps.piym) payer.p p) + pend.piym (~(put by pend.piym) txid p) + == + -- + == + :: + ++ handle-internal + |= intr=internal + ^- (quip card _state) + ?- -.intr + %add-poym-raw-txi + |^ + ?> =(src.bowl our.bowl) + ?~ txbu.poym `state + =. txis.u.txbu.poym + (update-poym-txis txis.u.txbu.poym +.intr) + :_ state + =+ pb=~(to-psbt txb:bl u.txbu.poym) + ?~ pb ~ + =+ vb=~(vbytes txb:bl u.txbu.poym) + =+ fee=~(fee txb:bl u.txbu.poym) + ~& >> "{} vbytes, {<(div fee vb)>} sats/byte, {} sats fee" + %- (slog [%leaf "PSBT: {}"]~) + [(give-update:hc [%psbt u.pb fee])]~ + :: update outgoing payment with a rawtx, if the txid is in poym's txis + :: + ++ update-poym-txis + |= [txis=(list txi) txid=hexb rawtx=hexb] + ^- (list txi) + =| i=@ + |- ?: (gte i (lent txis)) txis + =/ ith=txi (snag i txis) + =? txis =(txid txid.utxo.ith) + (snap txis i `txi`ith(rawtx `rawtx)) + $(i +(i)) + -- + :: + :: delete an incoming/outgoing payment when we see it included in a tx + :: + %close-pym + ?> =(src.bowl our.bowl) + |^ + =^ cards state + ?. included.ti.intr + `state + ?: (~(has by pend.piym) txid.ti.intr) + (piym-to-history ti.intr) + ?: (poym-has-txid txid.ti.intr) + (poym-to-history ti.intr) + `state + =^ cards2 state + (handle-tx-info:hc ti.intr) + :_ state + (weld cards cards2) + :: + ++ poym-has-txid + |= txid=hexb + ^- ? + ?~ txbu.poym %.n + ?~ signed-tx.u.txbu.poym %.n + =(txid (get-id:txu:bc (decode:txu:bc u.signed-tx.u.txbu.poym))) + :: - checks whether poym has a signed tx + :: - checks whether the txid matches that signed tx, if not, skip + :: - clears poym + :: - returns card that adds hest to history + :: + ++ poym-to-history + |= ti=info:tx + ^- (quip card _state) + |^ + ?~ txbu.poym `state + ?~ signed-tx.u.txbu.poym `state + ?. (poym-has-txid txid.ti) + `state + =+ vout=(get-vout txos.u.txbu.poym) + ?~ vout + ~|("poym-to-history: poym should always have an output" !!) + =/ new-hest=hest + %: mk-hest + ti xpub.u.txbu.poym + our.bowl payee.u.txbu.poym + u.vout note.poym + == + :- [(give-update:hc %new-tx new-hest)]~ + %= state + poym [~ ~] + history (~(put by history) txid.ti new-hest) + == + :: + ++ get-vout + |= txos=(list txo) + ^- (unit @ud) + =| idx=@ud + |- ?~ txos ~ + ?~ hk.i.txos `idx + $(idx +(idx), txos t.txos) + -- + :: - checks whether txid in pend.piym + :: - checks whether ti has a matching value output to piym + :: - if no match found, just deletes pend.piym with this tx + :: stops peer from spamming txids + :: - returns card that adds hest to history + :: + ++ piym-to-history + |= ti=info:tx + |^ ^- (quip card _state) + =+ pay=(~(get by pend.piym) txid.ti) + ?~ pay `state + :: if no matching output in piym, + :: delete from pend.piym to stop DDOS of txids + :: + =+ vout=(get-vout value.u.pay) + ?~ vout + `(del-pend-piym txid.ti) + =/ new-hest + (mk-hest ti xpub.u.pay payer.u.pay `our.bowl u.vout note.u.pay) + =. state (del-all-piym txid.ti payer.u.pay) + :- [(give-update:hc %new-tx new-hest)]~ + %_ state + history (~(put by history) txid.ti new-hest) + == + :: + ++ get-vout + |= value=sats + ^- (unit @ud) + =| idx=@ud + =+ os=outputs.ti + |- ?~ os ~ + ?: =(value.i.os value) + `idx + $(os t.os, idx +(idx)) + :: + ++ del-pend-piym + |= txid=hexb + ^- _state + state(pend.piym (~(del by pend.piym) txid.ti)) + :: + ++ del-all-piym + |= [txid=hexb payer=ship] + ^- _state + =+ nf=(~(gut by num-fam.piym) payer 1) + %= state + pend.piym (~(del by pend.piym) txid) + ps.piym (~(del by ps.piym) payer) + num-fam.piym (~(put by num-fam.piym) payer (dec nf)) + == + -- + :: + ++ mk-hest + |= $: ti=info:tx + =xpub:bc + payer=ship + payee=(unit ship) + vout=@ud + note=(unit @t) + == + ^- hest + :* xpub + txid.ti + confs.ti + recvd.ti + (turn inputs.ti |=(i=val:tx [i `payer])) + %+ turn outputs.ti + |= o=val:tx + ?: =(pos.o vout) + :: check whether this is the output that went to payee + [o payee] + [o `payer] + note + == + -- + :: + %fail-broadcast-tx + ?> =(src.bowl our.bowl) + ~& >>> "%fail-broadcast-tx" + :_ state(poym [~ ~]) + [(give-update:hc %error %broadcast-fail)]~ + :: + %succeed-broadcast-tx + ?> =(src.bowl our.bowl) + ~& > "%succeed-broadcast-tx" + :_ state + :- (give-update:hc %broadcast-success ~) + ?~ prov ~ + :- (poke-provider:hc [%tx-info txid.intr]) + ?~ txbu.poym ~ + ?~ payee.u.txbu.poym ~ + :_ ~ + %- poke-peer:hc + :* u.payee.u.txbu.poym + %expect-payment + txid.intr + value:(snag 0 txos.u.txbu.poym) + == + == + -- +:: +++ on-agent + ~/ %on-agent + |= [=wire =sign:agent:gall] + ^- (quip card _this) + |^ + ?+ -.sign (on-agent:def wire sign) + %watch-ack + ?~ p.sign `this + %- (slog leaf+"connection rejected by provider ({})" u.p.sign) + `this + :: + %kick + ?~ prov `this + ?. ?& ?=(%set-provider -.wire) + =(host.u.prov src.bowl) + == + `this + :_ this(prov [~ src.bowl %.n]) + %- zing + :~ (watch-provider:hc src.bowl) + (give-update:hc %change-provider `[src.bowl %.n])^~ + == + :: + %fact + =^ cards state + ?+ p.cage.sign `state + %btc-provider-status + (handle-provider-status !<(status:bp q.cage.sign)) + :: + %btc-provider-update + (handle-provider-update !<(update:bp q.cage.sign)) + :: + %json + ?+ wire `state + [%check-payee @ ~] + =/ who (slav %p i.t.wire) + :_ state + :~ [%give %fact ~[/all] cage.sign] + [%pass wire %agent [who %btc-wallet] %leave ~] + == + :: + [%permitted @ ~] + =/ who (slav %p i.t.wire) + :_ state + :~ [%give %fact ~[/all] cage.sign] + [%pass wire %agent [who %btc-provider] %leave ~] + == + == + == + [cards this] + == + :: + :: +handle-provider-status: handle connectivity updates from provider + :: - retry pend.piym on any %connected event, since we're checking mempool + :: - if status is %connected, retry all pending address lookups + :: - only retry all if previously disconnected + :: - if block is updated, retry all address reqs + :: - if provider's network doesn't match network in our state, leave + :: + ++ handle-provider-status + |= s=status:bp + ^- (quip card _state) + =^ cards state + ?~ prov `state + ?. =(host.u.prov src.bowl) `state + ?- -.s + %new-block + %: on-connected + u.prov network.s + block.s fee.s + `blockhash.s `blockfilter.s + == + :: + %connected + (on-connected u.prov network.s block.s fee.s ~ ~) + :: + %disconnected + `state(prov `u.prov(connected %.n)) + == + :_ state + :+ (give-update:hc %btc-state btc-state) + (give-update:hc %change-provider prov) + cards + :: + ++ on-connected + |= $: p=provider + net=network + block=@ud + fee=(unit sats) + blockhash=(unit hexb) + blockfilter=(unit hexb) + == + ^- (quip card _state) + |^ + :: request block-info for missing blocks + :: if blockhash or blockfilter are ~ request block-info for current block + :: + =| blocks=(list @ud) + =/ gap (sub block block.btc-state) + =? blocks (gth gap 1) + (gulf +(block.btc-state) (dec block)) + =? blocks ?&((gth gap 0) ?|(?=(~ blockhash) ?=(~ blockfilter))) + (snoc blocks block) + =? blocks (gth gap 50) ~ + :_ %_ state + prov `p(connected %.y) + btc-state [block fee now.bowl] + == + %- zing + :~ retry-ahistorical-txs + (retry-pend-piym net) + (retry-block-info blocks) + :: + ?. ?|(!connected.p (gth gap 0)) + ~ + %- zing + :~ (retry-poym net) + (retry-txs net) + (retry-scans net) + == + :: + ?. ?&(?=(^ blockhash) ?=(^ blockfilter) (gth gap 0)) + ~ + (retry-filtered-addrs:hc net u.blockhash u.blockfilter) + :: + ?. (gth gap 50) + ~ + (retry-addrs net) + == + :: + ++ retry-ahistorical-txs + ^- (list card) + %+ turn ~(tap in ahistorical-txs) + |= =txid + (poke-provider:hc [%tx-info txid]) + :: + :: +retry-pend-piym: check whether txids in pend-piym are in mempool + :: + ++ retry-pend-piym + |= =network + ^- (list card) + %+ murn ~(tap by pend.piym) + |= [=txid p=payment] + =/ w (~(get by walts) xpub.p) + ?~ w ~ + ?. =(network network.u.w) ~ + `(poke-provider:hc [%tx-info txid]) + :: + ++ retry-block-info + |= blocks=(list @ud) + %+ turn blocks + |= block=@ud + (poke-provider:hc %block-info `block) + :: + ++ retry-poym + |= =network + ^- (list card) + ?~ txbu.poym ~ + =/ w (~(get by walts) xpub.u.txbu.poym) + ?~ w ~ + ?. =(network network.u.w) ~ + %+ weld + ?~ signed-tx.u.txbu.poym ~ + ~[(poke-provider:hc [%broadcast-tx u.signed-tx.u.txbu.poym])] + %+ turn txis.u.txbu.poym + |= =txi + (poke-provider:hc [%raw-tx ~(get-txid txb:bl u.txbu.poym)]) + :: + :: +retry-txs: get info on txs without enough confirmations + :: + ++ retry-txs + |= =network + ^- (list card) + %+ murn ~(tap by history) + |= [=txid =hest] + =/ w (~(get by walts) xpub.hest) + ?~ w ~ + ?. =(network network.u.w) ~ + ?: (gte confs.hest confs.u.w) ~ + `(poke-provider:hc [%tx-info txid]) + :: + ++ retry-scans + |= =network + ^- (list card) + %- zing + %+ murn ~(tap by scans) + |= [[=xpub:bc =chyg] =batch] + =/ w (~(get by walts) xpub) + ?~ w ~ + ?. =(network network.u.w) ~ + `-:(req-scan:hc batch xpub chyg) + :: + :: +retry-addrs: get info on addresses with unconfirmed UTXOs + :: + ++ retry-addrs + |= =network + ^- (list card) + %- zing + %+ murn ~(val by walts) + |= w=walt + ?. =(network network.w) ~ + ^- (unit (list card)) + :- ~ + %+ turn ~(tap by wach.w) + |= [a=address *] + (poke-provider:hc [%address-info a]) + -- + :: + ++ handle-provider-update + |= upd=update:bp + ^- (quip card _state) + |^ + ?: =(~ prov) `state + ?. =(host:(need prov) src.bowl) `state + ?. ?=(%.y -.upd) `state + ?- -.p.upd + %address-info + :: located in the helper in Scan Logic to keep all of that unified + :: + (handle-address-info address.p.upd utxos.p.upd used.p.upd) + :: + %tx-info + :: TODO: why do we get a nest-fail when using =^ ? + =^ cards=(list card) state + (handle-tx-info:hc info.p.upd) + :_ state + :_ cards + (poke-internal:hc [%close-pym info.p.upd]) + :: + %raw-tx + :_ state + ~[(poke-internal:hc [%add-poym-raw-txi +.p.upd])] + :: + %broadcast-tx + :_ state + ?~ txbu.poym ~ + ?. =(~(get-txid txb:bl u.txbu.poym) txid.p.upd) + ~ + ?: ?|(broadcast.p.upd included.p.upd) + ~[(poke-internal:hc [%succeed-broadcast-tx txid.p.upd])] + :~ (poke-internal:hc [%fail-broadcast-tx txid.p.upd]) + (give-update:hc %cancel-tx txid.p.upd) + == + :: + %block-info + :_ state + %^ retry-filtered-addrs:hc + network.p.upd + blockhash.p.upd + blockfilter.p.upd + == + :: + :: Scan Logic + :: + :: Algorithm + :: Initiate a batch for each chyg, with max-gap idxs in it + :: Watch all of the addresses made from idxs + :: Request info on all addresses from provider + :: When an %address-info comes back: + :: - remove that idx from todo.batch + :: - run check-scan to check whether that chyg is done + :: - if it isn't, refill it with max-gap idxs to scan + :: + :: +handle-address-info: updates scans and wallet with address info + :: + ++ handle-address-info + |= [=address utxos=(set utxo) used=?] + ^- (quip card _state) + =/ ac (address-coords:bl address ~(val by walts)) + ?~ ac + `state + =/ [w=walt =chyg =idx] u.ac + =. walts + %+ ~(put by walts) xpub.w + %+ ~(update-address wad:bl w chyg) + address + [used chyg idx utxos] + :: if transactions haven't made it into history, request transaction info + :: + =^ cards=(list card) ahistorical-txs + %+ roll ~(tap in utxos) + |= [u=utxo cad=(list card) ah=(set txid)] + ^- [(list card) (set txid)] + ?: (~(has by history) txid.u) + [cad ah] + :- [(poke-provider:hc [%tx-info txid.u]) cad] + (~(put by ah) txid.u) + :: if the wallet+chyg is being scanned, update the scan batch + :: + =/ b (~(get by scans) [xpub.w chyg]) + ?~ b + [cards state] + =. scans + (del-scanned u.b(has-used ?|(used has-used.u.b)) xpub.w chyg idx) + ?: empty:(scan-status xpub.w chyg) + =^ scan-cards=(list card) state + (check-scan xpub.w) + [(weld scan-cards cards) state] + :: + [cards state] + :: + :: +del-scanned: delete scanned idxs + :: + ++ del-scanned + |= [b=batch =xpub:bc =chyg to-delete=idx] + ^- ^scans + %+ ~(put by scans) [xpub chyg] + b(todo (~(del in todo.b) to-delete)) + :: + ++ scan-status + |= [=xpub:bc =chyg] + ^- [empty=? done=?] + =/ b=batch (~(got by scans) [xpub chyg]) + =/ empty=? =(0 ~(wyt in todo.b)) + :- empty + ?&(empty ?!(has-used.b)) + :: +check-scan: initiate a scan if one hasn't started + :: check status of scan if one is running + :: + ++ check-scan + |= =xpub:bc + ^- (quip card _state) + =/ s0 (scan-status xpub %0) + =/ s1 (scan-status xpub %1) + ?: ?&(empty.s0 done.s0 empty.s1 done.s1) + (end-scan xpub) + =^ cards0=(list card) state + (bump-batch xpub %0) + =^ cards1=(list card) state + (bump-batch xpub %1) + :_ state + [(scan-progress:hc xpub) (weld cards0 cards1)] + :: + :: delete the xpub from scans and set wallet to scanned + :: + ++ end-scan + |= [=xpub:bc] + ^- (quip card _state) + =/ w=walt (~(got by walts) xpub) + =. scans (~(del by scans) [xpub %0]) + =: scans (~(del by scans) [xpub %1]) + walts (~(put by walts) xpub w(scanned %.y)) + == + %- (slog ~[leaf+"Scanned xpub {}"]) + =^ cards state + (set-curr-xpub:hc xpub) + [[(give-update:hc [%scan-progress ~ ~]) cards] state] + :: + :: +bump-batch + :: if the batch is done but the wallet isn't done scanning, + :: returns new address requests and updated batch + :: + ++ bump-batch + |= [=xpub:bc =chyg] + ^- (quip card _state) + =/ b=batch (~(got by scans) xpub chyg) + =/ s (scan-status xpub chyg) + ?. ?&(empty.s ?!(done.s)) + `state + =/ w=walt (~(got by walts) xpub) + =/ newb=batch + :+ (silt (gulf +(endpoint.b) (add endpoint.b max-gap.w))) + (add endpoint.b max-gap.w) + %.n + (req-scan:hc newb xpub chyg) + -- + -- +:: +++ on-peek + ~/ %on-peek + |= pax=path + ^- (unit (unit cage)) + ?+ pax (on-peek:def pax) + [%x %configured ~] + =/ provider=json + ?~ prov ~ + [%s (scot %p host.u.prov)] + =/ result=json + %- pairs:enjs:format + :~ [%provider provider] + [%'hasWallet' b+?=(^ walts)] + == + ``json+!>(result) + :: + [%x %scanned ~] + ``noun+!>(scanned-wallets:hc) + :: + [%x %balance @ ~] + ``noun+!>((balance:hc (xpub:bc +>-.pax))) + == +:: +++ on-watch + ~/ %on-watch + |= =path + ^- (quip card _this) + ?+ path (on-watch:def path) + [%check-payee @ ~] + =/ who (slav %p i.t.path) + ?> =(who our.bowl) + =/ response=json + %+ frond:enjs:format 'checkPayee' + %- pairs:enjs:format + :~ ['hasWallet' b+?=(^ curr-xpub)] + ['payee' (ship:enjs:format our.bowl)] + == + :_ this + [%give %fact ~ %json !>(response)]~ + :: + [%all ~] + ?> (team:title our.bowl src.bowl) + :_ this + [give-initial:hc]~ + == +:: +++ on-leave on-leave:def +++ on-arvo + |= [=wire sign=sign-arvo] + ^- (quip card _this) + ?. ?=([%migrate-settings ~] wire) (on-arvo:def wire sign) + ?> ?=([%behn *] sign) + (on-poke %noun !>(%migrate-settings)) +++ on-fail on-fail:def +-- +~% %btc-wallet-helper ..card ~ +|_ =bowl:gall +:: +++ retry-filtered-addrs + ~/ %retry-filtered-addrs + |= [=network blockhash=hexb blockfilter=hexb] + ^- (list card) + %- zing + %+ murn ~(val by walts) + |= w=walt + ^- (unit (list card)) + ?. =(network network.w) ~ + :- ~ + %+ turn + %~ tap in + %^ all-match:bip-b158:bc + blockfilter + blockhash + %+ turn ~(tap by wach.w) + |= [a=address *] + [a (to-script-pubkey:adr:bc a)] + |= [a=address spk=hexb] + ^- card + (poke-provider [%address-info a]) +:: +++ handle-tx-info + ~/ %handle-tx-info + |= ti=info:tx + ^- (quip card _state) + |^ + =/ h (~(get by history) txid.ti) + =. ahistorical-txs (~(del in ahistorical-txs) txid.ti) + =/ our-inputs=(set address) + %- silt + %+ skim + %+ turn inputs.ti + |=(=val:tx address.val) + is-our-address + =/ our-outputs=(set address) + %- silt + %+ skim + %+ turn outputs.ti + |=(=val:tx address.val) + is-our-address + :: all our addresses in inputs/outputs of tx + :: + =/ our-addrs=(set address) + (~(uni in our-inputs) our-outputs) + :: + =/ addr-info-cards=(list card) + %+ turn ~(tap in our-addrs) + |= a=address + ^- card + (poke-provider [%address-info a]) + ?: =(0 ~(wyt in our-addrs)) `state + =/ =xpub + xpub.w:(need (address-coords:bl (snag 0 ~(tap in our-addrs)) ~(val by walts))) + :: addresses in wallets, but tx not in history + :: + ?~ h + =/ new-hest=hest (mk-hest xpub our-inputs our-outputs) + =. history (~(put by history) txid.ti new-hest) + :_ state + :+ (give-update %balance current-balance) + (give-update %new-tx new-hest) + addr-info-cards + :: tx in history, but not in mempool/blocks + :: + ?. included.ti + :_ state(history (~(del by history) txid.ti)) + :+ (give-update %balance current-balance) + (give-update %cancel-tx txid.ti) + addr-info-cards + =/ new-hest u.h(confs confs.ti, recvd recvd.ti) + =. history (~(put by history) txid.ti new-hest) + :_ state + :+ (give-update %balance current-balance) + (give-update %new-tx new-hest) + addr-info-cards + :: + ++ mk-hest + :: has tx-info + |= [=xpub:bc our-inputs=(set address) our-outputs=(set address)] + ^- hest + :* xpub + txid.ti + confs.ti + recvd.ti + (turn inputs.ti |=(v=val:tx (is-our-ship our-inputs v))) + (turn outputs.ti |=(v=val:tx (is-our-ship our-outputs v))) + ~ + == + :: + ++ is-our-ship + |= [as=(set address) v=val:tx] + ^- [=val:tx s=(unit ship)] + [v ?:((~(has in as) address.v) `our.bowl ~)] + :: + ++ is-our-address + |=(a=address ?=(^ (address-coords:bl a ~(val by walts)))) + -- +:: +++ set-curr-xpub + |= =xpub + ^- (quip card _state) + ?~ (find ~[xpub] scanned-wallets) `state + =. curr-xpub `xpub + :_ state + [give-initial]~ +:: +:: +req-scan +:: - adds addresses in batch to wallet's watch map as un-used addresses +:: - returns provider %address-info request cards +:: +++ req-scan + ~/ %req-scan + |= [b=batch =xpub:bc =chyg] + ^- (quip card _state) + =/ w=walt (~(got by walts) xpub) + =/ as=(list [address [? ^chyg idx (set utxo)]]) + %+ turn ~(tap in todo.b) + |=(=idx [(~(mk-address wad:bl w chyg) idx) [%.n chyg idx *(set utxo)]]) + =. w + |- ?~ as w + $(as t.as, w (~(update-address wad:bl w chyg) -.i.as +.i.as)) + :- (turn as |=([a=address *] (poke-provider [%address-info a]))) + %_ state + scans + (~(put by scans) [xpub chyg] b) + :: + walts + (~(put by walts) xpub w) + == +:: +++ poke-provider + |= act=action:bp + ^- card + ?~ prov ~|("provider not set" !!) + :* %pass /[(scot %da now.bowl)] + %agent [host.u.prov %btc-provider] + %poke %btc-provider-action !>([act]) + == +:: +++ poke-peer + |= [target=ship act=action] + ^- card + :* %pass /[(scot %da now.bowl)] %agent + [target %btc-wallet] %poke + %btc-wallet-action !>(act) + == +:: +++ poke-internal + |= intr=internal + ^- card + :* %pass /[(scot %da now.bowl)] %agent + [our.bowl %btc-wallet] %poke + %btc-wallet-internal !>(intr) + == +:: +++ poke-our + |= [app=term =cage] + ^- card + [%pass / %agent [our.bowl app] %poke cage] +:: +++ give-update + |= upd=update + ^- card + [%give %fact ~[/all] %btc-wallet-update !>(upd)] +:: +++ scan-progress + |= [=xpub:bc] + |^ ^- card + %- give-update + :+ %scan-progress + (to-idx (~(gut by scans.state) [xpub %0] *batch)) + (to-idx (~(gut by scans.state) [xpub %1] *batch)) + ++ to-idx + |= b=batch + ^- (unit idx:bc) + =/ s=(list idx:bc) + (sort ~(tap in todo.b) lth) + ?~ s ~ `i.s + -- +:: +++ watch-provider + |= who=@p + ^- (list card) + =/ =dock [who %btc-provider] + =/ wir=wire /set-provider/(scot %p who) + =/ priv-wire=^wire (welp wir [%priv ~]) + :+ [%pass wir %agent dock %watch /clients] + [%pass priv-wire %agent dock %watch /clients/(scot %p our.bowl)] + ~ +:: +++ give-initial + ^- card + =^ a=(unit address) state + ?~ curr-xpub `state + =/ uw=(unit walt) (~(get by walts) u.curr-xpub) + ?: ?|(?=(~ uw) ?!(scanned.u.uw)) + ~|("no wallet with xpub or wallet not scanned yet" !!) + =/ [addr=address =idx w=walt] + ~(gen-address wad:bl u.uw %0) + [`addr state(walts (~(put by walts) u.curr-xpub w))] + %- give-update + ^- update + :* %initial + prov + curr-xpub + current-balance + current-history + btc-state + a + == +:: +++ current-balance + ^- (unit [sats sats]) + ?~ curr-xpub ~ + (balance u.curr-xpub) +:: +++ current-history + ^- ^history + ?~ curr-xpub ~ + %- ~(gas by *^history) + %+ skim ~(tap by history) + |= [txid =hest] + =(u.curr-xpub xpub.hest) +:: +++ balance + ~/ %balance + |= =xpub:bc + ^- (unit [sats sats]) + =/ w (~(get by walts) xpub) + ?~ w ~ + =/ values=(list [confirmed=sats unconfirmed=sats]) + %+ turn ~(val by wach.u.w) + |= =addi ^- [sats sats] + %+ roll + %+ turn ~(tap by utxos.addi) + |= =utxo + ^- [sats sats] + ?: (~(spendable sut:bl [u.w eny.bowl block.btc-state ~ 0 ~]) utxo) + [value.utxo 0] + [0 value.utxo] + |= [[a=sats b=sats] out=[p=sats q=sats]] + [(add a p.out) (add b q.out)] + :- ~ + %+ roll values + |= [[a=sats b=sats] out=[p=sats q=sats]] + [(add a p.out) (add b q.out)] +:: +++ is-dust + |= [=sats =address] + ^- ? + %+ lth sats + (mul 3 (input-weight:bc (get-bipt:adr:bc address))) +:: +++ is-broadcasting + ^- ? + ?~ txbu.poym %.n + ?=(^ signed-tx.u.txbu.poym) +:: +++ scanned-wallets + ^- (list xpub:bc) + %+ murn ~(tap by walts) + |= [=xpub:bc w=walt] + ^- (unit xpub:bc) + ?:(scanned.w `xpub ~) +:: +++ gall-scry + |* [=mold app=@tas =path] + .^(mold %gx (weld /(scot %p our.bowl)/[app]/(scot %da now.bowl) path)) +-- diff --git a/pkg/bitcoin/desk.bill b/pkg/bitcoin/desk.bill new file mode 100644 index 000000000..b6851316b --- /dev/null +++ b/pkg/bitcoin/desk.bill @@ -0,0 +1,2 @@ +:~ %btc-wallet +== diff --git a/pkg/bitcoin/desk.docket-0 b/pkg/bitcoin/desk.docket-0 new file mode 100644 index 000000000..284925fa2 --- /dev/null +++ b/pkg/bitcoin/desk.docket-0 @@ -0,0 +1,11 @@ +:~ + title+'Bitcoin' + info+'A Bitcoin Wallet that lets you send and receive Bitcoin directly to and from other Urbit users' + color+0xf9.8e40 + glob-http+['https://bootstrap.urbit.org/glob-0v3.7b5q1.gn30e.cpfem.abmqg.qh77v.glob' 0v3.7b5q1.gn30e.cpfem.abmqg.qh77v] + image+'https://urbit.ewr1.vultrobjects.com/hastuc-dibtux/2021.8.24..02.57.38-bitcoin.svg' + base+'bitcoin' + version+[0 0 1] + license+'MIT' + website+'https://tlon.io' +== diff --git a/pkg/bitcoin/desk.ship b/pkg/bitcoin/desk.ship new file mode 100644 index 000000000..2bc09561a --- /dev/null +++ b/pkg/bitcoin/desk.ship @@ -0,0 +1 @@ +~mister-dister-dozzod-dozzod diff --git a/pkg/arvo/gen/btc-provider/action.hoon b/pkg/bitcoin/gen/btc-provider/action.hoon similarity index 100% rename from pkg/arvo/gen/btc-provider/action.hoon rename to pkg/bitcoin/gen/btc-provider/action.hoon diff --git a/pkg/arvo/gen/btc-provider/command.hoon b/pkg/bitcoin/gen/btc-provider/command.hoon similarity index 100% rename from pkg/arvo/gen/btc-provider/command.hoon rename to pkg/bitcoin/gen/btc-provider/command.hoon diff --git a/pkg/arvo/gen/btc-wallet-check.hoon b/pkg/bitcoin/gen/btc-wallet-check.hoon similarity index 100% rename from pkg/arvo/gen/btc-wallet-check.hoon rename to pkg/bitcoin/gen/btc-wallet-check.hoon diff --git a/pkg/arvo/gen/btc-wallet/action.hoon b/pkg/bitcoin/gen/btc-wallet/action.hoon similarity index 100% rename from pkg/arvo/gen/btc-wallet/action.hoon rename to pkg/bitcoin/gen/btc-wallet/action.hoon diff --git a/pkg/arvo/gen/btc-wallet/command.hoon b/pkg/bitcoin/gen/btc-wallet/command.hoon similarity index 100% rename from pkg/arvo/gen/btc-wallet/command.hoon rename to pkg/bitcoin/gen/btc-wallet/command.hoon diff --git a/pkg/bitcoin/lib/agentio.hoon b/pkg/bitcoin/lib/agentio.hoon new file mode 120000 index 000000000..959a49843 --- /dev/null +++ b/pkg/bitcoin/lib/agentio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/agentio.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/azimuth.hoon b/pkg/bitcoin/lib/azimuth.hoon new file mode 120000 index 000000000..2bacb02b7 --- /dev/null +++ b/pkg/bitcoin/lib/azimuth.hoon @@ -0,0 +1 @@ +../../base-dev/lib/azimuth.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/azimuthio.hoon b/pkg/bitcoin/lib/azimuthio.hoon new file mode 120000 index 000000000..0b5df7063 --- /dev/null +++ b/pkg/bitcoin/lib/azimuthio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/azimuthio.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/bip/b158.hoon b/pkg/bitcoin/lib/bip/b158.hoon new file mode 120000 index 000000000..cba919a85 --- /dev/null +++ b/pkg/bitcoin/lib/bip/b158.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip/b158.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/bip/b173.hoon b/pkg/bitcoin/lib/bip/b173.hoon new file mode 120000 index 000000000..2999150e2 --- /dev/null +++ b/pkg/bitcoin/lib/bip/b173.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip/b173.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/bip/b174.hoon b/pkg/bitcoin/lib/bip/b174.hoon new file mode 120000 index 000000000..bc6cae53b --- /dev/null +++ b/pkg/bitcoin/lib/bip/b174.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip/b174.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/bip32.hoon b/pkg/bitcoin/lib/bip32.hoon new file mode 120000 index 000000000..1cbb7f892 --- /dev/null +++ b/pkg/bitcoin/lib/bip32.hoon @@ -0,0 +1 @@ +../../base-dev/lib/bip32.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/bip39.hoon b/pkg/bitcoin/lib/bip39.hoon new file mode 120000 index 000000000..36c4b7e83 --- /dev/null +++ b/pkg/bitcoin/lib/bip39.hoon @@ -0,0 +1 @@ +../../base-dev/lib/bip39.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/bip39/english.hoon b/pkg/bitcoin/lib/bip39/english.hoon new file mode 120000 index 000000000..f1ea0fe31 --- /dev/null +++ b/pkg/bitcoin/lib/bip39/english.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/bip39/english.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bitcoin-json.hoon b/pkg/bitcoin/lib/bitcoin-json.hoon similarity index 93% rename from pkg/arvo/lib/bitcoin-json.hoon rename to pkg/bitcoin/lib/bitcoin-json.hoon index fb2562932..d51db0b2a 100644 --- a/pkg/arvo/lib/bitcoin-json.hoon +++ b/pkg/bitcoin/lib/bitcoin-json.hoon @@ -110,6 +110,7 @@ %cancel-tx (hexb txid.upd) %new-address (address address.upd) %balance (balance balance.upd) + %scan-progress (scan-progress main.upd change.upd) %error s+error.upd %broadcast-success ~ == @@ -161,6 +162,19 @@ unconfirmed+(numb q.u.b) == :: + ++ scan-progress + |= [main=(unit idx:bitcoin) change=(unit idx:bitcoin)] + |^ ^- json + %- pairs + :~ main+(from-unit main) + change+(from-unit change) + == + ++ from-unit + |= i=(unit idx:bitcoin) + ?~ i ~ + (numb u.i) + -- + :: ++ btc-state |= bs=btc-state:btc-wallet ^- json diff --git a/pkg/bitcoin/lib/bitcoin-utils.hoon b/pkg/bitcoin/lib/bitcoin-utils.hoon new file mode 120000 index 000000000..7cc792906 --- /dev/null +++ b/pkg/bitcoin/lib/bitcoin-utils.hoon @@ -0,0 +1 @@ +../../base-dev/lib/bitcoin-utils.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/bitcoin.hoon b/pkg/bitcoin/lib/bitcoin.hoon similarity index 89% rename from pkg/arvo/lib/bitcoin.hoon rename to pkg/bitcoin/lib/bitcoin.hoon index d790ff5a0..e1dfdabfa 100644 --- a/pkg/arvo/lib/bitcoin.hoon +++ b/pkg/bitcoin/lib/bitcoin.hoon @@ -2,13 +2,13 @@ :: top-level Bitcoin constants :: expose BIP libraries :: -/- sur=bitcoin -/+ bech32=bip-b173, pbt=bip-b174, bcu=bitcoin-utils -=, sur -=, bcu +/- *bitcoin +/+ bech32=bip-b173, pbt=bip-b174, bcu=bitcoin-utils, bip-b158 +~% %bitcoin-lib ..part ~ |% ++ overhead-weight ^-(vbytes 11) ++ input-weight + ~/ %input-weight |= =bipt ^- vbytes ?- bipt @@ -40,8 +40,10 @@ :: adr: address manipulation :: ++ adr + ~% %adr ..overhead-weight ~ |% ++ get-bipt + ~/ %get-bipt |= a=address ^- bipt =/ spk=hexb (to-script-pubkey:adr a) @@ -52,35 +54,39 @@ ~|("Invalid address" !!) :: ++ to-cord + ~/ %to-cord |= a=address ^- cord ?: ?=([%base58 *] a) - (scot %uc +.a) + %- crip + %+ slag 2 + (scow %uc +.a) +.a :: ++ from-pubkey + ~/ %from-pubkey |= [=bipt =network pubkey=hexb] ^- address ?- bipt %44 :- %base58 =< ^-(@uc dat) - %- cat:byt + %- cat:byt:bcu :- ?- network %main 1^0x0 %testnet 1^0x6f == - ~[(hash-160 pubkey)] + ~[(hash-160:bcu pubkey)] :: %49 :- %base58 =< ^-(@uc dat) - %- cat:byt + %- cat:byt:bcu :~ ?- network %main 1^0x5 %testnet 1^0xc4 == - %- hash-160 - (cat:byt ~[2^0x14 (hash-160 pubkey)]) + %- hash-160:bcu + (cat:byt:bcu ~[2^0x14 (hash-160:bcu pubkey)]) == :: %84 @@ -89,6 +95,7 @@ == :: ++ from-cord + ~/ %from-cord |= addrc=@t |^ =/ addrt=tape (trip addrc) @@ -117,12 +124,13 @@ -- :: ++ to-script-pubkey + ~/ %to-script-pubkey |= =address ^- hexb ?- -.address %bech32 =+ h=(from-address:bech32 +.address) - %- cat:byt + %- cat:byt:bcu :~ 1^0x0 1^wid.h h @@ -130,21 +138,21 @@ :: %base58 =/ h=hexb [21 `@ux`+.address] - =+ lead-byt=dat:(take:byt 1 h) + =+ lead-byt=dat:(take:byt:bcu 1 h) =/ version-network=[bipt network] ?: =(0x0 lead-byt) [%44 %main] ?: =(0x6f lead-byt) [%44 %testnet] ?: =(0x5 lead-byt) [%49 %main] ?: =(0xc4 lead-byt) [%49 %testnet] ~|("Invalid base58 address: {<+.address>}" !!) - %- cat:byt + %- cat:byt:bcu ?: ?=(%44 -.version-network) :~ 3^0x76.a914 - (drop:byt 1 h) + (drop:byt:bcu 1 h) 2^0x88ac == :~ 2^0xa914 - (drop:byt 1 h) + (drop:byt:bcu 1 h) 1^0x87 == == @@ -155,6 +163,8 @@ :: - ignores signatures in inputs :: ++ txu + ~% %bitcoin-lib-txu ..overhead-weight ~ + =, bcu |% ++ en |% diff --git a/pkg/arvo/lib/btc-provider.hoon b/pkg/bitcoin/lib/btc-provider.hoon similarity index 86% rename from pkg/arvo/lib/btc-provider.hoon rename to pkg/bitcoin/lib/btc-provider.hoon index 98276607f..ab857b5c4 100644 --- a/pkg/arvo/lib/btc-provider.hoon +++ b/pkg/bitcoin/lib/btc-provider.hoon @@ -1,8 +1,6 @@ /- bp=btc-provider, json-rpc -/+ bc=bitcoin -^? -::=< [sur .] -::=, sur +/+ bc=bitcoin, bcu=bitcoin-utils +~% %btc-provider-lib ..part ~ |% :: +from-epoch: time since Jan 1, 1970 in seconds. :: @@ -25,8 +23,8 @@ ~[['Content-Type' 'application/json']] =, html %- some - %- as-octt:mimes - (en-json body) + %- as-octt:mimes + (en-json body) == :: ++ gen-request @@ -36,6 +34,7 @@ api-url.host-info ract :: ++ rpc + ~/ %rpc =, dejs:format |% ++ parse-result @@ -62,6 +61,7 @@ %get-block-info [id.res (block-info res.res)] == + :: ++ address-info %- ot :~ [%address (cu from-cord:adr:bc so)] @@ -69,47 +69,53 @@ [%used bo] [%block ni] == + :: ++ utxo - %- ot + %- ot :~ ['tx_pos' ni] - ['tx_hash' (cu from-cord:hxb:bc so)] + ['tx_hash' (cu from-cord:hxb:bcu so)] [%height ni] [%value ni] [%recvd (cu from-epoch ni)] == + :: ++ tx-vals %- ot :~ [%included bo] - [%txid (cu from-cord:hxb:bc so)] + [%txid (cu from-cord:hxb:bcu so)] [%confs ni] [%recvd (cu from-epoch ni)] [%inputs (ar tx-val)] [%outputs (ar tx-val)] == + :: ++ tx-val %- ot - :~ [%txid (cu from-cord:hxb:bc so)] + :~ [%txid (cu from-cord:hxb:bcu so)] [%pos ni] [%address (cu from-cord:adr:bc so)] [%value ni] == + :: ++ raw-tx %- ot - :~ [%txid (cu from-cord:hxb:bc so)] - [%rawtx (cu from-cord:hxb:bc so)] + :~ [%txid (cu from-cord:hxb:bcu so)] + [%rawtx (cu from-cord:hxb:bcu so)] == + :: ++ broadcast-tx %- ot - :~ [%txid (cu from-cord:hxb:bc so)] + :~ [%txid (cu from-cord:hxb:bcu so)] [%broadcast bo] [%included bo] == + :: ++ block-info %- ot :~ [%block ni] [%fee (mu ni)] - [%blockhash (cu from-cord:hxb:bc so)] - [%blockfilter (cu from-cord:hxb:bc so)] + [%blockhash (cu from-cord:hxb:bcu so)] + [%blockfilter (cu from-cord:hxb:bcu so)] == -- -- @@ -126,17 +132,17 @@ %get-tx-vals %- get-request %+ mk-url '/gettxvals/' - (to-cord:hxb:bc txid.ract) + (to-cord:hxb:bcu txid.ract) :: %get-raw-tx %- get-request %+ mk-url '/getrawtx/' - (to-cord:hxb:bc txid.ract) + (to-cord:hxb:bcu txid.ract) :: %broadcast-tx %- get-request %+ mk-url '/broadcasttx/' - (to-cord:hxb:bc rawtx.ract) + (to-cord:hxb:bcu rawtx.ract) :: %get-block-count %- get-request diff --git a/pkg/arvo/lib/btc.hoon b/pkg/bitcoin/lib/btc.hoon similarity index 95% rename from pkg/arvo/lib/btc.hoon rename to pkg/bitcoin/lib/btc.hoon index 179431c3d..f1db9d333 100644 --- a/pkg/arvo/lib/btc.hoon +++ b/pkg/bitcoin/lib/btc.hoon @@ -1,7 +1,7 @@ :: lib/btc.hoon :: /- *btc-wallet, json-rpc, bp=btc-provider -/+ bip32, bc=bitcoin +/+ bip32, bc=bitcoin, bcu=bitcoin-utils =, secp:crypto =+ ecc=secp256k1 |% @@ -424,6 +424,7 @@ %get-block-info [id.res (block-info res.res)] == + :: ++ address-info %- ot :~ [%address (cu from-cord:adr:bc so)] @@ -434,7 +435,7 @@ ++ utxo %- ot :~ ['tx_pos' ni] - ['tx_hash' (cu from-cord:hxb:bc so)] + ['tx_hash' (cu from-cord:hxb:bcu so)] [%height ni] [%value ni] [%recvd (cu from-epoch ni)] @@ -442,7 +443,7 @@ ++ tx-vals %- ot :~ [%included bo] - [%txid (cu from-cord:hxb:bc so)] + [%txid (cu from-cord:hxb:bcu so)] [%confs ni] [%recvd (cu from-epoch ni)] [%inputs (ar tx-val)] @@ -450,19 +451,19 @@ == ++ tx-val %- ot - :~ [%txid (cu from-cord:hxb:bc so)] + :~ [%txid (cu from-cord:hxb:bcu so)] [%pos ni] [%address (cu from-cord:adr:bc so)] [%value ni] == ++ raw-tx %- ot - :~ [%txid (cu from-cord:hxb:bc so)] - [%rawtx (cu from-cord:hxb:bc so)] + :~ [%txid (cu from-cord:hxb:bcu so)] + [%rawtx (cu from-cord:hxb:bcu so)] == ++ broadcast-tx %- ot - :~ [%txid (cu from-cord:hxb:bc so)] + :~ [%txid (cu from-cord:hxb:bcu so)] [%broadcast bo] [%included bo] == @@ -470,8 +471,8 @@ %- ot :~ [%block ni] [%fee (mu ni)] - [%blockhash (cu from-cord:hxb:bc so)] - [%blockfilter (cu from-cord:hxb:bc so)] + [%blockhash (cu from-cord:hxb:bcu so)] + [%blockfilter (cu from-cord:hxb:bcu so)] == -- -- @@ -488,25 +489,27 @@ %get-tx-vals %- get-request %+ mk-url '/gettxvals/' - (to-cord:hxb:bc txid.ract) + (to-cord:hxb:bcu txid.ract) :: %get-raw-tx %- get-request %+ mk-url '/getrawtx/' - (to-cord:hxb:bc txid.ract) + (to-cord:hxb:bcu txid.ract) :: %broadcast-tx %- get-request %+ mk-url '/broadcasttx/' - (to-cord:hxb:bc rawtx.ract) + (to-cord:hxb:bcu rawtx.ract) :: %get-block-count %- get-request (mk-url '/getblockcount' '') :: %get-block-info + =/ param=@t + ?~(block.ract '' (rsh [3 2] (scot %ui u.block.ract))) %- get-request - (mk-url '/getblockinfo' '') + (mk-url '/getblockinfo/' param) == ++ mk-url |= [base=@t params=@t] diff --git a/pkg/bitcoin/lib/cram.hoon b/pkg/bitcoin/lib/cram.hoon new file mode 120000 index 000000000..4005e57ee --- /dev/null +++ b/pkg/bitcoin/lib/cram.hoon @@ -0,0 +1 @@ +../../base-dev/lib/cram.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/dbug.hoon b/pkg/bitcoin/lib/dbug.hoon new file mode 120000 index 000000000..04f6855f7 --- /dev/null +++ b/pkg/bitcoin/lib/dbug.hoon @@ -0,0 +1 @@ +../../base-dev/lib/dbug.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/default-agent.hoon b/pkg/bitcoin/lib/default-agent.hoon new file mode 120000 index 000000000..698f6802d --- /dev/null +++ b/pkg/bitcoin/lib/default-agent.hoon @@ -0,0 +1 @@ +../../base-dev/lib/default-agent.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/der.hoon b/pkg/bitcoin/lib/der.hoon new file mode 120000 index 000000000..8446f8e92 --- /dev/null +++ b/pkg/bitcoin/lib/der.hoon @@ -0,0 +1 @@ +../../base-dev/lib/der.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/docket.hoon b/pkg/bitcoin/lib/docket.hoon new file mode 120000 index 000000000..e0f69ee1e --- /dev/null +++ b/pkg/bitcoin/lib/docket.hoon @@ -0,0 +1 @@ +../../garden-dev/lib/docket.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/ethereum.hoon b/pkg/bitcoin/lib/ethereum.hoon new file mode 120000 index 000000000..c0a2772eb --- /dev/null +++ b/pkg/bitcoin/lib/ethereum.hoon @@ -0,0 +1 @@ +../../base-dev/lib/ethereum.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/ethio.hoon b/pkg/bitcoin/lib/ethio.hoon new file mode 120000 index 000000000..9c5b58148 --- /dev/null +++ b/pkg/bitcoin/lib/ethio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/ethio.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/group-store.hoon b/pkg/bitcoin/lib/group-store.hoon similarity index 100% rename from pkg/arvo/lib/group-store.hoon rename to pkg/bitcoin/lib/group-store.hoon diff --git a/pkg/bitcoin/lib/group.hoon b/pkg/bitcoin/lib/group.hoon new file mode 100644 index 000000000..d314cbdd8 --- /dev/null +++ b/pkg/bitcoin/lib/group.hoon @@ -0,0 +1,137 @@ +/- *group +/+ store=group-store, resource +:: +|_ =bowl:gall ++$ card card:agent:gall +:: +++ is-running + .^(? %gu /(scot %p our.bowl)/group-store/(scot %da now.bowl)) +:: +++ resource-for-update + |= =vase + ^- (list resource) + =/ =update:store !<(update:store vase) + ?: ?=(%initial -.update) + ~ + ~[resource.update] +:: +++ scry-for + |* [=mold =path] + =. path + (snoc path %noun) + .^ mold + %gx + (scot %p our.bowl) + %group-store + (scot %da now.bowl) + path + == +++ scry-tag + |= [rid=resource =tag] + ^- (unit (set ship)) + =/ group + (scry-group rid) + ?~ group + ~ + `(~(gut by tags.u.group) tag ~) +:: +++ scry-group + |= rid=resource + ^- (unit group) + %+ scry-for ,(unit group) + `path`groups+(en-path:resource rid) +:: +++ scry-groups + ^- (set resource) + .^ ,(set resource) + %gy + (scot %p our.bowl) + %group-store + (scot %da now.bowl) + /groups + == +:: +++ members + |= rid=resource + ^- (set ship) + =; =group + members.group + (fall (scry-group rid) *group) +:: +++ is-member + |= [=ship group=resource] + ^- ? + =- (~(has in -) ship) + (members group) +:: +++ is-admin + |= [=ship group=resource] + ^- ? + =/ tags tags:(fall (scry-group group) *^group) + =/ admins=(set ^ship) (~(gut by tags) %admin ~) + (~(has in admins) ship) +:: +role-for-ship: get role for user +:: +:: Returns ~ if no such group exists or user is not +:: a member of the group. Returns [~ ~] if the user +:: is a member with no additional role. +++ role-for-ship + |= [rid=resource =ship] + ^- (unit (unit role-tag)) + =/ grp=(unit group) + (scry-group rid) + ?~ grp ~ + (role-for-ship-with-group u.grp rid ship) +:: +++ role-for-ship-with-group + |= [grp=group rid=resource =ship] + ^- (unit (unit role-tag)) + =* group grp + =* policy policy.group + =* tags tags.group + =/ admins=(set ^ship) + (~(gut by tags) %admin ~) + ?: (~(has in admins) ship) + ``%admin + =/ mods + (~(gut by tags) %moderator ~) + ?: (~(has in mods) ship) + ``%moderator + =/ janitors + (~(gut by tags) %janitor ~) + ?: (~(has in janitors) ship) + ``%janitor + ?: (~(has in members.group) ship) + [~ ~] + ~ +:: +++ can-join + |= [rid=resource =ship] + ^- ? + %+ scry-for ,? + ^- path + :- %groups + (weld (en-path:resource rid) /join/(scot %p ship)) +:: +++ get-tagged-ships + |= [rid=resource =tag] + ^- (set ship) + =/ grp=(unit group) + (scry-group rid) + ?~ grp ~ + (get-tagged-ships-with-group u.grp rid tag) +:: +++ get-tagged-ships-with-group + |= [grp=group rid=resource =tag] + ^- (set ship) + (~(get ju tags.grp) tag) +:: +++ is-managed + |= rid=resource + ^- ? + =/ group=(unit group) + (scry-group rid) + ?~ group %.n + !hidden.u.group +:: +-- diff --git a/pkg/bitcoin/lib/jose.hoon b/pkg/bitcoin/lib/jose.hoon new file mode 120000 index 000000000..6bff549ab --- /dev/null +++ b/pkg/bitcoin/lib/jose.hoon @@ -0,0 +1 @@ +../../base-dev/lib/jose.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/keygen.hoon b/pkg/bitcoin/lib/keygen.hoon new file mode 120000 index 000000000..8557d0c52 --- /dev/null +++ b/pkg/bitcoin/lib/keygen.hoon @@ -0,0 +1 @@ +../../base-dev/lib/keygen.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/language-server/build.hoon b/pkg/bitcoin/lib/language-server/build.hoon new file mode 120000 index 000000000..749928056 --- /dev/null +++ b/pkg/bitcoin/lib/language-server/build.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/build.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/language-server/complete.hoon b/pkg/bitcoin/lib/language-server/complete.hoon new file mode 120000 index 000000000..219d824c7 --- /dev/null +++ b/pkg/bitcoin/lib/language-server/complete.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/complete.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/language-server/easy-print.hoon b/pkg/bitcoin/lib/language-server/easy-print.hoon new file mode 120000 index 000000000..2160e2f5a --- /dev/null +++ b/pkg/bitcoin/lib/language-server/easy-print.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/easy-print.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/language-server/json.hoon b/pkg/bitcoin/lib/language-server/json.hoon new file mode 120000 index 000000000..96fe5b516 --- /dev/null +++ b/pkg/bitcoin/lib/language-server/json.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/json.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/language-server/parser.hoon b/pkg/bitcoin/lib/language-server/parser.hoon new file mode 120000 index 000000000..327e1a5de --- /dev/null +++ b/pkg/bitcoin/lib/language-server/parser.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/parser.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/language-server/rune-snippet.hoon b/pkg/bitcoin/lib/language-server/rune-snippet.hoon new file mode 120000 index 000000000..387505b59 --- /dev/null +++ b/pkg/bitcoin/lib/language-server/rune-snippet.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/language-server/rune-snippet.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/mip.hoon b/pkg/bitcoin/lib/mip.hoon new file mode 120000 index 000000000..47b46482a --- /dev/null +++ b/pkg/bitcoin/lib/mip.hoon @@ -0,0 +1 @@ +../../garden-dev/lib/mip.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/ph/io.hoon b/pkg/bitcoin/lib/ph/io.hoon new file mode 120000 index 000000000..9b660df8f --- /dev/null +++ b/pkg/bitcoin/lib/ph/io.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/ph/io.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/ph/util.hoon b/pkg/bitcoin/lib/ph/util.hoon new file mode 120000 index 000000000..ec423efc0 --- /dev/null +++ b/pkg/bitcoin/lib/ph/util.hoon @@ -0,0 +1 @@ +../../../base-dev/lib/ph/util.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/pill.hoon b/pkg/bitcoin/lib/pill.hoon new file mode 120000 index 000000000..41e912cf1 --- /dev/null +++ b/pkg/bitcoin/lib/pill.hoon @@ -0,0 +1 @@ +../../base-dev/lib/pill.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/pkcs.hoon b/pkg/bitcoin/lib/pkcs.hoon new file mode 120000 index 000000000..d7a2ab46f --- /dev/null +++ b/pkg/bitcoin/lib/pkcs.hoon @@ -0,0 +1 @@ +../../base-dev/lib/pkcs.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/primitive-rsa.hoon b/pkg/bitcoin/lib/primitive-rsa.hoon new file mode 120000 index 000000000..f9dde2d95 --- /dev/null +++ b/pkg/bitcoin/lib/primitive-rsa.hoon @@ -0,0 +1 @@ +../../base-dev/lib/primitive-rsa.hoon \ No newline at end of file diff --git a/pkg/arvo/lib/resource.hoon b/pkg/bitcoin/lib/resource.hoon similarity index 100% rename from pkg/arvo/lib/resource.hoon rename to pkg/bitcoin/lib/resource.hoon diff --git a/pkg/bitcoin/lib/ring.hoon b/pkg/bitcoin/lib/ring.hoon new file mode 120000 index 000000000..e5e819947 --- /dev/null +++ b/pkg/bitcoin/lib/ring.hoon @@ -0,0 +1 @@ +../../base-dev/lib/ring.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/server.hoon b/pkg/bitcoin/lib/server.hoon new file mode 120000 index 000000000..6176cfc00 --- /dev/null +++ b/pkg/bitcoin/lib/server.hoon @@ -0,0 +1 @@ +../../base-dev/lib/server.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/shoe.hoon b/pkg/bitcoin/lib/shoe.hoon new file mode 120000 index 000000000..a4aab1dd7 --- /dev/null +++ b/pkg/bitcoin/lib/shoe.hoon @@ -0,0 +1 @@ +../../base-dev/lib/shoe.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/skeleton.hoon b/pkg/bitcoin/lib/skeleton.hoon new file mode 120000 index 000000000..77626a327 --- /dev/null +++ b/pkg/bitcoin/lib/skeleton.hoon @@ -0,0 +1 @@ +../../base-dev/lib/skeleton.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/sole.hoon b/pkg/bitcoin/lib/sole.hoon new file mode 120000 index 000000000..f776890f2 --- /dev/null +++ b/pkg/bitcoin/lib/sole.hoon @@ -0,0 +1 @@ +../../base-dev/lib/sole.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/strand.hoon b/pkg/bitcoin/lib/strand.hoon new file mode 120000 index 000000000..d95df7948 --- /dev/null +++ b/pkg/bitcoin/lib/strand.hoon @@ -0,0 +1 @@ +../../base-dev/lib/strand.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/strandio.hoon b/pkg/bitcoin/lib/strandio.hoon new file mode 120000 index 000000000..0caebfac1 --- /dev/null +++ b/pkg/bitcoin/lib/strandio.hoon @@ -0,0 +1 @@ +../../base-dev/lib/strandio.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/test.hoon b/pkg/bitcoin/lib/test.hoon new file mode 120000 index 000000000..cc50ce7cf --- /dev/null +++ b/pkg/bitcoin/lib/test.hoon @@ -0,0 +1 @@ +../../base-dev/lib/test.hoon \ No newline at end of file diff --git a/pkg/bitcoin/lib/verb.hoon b/pkg/bitcoin/lib/verb.hoon new file mode 120000 index 000000000..939072347 --- /dev/null +++ b/pkg/bitcoin/lib/verb.hoon @@ -0,0 +1 @@ +../../base-dev/lib/verb.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/belt.hoon b/pkg/bitcoin/mar/belt.hoon new file mode 120000 index 000000000..0c8999932 --- /dev/null +++ b/pkg/bitcoin/mar/belt.hoon @@ -0,0 +1 @@ +../../base-dev/mar/belt.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/bill.hoon b/pkg/bitcoin/mar/bill.hoon new file mode 120000 index 000000000..801d99730 --- /dev/null +++ b/pkg/bitcoin/mar/bill.hoon @@ -0,0 +1 @@ +../../base-dev/mar/bill.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/blit.hoon b/pkg/bitcoin/mar/blit.hoon new file mode 120000 index 000000000..3ea8dc943 --- /dev/null +++ b/pkg/bitcoin/mar/blit.hoon @@ -0,0 +1 @@ +../../base-dev/mar/blit.hoon \ No newline at end of file diff --git a/pkg/arvo/mar/btc-provider/action.hoon b/pkg/bitcoin/mar/btc-provider/action.hoon similarity index 100% rename from pkg/arvo/mar/btc-provider/action.hoon rename to pkg/bitcoin/mar/btc-provider/action.hoon diff --git a/pkg/arvo/mar/btc-provider/status.hoon b/pkg/bitcoin/mar/btc-provider/status.hoon similarity index 100% rename from pkg/arvo/mar/btc-provider/status.hoon rename to pkg/bitcoin/mar/btc-provider/status.hoon diff --git a/pkg/arvo/mar/btc-provider/update.hoon b/pkg/bitcoin/mar/btc-provider/update.hoon similarity index 100% rename from pkg/arvo/mar/btc-provider/update.hoon rename to pkg/bitcoin/mar/btc-provider/update.hoon diff --git a/pkg/arvo/mar/btc-wallet/action.hoon b/pkg/bitcoin/mar/btc-wallet/action.hoon similarity index 100% rename from pkg/arvo/mar/btc-wallet/action.hoon rename to pkg/bitcoin/mar/btc-wallet/action.hoon diff --git a/pkg/arvo/mar/btc-wallet/command.hoon b/pkg/bitcoin/mar/btc-wallet/command.hoon similarity index 100% rename from pkg/arvo/mar/btc-wallet/command.hoon rename to pkg/bitcoin/mar/btc-wallet/command.hoon diff --git a/pkg/arvo/mar/btc-wallet/internal.hoon b/pkg/bitcoin/mar/btc-wallet/internal.hoon similarity index 100% rename from pkg/arvo/mar/btc-wallet/internal.hoon rename to pkg/bitcoin/mar/btc-wallet/internal.hoon diff --git a/pkg/arvo/mar/btc-wallet/update.hoon b/pkg/bitcoin/mar/btc-wallet/update.hoon similarity index 100% rename from pkg/arvo/mar/btc-wallet/update.hoon rename to pkg/bitcoin/mar/btc-wallet/update.hoon diff --git a/pkg/bitcoin/mar/docket-0.hoon b/pkg/bitcoin/mar/docket-0.hoon new file mode 120000 index 000000000..2bb549dd9 --- /dev/null +++ b/pkg/bitcoin/mar/docket-0.hoon @@ -0,0 +1 @@ +../../garden-dev/mar/docket-0.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/hoon.hoon b/pkg/bitcoin/mar/hoon.hoon new file mode 120000 index 000000000..95f8f67f9 --- /dev/null +++ b/pkg/bitcoin/mar/hoon.hoon @@ -0,0 +1 @@ +../../base-dev/mar/hoon.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/htm.hoon b/pkg/bitcoin/mar/htm.hoon new file mode 120000 index 000000000..d29e24bac --- /dev/null +++ b/pkg/bitcoin/mar/htm.hoon @@ -0,0 +1 @@ +../../base-dev/mar/htm.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/html.hoon b/pkg/bitcoin/mar/html.hoon new file mode 120000 index 000000000..14a5f8f7b --- /dev/null +++ b/pkg/bitcoin/mar/html.hoon @@ -0,0 +1 @@ +../../base-dev/mar/html.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/httr.hoon b/pkg/bitcoin/mar/httr.hoon new file mode 120000 index 000000000..572665778 --- /dev/null +++ b/pkg/bitcoin/mar/httr.hoon @@ -0,0 +1 @@ +../../base-dev/mar/httr.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/hymn.hoon b/pkg/bitcoin/mar/hymn.hoon new file mode 120000 index 000000000..905156749 --- /dev/null +++ b/pkg/bitcoin/mar/hymn.hoon @@ -0,0 +1 @@ +../../base-dev/mar/hymn.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/js.hoon b/pkg/bitcoin/mar/js.hoon new file mode 120000 index 000000000..00189f4c6 --- /dev/null +++ b/pkg/bitcoin/mar/js.hoon @@ -0,0 +1 @@ +../../base-dev/mar/js.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/json.hoon b/pkg/bitcoin/mar/json.hoon new file mode 120000 index 000000000..e77f85d05 --- /dev/null +++ b/pkg/bitcoin/mar/json.hoon @@ -0,0 +1 @@ +../../base-dev/mar/json.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/json/rpc/response.hoon b/pkg/bitcoin/mar/json/rpc/response.hoon new file mode 120000 index 000000000..52c97c864 --- /dev/null +++ b/pkg/bitcoin/mar/json/rpc/response.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/json/rpc/response.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/kelvin.hoon b/pkg/bitcoin/mar/kelvin.hoon new file mode 120000 index 000000000..195ebe0dc --- /dev/null +++ b/pkg/bitcoin/mar/kelvin.hoon @@ -0,0 +1 @@ +../../base-dev/mar/kelvin.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/language-server/rpc/notification.hoon b/pkg/bitcoin/mar/language-server/rpc/notification.hoon new file mode 120000 index 000000000..b95e54c35 --- /dev/null +++ b/pkg/bitcoin/mar/language-server/rpc/notification.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/language-server/rpc/notification.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/language-server/rpc/request.hoon b/pkg/bitcoin/mar/language-server/rpc/request.hoon new file mode 120000 index 000000000..26203cf5b --- /dev/null +++ b/pkg/bitcoin/mar/language-server/rpc/request.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/language-server/rpc/request.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/language-server/rpc/response.hoon b/pkg/bitcoin/mar/language-server/rpc/response.hoon new file mode 120000 index 000000000..9dddb2cef --- /dev/null +++ b/pkg/bitcoin/mar/language-server/rpc/response.hoon @@ -0,0 +1 @@ +../../../../base-dev/mar/language-server/rpc/response.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/mime.hoon b/pkg/bitcoin/mar/mime.hoon new file mode 120000 index 000000000..0d85898f3 --- /dev/null +++ b/pkg/bitcoin/mar/mime.hoon @@ -0,0 +1 @@ +../../base-dev/mar/mime.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/noun.hoon b/pkg/bitcoin/mar/noun.hoon new file mode 120000 index 000000000..97cc30876 --- /dev/null +++ b/pkg/bitcoin/mar/noun.hoon @@ -0,0 +1 @@ +../../base-dev/mar/noun.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/path.hoon b/pkg/bitcoin/mar/path.hoon new file mode 120000 index 000000000..c07b00064 --- /dev/null +++ b/pkg/bitcoin/mar/path.hoon @@ -0,0 +1 @@ +../../base-dev/mar/path.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/png.hoon b/pkg/bitcoin/mar/png.hoon new file mode 120000 index 000000000..c2d8cf9fa --- /dev/null +++ b/pkg/bitcoin/mar/png.hoon @@ -0,0 +1 @@ +../../base-dev/mar/png.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/purl.hoon b/pkg/bitcoin/mar/purl.hoon new file mode 120000 index 000000000..d0d2cc0de --- /dev/null +++ b/pkg/bitcoin/mar/purl.hoon @@ -0,0 +1 @@ +../../base-dev/mar/purl.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/ship.hoon b/pkg/bitcoin/mar/ship.hoon new file mode 120000 index 000000000..72de2c03c --- /dev/null +++ b/pkg/bitcoin/mar/ship.hoon @@ -0,0 +1 @@ +../../base-dev/mar/ship.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/sole/action.hoon b/pkg/bitcoin/mar/sole/action.hoon new file mode 120000 index 000000000..b349bd771 --- /dev/null +++ b/pkg/bitcoin/mar/sole/action.hoon @@ -0,0 +1 @@ +../../../base-dev/mar/sole/action.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/sole/effect.hoon b/pkg/bitcoin/mar/sole/effect.hoon new file mode 120000 index 000000000..bc11205c0 --- /dev/null +++ b/pkg/bitcoin/mar/sole/effect.hoon @@ -0,0 +1 @@ +../../../base-dev/mar/sole/effect.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/svg.hoon b/pkg/bitcoin/mar/svg.hoon new file mode 120000 index 000000000..2b406c2ac --- /dev/null +++ b/pkg/bitcoin/mar/svg.hoon @@ -0,0 +1 @@ +../../base-dev/mar/svg.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/tang.hoon b/pkg/bitcoin/mar/tang.hoon new file mode 120000 index 000000000..9206e52b2 --- /dev/null +++ b/pkg/bitcoin/mar/tang.hoon @@ -0,0 +1 @@ +../../base-dev/mar/tang.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/tape.hoon b/pkg/bitcoin/mar/tape.hoon new file mode 120000 index 000000000..be51fcb2d --- /dev/null +++ b/pkg/bitcoin/mar/tape.hoon @@ -0,0 +1 @@ +../../base-dev/mar/tape.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/txt-diff.hoon b/pkg/bitcoin/mar/txt-diff.hoon new file mode 120000 index 000000000..1f7c04285 --- /dev/null +++ b/pkg/bitcoin/mar/txt-diff.hoon @@ -0,0 +1 @@ +../../base-dev/mar/txt-diff.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/txt.hoon b/pkg/bitcoin/mar/txt.hoon new file mode 120000 index 000000000..432541575 --- /dev/null +++ b/pkg/bitcoin/mar/txt.hoon @@ -0,0 +1 @@ +../../base-dev/mar/txt.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/udon.hoon b/pkg/bitcoin/mar/udon.hoon new file mode 120000 index 000000000..215e0ada9 --- /dev/null +++ b/pkg/bitcoin/mar/udon.hoon @@ -0,0 +1 @@ +../../base-dev/mar/udon.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/umd.hoon b/pkg/bitcoin/mar/umd.hoon new file mode 120000 index 000000000..9b827a24d --- /dev/null +++ b/pkg/bitcoin/mar/umd.hoon @@ -0,0 +1 @@ +../../base-dev/mar/umd.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/urb.hoon b/pkg/bitcoin/mar/urb.hoon new file mode 120000 index 000000000..2d8112d1d --- /dev/null +++ b/pkg/bitcoin/mar/urb.hoon @@ -0,0 +1 @@ +../../base-dev/mar/urb.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/urbit.hoon b/pkg/bitcoin/mar/urbit.hoon new file mode 120000 index 000000000..70a62a723 --- /dev/null +++ b/pkg/bitcoin/mar/urbit.hoon @@ -0,0 +1 @@ +../../base-dev/mar/urbit.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/woff2.hoon b/pkg/bitcoin/mar/woff2.hoon new file mode 120000 index 000000000..beaf4875c --- /dev/null +++ b/pkg/bitcoin/mar/woff2.hoon @@ -0,0 +1 @@ +../../base-dev/mar/woff2.hoon \ No newline at end of file diff --git a/pkg/bitcoin/mar/xml.hoon b/pkg/bitcoin/mar/xml.hoon new file mode 120000 index 000000000..e6323e215 --- /dev/null +++ b/pkg/bitcoin/mar/xml.hoon @@ -0,0 +1 @@ +../../base-dev/mar/xml.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/aquarium.hoon b/pkg/bitcoin/sur/aquarium.hoon new file mode 120000 index 000000000..1195b2c62 --- /dev/null +++ b/pkg/bitcoin/sur/aquarium.hoon @@ -0,0 +1 @@ +../../base-dev/sur/aquarium.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/asn1.hoon b/pkg/bitcoin/sur/asn1.hoon new file mode 120000 index 000000000..7888cada0 --- /dev/null +++ b/pkg/bitcoin/sur/asn1.hoon @@ -0,0 +1 @@ +../../base-dev/sur/asn1.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/bitcoin.hoon b/pkg/bitcoin/sur/bitcoin.hoon new file mode 120000 index 000000000..d72c2c830 --- /dev/null +++ b/pkg/bitcoin/sur/bitcoin.hoon @@ -0,0 +1 @@ +../../base-dev/sur/bitcoin.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/btc-provider.hoon b/pkg/bitcoin/sur/btc-provider.hoon similarity index 90% rename from pkg/arvo/sur/btc-provider.hoon rename to pkg/bitcoin/sur/btc-provider.hoon index 65c59be46..8f942dc6c 100644 --- a/pkg/arvo/sur/btc-provider.hoon +++ b/pkg/bitcoin/sur/btc-provider.hoon @@ -24,6 +24,7 @@ $% [%set-credentials api-url=@t =network] [%add-whitelist wt=whitelist-target] [%remove-whitelist wt=whitelist-target] + [%set-interval inte=@dr] == +$ action $% [%address-info =address] @@ -31,6 +32,7 @@ [%raw-tx txid=hexb] [%broadcast-tx rawtx=hexb] [%ping ~] + [%block-info block=(unit @ud)] == :: +$ result @@ -38,6 +40,7 @@ [%tx-info =info:tx] [%raw-tx txid=hexb rawtx=hexb] [%broadcast-tx txid=hexb broadcast=? included=?] + [%block-info =network block=@ud fee=(unit sats) blockhash=hexb blockfilter=hexb] == +$ error $% [%not-connected status=@ud] @@ -60,7 +63,7 @@ [%get-raw-tx txid=hexb] [%broadcast-tx rawtx=hexb] [%get-block-count ~] - [%get-block-info ~] + [%get-block-info block=(unit @ud)] == :: +$ result diff --git a/pkg/arvo/sur/btc-wallet.hoon b/pkg/bitcoin/sur/btc-wallet.hoon similarity index 96% rename from pkg/arvo/sur/btc-wallet.hoon rename to pkg/bitcoin/sur/btc-wallet.hoon index 85d30a2ba..790aec3cd 100644 --- a/pkg/arvo/sur/btc-wallet.hoon +++ b/pkg/bitcoin/sur/btc-wallet.hoon @@ -162,6 +162,10 @@ [%new-address =address] [%balance balance=(unit [confirmed=sats unconfirmed=sats])] [%error =error] + :: current index being scanned in each wallet part + :: ~ if scan of that part is done + :: + [%scan-progress main=(unit idx) change=(unit idx)] == :: -- diff --git a/pkg/bitcoin/sur/docket.hoon b/pkg/bitcoin/sur/docket.hoon new file mode 120000 index 000000000..e13676adb --- /dev/null +++ b/pkg/bitcoin/sur/docket.hoon @@ -0,0 +1 @@ +../../garden-dev/sur/docket.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/group-store.hoon b/pkg/bitcoin/sur/group-store.hoon similarity index 100% rename from pkg/arvo/sur/group-store.hoon rename to pkg/bitcoin/sur/group-store.hoon diff --git a/pkg/arvo/sur/group.hoon b/pkg/bitcoin/sur/group.hoon similarity index 100% rename from pkg/arvo/sur/group.hoon rename to pkg/bitcoin/sur/group.hoon diff --git a/pkg/bitcoin/sur/hark-store.hoon b/pkg/bitcoin/sur/hark-store.hoon new file mode 120000 index 000000000..5d606e793 --- /dev/null +++ b/pkg/bitcoin/sur/hark-store.hoon @@ -0,0 +1 @@ +../../garden-dev/sur/hark-store.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/hood.hoon b/pkg/bitcoin/sur/hood.hoon new file mode 120000 index 000000000..b212f501e --- /dev/null +++ b/pkg/bitcoin/sur/hood.hoon @@ -0,0 +1 @@ +../../base-dev/sur/hood.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/json/rpc.hoon b/pkg/bitcoin/sur/json/rpc.hoon new file mode 120000 index 000000000..e499542f6 --- /dev/null +++ b/pkg/bitcoin/sur/json/rpc.hoon @@ -0,0 +1 @@ +../../../base-dev/sur/json/rpc.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/keygen.hoon b/pkg/bitcoin/sur/keygen.hoon new file mode 120000 index 000000000..99bcd5fc8 --- /dev/null +++ b/pkg/bitcoin/sur/keygen.hoon @@ -0,0 +1 @@ +../../base-dev/sur/keygen.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/language-server.hoon b/pkg/bitcoin/sur/language-server.hoon new file mode 120000 index 000000000..a1c726780 --- /dev/null +++ b/pkg/bitcoin/sur/language-server.hoon @@ -0,0 +1 @@ +../../base-dev/sur/language-server.hoon \ No newline at end of file diff --git a/pkg/arvo/sur/resource.hoon b/pkg/bitcoin/sur/resource.hoon similarity index 100% rename from pkg/arvo/sur/resource.hoon rename to pkg/bitcoin/sur/resource.hoon diff --git a/pkg/bitcoin/sur/ring.hoon b/pkg/bitcoin/sur/ring.hoon new file mode 120000 index 000000000..633c96332 --- /dev/null +++ b/pkg/bitcoin/sur/ring.hoon @@ -0,0 +1 @@ +../../base-dev/sur/ring.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/settings.hoon b/pkg/bitcoin/sur/settings.hoon new file mode 120000 index 000000000..c2c70beef --- /dev/null +++ b/pkg/bitcoin/sur/settings.hoon @@ -0,0 +1 @@ +../../garden-dev/sur/settings.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/sole.hoon b/pkg/bitcoin/sur/sole.hoon new file mode 120000 index 000000000..8cac11891 --- /dev/null +++ b/pkg/bitcoin/sur/sole.hoon @@ -0,0 +1 @@ +../../base-dev/sur/sole.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/spider.hoon b/pkg/bitcoin/sur/spider.hoon new file mode 120000 index 000000000..12ae2c187 --- /dev/null +++ b/pkg/bitcoin/sur/spider.hoon @@ -0,0 +1 @@ +../../base-dev/sur/spider.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sur/verb.hoon b/pkg/bitcoin/sur/verb.hoon new file mode 120000 index 000000000..1a6100d9c --- /dev/null +++ b/pkg/bitcoin/sur/verb.hoon @@ -0,0 +1 @@ +../../base-dev/sur/verb.hoon \ No newline at end of file diff --git a/pkg/bitcoin/sys.kelvin b/pkg/bitcoin/sys.kelvin new file mode 100644 index 000000000..b7464903a --- /dev/null +++ b/pkg/bitcoin/sys.kelvin @@ -0,0 +1 @@ +[%zuse 420] diff --git a/pkg/arvo/ted/btc-rpc.hoon b/pkg/bitcoin/ted/btc-rpc.hoon similarity index 95% rename from pkg/arvo/ted/btc-rpc.hoon rename to pkg/bitcoin/ted/btc-rpc.hoon index 81f2ddc46..b11f0c4a0 100644 --- a/pkg/arvo/ted/btc-rpc.hoon +++ b/pkg/bitcoin/ted/btc-rpc.hoon @@ -1,7 +1,7 @@ :: Note: these are for BTC testnet :: /- spider, rpc=json-rpc -/+ strandio, bc=bitcoin +/+ strandio, bc=bitcoin, bcu=bitcoin-utils =, strand=strand:spider => |% @@ -47,9 +47,9 @@ ++ electrs-script-hash |= a=address:bc ^- hexb:bc - %- flip:byt:bc - %- sha256:bc - (script-pubkey:bc a) + %- flip:byt:bcu + %- sha256:bcu + (to-script-pubkey:adr:bc a) :: ++ parse-json-rpc |= =json diff --git a/pkg/arvo/tests/lib/bip/b158.hoon b/pkg/bitcoin/tests/lib/bip/b158.hoon similarity index 93% rename from pkg/arvo/tests/lib/bip/b158.hoon rename to pkg/bitcoin/tests/lib/bip/b158.hoon index 925ca1cfb..ed8cdfce3 100644 --- a/pkg/arvo/tests/lib/bip/b158.hoon +++ b/pkg/bitcoin/tests/lib/bip/b158.hoon @@ -151,9 +151,11 @@ :: ++ check-all-match |= v=match-vector - =+ k=(to-key blockhash.v) + =/ b=hexb (from-cord:hxb (crip blockhash.v)) + =/ inc=(list [address hexb]) (turn inc-spks.v |=(h=hexb [*address h])) + =/ exc=(list [address hexb]) (turn exc-spks.v |=(h=hexb [*address h])) %+ expect-eq - !>(`(set hexb)`(sy inc-spks.v)) - !>(`(set hexb)`(all-match filter.v k (weld inc-spks.v exc-spks.v))) + !>(`(set [address hexb])`(sy inc)) + !>(`(set [address hexb])`(all-match filter.v b (weld inc exc))) -- -- diff --git a/pkg/arvo/tests/lib/bip/b174.hoon b/pkg/bitcoin/tests/lib/bip/b174.hoon similarity index 100% rename from pkg/arvo/tests/lib/bip/b174.hoon rename to pkg/bitcoin/tests/lib/bip/b174.hoon diff --git a/pkg/arvo/tests/lib/bip32.hoon b/pkg/bitcoin/tests/lib/bip32.hoon similarity index 100% rename from pkg/arvo/tests/lib/bip32.hoon rename to pkg/bitcoin/tests/lib/bip32.hoon diff --git a/pkg/arvo/tests/lib/bip39.hoon b/pkg/bitcoin/tests/lib/bip39.hoon similarity index 100% rename from pkg/arvo/tests/lib/bip39.hoon rename to pkg/bitcoin/tests/lib/bip39.hoon diff --git a/pkg/arvo/tests/lib/bitcoin.hoon b/pkg/bitcoin/tests/lib/bitcoin.hoon similarity index 99% rename from pkg/arvo/tests/lib/bitcoin.hoon rename to pkg/bitcoin/tests/lib/bitcoin.hoon index 29bc64eff..2eec93707 100644 --- a/pkg/arvo/tests/lib/bitcoin.hoon +++ b/pkg/bitcoin/tests/lib/bitcoin.hoon @@ -1,4 +1,4 @@ -/+ *test, *bitcoin, bip32 +/+ *test, *bitcoin, *bitcoin-utils, bip32 =, secp:crypto =+ ecc=secp256k1 |% diff --git a/pkg/arvo/tests/lib/btc.hoon b/pkg/bitcoin/tests/lib/btc.hoon similarity index 100% rename from pkg/arvo/tests/lib/btc.hoon rename to pkg/bitcoin/tests/lib/btc.hoon diff --git a/pkg/btc-wallet/.eslintignore b/pkg/btc-wallet/.eslintignore new file mode 100644 index 000000000..8dbaf7dc4 --- /dev/null +++ b/pkg/btc-wallet/.eslintignore @@ -0,0 +1,2 @@ +config/webpack.dev.js +config/webpack.prod.js diff --git a/pkg/btc-wallet/.eslintrc.json b/pkg/btc-wallet/.eslintrc.json new file mode 100644 index 000000000..b4bed6fb2 --- /dev/null +++ b/pkg/btc-wallet/.eslintrc.json @@ -0,0 +1,27 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": ["eslint:recommended", "plugin:react/recommended", "prettier"], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 11, + "sourceType": "module" + }, + "plugins": ["react"], + "rules": { + "react/prop-types": 0 + }, + "settings": { + "react": { + "version": "detect" + } + } +} diff --git a/pkg/btc-wallet/.gitignore b/pkg/btc-wallet/.gitignore new file mode 100644 index 000000000..0b4cb55f9 --- /dev/null +++ b/pkg/btc-wallet/.gitignore @@ -0,0 +1 @@ +.eslintcache diff --git a/pkg/btc-wallet/.husky/.gitignore b/pkg/btc-wallet/.husky/.gitignore new file mode 100644 index 000000000..31354ec13 --- /dev/null +++ b/pkg/btc-wallet/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/pkg/btc-wallet/.husky/pre-commit b/pkg/btc-wallet/.husky/pre-commit new file mode 100755 index 000000000..22cde47be --- /dev/null +++ b/pkg/btc-wallet/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +cd pkg/btc-wallet && npx lint-staged src diff --git a/pkg/btc-wallet/.prettierrc b/pkg/btc-wallet/.prettierrc new file mode 100644 index 000000000..937375d24 --- /dev/null +++ b/pkg/btc-wallet/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": true, + "singleQuote": true +} diff --git a/pkg/btc-wallet/README.md b/pkg/btc-wallet/README.md index 9c8cc6f54..60933f149 100644 --- a/pkg/btc-wallet/README.md +++ b/pkg/btc-wallet/README.md @@ -5,4 +5,4 @@ dojo: it should return with the following hash: -`0v2.3qak4.al612.8m1ig.kg03r.mfide` +`0v758lj.uf0s5.0nh3m.gunn6.942gj` diff --git a/pkg/btc-wallet/config/webpack.dev.js b/pkg/btc-wallet/config/webpack.dev.js index 368de7717..8b3101204 100644 --- a/pkg/btc-wallet/config/webpack.dev.js +++ b/pkg/btc-wallet/config/webpack.dev.js @@ -1,14 +1,15 @@ const path = require('path'); const webpack = require('webpack'); -// const HtmlWebpackPlugin = require('html-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); // const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const urbitrc = require('./urbitrc'); const fs = require('fs-extra'); const _ = require('lodash'); -function copy(src,dest) { - return new Promise((res,rej) => - fs.copy(src,dest, err => err ? rej(err) : res())); +function copy(src, dest) { + return new Promise((res, rej) => + fs.copy(src, dest, (err) => (err ? rej(err) : res())) + ); } class UrbitShipPlugin { @@ -33,29 +34,32 @@ let devServer = { host: '0.0.0.0', disableHostCheck: true, historyApiFallback: true, + publicPath: '/apps/bitcoin/', }; -const router = _.mapKeys(urbitrc.FLEET || {}, (value, key) => `${key}.localhost:9000`); +const router = _.mapKeys( + urbitrc.FLEET || {}, + (value, key) => `${key}.localhost:9000` +); -if(urbitrc.URL) { +if (urbitrc.URL) { devServer = { ...devServer, - index: '', - proxy: { - '/~btc/js/bundle/index.*.js': { + index: 'index.html', + proxy: [ + { target: 'http://localhost:9000', - pathRewrite: (req, path) => { - return '/index.js' - } - }, - '**': { changeOrigin: true, target: urbitrc.URL, router, - // ensure proxy doesn't timeout channels - proxyTimeout: 0 - } - } + context: (path) => { + if (path === '/apps/bitcoin/desk.js') { + return true; + } + return !path.startsWith('/apps/bitcoin'); + }, + }, + ], }; } @@ -63,30 +67,16 @@ module.exports = { node: { fs: 'empty' }, mode: 'development', entry: { - app: './src/index.js' + app: './src/index.tsx', }, module: { rules: [ { test: /\.(j|t)sx?$/, use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env', ['@babel/preset-react', { - runtime: 'automatic', - development: 'true', - importSource: '@welldone-software/why-did-you-render', - }]], - plugins: [ - '@babel/transform-runtime', - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-class-properties', - 'react-hot-loader/babel' - ] - } + loader: 'ts-loader', }, - exclude: /node_modules/ + exclude: /node_modules/, }, { test: /\.css$/i, @@ -96,33 +86,37 @@ module.exports = { // Translates CSS into CommonJS 'css-loader', // Compiles Sass to CSS - 'sass-loader' - ] - } - ] + 'sass-loader', + ], + }, + ], }, resolve: { - extensions: ['.js', '.ts', '.tsx'] + extensions: ['.js', '.ts', '.tsx'], }, devtool: 'inline-source-map', devServer: devServer, plugins: [ - new UrbitShipPlugin(urbitrc) + new UrbitShipPlugin(urbitrc), + new HtmlWebpackPlugin({ + title: 'Bitcoin Wallet', + template: './public/index.html', + }), ], watch: true, watchOptions: { poll: true, - ignored: '/node_modules/' + ignored: '/node_modules/', }, output: { filename: 'index.js', chunkFilename: 'index.js', path: path.resolve(__dirname, '../dist'), - publicPath: '/', - globalObject: 'this' + publicPath: '/apps/bitcoin/', + globalObject: 'this', }, optimization: { minimize: false, - usedExports: true - } + usedExports: true, + }, }; diff --git a/pkg/btc-wallet/config/webpack.prod.js b/pkg/btc-wallet/config/webpack.prod.js index ed7403784..930182af0 100644 --- a/pkg/btc-wallet/config/webpack.prod.js +++ b/pkg/btc-wallet/config/webpack.prod.js @@ -1,60 +1,58 @@ const path = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); // const urbitrc = require('./urbitrc'); module.exports = { node: { fs: 'empty' }, mode: 'production', entry: { - app: './src/index.js' + app: './src/index.tsx', }, module: { rules: [ { - test: /\.jsx?$/, + test: /\.(j|t)sx?$/, use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env', '@babel/preset-react'], - plugins: [ - '@babel/transform-runtime', - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-class-properties' - ] - } + loader: 'ts-loader', }, - exclude: /node_modules/ + exclude: /node_modules/, }, { - test: /\.css$/i, + test: /\.css$/i, use: [ // Creates `style` nodes from JS strings 'style-loader', // Translates CSS into CommonJS 'css-loader', // Compiles Sass to CSS - 'sass-loader' - ] - } - ] + 'sass-loader', + ], + }, + ], }, resolve: { - extensions: ['.js', '.ts', '.tsx'] + extensions: ['.js', '.ts', '.tsx'], }, devtool: 'source-map', plugins: [ - new CleanWebpackPlugin() + new CleanWebpackPlugin(), + new HtmlWebpackPlugin({ + title: 'Bitcoin Wallet', + template: './public/index.html', + }), ], output: { filename: (pathData) => { - return pathData.chunk.name === 'app' ? 'index.[contenthash].js' : '[name].js'; + return pathData.chunk.name === 'app' + ? 'index.[contenthash].js' + : '[name].js'; }, - path: path.resolve(__dirname, `../../arvo/app/btc-wallet/js/bundle`), - publicPath: '/', + path: path.resolve(__dirname, '../dist'), + publicPath: '/apps/bitcoin/', }, optimization: { minimize: true, - usedExports: true - } + usedExports: true, + }, }; diff --git a/pkg/btc-wallet/package-lock.json b/pkg/btc-wallet/package-lock.json index 1f96d7f14..6ade58829 100644 --- a/pkg/btc-wallet/package-lock.json +++ b/pkg/btc-wallet/package-lock.json @@ -1,5 +1,5 @@ { - "name": "urbit-bitcoin-wallet", + "name": "btc-wallet", "version": "0.1.0", "lockfileVersion": 1, "requires": true, @@ -1159,6 +1159,34 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + } + } + }, "@reach/auto-id": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.10.5.tgz", @@ -1402,6 +1430,22 @@ "@types/node": "*" } }, + "@types/history": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", + "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==", + "dev": true + }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dev": true, + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -1413,6 +1457,12 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" }, + "@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -1425,12 +1475,82 @@ "integrity": "sha512-kjivUwDJfIjngzbhooRnOLhGYz6oRFi+L+EpMjxroDYXwDw9lHrJJ43E+dJ6KAd3V3WxWAJ/qZE9XKYHhjPOFQ==", "dev": true }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "dev": true + }, + "@types/react": { + "version": "17.0.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz", + "integrity": "sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", + "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-router": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.16.tgz", + "integrity": "sha512-8d7nR/fNSqlTFGHti0R3F9WwIertOaaA1UEB8/jr5l5mDMOs4CidEgvvYMw4ivqrBK+vtVLxyTj2P+Pr/dtgzg==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react-router-dom": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz", + "integrity": "sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", "dev": true }, + "@types/styled-components": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.11.tgz", + "integrity": "sha512-u8g3bSw9KUiZY+S++gh+LlURGraqBe3MC5I5dygrNjGDHWWQfsmZZRTJ9K9oHU2CqWtxChWmJkDI/gp+TZPQMw==", + "dev": true, + "requires": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "csstype": "^3.0.2" + } + }, "@types/tapable": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz", @@ -1465,6 +1585,12 @@ "source-map": "^0.6.0" } }, + "@types/webpack-env": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.2.tgz", + "integrity": "sha512-vKx7WNQNZDyJveYcHAm9ZxhqSGLYwoyLhrHjLBOkw3a7cT76sTdjgtwyijhk1MaHyRIuSztcVwrUOO/NEu68Dw==", + "dev": true + }, "@types/webpack-sources": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", @@ -1696,6 +1822,22 @@ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1724,6 +1866,23 @@ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, "ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", @@ -1764,6 +1923,15 @@ "resolved": "https://registry.npmjs.org/argon2-wasm/-/argon2-wasm-0.9.0.tgz", "integrity": "sha512-bt5xqrDt5FnA1gdLLouOwi2NN1h9BeML8DmKth7CCYhygoXUEDeIxEMB++q+CUPQ8U5gju065Z0MjI+hVSXX7A==" }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -1788,6 +1956,119 @@ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "dependencies": { + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + } + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } + } + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -1809,6 +2090,18 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + } + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -1859,6 +2152,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", @@ -2617,6 +2916,12 @@ "get-intrinsic": "^1.0.2" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", @@ -2748,6 +3053,12 @@ "source-map": "~0.6.0" } }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, "clean-webpack-plugin": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", @@ -2758,6 +3069,62 @@ "del": "^4.1.1" } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -3052,6 +3419,19 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", @@ -3184,6 +3564,12 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, "cycle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", @@ -3214,11 +3600,23 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, "deep-equal": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz", "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=" }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "deep-rename-keys": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz", @@ -3409,6 +3807,15 @@ "buffer-indexof": "^1.0.0" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -3641,6 +4048,23 @@ } } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + } + } + }, "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -3656,6 +4080,15 @@ "prr": "~1.0.1" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-abstract": { "version": "1.18.0-next.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", @@ -3704,6 +4137,209 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "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 + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz", + "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==", + "dev": true, + "requires": { + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.4", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + } + } + }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", @@ -3714,6 +4350,77 @@ "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -4098,6 +4805,15 @@ "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", "dev": true }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", @@ -4219,6 +4935,47 @@ "resolve-dir": "^1.0.1" } }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -4429,6 +5186,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4451,6 +5214,12 @@ "has-symbols": "^1.0.1" } }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -4910,6 +5679,18 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "husky": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", + "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "dev": true + }, "i": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", @@ -4943,6 +5724,30 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", @@ -5004,6 +5809,12 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", @@ -5045,6 +5856,17 @@ "ipaddr.js": "^1.9.0" } }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -5101,6 +5923,12 @@ "call-bind": "^1.0.0" } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-bigint": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", @@ -5223,6 +6051,12 @@ "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", "dev": true }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -5264,6 +6098,12 @@ "has-symbols": "^1.0.1" } }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -5285,6 +6125,12 @@ "has-symbols": "^1.0.1" } }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -5328,6 +6174,16 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -5339,11 +6195,23 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json3": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", @@ -5366,6 +6234,30 @@ "graceful-fs": "^4.1.6" } }, + "jsx-ast-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "dev": true, + "requires": { + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + }, + "dependencies": { + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, "keccak": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", @@ -5391,6 +6283,217 @@ "is-buffer": "^1.1.5" } }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.0.0.tgz", + "integrity": "sha512-3rsRIoyaE8IphSUtO1RVTFl1e0SLBtxxUOPBtHxQgBHS5/i6nqvjcUfNioMa4BU9yGnPzbO+xkfLtXtxBpCzjw==", + "dev": true, + "requires": { + "chalk": "^4.1.1", + "cli-truncate": "^2.1.0", + "commander": "^7.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^5.0.0", + "listr2": "^3.8.2", + "log-symbols": "^4.1.0", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "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 + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "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" + } + } + } + }, + "listr2": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.10.0.tgz", + "integrity": "sha512-eP40ZHihu70sSmqFNbNy2NL1YwImmlMmPh9WO5sLmPDleurMHt3n+SwEWNu2kzKScexZnkyFtc1VI0z/TGlmpw==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^1.2.2", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, "loader-runner": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", @@ -5430,6 +6533,12 @@ "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -5441,6 +6550,91 @@ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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" + } + } + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + } + }, "loglevel": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", @@ -5566,6 +6760,12 @@ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, + "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 + }, "merkle-lib": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz", @@ -5719,6 +6919,12 @@ "mime-db": "1.46.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -5924,6 +7130,12 @@ } } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -6152,6 +7364,225 @@ "object-keys": "^1.1.1" } }, + "object.entries": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } + } + }, + "object.fromentries": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } + } + }, "object.getownpropertydescriptors": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", @@ -6264,6 +7695,115 @@ "isobject": "^3.0.1" } }, + "object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } + } + }, "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -6302,6 +7842,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -6311,6 +7860,20 @@ "is-wsl": "^1.1.0" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -6427,6 +7990,15 @@ "tslib": "^2.0.3" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-asn1": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", @@ -6440,6 +8012,18 @@ "safe-buffer": "^5.1.1" } }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -6516,6 +8100,12 @@ "isarray": "0.0.1" } }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pbkdf2": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", @@ -6564,6 +8154,15 @@ "find-up": "^4.0.0" } }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -6664,6 +8263,18 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", + "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", + "dev": true + }, "pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", @@ -6686,6 +8297,12 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", @@ -7034,6 +8651,12 @@ "define-properties": "^1.1.3" } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, "regexpu-core": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", @@ -7160,6 +8783,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -7230,6 +8859,16 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -7273,6 +8912,23 @@ "aproba": "^1.1.1" } }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -7369,6 +9025,12 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -7578,6 +9240,25 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "dependencies": { + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + } + } + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -7590,6 +9271,43 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7825,6 +9543,12 @@ "extend-shallow": "^3.0.0" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -7969,6 +9693,12 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -7979,6 +9709,120 @@ "strip-ansi": "^6.0.0" } }, + "string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } + } + }, "string.prototype.trimend": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", @@ -8056,6 +9900,17 @@ } } }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -8070,6 +9925,18 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "style-loader": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", @@ -8169,6 +10036,40 @@ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-4.0.0.tgz", "integrity": "sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ==" }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -8294,6 +10195,18 @@ } } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -8425,6 +10338,130 @@ "resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.1.1.tgz", "integrity": "sha512-74MoNHhwLVuzwaPDcAecFjSkOA9vwWqyOdkeB0Be8Jc/IWSS5SNZKapFllqzkTliqZptkvqX5CZnVeDvfhN8cw==" }, + "ts-loader": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.2.0.tgz", + "integrity": "sha512-ebXBFrNyMSmbWgjnb3WBloUBK+VSx1xckaXsMXxlZRDqce/OPdYBVN5efB0W3V0defq0Gcy4YuzvPGqRgjj85A==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^2.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "tslib": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", @@ -8441,6 +10478,21 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -8463,9 +10515,9 @@ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" }, "typescript": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", - "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true }, "unbox-primitive": { @@ -8583,13 +10635,14 @@ "dev": true }, "urbit-key-generation": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/urbit-key-generation/-/urbit-key-generation-0.18.0.tgz", - "integrity": "sha512-L5yjwfj30sQmJ7KsdtYvQI03A4pluZPf1TumQdrT1MccQYGWB0aedfwTPZnrsXHHqvzGCCQgHBagdMmFBgSddg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/urbit-key-generation/-/urbit-key-generation-0.19.0.tgz", + "integrity": "sha512-lWthsvbVUXfvMFdVewxeP6kAoObQ3+nYh+mZN7+oPVWPjjC94elBnDr4R+WcCfCdWkjzwYk+2hrw2y75ncsVyw==", "requires": { "argon2-wasm": "^0.9.0", "bip32": "^1.0.2", "bip39": "^2.5.0", + "bs58check": "^2.1.2", "js-sha256": "^0.9.0", "keccak": "^1.4.0", "secp256k1": "^3.5.2", @@ -9791,6 +11844,12 @@ } } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "worker-farm": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", @@ -9881,6 +11940,12 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", diff --git a/pkg/btc-wallet/package.json b/pkg/btc-wallet/package.json index 0b0a45604..548132093 100644 --- a/pkg/btc-wallet/package.json +++ b/pkg/btc-wallet/package.json @@ -1,7 +1,8 @@ { - "name": "urbit-bitcoin-wallet", + "name": "btc-wallet", "version": "0.1.0", "main": "node install.js", + "private": true, "scripts": { "start": "webpack-dev-server --config config/webpack.dev.js", "build:dev": "cross-env NODE_ENV=production webpack --config config/webpack.dev.js", @@ -19,17 +20,29 @@ "@babel/preset-env": "^7.9.5", "@babel/preset-react": "^7.9.4", "@babel/preset-typescript": "^7.13.0", + "@types/lodash": "^4.14.171", + "@types/react-dom": "^17.0.9", + "@types/react-router-dom": "^5.1.8", + "@types/styled-components": "^5.1.11", + "@types/webpack-env": "^1.16.2", "@welldone-software/why-did-you-render": "^6.1.1", "babel-loader": "^8.1.0", "babel-plugin-root-import": "^6.5.0", "clean-webpack-plugin": "^3.0.0", "cross-env": "^7.0.2", + "eslint": "^7.29.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-react": "^7.24.0", "file-loader": "^6.0.0", "html-webpack-plugin": "^4.2.0", + "husky": "^6.0.0", + "lint-staged": "^11.0.0", + "prettier": "^2.3.1", "react-hot-loader": "^4.12.21", "sass": "^1.26.5", "sass-loader": "^8.0.2", - "typescript": "^4.2.3", + "ts-loader": "8.2.0", + "typescript": "^4.3.5", "webpack": "^4.43.0", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3" @@ -71,5 +84,9 @@ }, "resolutions": { "natives": "1.1.3" + }, + "lint-staged": { + "*.js": "eslint --cache --fix", + "*.{js,css,md}": "prettier --write" } } diff --git a/pkg/btc-wallet/public/index.html b/pkg/btc-wallet/public/index.html new file mode 100644 index 000000000..3bd422321 --- /dev/null +++ b/pkg/btc-wallet/public/index.html @@ -0,0 +1,30 @@ + + + + Wallet + + + + + + + + + +
+
+ + + + diff --git a/pkg/btc-wallet/src/App.tsx b/pkg/btc-wallet/src/App.tsx new file mode 100644 index 000000000..fb9d0168e --- /dev/null +++ b/pkg/btc-wallet/src/App.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { BrowserRouter } from 'react-router-dom'; +import { ThemeProvider } from 'styled-components'; +import light from './themes/light'; +import { Box, Reset } from '@tlon/indigo-react'; +import StartupModal from './components/StartupModal'; +import { useSettings } from './hooks/useSettings'; +import Body from './components/Body'; +import Header from './components/Header'; + +const App: React.FC = () => { + const { loaded, wallet, provider, scanProgress } = useSettings(); + const scanning = scanProgress?.main !== null || scanProgress?.change !== null; + const blur = !loaded || scanning ? false : !(wallet && provider); + + return ( + + + + {loaded && !scanning ? : null} + +
+ + + + + ); +}; + +export default App; diff --git a/pkg/btc-wallet/src/components/Balance.tsx b/pkg/btc-wallet/src/components/Balance.tsx new file mode 100644 index 000000000..2fcab6afd --- /dev/null +++ b/pkg/btc-wallet/src/components/Balance.tsx @@ -0,0 +1,162 @@ +import React, { useState } from 'react'; +import { Row, Text, Button, Col } from '@tlon/indigo-react'; +import Send from './Send/Send'; +import CurrencyPicker from './CurrencyPicker'; +import { copyToClipboard, satsToCurrency } from '../lib/util'; +import { useSettings } from '../hooks/useSettings'; +import { api } from '../lib/api'; + +const Balance = () => { + const { + address, + confirmedBalance: sats, + unconfirmedBalance: unconfirmedSats, + denomination, + currencyRates, + setPsbt, + setFee, + setError, + scanProgress, + } = useSettings(); + const [sending, setSending] = useState(false); + const [copiedButton, setCopiedButton] = useState(false); + const [copiedString, setCopiedString] = useState(false); + const scanning = scanProgress?.main !== null || scanProgress?.change !== null; + + const copyAddress = async (arg: 'string' | 'button') => { + await copyToClipboard(address); + api.btcWalletCommand({ 'gen-new-address': null }); + + if (arg === 'button') { + setCopiedButton(true); + setTimeout(() => { + setCopiedButton(false); + }, 2000); + } else if (arg === 'string') { + setCopiedString(true); + setTimeout(() => { + setCopiedString(false); + }, 2000); + } + }; + + const unconfirmedString = unconfirmedSats ? ` (${unconfirmedSats}) ` : ''; + + const value = satsToCurrency(sats, denomination, currencyRates); + const sendDisabled = sats === 0; + const addressText = + address === null ? '' : address.slice(0, 6) + '...' + address.slice(-6); + + const conversion = currencyRates[denomination]?.last; + + return ( + <> + {sending ? ( + { + setSending(false); + setPsbt(''); + setFee(0); + setError(''); + }} + /> + ) : ( + + + + Balance + + copyAddress('string')} + > + {copiedString ? 'copied' : addressText} + + + + + + {value} + + {scanning ? ( + + + + Balance will be updated shortly: + + + + + {scanProgress.main === null ? 0 : scanProgress.main} main + wallet addresses scanned + + + + {scanProgress.change === null ? 0 : scanProgress.change}{' '} + change wallet addresses scanned + + + ) : ( + {`${sats}${unconfirmedString} sats`} + )} + + + + + + + )} + + ); +}; + +export default Balance; diff --git a/pkg/btc-wallet/src/components/Body.tsx b/pkg/btc-wallet/src/components/Body.tsx new file mode 100644 index 000000000..0f2bdde38 --- /dev/null +++ b/pkg/btc-wallet/src/components/Body.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { Box, LoadingSpinner, Col } from '@tlon/indigo-react'; +import { Switch, Route } from 'react-router-dom'; +import Balance from './Balance'; +import Transactions from './Transactions/Transactions'; +import Warning from './Warning'; +import Settings from './Settings'; +import { useSettings } from '../hooks/useSettings'; + +const Body: React.FC = () => { + const { loaded, showWarning: warning } = useSettings(); + const cardWidth = window.innerWidth <= 475 ? '350px' : '400px'; + return !loaded ? ( + + + + ) : ( + + + + + + + + + {!warning ? null : } + + + + + + ); +}; + +export default Body; diff --git a/pkg/btc-wallet/src/components/CurrencyPicker.tsx b/pkg/btc-wallet/src/components/CurrencyPicker.tsx new file mode 100644 index 000000000..7e3498d26 --- /dev/null +++ b/pkg/btc-wallet/src/components/CurrencyPicker.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { Icon, Row, Text } from '@tlon/indigo-react'; +import { api } from '../lib/api'; +import { useSettings } from '../hooks/useSettings'; + +const CurrencyPicker = () => { + const { denomination, currencyRates } = useSettings(); + const switchCurrency = () => { + let newCurrency; + if (denomination === 'BTC') { + if ((currencyRates as any)['USD']) { + newCurrency = 'USD'; + } + } else if (denomination === 'USD') { + newCurrency = 'BTC'; + } + console.log({ newCurrency, denomination }); + let setCurrency = { + 'put-entry': { + desk: window.desk, + value: newCurrency, + 'entry-key': 'currency', + 'bucket-key': 'btc-wallet', + }, + }; + api.settingsEvent(setCurrency); + }; + + return ( + switchCurrency()}> + + + {denomination} + + + ); +}; + +export default CurrencyPicker; diff --git a/pkg/btc-wallet/src/components/Error.tsx b/pkg/btc-wallet/src/components/Error.tsx new file mode 100644 index 000000000..cf41266df --- /dev/null +++ b/pkg/btc-wallet/src/components/Error.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Text } from '@tlon/indigo-react'; + +enum ErrorTypes { + 'cant-pay-ourselves' = 'Cannot pay ourselves', + 'no-comets' = 'Cannot pay comets', + 'no-dust' = 'Cannot send dust', + 'tx-being-signed' = 'Cannot pay when transaction is being signed', + 'insufficient-balance' = 'Insufficient confirmed balance', + 'broadcast-fail' = 'Transaction broadcast failed', + 'invalid-master-ticker' = 'Invalid master ticket', + 'invalid-signed' = 'Invalid signed bitcoin transaction', +} + +const Error = ({ + error, + fontSize, + ...rest +}: { + error: string; + fontSize?: string; +}) => ( + + { + (ErrorTypes as any)[ + Object.keys(ErrorTypes).filter((et) => et === error)[0] + ] + } + +); + +export default Error; diff --git a/pkg/btc-wallet/src/components/Header.tsx b/pkg/btc-wallet/src/components/Header.tsx new file mode 100644 index 000000000..4f32d9d41 --- /dev/null +++ b/pkg/btc-wallet/src/components/Header.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { Box, Icon, Row, Text } from '@tlon/indigo-react'; +import { Link } from 'react-router-dom'; +import { useSettings } from '../hooks/useSettings'; + +const Header = () => { + const { provider } = useSettings(); + + let connection = null; + if (!(provider && provider.connected)) { + connection = ( + + Provider Offline + + ); + } + + return ( + + + + + + + Bitcoin + + + + {connection} + + + + + + + + + + + + + ); +}; + +export default Header; diff --git a/pkg/btc-wallet/src/components/ProviderModal.tsx b/pkg/btc-wallet/src/components/ProviderModal.tsx new file mode 100644 index 000000000..73c0d57c5 --- /dev/null +++ b/pkg/btc-wallet/src/components/ProviderModal.tsx @@ -0,0 +1,166 @@ +import React, { useEffect, useState } from 'react'; +import { + Box, + Text, + Button, + StatelessTextInput, + Icon, + Row, + LoadingSpinner, +} from '@tlon/indigo-react'; +import { isValidPatp } from 'urbit-ob'; +import { api } from '../lib/api'; +import { useSettings } from '../hooks/useSettings'; + +enum providerStatuses { + checking, + failed, + ready, + initial = '', +} + +const ProviderModal = () => { + const { providerPerms } = useSettings(); + const [providerStatus, setProviderStatus] = useState( + providerStatuses.initial + ); + const [potentialProvider, setPotentialProvider] = useState(null); + const [provider, setProvider] = useState(null); + const [connecting, setConnecting] = useState(false); + + const checkProvider = (e: React.ChangeEvent) => { + // TODO: loading states + setProviderStatus(providerStatuses.initial); + let givenProvider = e.target.value; + if (isValidPatp(givenProvider)) { + let command = { + 'check-provider': givenProvider, + }; + setPotentialProvider(givenProvider); + setProviderStatus(providerStatuses.checking); + api.btcWalletCommand(command); + setTimeout(() => { + setProviderStatus(providerStatuses.failed); + }, 5000); + } + setProvider(givenProvider); + }; + + const submitProvider = () => { + if (providerStatus === providerStatuses.ready) { + let command = { + 'set-provider': provider, + }; + api.btcWalletCommand(command); + setConnecting(true); + } + }; + + useEffect(() => { + if (providerStatus !== providerStatuses.ready) { + if (providerPerms.provider === provider && providerPerms.permitted) { + setProviderStatus(providerStatuses.ready); + } + } + }, [providerStatus, providerPerms, provider, setProviderStatus]); + + let workingNode = null; + let workingColor = null; + let workingBg = null; + if (providerStatus === providerStatuses.ready) { + workingColor = 'green'; + workingBg = 'veryLightGreen'; + workingNode = ( + + + {provider} is a working provider node + + + ); + } else if (providerStatus === providerStatuses.failed) { + workingColor = 'red'; + workingBg = 'veryLightRed'; + workingNode = ( + + + {potentialProvider} is not a working provider node + + + ); + } + + return ( + + + + + Step 1 of 2: Set up Bitcoin Provider Node + + + + + In order to use the Bitcoin wallet on your ship you'll need to + set a provider node. A provider node is an urbit ship which maintains + a synced Bitcoin ledger. + + {' '} + Learn More + + + + + + Provider Node + + + + ) => + checkProvider(e) + } + /> + {providerStatus === providerStatuses.checking ? ( + + ) : null} + + {workingNode} + + + {connecting ? : null} + + + ); +}; + +export default ProviderModal; diff --git a/pkg/btc-wallet/src/components/Send/BridgeInvoice.tsx b/pkg/btc-wallet/src/components/Send/BridgeInvoice.tsx new file mode 100644 index 000000000..0186bcc82 --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/BridgeInvoice.tsx @@ -0,0 +1,246 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { + Box, + Icon, + StatelessTextInput as Input, + Row, + Text, + Button, + Col, + LoadingSpinner, +} from '@tlon/indigo-react'; +import Sigil from '../Sigil'; +import * as bitcoin from 'bitcoinjs-lib'; +import { isValidPatp } from 'urbit-ob'; +import Sent from './Sent'; +import Error from '../Error'; +import { satsToCurrency } from '../../lib/util'; +import { useSettings } from '../../hooks/useSettings'; +import { api } from '../../lib/api'; + +type Props = { + payee: string; + stopSending: () => void; + satsAmount: number; +}; + +const BridgeInvoice: React.FC = ({ payee, stopSending, satsAmount }) => { + const { + error, + currencyRates, + fee, + broadcastSuccess, + denomination, + psbt, + history, + } = useSettings(); + const [txHex, setTxHex] = useState(''); + const [ready, setReady] = useState(false); + const [historyLength, setHistoryLength] = useState(0); + const [localError, setLocalError] = useState(''); + const [broadcasting, setBroadcasting] = useState(false); + const invoiceRef = useRef(); + + useEffect(() => { + if (broadcasting && localError !== '') { + setBroadcasting(false); + } + if (error !== '') { + setLocalError(error); + } + }, [error, broadcasting, setBroadcasting]); + + useEffect(() => { + window.open('https://bridge.urbit.org/?kind=btc&utx=' + psbt); + }, []); + + useEffect(() => { + if (historyLength === 0) { + setHistoryLength(history.length); + } + if (broadcasting && history.length > historyLength) { + setBroadcasting(false); + stopSending(); + } + }, [history]); + + const broadCastTx = (hex: string) => { + let command = { + 'broadcast-tx': hex, + }; + return api.btcWalletCommand(command); + }; + + const sendBitcoin = (hex: string) => { + try { + bitcoin.Transaction.fromHex(hex); + broadCastTx(hex); + setBroadcasting(true); + } catch (e) { + setLocalError('invalid-signed'); + setBroadcasting(false); + } + }; + + const checkTxHex = (e: React.ChangeEvent) => { + // TODO: validate this hex with something other than length check. + if (e.target.value.length > 0) { + setTxHex(e.target.value); + setReady(true); + setLocalError(''); + } else { + setLocalError('Invalid transaction hex'); + } + }; + + let inputColor = 'black'; + let inputBg = 'white'; + let inputBorder = 'lightGray'; + + if (localError !== '') { + inputColor = 'red'; + inputBg = 'veryLightRed'; + inputBorder = 'red'; + } + + const isShip = isValidPatp(payee); + + const icon = isShip ? ( + + ) : ( + + + + ); + + return ( + <> + {broadcastSuccess ? ( + + ) : ( + + + stopSending()} /> + + + + + {satsToCurrency(satsAmount, denomination, currencyRates)} + + + + {`${satsAmount} sats`} + + + {`Fee: ${satsToCurrency( + fee, + denomination, + currencyRates + )} (${fee} sats)`} + + + + You are paying + + + + {icon} + + {payee} + + + + + + Bridge signed transaction + + + + + Copy the signed transaction from Bridge + + + ) => checkTxHex(e)} + /> + {localError !== '' && ( + + + + )} + + + { + // @ts-ignore + broadcasting ? : null + } + + + )} + + ); +}; + +export default BridgeInvoice; diff --git a/pkg/btc-wallet/src/components/Send/ExternalInvoice.tsx b/pkg/btc-wallet/src/components/Send/ExternalInvoice.tsx new file mode 100644 index 000000000..e4270579d --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/ExternalInvoice.tsx @@ -0,0 +1,298 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { + Box, + Icon, + StatelessTextInput as Input, + Row, + Text, + Button, + Col, + LoadingSpinner, +} from '@tlon/indigo-react'; +import Sigil from '../Sigil'; +import * as bitcoin from 'bitcoinjs-lib'; +import { isValidPatp } from 'urbit-ob'; +import Sent from './Sent'; +import Error from '../Error'; +import { copyToClipboard, satsToCurrency } from '../../lib/util'; +import { useSettings } from '../../hooks/useSettings'; +import { api } from '../../lib/api'; + +type Props = { + payee: string; + stopSending: () => void; + satsAmount: number; +}; + +const ExternalInvoice: React.FC = ({ + payee, + stopSending, + satsAmount, +}) => { + const { + error, + currencyRates, + fee, + broadcastSuccess, + denomination, + psbt, + history, + } = useSettings(); + const [txHex, setTxHex] = useState(''); + const [ready, setReady] = useState(false); + const [historyLength, setHistoryLength] = useState(0); + const [localError, setLocalError] = useState(''); + const [broadcasting, setBroadcasting] = useState(false); + const invoiceRef = useRef(); + + useEffect(() => { + if (broadcasting && localError !== '') { + setBroadcasting(false); + } + if (error !== '') { + setLocalError(error); + } + }, [error, broadcasting, setBroadcasting]); + + useEffect(() => { + if (historyLength === 0) { + setHistoryLength(history.length); + } + if (broadcasting && history.length > historyLength) { + setBroadcasting(false); + stopSending(); + } + }, [history]); + + const broadCastTx = (hex: string) => { + let command = { + 'broadcast-tx': hex, + }; + return api.btcWalletCommand(command); + }; + + const sendBitcoin = (hex: string) => { + try { + bitcoin.Transaction.fromHex(hex); + broadCastTx(hex); + setBroadcasting(true); + } catch (e) { + setLocalError('invalid-signed'); + setBroadcasting(false); + } + }; + + const checkTxHex = (e: React.ChangeEvent) => { + // TODO: validate this hex with something other than length check. + if (e.target.value.length > 0) { + setTxHex(e.target.value); + setReady(true); + setLocalError(''); + } else { + setLocalError('Invalid transaction hex'); + } + }; + + const copyPsbt = () => { + copyToClipboard(psbt); + }; + + const downloadPsbtFile = () => { + const blob = new Blob([psbt]); + const downloadURL = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = downloadURL; + link.setAttribute('download', 'urbit.psbt'); + document.body.appendChild(link); + link.click(); + link.parentNode.removeChild(link); + }; + + let inputColor = 'black'; + let inputBg = 'white'; + let inputBorder = 'lightGray'; + + if (localError !== '') { + inputColor = 'red'; + inputBg = 'veryLightRed'; + inputBorder = 'red'; + } + + const isShip = isValidPatp(payee); + + const icon = isShip ? ( + + ) : ( + + + + ); + + return ( + <> + {broadcastSuccess ? ( + + ) : ( + + + stopSending()} /> + + + + + {satsToCurrency(satsAmount, denomination, currencyRates)} + + + + {`${satsAmount} sats`} + + + {`Fee: ${satsToCurrency( + fee, + denomination, + currencyRates + )} (${fee} sats)`} + + + + You are paying + + + + {icon} + + {payee} + + + + + + Partially-signed Bitcoin Transaction (PSBT) + + + + + + + + + + + Signed Tx + + ) => + checkTxHex(e) + } + /> + {localError !== '' && ( + + + + )} + + + + {broadcasting ? : null} + + + )} + + ); +}; + +export default ExternalInvoice; diff --git a/pkg/btc-wallet/src/components/Send/FeePicker.tsx b/pkg/btc-wallet/src/components/Send/FeePicker.tsx new file mode 100644 index 000000000..b84ef01b7 --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/FeePicker.tsx @@ -0,0 +1,100 @@ +import React, { useEffect, useRef } from 'react'; +import { + Box, + Text, + Col, + StatelessRadioButtonField as RadioButton, + Label, +} from '@tlon/indigo-react'; +import { FeeChoices, feeLevels } from './Send'; + +type Props = { + feeChoices: FeeChoices; + feeValue: number; + setFeeValue: React.Dispatch; + feeDismiss: () => void; +}; + +const FeePicker: React.FC = ({ + feeChoices, + feeValue, + setFeeValue, + feeDismiss, +}) => { + const modalRef = useRef(null); + const clickDismiss = (e: any) => { + if (modalRef && !modalRef.current.contains(e.target)) { + feeDismiss(); + } + }; + useEffect(() => { + document.addEventListener('click', clickDismiss); + return () => { + document.removeEventListener('click', clickDismiss); + }; + }, []); + + return ( + + + Transaction Speed + + + { + setFeeValue(feeLevels.low); + feeDismiss(); + }} + > + + + + { + setFeeValue(feeLevels.mid); + feeDismiss(); + }} + > + + + + { + setFeeValue(feeLevels.high); + feeDismiss(); + }} + > + + + + + ); +}; + +export default FeePicker; diff --git a/pkg/btc-wallet/src/components/Send/Invoice.tsx b/pkg/btc-wallet/src/components/Send/Invoice.tsx new file mode 100644 index 000000000..ba4675bd7 --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/Invoice.tsx @@ -0,0 +1,292 @@ +import React, { useState, useEffect } from 'react'; +import { + Box, + Icon, + StatelessTextInput as Input, + Row, + Text, + Button, + Col, + LoadingSpinner, +} from '@tlon/indigo-react'; +import * as kg from 'urbit-key-generation'; +import { patp2dec, isValidPatq, isValidPatp } from 'urbit-ob'; +import * as bitcoin from 'bitcoinjs-lib'; +import Sigil from '../Sigil'; +import Sent from './Sent'; +import { satsToCurrency } from '../../lib/util'; +import Error from '../Error'; +import { useSettings } from '../../hooks/useSettings'; +import { api } from '../../lib/api'; +import { UrbitWallet } from '../../types'; + +const BITCOIN_MAINNET_INFO = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bech32: 'bc', + bip32: { + public: 0x04b24746, + private: 0x04b2430c, + }, + pubKeyHash: 0x00, + scriptHash: 0x05, + wif: 0x80, +}; + +const BITCOIN_TESTNET_INFO = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bech32: 'tb', + bip32: { + public: 0x045f1cf6, + private: 0x045f18bc, + }, + pubKeyHash: 0x6f, + scriptHash: 0xc4, + wif: 0xef, +}; + +type Props = { + stopSending: () => void; + payee: string; + satsAmount: number; +}; + +const Invoice: React.FC = ({ stopSending, payee, satsAmount }) => { + const { + error, + currencyRates, + psbt, + fee, + broadcastSuccess, + network, + denomination, + history, + } = useSettings(); + const [masterTicket, setMasterTicket] = useState(''); + const [ready, setReady] = useState(false); + const [historyLength, setHistoryLength] = useState(0); + const [localError, setLocalError] = useState(error); + const [broadcasting, setBroadcasting] = useState(false); + + useEffect(() => { + if (broadcasting && localError !== '') { + setBroadcasting(false); + } + }, [error, broadcasting, setBroadcasting]); + + const broadCastTx = (psbtHex: string) => { + let command = { + 'broadcast-tx': psbtHex, + }; + return api.btcWalletCommand(command); + }; + + useEffect(() => { + if (historyLength === 0) { + setHistoryLength(history.length); + } + if (broadcasting && history.length > historyLength) { + setBroadcasting(false); + stopSending(); + } + }, [history]); + + const sendBitcoin = (ticket: string, psbt: string) => { + const newPsbt = bitcoin.Psbt.fromBase64(psbt); + setBroadcasting(true); + kg.generateWallet({ + ticket, + ship: parseInt(patp2dec('~' + window.ship)), + }).then((urbitWallet: UrbitWallet) => { + // this wasn't being used, not clear why it was pulled out. + // const { xpub } = + // network === 'testnet' + // ? urbitWallet.bitcoinTestnet.keys + // : urbitWallet.bitcoinMainnet.keys; + + const { xprv: zprv } = urbitWallet.bitcoinMainnet.keys; + const { xprv: vprv } = urbitWallet.bitcoinTestnet.keys; + + const isTestnet = network === 'testnet'; + const derivationPrefix = isTestnet ? "m/84'/1'/0'/" : "m/84'/0'/0'/"; + + const btcWallet = isTestnet + ? bitcoin.bip32.fromBase58(vprv, BITCOIN_TESTNET_INFO) + : bitcoin.bip32.fromBase58(zprv, BITCOIN_MAINNET_INFO); + + try { + const hex = newPsbt.data.inputs + .reduce((psbt, input, idx) => { + // removing already derived part, eg m/84'/0'/0'/0/0 becomes 0/0 + const path = input.bip32Derivation[0].path + .split(derivationPrefix) + .join(''); + const prv = btcWallet.derivePath(path).privateKey; + return psbt.signInput(idx, bitcoin.ECPair.fromPrivateKey(prv)); + }, newPsbt) + .finalizeAllInputs() + .extractTransaction() + .toHex(); + + broadCastTx(hex); + } catch (e) { + setLocalError('invalid-master-ticket'); + setBroadcasting(false); + } + }); + }; + + const checkTicket = ({ + target: { value }, + }: React.ChangeEvent) => { + // TODO: port over bridge ticket validation logic + setMasterTicket(value); + setReady(isValidPatq(value)); + setLocalError(isValidPatq(value) ? '' : 'invalid-master-ticket'); + }; + + let inputColor = 'black'; + let inputBg = 'white'; + let inputBorder = 'lightGray'; + + if (error !== '') { + inputColor = 'red'; + inputBg = 'veryLightRed'; + inputBorder = 'red'; + } + + const isShip = isValidPatp(payee); + + const icon = isShip ? ( + + ) : ( + + + + ); + + return ( + <> + {broadcastSuccess ? ( + + ) : ( + + + stopSending()} /> + + + + + {satsToCurrency(satsAmount, denomination, currencyRates)} + + + + {`${satsAmount} sats`} + + + {`Fee: ${satsToCurrency( + fee, + denomination, + currencyRates + )} (${fee} sats)`} + + + + You are paying + + + + {icon} + + {payee} + + + + + + Ticket + + value.replace(/[^~-]+/g, '••••••')} + placeholder="••••••-••••••-••••••-••••••" + autoCapitalize="none" + autoCorrect="off" + color={inputColor} + backgroundColor={inputBg} + borderColor={inputBorder} + onChange={(e: React.ChangeEvent) => + checkTicket(e) + } + /> + + {error !== '' && ( + + + + )} + + + { + // @ts-ignore + broadcasting ? : null + } + + + )} + + ); +}; + +export default Invoice; diff --git a/pkg/btc-wallet/src/components/Send/Send.tsx b/pkg/btc-wallet/src/components/Send/Send.tsx new file mode 100644 index 000000000..22c5ab3c3 --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/Send.tsx @@ -0,0 +1,512 @@ +import React, { useEffect, useState } from 'react'; +import { + Box, + Icon, + StatelessTextInput as Input, + Row, + Text, + Button, + Col, + LoadingSpinner, +} from '@tlon/indigo-react'; +import Invoice from './Invoice'; +import BridgeInvoice from './BridgeInvoice'; +import ExternalInvoice from './ExternalInvoice'; +import FeePicker from './FeePicker'; +import Error from '../Error'; +import Signer from './Signer'; +import { validate } from 'bitcoin-address-validation'; +import * as ob from 'urbit-ob'; +import { useSettings } from '../../hooks/useSettings'; +import { api } from '../../lib/api'; +import { deSig } from '../../lib/util'; + +enum focusFields { + payee, + currency, + sats, + note, + empty = '', +} + +export enum feeLevels { + low, + mid, + high, +} + +export enum signMethods { + bridge = 'bridge', + masterTicket = 'masterTicket', + external = 'external', +} + +enum payeeTypes { + ship, + address, + initial = '', +} + +export type FeeChoices = { + [feeLevels.low]: [number, number]; + [feeLevels.mid]: [number, number]; + [feeLevels.high]: [number, number]; +}; + +type Props = { + stopSending: () => void; + value: string; + conversion: number; +}; + +const Send: React.FC = ({ stopSending, value, conversion }) => { + const { error, setError, network, psbt, denomination, shipWallets } = + useSettings(); + const [signing, setSigning] = useState(false); + const [denomAmount, setDenomAmount] = useState(0.0); + const [satsAmount, setSatsAmount] = useState(0); + const [payee, setPayee] = useState(''); + const [checkingPatp, setCheckingPatp] = useState(false); + const [payeeType, setPayeeType] = useState(payeeTypes.initial); + const [ready, setReady] = useState(false); + const [validPayee, setValidPayee] = useState(false); + const [focusedField, setFocusedField] = useState(focusFields.empty); + const [feeChoices, setFeeChoices] = useState({ + [feeLevels.low]: [10, 1], + [feeLevels.mid]: [10, 1], + [feeLevels.high]: [10, 1], + }); + const [feeValue, setFeeValue] = useState(feeLevels.mid); + const [showFeePicker, setShowFeePicker] = useState(false); + const [note, setNote] = useState(''); + const [choosingSignMethod, setChoosingSignMethod] = useState(false); + const [signMethod, setSignMethod] = useState(signMethods.bridge); + + const feeDismiss = () => { + setShowFeePicker(false); + }; + + const handleSetSignMethod = (signMethod: signMethods) => { + setSignMethod(signMethod); + setChoosingSignMethod(false); + }; + + const checkPayee = (e: React.ChangeEvent) => { + setError(''); + + const validPatPCommand = (validPatP: string) => { + let command = { 'check-payee': validPatP }; + api.btcWalletCommand(command); + setTimeout(() => { + setCheckingPatp(false); + }, 5000); + setCheckingPatp(true); + setPayeeType(payeeTypes.ship); + setPayee(validPatP); + }; + + let payeeReceived = e.target.value; + let isPatp = ob.isValidPatp(`~${deSig(payeeReceived)}`); + let isAddress = validate(payeeReceived); + if (isPatp) { + validPatPCommand(`~${deSig(payeeReceived)}`); + } else if (isAddress) { + setPayee(payeeReceived); + setReady(true); + setCheckingPatp(false); + setPayeeType(payeeTypes.address); + setValidPayee(true); + } else { + setPayee(payeeReceived); + setReady(false); + setCheckingPatp(false); + setPayeeType(payeeTypes.initial); + setValidPayee(false); + } + }; + + const toggleSignMethod = () => { + setChoosingSignMethod(!choosingSignMethod); + }; + + const initPayment = () => { + if (payeeType === payeeTypes.ship) { + let command = { + 'init-payment': { + payee, + value: satsAmount, + feyb: feeChoices[feeValue][1], + note: note || null, + }, + }; + + api.btcWalletCommand(command).then(() => setSigning(true)); + } else if (payeeType === payeeTypes.address) { + let command = { + 'init-payment-external': { + address: payee, + value: satsAmount, + feyb: 1, + note: note || null, + }, + }; + api.btcWalletCommand(command).then(() => setSigning(true)); + } + }; + + useEffect(() => { + if (network === 'bitcoin') { + let url = 'https://bitcoiner.live/api/fees/estimates/latest'; + fetch(url) + .then((res) => res.json()) + .then((n) => { + // let estimates = Object.keys(n.estimates); + // let mid = Math.floor(estimates.length / 2); + // let high = estimates.length - 1; + setFeeChoices({ + [feeLevels.high]: [30, n.estimates[30]['sat_per_vbyte']], + [feeLevels.mid]: [180, n.estimates[180]['sat_per_vbyte']], + [feeLevels.low]: [360, n.estimates[360]['sat_per_vbyte']], + }); + }); + } + }, []); + + useEffect(() => { + if (!ready && !checkingPatp) { + if (shipWallets.payee === payee.slice(1) && shipWallets.hasWallet) { + setReady(true); + setCheckingPatp(false); + setValidPayee(true); + } + } + }, [ready, checkingPatp, shipWallets, payee]); + + let payeeColor = 'black'; + let payeeBg = 'white'; + let payeeBorder = 'lightGray'; + if (error) { + payeeColor = 'red'; + payeeBorder = 'red'; + payeeBg = 'veryLightRed'; + } else if (focusedField === focusFields.payee && validPayee) { + payeeColor = 'green'; + payeeBorder = 'green'; + payeeBg = 'veryLightGreen'; + } else if (focusedField !== focusFields.payee && validPayee) { + payeeColor = 'blue'; + payeeBorder = 'white'; + payeeBg = 'white'; + } else if (focusedField !== focusFields.payee && !validPayee) { + payeeColor = 'red'; + payeeBorder = 'red'; + payeeBg = 'veryLightRed'; + } else if ( + focusedField === focusFields.payee && + !validPayee && + !checkingPatp && + payeeType === payeeTypes.ship + ) { + payeeColor = 'red'; + payeeBorder = 'red'; + payeeBg = 'veryLightRed'; + } + + const signReady = ready && satsAmount > 0 && !signing; + + let invoice = null; + + switch (signMethod) { + case signMethods.masterTicket: { + invoice = ( + + ); + break; + } + case signMethods.bridge: { + invoice = ( + + ); + break; + } + case signMethods.external: { + invoice = ( + + ); + break; + } + default: + break; + } + + return ( + <> + {signing && psbt ? ( + invoice + ) : ( + + + + + Send BTC + + + {value} + + stopSending()} /> + + + + + To + + {checkingPatp ? ( + + ) : null} + + { + setFocusedField(focusFields.payee); + }} + onBlur={() => { + setFocusedField(focusFields.empty); + }} + color={payeeColor} + backgroundColor={payeeBg} + borderColor={payeeBorder} + ml={2} + flexGrow="1" + fontSize="14px" + placeholder="~sampel-palnet or BTC address" + value={payee} + fontFamily="mono" + disabled={signing} + onChange={(e: React.ChangeEvent) => + checkPayee(e) + } + /> + + {error && ( + + {/* yes this is a hack */} + + + + )} + + + Amount + + { + setFocusedField(focusFields.currency); + }} + onBlur={() => { + setFocusedField(focusFields.empty); + }} + fontSize="14px" + width="100%" + type="number" + borderColor={ + focusedField === focusFields.currency ? 'lightGray' : 'none' + } + disabled={signing} + value={denomAmount} + onChange={(e: React.ChangeEvent) => { + setDenomAmount(parseFloat(e.target.value)); + setSatsAmount( + Math.round( + (parseFloat(e.target.value) / conversion) * 100000000 + ) + ); + }} + /> + + {denomination} + + + + {/* yes this is a hack */} + + { + setFocusedField(focusFields.sats); + }} + onBlur={() => { + setFocusedField(focusFields.empty); + }} + fontSize="14px" + width="100%" + type="number" + borderColor={ + focusedField === focusFields.sats ? 'lightGray' : 'none' + } + disabled={signing} + value={satsAmount} + onChange={(e: React.ChangeEvent) => { + setDenomAmount( + parseFloat(e.target.value) * (conversion / 100000000) + ); + setSatsAmount(parseInt(e.target.value, 10)); + }} + /> + + sats + + + + + Fee + + + + {feeChoices[feeValue][1]} sats/vbyte + + + + + + {!showFeePicker ? null : ( + + )} + + + + Note + + { + setFocusedField(focusFields.note); + }} + onBlur={() => { + setFocusedField(focusFields.empty); + }} + fontSize="14px" + width="100%" + placeholder="What's this for?" + type="text" + borderColor={ + focusedField === focusFields.note ? 'lightGray' : 'none' + } + disabled={signing} + value={note} + onChange={(e: React.ChangeEvent) => { + setNote(e.target.value); + }} + /> + + + + {!(signing && !error) ? null : ( + + )} + + + + {signMethod === signMethods.masterTicket && ( + + + + We recommend that you sign transactions using Bridge to protect + your master ticket. + + + )} + + )} + + ); +}; + +export default Send; diff --git a/pkg/btc-wallet/src/components/Send/Sent.tsx b/pkg/btc-wallet/src/components/Send/Sent.tsx new file mode 100644 index 000000000..1990d4b28 --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/Sent.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Icon, Row, Col, Center, Text } from '@tlon/indigo-react'; +import { satsToCurrency } from '../../lib/util'; +import { useSettings } from '../../hooks/useSettings'; + +type Props = { + payee: string; + stopSending: () => void; + satsAmount: number; +}; + +const Sent: React.FC = ({ payee, stopSending, satsAmount }) => { + const { denomination, currencyRates } = useSettings(); + return ( + + + + +
+ {`You sent BTC to ${payee}`} +
+
+ + {satsToCurrency(satsAmount, denomination, currencyRates)} + + {`${satsAmount} sats`} +
+ + ); +}; + +export default Sent; diff --git a/pkg/btc-wallet/src/components/Send/Signer.tsx b/pkg/btc-wallet/src/components/Send/Signer.tsx new file mode 100644 index 000000000..f78301172 --- /dev/null +++ b/pkg/btc-wallet/src/components/Send/Signer.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { Box, Button, Icon, Row } from '@tlon/indigo-react'; +import { signMethods } from './Send'; + +const signMethodLabels = { + bridge: 'Sign with Bridge', + masterTicket: 'Sign with Master Ticket', + external: 'Sign Externally (PSBT)', +}; + +type Props = { + signReady: boolean; + initPayment: () => void; + choosingSignMethod: boolean; + signMethod: signMethods; + setSignMethod: (arg: signMethods) => void; +}; + +const Signer: React.FC = ({ + signReady, + initPayment, + choosingSignMethod, + signMethod, + setSignMethod, +}) => { + return choosingSignMethod ? ( + + {Object.keys(signMethods).map((method) => ( + + + {signMethod === (signMethods as any)[method] && ( + + )} + + ))} + + ) : ( + + ); +}; + +export default Signer; diff --git a/pkg/btc-wallet/src/components/Settings.tsx b/pkg/btc-wallet/src/components/Settings.tsx new file mode 100644 index 000000000..bf2b8a981 --- /dev/null +++ b/pkg/btc-wallet/src/components/Settings.tsx @@ -0,0 +1,121 @@ +import React from 'react'; +import { Box, Icon, Row, Text, Button, Col } from '@tlon/indigo-react'; +import { useSettings } from '../hooks/useSettings'; +import { api } from '../lib/api'; +import { Link } from 'react-router-dom'; + +const Settings = () => { + const { wallet, provider } = useSettings(); + + const changeProvider = () => { + api.btcWalletCommand({ 'set-provider': null }); + window.location.reload(); + }; + + const replaceWallet = () => { + api.btcWalletCommand({ + 'delete-wallet': wallet, + }); + }; + + let connColor = 'red'; + let connBackground = 'veryLightRed'; + let conn = 'Offline'; + let host = ''; + if (provider) { + if (provider.connected) conn = 'Connected'; + if (provider.host) host = provider.host; + if (provider.connected && provider.host) { + connColor = 'orange'; + connBackground = 'lightOrange'; + } + } + + return ( + + + + XPub Derivation + + + + + + + + + + {wallet} + + + + + + + + BTC Node Provider + + + + + ~{host} + + + {conn} + + + + + + + ); +}; + +export default Settings; diff --git a/pkg/btc-wallet/src/js/components/lib/sigil.js b/pkg/btc-wallet/src/components/Sigil.tsx similarity index 78% rename from pkg/btc-wallet/src/js/components/lib/sigil.js rename to pkg/btc-wallet/src/components/Sigil.tsx index e47eff93f..5de8569bd 100644 --- a/pkg/btc-wallet/src/js/components/lib/sigil.js +++ b/pkg/btc-wallet/src/components/Sigil.tsx @@ -2,11 +2,11 @@ import React, { memo } from 'react'; import { sigil, reactRenderer } from '@tlon/sigil-js'; import { Box } from '@tlon/indigo-react'; -export const foregroundFromBackground = (background) => { +export const foregroundFromBackground = (background: string) => { const rgb = { r: parseInt(background.slice(1, 3), 16), g: parseInt(background.slice(3, 5), 16), - b: parseInt(background.slice(5, 7), 16) + b: parseInt(background.slice(5, 7), 16), }; const brightness = (299 * rgb.r + 587 * rgb.g + 114 * rgb.b) / 1000; const whiteBrightness = 255; @@ -14,7 +14,19 @@ export const foregroundFromBackground = (background) => { return whiteBrightness - brightness < 50 ? 'black' : 'white'; }; -export const Sigil = memo( +type Props = { + classes?: string; + color: string; + foreground?: string; + ship: string; + size: number; + svgClass?: string; + icon?: boolean; + padding?: number; + display?: string; +}; + +const Sigil: React.FC = memo( ({ classes = '', color, @@ -24,7 +36,7 @@ export const Sigil = memo( svgClass = '', icon = false, padding = 0, - display = 'inline-block' + display = 'inline-block', }) => { const innerSize = Number(size) - 2 * padding; const paddingPx = `${padding}px`; @@ -55,7 +67,7 @@ export const Sigil = memo( size: innerSize, icon, colors: [color, foregroundColor], - class: svgClass + class: svgClass, })} ); diff --git a/pkg/btc-wallet/src/components/StartupModal.tsx b/pkg/btc-wallet/src/components/StartupModal.tsx new file mode 100644 index 000000000..e21f6ce2c --- /dev/null +++ b/pkg/btc-wallet/src/components/StartupModal.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { Box } from '@tlon/indigo-react'; +import WalletModal from './WalletModal'; +import ProviderModal from './ProviderModal'; +import { useSettings } from '../hooks/useSettings'; + +const StartupModal: React.FC = () => { + const { wallet, provider } = useSettings(); + let modal = null; + + if (wallet && provider) { + return null; + } else if (!provider) { + modal = ; + } else if (!wallet) { + modal = ; + } + return ( + + + {modal} + + + ); +}; + +export default StartupModal; diff --git a/pkg/btc-wallet/src/components/Transactions/Transaction.tsx b/pkg/btc-wallet/src/components/Transactions/Transaction.tsx new file mode 100644 index 000000000..fd0df48ca --- /dev/null +++ b/pkg/btc-wallet/src/components/Transactions/Transaction.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { Box, Row, Text, Col } from '@tlon/indigo-react'; +import _ from 'lodash'; +import TxAction from './TxAction'; +import TxCounterparty from './TxCounterparty'; +import { satsToCurrency } from '../../lib/util'; +import { useSettings } from '../../hooks/useSettings'; +import { Transaction as TransactionType } from '../../types'; + +const Transaction = ({ tx }: { tx: TransactionType }) => { + const { denomination, currencyRates } = useSettings(); + const pending = !tx.recvd; + + let weSent = _.find(tx.inputs, (input) => { + return input.ship === window.ship; + }); + let weRecv = tx.outputs.every((output) => { + return output.ship === window.ship; + }); + + let action: 'sent' | 'recv' | 'fail' = weRecv + ? 'recv' + : weSent + ? 'sent' + : 'recv'; + + let counterShip = null; + let counterAddress = null; + let value; + let sign; + + if (action === 'sent') { + let counter = _.find(tx.outputs, (output) => { + return output.ship !== window.ship; + }); + counterShip = _.get(counter, 'ship', null); + counterAddress = _.get(counter, 'val.address', null); + value = _.get(counter, 'val.value', null); + sign = '-'; + } else if (action === 'recv') { + value = _.reduce( + tx.outputs, + (sum, output) => { + if (output.ship === window.ship) { + return sum + output.val.value; + } else { + return sum; + } + }, + 0 + ); + + if (weSent && weRecv) { + counterAddress = _.get( + _.find(tx.inputs, (input) => { + return input.ship === window.ship; + }), + 'val.address', + null + ); + } else { + let counter = _.find(tx.inputs, (input) => { + return input.ship !== window.ship; + }); + counterShip = _.get(counter, 'ship', null); + counterAddress = _.get(counter, 'val.address', null); + } + sign = ''; + } + + let currencyValue = sign + satsToCurrency(value, denomination, currencyRates); + + const failure = Boolean(tx.failure); + if (failure) action = 'fail'; + + const txid = tx.txid.dat.slice(2).replaceAll('.', ''); + + return ( + + + + + {sign} + {value} sats + + + + + + {currencyValue} + + + ); +}; + +export default Transaction; diff --git a/pkg/btc-wallet/src/components/Transactions/Transactions.tsx b/pkg/btc-wallet/src/components/Transactions/Transactions.tsx new file mode 100644 index 000000000..0eec82fb9 --- /dev/null +++ b/pkg/btc-wallet/src/components/Transactions/Transactions.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { Box, Text, Col } from '@tlon/indigo-react'; +import Transaction from './Transaction'; +import { useSettings } from '../../hooks/useSettings'; + +const Transactions = () => { + const { history } = useSettings(); + if (!history || history.length <= 0) { + return ( + + + No Transactions Yet + + + ); + } else { + return ( + + {history.map((tx, i) => { + return ; + })} + + ); + } +}; + +export default Transactions; diff --git a/pkg/btc-wallet/src/components/Transactions/TxAction.tsx b/pkg/btc-wallet/src/components/Transactions/TxAction.tsx new file mode 100644 index 000000000..6ed9e954d --- /dev/null +++ b/pkg/btc-wallet/src/components/Transactions/TxAction.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { Box, Icon, Row, Text, LoadingSpinner } from '@tlon/indigo-react'; +import { useSettings } from '../../hooks/useSettings'; + +type Props = { + action: 'sent' | 'recv' | 'fail'; + pending: boolean; + txid: string; +}; + +const TxAction: React.FC = ({ action, pending, txid }) => { + const { network } = useSettings(); + const leftIcon = + action === 'sent' + ? 'ArrowSouth' + : action === 'recv' + ? 'ArrowNorth' + : action === 'fail' + ? 'X' + : 'NullIcon'; + + const actionColor = + action === 'sent' + ? 'sentBlue' + : action === 'recv' + ? 'recvGreen' + : action === 'fail' + ? 'gray' + : 'red'; + + const actionText = + action === 'sent' && !pending + ? 'Sent BTC' + : action === 'sent' && pending + ? 'Sending BTC' + : action === 'recv' && !pending + ? 'Received BTC' + : action === 'recv' && pending + ? 'Receiving BTC' + : action === 'fail' + ? 'Failed' + : 'error'; + + const pendingSpinner = !pending ? null : ( + + ); + + const url = + network === 'testnet' + ? `http://blockstream.info/testnet/tx/${txid}` + : `http://blockstream.info/tx/${txid}`; + + return ( + + + + + + {actionText} + + + + + {pendingSpinner} + + ); +}; + +export default TxAction; diff --git a/pkg/btc-wallet/src/components/Transactions/TxCounterparty.tsx b/pkg/btc-wallet/src/components/Transactions/TxCounterparty.tsx new file mode 100644 index 000000000..8bbdad07d --- /dev/null +++ b/pkg/btc-wallet/src/components/Transactions/TxCounterparty.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { Box, Icon, Row, Text } from '@tlon/indigo-react'; +import Sigil from '../Sigil'; + +type Props = { + ship: string; + address: string; +}; + +const TxCounterparty: React.FC = ({ ship, address }) => { + const icon = ship ? ( + + ) : ( + + + + ); + const addressText = !address + ? '' + : address.slice(0, 6) + '...' + address.slice(-6); + const text = ship ? `~${ship}` : addressText; + + return ( + + {icon} + + {text} + + + ); +}; + +export default TxCounterparty; diff --git a/pkg/btc-wallet/src/components/WalletModal.tsx b/pkg/btc-wallet/src/components/WalletModal.tsx new file mode 100644 index 000000000..e46c865d7 --- /dev/null +++ b/pkg/btc-wallet/src/components/WalletModal.tsx @@ -0,0 +1,268 @@ +import React, { useState } from 'react'; +import { + Box, + Text, + Button, + StatelessTextInput, + Icon, + Row, + LoadingSpinner, +} from '@tlon/indigo-react'; +import { patp2dec, isValidPatq } from 'urbit-ob'; +import * as kg from 'urbit-key-generation'; +import { useSettings } from '../hooks/useSettings'; +import { api } from '../lib/api'; +import { UrbitWallet } from '../types'; + +const WalletModal: React.FC = () => { + const { network } = useSettings(); + const [mode, setMode] = useState('xpub'); + const [masterTicket, setMasterTicket] = useState(''); + const [confirmedMasterTicket, setConfirmedMasterTicket] = useState(''); + const [xpub, setXpub] = useState(''); + const [readyToSubmit, setReadyToSubmit] = useState(false); + const [processingSubmission, setProcessingSubmission] = useState(false); + const [confirmingMasterTicket, setConfirmingMasterTicket] = useState(false); + const [error, setError] = useState(false); + + const checkTicket = ({ + target: { value }, + }: React.ChangeEvent) => { + // TODO: port over bridge ticket validation logic + if (confirmingMasterTicket) { + setConfirmedMasterTicket(value); + setReadyToSubmit(isValidPatq(value)); + } else { + setMasterTicket(value); + setReadyToSubmit(isValidPatq(value)); + } + }; + + const checkXPub = ({ + target: { value: xpubGiven }, + }: React.ChangeEvent) => { + setXpub(xpubGiven); + setReadyToSubmit(xpubGiven.length > 0); + }; + + const submitXPub = (givenXpub: string) => { + type AddWalletCommand = { + 'add-wallet': { + xpub: string; + fprint: number[]; + 'scan-to': number | null; + 'max-gap': number; + confs: number; + }; + }; + const command: AddWalletCommand = { + 'add-wallet': { + xpub: givenXpub, + fprint: [4, 0], + 'scan-to': null, + 'max-gap': 8, + confs: 1, + }, + }; + api.btcWalletCommand(command); + setProcessingSubmission(true); + }; + + const submitMasterTicket = (ticket: string) => { + setProcessingSubmission(true); + kg.generateWallet({ + ticket, + ship: parseInt(patp2dec('~' + window.ship)), + }).then((urbitWallet: UrbitWallet) => { + const { xpub: xpubFromWallet } = + network === 'testnet' + ? urbitWallet.bitcoinTestnet.keys + : urbitWallet.bitcoinMainnet.keys; + + submitXPub(xpubFromWallet); + }); + }; + + const buttonDisabled = !readyToSubmit || processingSubmission; + const inputDisabled = processingSubmission; + // const processingSpinner = !processingSubmission ? null : ; + + if (mode === 'masterTicket') { + return ( + + + + + Step 2 of 2: Import your extended public key + + + + + + We recommend that you import your wallet using Bridge to protect + your master ticket. + + + + {confirmingMasterTicket && ( + { + setConfirmingMasterTicket(false); + setMasterTicket(''); + setConfirmedMasterTicket(''); + setError(false); + }} + /> + )} + + {confirmingMasterTicket ? 'Confirm Master Ticket' : 'Master Ticket'} + + + + value.replace(/[^~-]+/g, '••••••')} + placeholder="••••••-••••••-••••••-••••••" + autoCapitalize="none" + autoCorrect="off" + onChange={(e: React.ChangeEvent) => + checkTicket(e) + } + /> + {!inputDisabled ? null : } + + {error && ( + + + Master tickets do not match + + + )} + + + + + + ); + } else if (mode === 'xpub') { + return ( + + + + + Step 2 of 2: Import your extended public key + + + + + Visit{' '} + + bridge.urbit.org + {' '} + to obtain your key + + + + + Extended Public Key (XPub) + + + + ) => checkXPub(e)} + mr={1} + /> + {!inputDisabled ? null : } + + + { + if (inputDisabled) return; + setMode('masterTicket'); + setXpub(''); + setMasterTicket(''); + setReadyToSubmit(false); + }} + > + Import using master ticket -> + + + + + ); + } +}; + +export default WalletModal; diff --git a/pkg/btc-wallet/src/components/Warning.tsx b/pkg/btc-wallet/src/components/Warning.tsx new file mode 100644 index 000000000..466f14414 --- /dev/null +++ b/pkg/btc-wallet/src/components/Warning.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { Box, Text, Button, Col, Anchor } from '@tlon/indigo-react'; +import { api } from '../lib/api'; +import { useSettings } from '../hooks/useSettings'; + +const Warning = () => { + const { setShowWarning } = useSettings(); + const understand = () => { + setShowWarning(false); + let removeWarning = { + 'put-entry': { + value: false, + desk: window.desk, + 'entry-key': 'warning', + 'bucket-key': 'btc-wallet', + }, + }; + api.settingsEvent(removeWarning); + }; + + return ( + + + + Warning! + +
+ + Be safe while using this wallet, and be sure to store responsible + amounts of BTC. + + + Always ensure that the checksum of the wallet matches that of the + wallet's repo. + +
+ + + Learn more on urbit.org + + + + +
+ ); +}; + +export default Warning; diff --git a/pkg/btc-wallet/src/hooks/useSettings.tsx b/pkg/btc-wallet/src/hooks/useSettings.tsx new file mode 100644 index 000000000..4845b5cf7 --- /dev/null +++ b/pkg/btc-wallet/src/hooks/useSettings.tsx @@ -0,0 +1,397 @@ +import React, { createContext, useContext, useEffect, useState } from 'react'; +import _ from 'lodash'; +import { api } from '../lib/api'; +import { mapDenominationToSymbol, reduceHistory } from '../lib/util'; +import { + CurrencyRate, + Denomination, + Network, + Provider, + ProviderPerms, + ScanProgress, + ShipWallets, + Transaction, + TxidType, +} from '../types'; + +type SettingsContextType = { + network: Network; + setNetwork: React.Dispatch>; + loadedBtc: boolean; + setLoadedBtc: React.Dispatch>; + loadedSettings: boolean; + setLoadedSettings: React.Dispatch>; + loaded: boolean; + setLoaded: React.Dispatch>; + providerPerms: ProviderPerms; + setProviderPerms: React.Dispatch>; + shipWallets: ShipWallets; + setShipWallets: React.Dispatch>; + provider: Provider; + setProvider: React.Dispatch>; + wallet: string | null; + setWallet: React.Dispatch>; + confirmedBalance: number; + setConfirmedBalance: React.Dispatch>; + unconfirmedBalance: number; + setUnconfirmedBalance: React.Dispatch>; + btcState: any; + setBtcState: React.Dispatch>; + history: Transaction[]; + setHistory: React.Dispatch>; + fee: number; + setFee: React.Dispatch>; + psbt: string; + setPsbt: React.Dispatch>; + address: string | null; + setAddress: React.Dispatch>; + currencyRates: CurrencyRate; + setCurrencyRates: React.Dispatch>; + denomination: Denomination; + setDenomination: React.Dispatch>; + showWarning: boolean; + setShowWarning: React.Dispatch>; + error: string; + setError: React.Dispatch>; + broadcastSuccess: boolean; + setBroadcastSuccess: React.Dispatch>; + scanProgress: ScanProgress; + setScanProgress: React.Dispatch>; +}; + +export const SettingsContext = createContext({ + network: 'bitcoin', + setNetwork: () => {}, + loadedBtc: false, + setLoadedBtc: () => {}, + loadedSettings: true, + setLoadedSettings: () => {}, + loaded: false, + setLoaded: () => {}, + providerPerms: { provider: '', permitted: false }, + setProviderPerms: () => {}, + shipWallets: { payee: '', hasWallet: false }, + setShipWallets: () => {}, + provider: null, + setProvider: () => {}, + wallet: null, + setWallet: () => {}, + confirmedBalance: 0, + setConfirmedBalance: () => {}, + unconfirmedBalance: 0, + setUnconfirmedBalance: () => {}, + btcState: null, + setBtcState: () => {}, + history: [], + setHistory: () => {}, + fee: 0, + setFee: () => {}, + psbt: '', + setPsbt: () => {}, + address: null, + setAddress: () => {}, + currencyRates: { + BTC: { last: 1, symbol: 'BTC' }, + }, + setCurrencyRates: () => {}, + denomination: 'BTC', + setDenomination: () => {}, + showWarning: false, + setShowWarning: () => {}, + error: '', + setError: () => {}, + broadcastSuccess: false, + setBroadcastSuccess: () => {}, + scanProgress: { main: null, change: null }, + setScanProgress: () => {}, +}); + +type Props = { + channel: { setOnChannelError: (arg: () => void) => void }; +}; + +export const SettingsProvider: React.FC = ({ channel, children }) => { + const [network, setNetwork] = useState('bitcoin'); + const [channelData, setChannelData] = useState(null); + const [loadedBtc, setLoadedBtc] = useState(false); + const [loadedSettings, setLoadedSettings] = useState(false); + const [loaded, setLoaded] = useState(false); + const [providerPerms, setProviderPerms] = useState({ + provider: '', + permitted: false, + }); + const [shipWallets, setShipWallets] = useState({ + payee: '', + hasWallet: false, + }); + const [provider, setProvider] = useState(null); + const [wallet, setWallet] = useState(null); + const [confirmedBalance, setConfirmedBalance] = useState(0); + const [unconfirmedBalance, setUnconfirmedBalance] = useState(0); + const [btcState, setBtcState] = useState(null); + const [history, setHistory] = useState([]); + const [psbt, setPsbt] = useState(''); + const [fee, setFee] = useState(0); + const [address, setAddress] = useState(null); + const [currencyRates, setCurrencyRates] = useState({ + BTC: { last: 1, symbol: 'BTC' }, + }); + const [denomination, setDenomination] = useState('BTC'); + const [showWarning, setShowWarning] = useState(false); + const [error, setError] = useState(''); + const [broadcastSuccess, setBroadcastSuccess] = useState(false); + const [scanProgress, setScanProgress] = useState({ + main: null, + change: null, + }); + + const { Provider } = SettingsContext; + + const success = (event: any) => { + console.log({ event }); + setChannelData(event); + }; + const fail = (error: any) => console.log({ error }); + + const initializeBtcWallet = () => { + api.bind('/all', 'PUT', api.ship, 'btc-wallet', success, fail); + }; + + const initializeSettings = () => { + let app = 'settings-store'; + let path = `/bucket/${window.desk}/btc-wallet`; + + fetch(`/~/scry/${app}${path}.json`) + .then((res) => res.json()) + .then((n) => { + let data = _.get(n, 'initial', false); + let bucketData = _.get(n, 'bucket', false); + if (data) { + setChannelData(n); + } + if (bucketData) { + let bucketWarning = _.get(n, 'bucket.warning', -1); + if (bucketWarning !== -1) { + setShowWarning(bucketWarning); + } + let bucketCurrency = _.get(n, 'bucket.currency', -1); + if (bucketCurrency !== -1) { + setDenomination(bucketCurrency); + } + setLoadedSettings(true); + if (loadedBtc) { + setLoaded(true); + } + } + }); + + api.bind(path, 'PUT', api.ship, app, success, fail); + }; + + const initializeCurrencyPoll = () => { + fetch('https://blockchain.info/ticker') + .then((res) => res.json()) + .then((n) => { + const newCurrencyRates: any = currencyRates; + for (let c in n) { + newCurrencyRates[c] = n[c]; + newCurrencyRates[c].symbol = mapDenominationToSymbol(c); + } + setCurrencyRates(newCurrencyRates); + setTimeout(() => initializeCurrencyPoll(), 1000 * 60 * 15); + }); + }; + + const start = () => { + if (api.ship) { + initializeBtcWallet(); + initializeSettings(); + initializeCurrencyPoll(); + } + }; + + const handleNewTx = (newTx: Transaction) => { + const { txid, recvd } = newTx; + let old = _.findIndex(history, (h: Transaction) => { + return h.txid.dat === txid.dat && h.txid.wid === txid.wid; + }); + if (old !== -1) { + const newHistory = history.filter((_, i) => i !== old); + setHistory(newHistory); + } + if (recvd === null && old === -1) { + const newHistory = [...history, newTx]; + setHistory(newHistory); + } else if (recvd !== null && old === -1) { + // we expect history to have null recvd values first, and the rest in + // descending order + let insertionIndex = _.findIndex(history, (h: Transaction) => { + return h.recvd < recvd && h.recvd !== null; + }); + const newHistory = history.map((o, i) => + i === insertionIndex ? newTx : o + ); + setHistory(newHistory); + } + }; + + const handleCancelTx = ({ wid, dat }: TxidType) => { + let entryIndex = _.findIndex(history, (h: Transaction) => { + return wid === h.txid.wid && dat === h.txid.dat; + }); + if (entryIndex > -1) { + history[entryIndex].failure = true; + } + }; + + useEffect(() => { + const initialData = channelData?.data?.initial; + const putEntryData = channelData?.data?.['settings-event']?.['put-entry']; + const btcStateData = channelData?.data?.['btc-state']; + const changeProvider = channelData?.data?.['change-provider']; + const newTx = channelData?.data?.['new-tx']; + const providerStatus = channelData?.data?.providerStatus; + const checkPayee = channelData?.data?.checkPayee; + const changeWallet = channelData?.data?.changeWallet; + const psbtData = channelData?.data.psbt; + const cancelTx = channelData?.data['cancel-tx']; + const addressData = channelData?.data?.address; + const balanceData = channelData?.data?.balance; + const errorData = channelData?.data?.error; + const broadcastSuccessData = channelData?.data?.['broadcast-success']; + const broadcastFailData = channelData?.data?.['broadcast-fail']; + const scanProgressData = channelData?.data?.['scan-progress']; + if (initialData) { + setProvider(initialData.provider); + setWallet(initialData.wallet); + setConfirmedBalance(_.get(initialData.balance, 'confirmed', null)); + setUnconfirmedBalance(_.get(initialData.balance, 'unconfirmed', null)); + setBtcState(initialData['btc-state']); + setHistory(reduceHistory(initialData.history)); + setAddress(initialData.address); + setLoadedBtc(true); + if (loadedSettings) { + setLoaded(true); + } + } + if (putEntryData && putEntryData?.['entry-key'] === 'currency') { + setDenomination(putEntryData.value); + } + if (putEntryData && putEntryData?.['entry-key'] === 'warning') { + setShowWarning(putEntryData.value); + } + if (btcStateData) { + setBtcState(btcStateData); + } + if (changeProvider) { + setProvider(changeProvider); + } + if (newTx) { + handleNewTx(newTx); + } + if (providerStatus) { + let newProviderPerms: any = providerPerms; + for (let c in providerStatus) { + newProviderPerms[c] = providerStatus[c]; + } + setProviderPerms(newProviderPerms); + } + if (checkPayee) { + let newShipWallets: any = shipWallets; + + for (let c in checkPayee) { + newShipWallets[c] = checkPayee[c]; + } + setShipWallets(newShipWallets); + } + if (changeWallet) { + setWallet(changeWallet); + } + if (psbtData) { + setPsbt(psbtData.pb); + setFee(psbtData.fee); + } + if (cancelTx) { + handleCancelTx(cancelTx); + } + if (addressData) { + setAddress(addressData); + } + if (balanceData) { + setUnconfirmedBalance(balanceData.unconfirmed); + setConfirmedBalance(balanceData.confirmed); + } + if (errorData) { + setError(errorData); + } + if (broadcastSuccessData) { + setBroadcastSuccess(true); + } + if (broadcastFailData) { + setBroadcastSuccess(false); + } + if (scanProgressData) { + setScanProgress(scanProgressData); + } + }, [channelData]); + + useEffect(() => { + channel.setOnChannelError(() => { + start(); + }); + start(); + }, []); + + return ( + + {children} + + ); +}; + +export const useSettings = () => useContext(SettingsContext); diff --git a/pkg/btc-wallet/src/index.js b/pkg/btc-wallet/src/index.js deleted file mode 100644 index 64f6a0526..000000000 --- a/pkg/btc-wallet/src/index.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { Root } from './js/components/root.js'; -import { api } from './js/api.js'; -import { subscription } from "./js/subscription.js"; - -import './css/indigo-static.css'; -import './css/fonts.css'; -import './css/custom.css'; - -// rebuild x3 - -window.NETWORK = 'testnet'; // 'bitcoin' - -const channel = new window.channel(); -api.setChannel(window.ship, channel); - - -if (module.hot) { - module.hot.accept() -} - -ReactDOM.render(( - -), document.querySelectorAll("#root")[0]); diff --git a/pkg/btc-wallet/src/index.tsx b/pkg/btc-wallet/src/index.tsx new file mode 100644 index 000000000..848e9910d --- /dev/null +++ b/pkg/btc-wallet/src/index.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { api } from './lib/api'; +import Channel from './lib/channel'; +import { SettingsProvider } from './hooks/useSettings'; +import App from './App'; + +import './css/indigo-static.css'; +import './css/fonts.css'; +import './css/custom.css'; + +const channel = new Channel(); +api.setChannel(window.ship, channel); + +if (module.hot) { + module.hot.accept(); +} + +ReactDOM.render( + + + , + document.querySelectorAll('#root')[0] +); diff --git a/pkg/btc-wallet/src/js/api.js b/pkg/btc-wallet/src/js/api.js deleted file mode 100644 index 3de39b6ea..000000000 --- a/pkg/btc-wallet/src/js/api.js +++ /dev/null @@ -1,52 +0,0 @@ -import _ from 'lodash'; - -class UrbitApi { - setChannel(ship, channel) { - this.ship = ship; - this.channel = channel; - this.bindPaths = []; - } - - bind(path, method, ship = this.ship, appl = "btc-wallet", success, fail) { - this.bindPaths = _.uniq([...this.bindPaths, path]); - - window.subscriptionId = this.channel.subscribe(ship, appl, path, - (err) => { - fail(err); - }, - (event) => { - success({ - data: event, - from: { - ship, - path - } - }); - }, - (err) => { - fail(err); - }); - } - - btcWalletCommand(data) { - return this.action("btc-wallet", "btc-wallet-command", data); - } - - settingsEvent(data) { - return this.action("settings-store", "settings-event", data); - } - - action(appl, mark, data) { - return new Promise((resolve, reject) => { - this.channel.poke(ship, appl, mark, data, - (json) => { - resolve(json); - }, - (err) => { - reject(err); - }); - }); - } -} -export let api = new UrbitApi(); -window.api = api; diff --git a/pkg/btc-wallet/src/js/components/lib/balance.js b/pkg/btc-wallet/src/js/components/lib/balance.js deleted file mode 100644 index 655b1b514..000000000 --- a/pkg/btc-wallet/src/js/components/lib/balance.js +++ /dev/null @@ -1,149 +0,0 @@ -import React, { Component } from 'react'; -import { - Box, - Icon, - Row, - Text, - Button, - Col, -} from '@tlon/indigo-react'; - -import Send from './send.js' -import CurrencyPicker from './currencyPicker.js' -import { currencyToSats, satsToCurrency } from '../../lib/util.js'; - - -export default class Balance extends Component { - constructor(props) { - super(props); - - this.state = { - sending: false, - copiedButton: false, - copiedString: false, - } - - this.copyAddress = this.copyAddress.bind(this); - } - - copyAddress(arg) { - let address = this.props.state.address; - function listener(e) { - e.clipboardData.setData('text/plain', address); - e.preventDefault(); - } - - document.addEventListener('copy', listener); - document.execCommand('copy'); - document.removeEventListener('copy', listener); - - this.props.api.btcWalletCommand({'gen-new-address': null}); - - if (arg === 'button'){ - this.setState({copiedButton: true}); - setTimeout(() => { this.setState({copiedButton: false}); }, 2000); - } else if (arg === 'string') { - this.setState({copiedString: true}); - setTimeout(() => { this.setState({copiedString: false}); }, 2000); - } - } - - - render() { - const sats = (this.props.state.confirmedBalance || 0); - const unconfirmedSats = this.props.state.unconfirmedBalance; - - const unconfirmedString = unconfirmedSats ? ` (${unconfirmedSats}) ` : ''; - - const denomination = this.props.state.denomination; - const value = satsToCurrency(sats, denomination, this.props.state.currencyRates); - const sendDisabled = (sats === 0); - const addressText = (this.props.state.address === null) ? '' : - this.props.state.address.slice(0, 6) + '...' + - this.props.state.address.slice(-6); - - const conversion = this.props.state.currencyRates[denomination].last; - - return ( - <> - {this.state.sending ? - { - this.setState({sending: false}); - store.handleEvent({data: {psbt: '', fee: 0, error: '', "broadcast-fail": null}}); - }} - /> : - - - Balance - {this.copyAddress('string')}}> - {this.state.copiedString ? "copied" : addressText} - - - - - - {value} - - {`${sats}${unconfirmedString} sats`} - - - +)) as PolymorphicButton; diff --git a/pkg/grid/src/components/DeskLink.tsx b/pkg/grid/src/components/DeskLink.tsx new file mode 100644 index 000000000..5e2ec45c1 --- /dev/null +++ b/pkg/grid/src/components/DeskLink.tsx @@ -0,0 +1,40 @@ +import React, { ReactNode } from 'react'; +import { Link, useHistory } from 'react-router-dom'; +import { useCharge } from '../state/docket'; +import { getAppHref } from '../state/util'; + +interface DeskLinkProps extends React.AnchorHTMLAttributes { + desk: string; + to?: string; + children?: ReactNode; + className?: string; +} + +export function DeskLink({ children, className, desk, to = '', ...rest }: DeskLinkProps) { + const { push } = useHistory(); + const charge = useCharge(desk); + + if (!charge) { + return null; + } + if (desk === window.desk) { + return ( + + {children} + + ); + } + const href = `${getAppHref(charge.href)}${to}`; + return ( + push('/')} + > + {children} + + ); +} diff --git a/pkg/grid/src/components/Dialog.tsx b/pkg/grid/src/components/Dialog.tsx new file mode 100644 index 000000000..6144a7822 --- /dev/null +++ b/pkg/grid/src/components/Dialog.tsx @@ -0,0 +1,51 @@ +import React, { FC } from 'react'; +import * as DialogPrimitive from '@radix-ui/react-dialog'; +import type * as Polymorphic from '@radix-ui/react-polymorphic'; +import classNames from 'classnames'; + +export const Dialog: FC = ({ children, ...props }) => { + return ( + + + {children} + + ); +}; + +type DialogContentComponent = Polymorphic.ForwardRefComponent< + Polymorphic.IntrinsicElement, + Polymorphic.OwnProps & { + containerClass?: string; + showClose?: boolean; + } +>; + +export const DialogContent = React.forwardRef( + ({ showClose = true, containerClass, children, className, ...props }, forwardedRef) => ( + +
+ {children} + {showClose && ( + + + + + + + )} +
+
+ ) +) as DialogContentComponent; + +export const DialogTrigger = DialogPrimitive.Trigger; +export const DialogClose = DialogPrimitive.Close; diff --git a/pkg/grid/src/components/DocketHeader.tsx b/pkg/grid/src/components/DocketHeader.tsx new file mode 100644 index 000000000..f8db3f7e6 --- /dev/null +++ b/pkg/grid/src/components/DocketHeader.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { DocketImage } from './DocketImage'; +import { getAppName } from '../state/util'; +import { DocketWithDesk } from '../state/docket'; + +interface DocketHeaderProps { + docket: DocketWithDesk; + children?: React.ReactNode; +} + +export function DocketHeader(props: DocketHeaderProps) { + const { docket, children } = props; + const { info, image, color } = docket; + + return ( +
+ +
+

{getAppName(docket)}

+ {info &&

{info}

} +
+ {children} +
+ ); +} diff --git a/pkg/grid/src/components/DocketImage.tsx b/pkg/grid/src/components/DocketImage.tsx new file mode 100644 index 000000000..01267a7b5 --- /dev/null +++ b/pkg/grid/src/components/DocketImage.tsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; +import { Docket } from '@urbit/api/docket'; +import cn from 'classnames'; +import { useTileColor } from '../tiles/useTileColor'; + +type DocketImageSizes = 'xs' | 'small' | 'default' | 'full'; + +interface DocketImageProps extends Pick { + className?: string; + size?: DocketImageSizes; +} + +const sizeMap: Record = { + xs: 'w-6 h-6 mr-2 rounded', + small: 'w-8 h-8 mr-3 rounded-md', + default: 'w-12 h-12 mr-3 rounded-lg', + full: 'w-20 h-20 md:w-32 md:h-32 rounded-2xl' +}; + +export function DocketImage({ color, image, className = '', size = 'full' }: DocketImageProps) { + const { tileColor } = useTileColor(color); + const [imageError, setImageError] = useState(false); + + return ( +
+ {image && !imageError && ( + setImageError(true)} + /> + )} +
+ ); +} diff --git a/pkg/grid/src/components/ErrorAlert.tsx b/pkg/grid/src/components/ErrorAlert.tsx new file mode 100644 index 000000000..93d18bc5a --- /dev/null +++ b/pkg/grid/src/components/ErrorAlert.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import cn from 'classnames'; +import { Dialog, DialogClose, DialogContent } from './Dialog'; +import { Button } from './Button'; + +interface ErrorAlertProps { + error: Error; + resetErrorBoundary: () => void; + className?: string; +} + +const SubmitIssue = ({ error }: { error: Error }) => { + const title = error.message; + const body = `\`\`\`%0A${error.stack?.replaceAll('\n', '%0A')}%0A\`\`\``; + + return ( + + ); +}; + +export const ErrorAlert = ({ error, resetErrorBoundary, className }: ErrorAlertProps) => { + return ( + resetErrorBoundary()}> + +

+ Encountered error: + {error.message} +

+ {error.stack && ( +
+
{error.stack}
+
+ )} +
+ + Try Again + + +
+
+
+ ); +}; diff --git a/pkg/grid/src/components/ProviderLink.tsx b/pkg/grid/src/components/ProviderLink.tsx new file mode 100644 index 000000000..18204b4a8 --- /dev/null +++ b/pkg/grid/src/components/ProviderLink.tsx @@ -0,0 +1,42 @@ +import classNames from 'classnames'; +import React from 'react'; +import { Link, LinkProps } from 'react-router-dom'; +import { Contact, Provider } from '@urbit/api'; +import { ShipName } from './ShipName'; +import { Avatar, AvatarSizes } from './Avatar'; + +export type ProviderLinkProps = Omit & { + provider: { shipName: string } & Contact; + size?: AvatarSizes; + selected?: boolean; + to?: (p: Provider) => LinkProps['to']; +}; + +export const ProviderLink = ({ + provider, + to, + selected = false, + size = 'default', + className, + ...props +}: ProviderLinkProps) => { + const small = size === 'small' || size === 'xs'; + return ( + + +
+

{provider.nickname || }

+ {provider.status && size === 'default' &&

{provider.status}

} +
+ + ); +}; diff --git a/pkg/grid/src/components/ProviderList.tsx b/pkg/grid/src/components/ProviderList.tsx new file mode 100644 index 000000000..47d32adcf --- /dev/null +++ b/pkg/grid/src/components/ProviderList.tsx @@ -0,0 +1,63 @@ +import React, { MouseEvent, useCallback } from 'react'; +import { Contact, Provider } from '@urbit/api'; +import classNames from 'classnames'; +import { MatchItem } from '../nav/Nav'; +import { useRecentsStore } from '../nav/search/Home'; +import { ProviderLink, ProviderLinkProps } from './ProviderLink'; + +export type ProviderListProps = { + providers: ({ shipName: string } & Contact)[]; + labelledBy: string; + matchAgainst?: MatchItem; + onClick?: (e: MouseEvent, p: Provider) => void; + listClass?: string; +} & Omit; + +export function providerMatches(target: Provider, match?: MatchItem): boolean { + if (!match) { + return false; + } + + const matchValue = match.display || match.value; + return target.nickname === matchValue || target.shipName === matchValue; +} + +export const ProviderList = ({ + providers, + labelledBy, + matchAgainst, + onClick, + listClass, + size = 'default', + ...props +}: ProviderListProps) => { + const addRecentDev = useRecentsStore((state) => state.addRecentDev); + const selected = useCallback( + (provider: Provider) => providerMatches(provider, matchAgainst), + [matchAgainst] + ); + + return ( +
    + {providers.map((p) => ( +
  • + { + addRecentDev(p.shipName); + if (onClick) { + onClick(e, p); + } + }} + /> +
  • + ))} +
+ ); +}; diff --git a/pkg/grid/src/components/Setting.tsx b/pkg/grid/src/components/Setting.tsx new file mode 100644 index 000000000..10fd5b716 --- /dev/null +++ b/pkg/grid/src/components/Setting.tsx @@ -0,0 +1,44 @@ +import classNames from 'classnames'; +import React, { FC, HTMLAttributes } from 'react'; +import slugify from 'slugify'; +import { useAsyncCall } from '../logic/useAsyncCall'; +import { Spinner } from './Spinner'; +import { Toggle } from './Toggle'; + +type SettingsProps = { + name: string; + on: boolean; + disabled?: boolean; + toggle: (open: boolean) => Promise; +} & HTMLAttributes; + +export const Setting: FC = ({ + name, + on, + disabled = false, + toggle, + className, + children +}) => { + const { status, call } = useAsyncCall(toggle); + const id = slugify(name); + + return ( +
+

+ {name} {status === 'loading' && } +

+
+ +
{children}
+
+
+ ); +}; diff --git a/pkg/grid/src/components/ShipName.tsx b/pkg/grid/src/components/ShipName.tsx new file mode 100644 index 000000000..9702c37ec --- /dev/null +++ b/pkg/grid/src/components/ShipName.tsx @@ -0,0 +1,28 @@ +import { cite } from '@urbit/api'; +import React, { HTMLAttributes } from 'react'; + +type ShipNameProps = { + name: string; +} & HTMLAttributes; + +export const ShipName = ({ name, ...props }: ShipNameProps) => { + const separator = /([_^-])/; + const parts = cite(name).replace('~', '').split(separator); + const first = parts.shift(); + + return ( + + ~ + {first} + {parts.length > 1 && ( + <> + {parts.map((piece, index) => ( + + {piece} + + ))} + + )} + + ); +}; diff --git a/pkg/grid/src/components/Spinner.tsx b/pkg/grid/src/components/Spinner.tsx new file mode 100644 index 000000000..5e7579a1a --- /dev/null +++ b/pkg/grid/src/components/Spinner.tsx @@ -0,0 +1,7 @@ +import classNames from 'classnames'; +import React from 'react'; +import { SpinnerIcon } from './icons/SpinnerIcon'; + +export const Spinner = ({ className, ...props }: React.HTMLAttributes) => ( + +); diff --git a/pkg/grid/src/components/Toggle.tsx b/pkg/grid/src/components/Toggle.tsx new file mode 100644 index 000000000..06cb194f5 --- /dev/null +++ b/pkg/grid/src/components/Toggle.tsx @@ -0,0 +1,60 @@ +import classNames from 'classnames'; +import React, { useState } from 'react'; +import * as RadixToggle from '@radix-ui/react-toggle'; +import type * as Polymorphic from '@radix-ui/react-polymorphic'; + +type ToggleComponent = Polymorphic.ForwardRefComponent< + Polymorphic.IntrinsicElement, + Polymorphic.OwnProps & { + loading?: boolean; + toggleClass?: string; + knobClass?: string; + } +>; + +export const Toggle = React.forwardRef( + ( + { defaultPressed, pressed, onPressedChange, disabled, className, toggleClass, loading = false }, + ref + ) => { + const [on, setOn] = useState(defaultPressed); + const isControlled = !!onPressedChange; + const proxyPressed = isControlled ? pressed : on; + const proxyOnPressedChange = isControlled ? onPressedChange : setOn; + const knobPosition = proxyPressed ? 18 : 2; + + return ( + + + + + + + ); + } +) as ToggleComponent; diff --git a/pkg/grid/src/components/TreatyMeta.tsx b/pkg/grid/src/components/TreatyMeta.tsx new file mode 100644 index 000000000..00974bb70 --- /dev/null +++ b/pkg/grid/src/components/TreatyMeta.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { daToDate, Treaty } from '@urbit/api'; + +import moment from 'moment'; +import { Attribute } from './Attribute'; + +const meta = ['license', 'website', 'version'] as const; + +export function TreatyMeta(props: { treaty: Treaty }) { + const { treaty } = props; + const { desk, ship, cass } = treaty; + return ( +
+ + {ship}/{desk} + + + {moment(daToDate(cass.da)).format('YYYY.MM.DD')} + + {meta.map((d) => ( + + {treaty[d]} + + ))} +
+ ); +} diff --git a/pkg/grid/src/components/VatMeta.tsx b/pkg/grid/src/components/VatMeta.tsx new file mode 100644 index 000000000..ceb3a575a --- /dev/null +++ b/pkg/grid/src/components/VatMeta.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Vat } from '@urbit/api/hood'; + +import { Attribute } from './Attribute'; + +export function VatMeta(props: { vat: Vat }) { + const { vat } = props; + const { desk, arak, cass, hash } = vat; + + const { desk: foreignDesk, ship, next } = arak.rail || {}; + const pluralUpdates = next?.length !== 1; + return ( +
+ + {hash} + + + %{desk} + + {next && next.length > 0 ? ( + + {next.length} update{pluralUpdates ? 's are' : ' is'} pending a System Update + + ) : null} +
+ ); +} diff --git a/pkg/grid/src/components/icons/Adjust.tsx b/pkg/grid/src/components/icons/Adjust.tsx new file mode 100644 index 000000000..d9aef173a --- /dev/null +++ b/pkg/grid/src/components/icons/Adjust.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +export const Adjust = (props: React.SVGProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/Bullet.tsx b/pkg/grid/src/components/icons/Bullet.tsx new file mode 100644 index 000000000..a5a2075d7 --- /dev/null +++ b/pkg/grid/src/components/icons/Bullet.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export const Bullet = (props: React.SVGProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/Cross.tsx b/pkg/grid/src/components/icons/Cross.tsx new file mode 100644 index 000000000..70c41ddb2 --- /dev/null +++ b/pkg/grid/src/components/icons/Cross.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +export const Cross = (props: React.SVGProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/Elbow.tsx b/pkg/grid/src/components/icons/Elbow.tsx new file mode 100644 index 000000000..6b50598f2 --- /dev/null +++ b/pkg/grid/src/components/icons/Elbow.tsx @@ -0,0 +1,14 @@ +import React, { HTMLAttributes } from 'react'; + +type ElbowProps = HTMLAttributes; + +export const Elbow = (props: ElbowProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/Interface.tsx b/pkg/grid/src/components/icons/Interface.tsx new file mode 100644 index 000000000..e0866da7a --- /dev/null +++ b/pkg/grid/src/components/icons/Interface.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +export const Interface = (props: React.SVGProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/LeftArrow.tsx b/pkg/grid/src/components/icons/LeftArrow.tsx new file mode 100644 index 000000000..b6a98f8b5 --- /dev/null +++ b/pkg/grid/src/components/icons/LeftArrow.tsx @@ -0,0 +1,15 @@ +import React, { HTMLAttributes } from 'react'; + +type LeftArrowProps = HTMLAttributes; + +export const LeftArrow = (props: LeftArrowProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/Notifications.tsx b/pkg/grid/src/components/icons/Notifications.tsx new file mode 100644 index 000000000..c4cabc2dd --- /dev/null +++ b/pkg/grid/src/components/icons/Notifications.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +export const Notifications = (props: React.SVGProps) => ( + + + +); diff --git a/pkg/grid/src/components/icons/SpinnerIcon.tsx b/pkg/grid/src/components/icons/SpinnerIcon.tsx new file mode 100644 index 000000000..405b2821d --- /dev/null +++ b/pkg/grid/src/components/icons/SpinnerIcon.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +export const SpinnerIcon = (props: React.SVGProps) => ( + + + + +); diff --git a/pkg/grid/src/components/icons/System.tsx b/pkg/grid/src/components/icons/System.tsx new file mode 100644 index 000000000..0a8b1a1ac --- /dev/null +++ b/pkg/grid/src/components/icons/System.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +export const System = (props: React.SVGProps) => ( + + + + +); diff --git a/pkg/grid/src/env.d.ts b/pkg/grid/src/env.d.ts new file mode 100644 index 000000000..2fda24a0d --- /dev/null +++ b/pkg/grid/src/env.d.ts @@ -0,0 +1,8 @@ +interface ImportMetaEnv extends Readonly> { + readonly VITE_LAST_WIPE: string; + readonly VITE_STORAGE_VERSION: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/pkg/grid/src/global.d.ts b/pkg/grid/src/global.d.ts new file mode 100644 index 000000000..8b3e7e6fa --- /dev/null +++ b/pkg/grid/src/global.d.ts @@ -0,0 +1,3 @@ +declare module 'urbit-ob' { + export function isValidPatp(patp: string): boolean; +} diff --git a/pkg/grid/src/logic/useAsyncCall.ts b/pkg/grid/src/logic/useAsyncCall.ts new file mode 100644 index 000000000..63ff02d7f --- /dev/null +++ b/pkg/grid/src/logic/useAsyncCall.ts @@ -0,0 +1,30 @@ +import { useCallback, useState } from 'react'; + +export type Status = 'initial' | 'loading' | 'success' | 'error'; + +export function useAsyncCall(cb: (...args: any[]) => Promise) { + const [status, setStatus] = useState('initial'); + const [error, setError] = useState(null); + + const call = useCallback( + (...args: any[]) => { + setStatus('loading'); + cb(...args) + .then((result) => { + setStatus('success'); + return result; + }) + .catch((err) => { + setError(err); + setStatus('error'); + }); + }, + [cb] + ); + + return { + call, + status, + error + }; +} diff --git a/pkg/grid/src/logic/useDebounce.ts b/pkg/grid/src/logic/useDebounce.ts new file mode 100644 index 000000000..550db124c --- /dev/null +++ b/pkg/grid/src/logic/useDebounce.ts @@ -0,0 +1,30 @@ +import { debounce, DebounceSettings } from 'lodash'; +import { useRef, useEffect, useCallback } from 'react'; +import { useIsMounted } from './useIsMounted'; + +export function useDebounce( + cb: (...args: any[]) => void, + delay: number, + options?: DebounceSettings +) { + const isMounted = useIsMounted(); + const inputsRef = useRef({ cb, delay }); // mutable ref like with useThrottle + + useEffect(() => { + inputsRef.current = { cb, delay }; + }); // also track cur. delay + + return useCallback( + debounce( + (...args) => { + // Debounce is an async callback. Cancel it, if in the meanwhile + // (1) component has been unmounted (see isMounted in snippet) + // (2) delay has changed + if (inputsRef.current.delay === delay && isMounted()) inputsRef.current.cb(...args); + }, + delay, + options + ), + [delay, debounce] + ); +} diff --git a/pkg/grid/src/logic/useErrorHandler.ts b/pkg/grid/src/logic/useErrorHandler.ts new file mode 100644 index 000000000..bf5122e77 --- /dev/null +++ b/pkg/grid/src/logic/useErrorHandler.ts @@ -0,0 +1,17 @@ +import { useErrorHandler as useBoundaryHandler } from 'react-error-boundary'; + +export function useErrorHandler() { + const handle = useBoundaryHandler(); + + function handleError(cb: (...args: any[]) => any) { + return (...args: any[]) => { + try { + cb(...args); + } catch (error) { + handle(error); + } + }; + } + + return handleError; +} diff --git a/pkg/grid/src/logic/useIsMounted.ts b/pkg/grid/src/logic/useIsMounted.ts new file mode 100644 index 000000000..a35b8472b --- /dev/null +++ b/pkg/grid/src/logic/useIsMounted.ts @@ -0,0 +1,11 @@ +import { useRef, useEffect } from 'react'; + +export function useIsMounted() { + const isMountedRef = useRef(true); + useEffect(() => { + return () => { + isMountedRef.current = false; + }; + }, []); + return () => isMountedRef.current; +} diff --git a/pkg/grid/src/logic/useMedia.ts b/pkg/grid/src/logic/useMedia.ts new file mode 100644 index 000000000..07c560ff0 --- /dev/null +++ b/pkg/grid/src/logic/useMedia.ts @@ -0,0 +1,21 @@ +import { useCallback, useEffect, useState } from 'react'; + +export const useMedia = (mediaQuery: string) => { + const [match, setMatch] = useState(false); + + const update = useCallback((e: MediaQueryListEvent) => { + setMatch(e.matches); + }, []); + + useEffect(() => { + const query = window.matchMedia(mediaQuery); + + query.addEventListener('change', update); + update({ matches: query.matches } as MediaQueryListEvent); + return () => { + query.removeEventListener('change', update); + }; + }, [update]); + + return match; +}; diff --git a/pkg/grid/src/logic/useQuery.ts b/pkg/grid/src/logic/useQuery.ts new file mode 100644 index 000000000..142a15aff --- /dev/null +++ b/pkg/grid/src/logic/useQuery.ts @@ -0,0 +1,46 @@ +import _ from 'lodash'; +import { useCallback, useMemo } from 'react'; +import { useLocation } from 'react-router-dom'; + +function mergeQuery(search: URLSearchParams, added: Record) { + _.forIn(added, (v, k) => { + if (v) { + search.append(k, v); + } else { + search.delete(k); + } + }); +} + +export function useQuery() { + const { search, pathname } = useLocation(); + + const query = useMemo(() => new URLSearchParams(search), [search]); + + const appendQuery = useCallback( + (added: Record) => { + const q = new URLSearchParams(search); + mergeQuery(q, added); + return q.toString(); + }, + [search] + ); + + const toQuery = useCallback( + (params: Record, path = pathname) => { + const q = new URLSearchParams(search); + mergeQuery(q, params); + return { + pathname: path, + search: q.toString() + }; + }, + [search, pathname] + ); + + return { + query, + appendQuery, + toQuery + }; +} diff --git a/pkg/grid/src/logic/useWaitForProps.ts b/pkg/grid/src/logic/useWaitForProps.ts new file mode 100644 index 000000000..278bb57b5 --- /dev/null +++ b/pkg/grid/src/logic/useWaitForProps.ts @@ -0,0 +1,37 @@ +import { useCallback, useEffect, useState } from 'react'; + +export function useWaitForProps

(props: P, timeout = 0) { + const [mainResolve, setMainResolve] = useState<() => void>(() => () => {}); + const [ready, setReady] = useState<(p: P) => boolean | undefined>(); + + useEffect(() => { + if (typeof ready === 'function' && ready(props)) { + mainResolve(); + } + }, [props, ready, mainResolve]); + + /** + * Waits until some predicate is true + * + * @param r - Predicate to wait for + * @returns A promise that resolves when `r` returns true, or rejects if the + * waiting times out + * + */ + const waiter = useCallback( + (r: (props: P) => boolean) => { + setReady(() => r); + return new Promise((resolve, reject) => { + setMainResolve(() => resolve); + if (timeout > 0) { + setTimeout(() => { + reject(new Error('Timed out')); + }, timeout); + } + }); + }, + [setMainResolve, setReady, timeout] + ); + + return waiter; +} diff --git a/pkg/grid/src/main.tsx b/pkg/grid/src/main.tsx new file mode 100644 index 000000000..ed91dc168 --- /dev/null +++ b/pkg/grid/src/main.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { App } from './app'; +import './styles/index.css'; + +ReactDOM.render( + + + , + document.getElementById('app') +); diff --git a/pkg/grid/src/nav/Help.tsx b/pkg/grid/src/nav/Help.tsx new file mode 100644 index 000000000..51db624b9 --- /dev/null +++ b/pkg/grid/src/nav/Help.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import helpAndSupport from '../assets/help-and-support.svg'; + +export const Help = () => { + return ( +

+ +
+
+

For general help, ask the community

+ + Join Urbit Community + +
+
+

For all other issues:

+ + support@urbit.org + +
+
+
+ ); +}; diff --git a/pkg/grid/src/nav/Leap.tsx b/pkg/grid/src/nav/Leap.tsx new file mode 100644 index 000000000..526cbd3a0 --- /dev/null +++ b/pkg/grid/src/nav/Leap.tsx @@ -0,0 +1,280 @@ +import classNames from 'classnames'; +import React, { + ChangeEvent, + FocusEvent, + FormEvent, + KeyboardEvent, + HTMLAttributes, + useCallback, + useImperativeHandle, + useRef, + useEffect +} from 'react'; +import { Link, useHistory, useRouteMatch } from 'react-router-dom'; +import { Cross } from '../components/icons/Cross'; +import { useDebounce } from '../logic/useDebounce'; +import { useErrorHandler } from '../logic/useErrorHandler'; +import { MenuState, useLeapStore } from './Nav'; + +function normalizePathEnding(path: string) { + const end = path.length - 1; + return path[end] === '/' ? path.substring(0, end - 1) : path; +} + +export function createPreviousPath(current: string): string { + const parts = normalizePathEnding(current).split('/'); + parts.pop(); + + if (parts[parts.length - 1] === 'leap') { + parts.push('search'); + } + + return parts.join('/'); +} + +type LeapProps = { + menu: MenuState; + dropdown: string; + navOpen: boolean; + shouldDim: boolean; +} & HTMLAttributes; + +function normalizeMatchString(match: string, keepAltChars: boolean): string { + let normalizedString = match.toLocaleLowerCase().trim(); + + if (!keepAltChars) { + normalizedString = normalizedString.replace(/[^\w]/, ''); + } + + return normalizedString; +} + +export const Leap = React.forwardRef( + ({ menu, dropdown, navOpen, shouldDim, className }: LeapProps, ref) => { + const { push } = useHistory(); + const match = useRouteMatch<{ menu?: MenuState; query?: string; desk?: string }>( + `/leap/${menu}/:query?/(apps)?/:desk?` + ); + const appsMatch = useRouteMatch(`/leap/${menu}/${match?.params.query}/apps`); + const inputRef = useRef(null); + useImperativeHandle(ref, () => inputRef.current); + const { rawInput, selectedMatch, matches, selection, select } = useLeapStore(); + const handleError = useErrorHandler(); + + useEffect(() => { + const onTreaty = appsMatch && !appsMatch.isExact; + if (selection && rawInput === '' && !onTreaty) { + inputRef.current?.focus(); + } else if (selection && onTreaty) { + inputRef.current?.blur(); + } + }, [selection, rawInput, appsMatch]); + + useEffect(() => { + const newMatch = getMatch(rawInput); + + if (newMatch && rawInput) { + useLeapStore.setState({ selectedMatch: newMatch }); + } + }, [rawInput, matches]); + + const toggleSearch = useCallback(() => { + if (selection || menu === 'search') { + return; + } + + push('/leap/search'); + }, [selection, menu]); + + const onFocus = useCallback( + (e: FocusEvent) => { + // refocusing tab with input focused is false trigger + const windowFocus = e.nativeEvent.currentTarget === document.body; + if (windowFocus) { + return; + } + + toggleSearch(); + }, + [toggleSearch] + ); + + const getMatch = useCallback( + (value: string) => { + const onlySymbols = !value.match(/[\w]/g); + const normValue = normalizeMatchString(value, onlySymbols); + return matches.find( + (m) => + (m.display && normalizeMatchString(m.display, onlySymbols).startsWith(normValue)) || + normalizeMatchString(m.value, onlySymbols).startsWith(normValue) + ); + }, + [matches] + ); + + const navigateByInput = useCallback( + (input: string) => { + const normalizedValue = input.trim().replace(/(~?[\w^_-]{3,13})\//, '$1/apps/'); + push(`/leap/${menu}/${normalizedValue}`); + }, + [menu] + ); + + const debouncedSearch = useDebounce( + (input: string) => { + if (!match || appsMatch) { + return; + } + + useLeapStore.setState({ searchInput: input }); + navigateByInput(input); + }, + 300, + { leading: true } + ); + + const handleSearch = useCallback(debouncedSearch, [match]); + + const onChange = useCallback( + handleError((e: ChangeEvent) => { + const input = e.target as HTMLInputElement; + const value = input.value.trim(); + const isDeletion = (e.nativeEvent as InputEvent).inputType === 'deleteContentBackward'; + const inputMatch = getMatch(value); + const matchValue = inputMatch?.display || inputMatch?.value; + + if (matchValue && inputRef.current && !isDeletion) { + inputRef.current.value = matchValue; + const start = matchValue.startsWith(value) + ? value.length + : matchValue.substring(0, matchValue.indexOf(value)).length + value.length; + inputRef.current.setSelectionRange(start, matchValue.length); + useLeapStore.setState({ + rawInput: matchValue, + selectedMatch: inputMatch + }); + } else { + useLeapStore.setState({ + rawInput: value, + selectedMatch: matches[0] + }); + } + + handleSearch(value); + }), + [matches] + ); + + const onSubmit = useCallback( + handleError((e: FormEvent) => { + e.preventDefault(); + + const value = inputRef.current?.value.trim(); + const currentMatch = selectedMatch || (value && getMatch(value)); + + if (!currentMatch) { + return; + } + + if (currentMatch?.openInNewTab) { + window.open(currentMatch.url, currentMatch.value); + return; + } + + push(currentMatch.url); + useLeapStore.setState({ rawInput: '' }); + }), + [match, selectedMatch] + ); + + const onKeyDown = useCallback( + handleError((e: KeyboardEvent) => { + const deletion = e.key === 'Backspace' || e.key === 'Delete'; + const arrow = e.key === 'ArrowDown' || e.key === 'ArrowUp'; + + if (deletion && !rawInput && selection) { + e.preventDefault(); + select(null, appsMatch && !appsMatch.isExact ? undefined : match?.params.query); + const pathBack = createPreviousPath(match?.url || ''); + push(pathBack); + } + + if (arrow) { + e.preventDefault(); + if (matches.length === 0) { + return; + } + + const currentIndex = selectedMatch + ? matches.findIndex((m) => { + const matchValue = m.display || m.value; + const searchValue = selectedMatch.display || selectedMatch.value; + return matchValue === searchValue; + }) + : 0; + const unsafeIndex = e.key === 'ArrowUp' ? currentIndex - 1 : currentIndex + 1; + const index = (unsafeIndex + matches.length) % matches.length; + + const newMatch = matches[index]; + const matchValue = newMatch.display || newMatch.value; + useLeapStore.setState({ + rawInput: matchValue, + // searchInput: matchValue, + selectedMatch: newMatch + }); + } + }), + [selection, rawInput, match, matches, selectedMatch] + ); + + return ( +
+
+ + +
+ {menu === 'search' && ( + select(null)} + > + + Close + + )} +
+ ); + } +); diff --git a/pkg/grid/src/nav/Nav.tsx b/pkg/grid/src/nav/Nav.tsx new file mode 100644 index 000000000..fddfe25da --- /dev/null +++ b/pkg/grid/src/nav/Nav.tsx @@ -0,0 +1,179 @@ +import { DialogContent } from '@radix-ui/react-dialog'; +import * as Portal from '@radix-ui/react-portal'; +import classNames from 'classnames'; +import React, { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'; +import { ErrorBoundary } from 'react-error-boundary'; +import { Route, Switch, useHistory, useRouteMatch } from 'react-router-dom'; +import create from 'zustand'; +import { Dialog } from '../components/Dialog'; +import { ErrorAlert } from '../components/ErrorAlert'; +import { Help } from './Help'; +import { Leap } from './Leap'; +import { Notifications } from './Notifications'; +import { NotificationsLink } from './NotificationsLink'; +import { Search } from './Search'; +import { SystemMenu } from './SystemMenu'; +import { SystemPreferences } from './SystemPreferences'; + +export interface MatchItem { + url: string; + openInNewTab: boolean; + value: string; + display?: string; +} + +interface LeapStore { + rawInput: string; + searchInput: string; + matches: MatchItem[]; + selectedMatch?: MatchItem; + selection: React.ReactNode; + select: (selection: React.ReactNode, input?: string) => void; +} + +export const useLeapStore = create((set) => ({ + rawInput: '', + searchInput: '', + matches: [], + selectedMatch: undefined, + selection: null, + select: (selection: React.ReactNode, input?: string) => + set({ + rawInput: input || '', + searchInput: input || '', + selection + }) +})); + +window.leap = useLeapStore.getState; + +export type MenuState = + | 'closed' + | 'search' + | 'notifications' + | 'help-and-support' + | 'system-preferences'; + +interface NavProps { + menu?: MenuState; +} + +export const Nav: FunctionComponent = ({ menu }) => { + const { push } = useHistory(); + const inputRef = useRef(null); + const navRef = useRef(null); + const dialogNavRef = useRef(null); + const systemMenuOpen = useRouteMatch('/system-menu'); + const [dialogContentOpen, setDialogContentOpen] = useState(false); + const select = useLeapStore((state) => state.select); + + const menuState = menu || 'closed'; + const isOpen = menuState !== 'closed'; + const eitherOpen = isOpen || systemMenuOpen; + + useEffect(() => { + if (!isOpen) { + select(null); + setDialogContentOpen(false); + } + }, [isOpen]); + + const onOpen = useCallback( + (event: Event) => { + event.preventDefault(); + + setDialogContentOpen(true); + if (menu === 'search' && inputRef.current) { + setTimeout(() => { + inputRef.current?.focus(); + }, 0); + } + }, + [menu] + ); + + const onDialogClose = useCallback((open: boolean) => { + if (!open) { + push('/'); + } + }, []); + + const preventClose = useCallback((e) => { + const target = e.target as HTMLElement; + const hasNavAncestor = target.closest('#dialog-nav'); + + if (hasNavAncestor) { + e.preventDefault(); + } + }, []); + + return ( + push('/')}> + {/* Using portal so that we can retain the same nav items both in the dialog and in the base header */} + + + + + +
+ + +
+
+ + + + + + +
+ +
+ + ); +}; diff --git a/pkg/grid/src/nav/Notifications.tsx b/pkg/grid/src/nav/Notifications.tsx new file mode 100644 index 000000000..4b2fb3526 --- /dev/null +++ b/pkg/grid/src/nav/Notifications.tsx @@ -0,0 +1,80 @@ +import React, { useEffect } from 'react'; +import { ErrorBoundary } from 'react-error-boundary'; +import { Link, NavLink, Route, RouteComponentProps, Switch } from 'react-router-dom'; +import { Button } from '../components/Button'; +import { ErrorAlert } from '../components/ErrorAlert'; +import { useHarkStore } from '../state/hark'; +import { Inbox } from './notifications/Inbox'; + +export const Notifications = ({ history }: RouteComponentProps) => { + const markAllAsRead = () => { + const { archiveAll } = useHarkStore.getState(); + archiveAll(); + }; + + useEffect(() => { + function visibilitychange() { + if (document.visibilityState === 'hidden') { + useHarkStore.getState().opened(); + } + } + document.addEventListener('visibilitychange', visibilitychange); + + return () => { + document.removeEventListener('visibilitychange', visibilitychange); + useHarkStore.getState().opened(); + }; + }, []); + // const select = useLeapStore((s) => s.select); + + return ( + history.push('/leap/notifications')} + > +
+
+ + New + + + Archive + + + + +
+ + + + + + + + +
+
+ ); +}; diff --git a/pkg/grid/src/nav/NotificationsLink.tsx b/pkg/grid/src/nav/NotificationsLink.tsx new file mode 100644 index 000000000..d1997165b --- /dev/null +++ b/pkg/grid/src/nav/NotificationsLink.tsx @@ -0,0 +1,79 @@ +import classNames from 'classnames'; +import React, { useCallback } from 'react'; +import { Timebox } from '@urbit/api'; +import { Link, LinkProps } from 'react-router-dom'; +import { Bullet } from '../components/icons/Bullet'; +import { Cross } from '../components/icons/Cross'; +import { useHarkStore } from '../state/hark'; +import { useLeapStore } from './Nav'; + +type NotificationsState = 'empty' | 'unread' | 'attention-needed' | 'open'; + +function getNotificationsState(isOpen: boolean, box: Timebox): NotificationsState { + const notifications = Object.values(box); + if ( + notifications.filter( + ({ bin }) => bin.place.desk === window.desk && ['/lag', 'blocked'].includes(bin.place.path) + ).length > 0 + ) { + return 'attention-needed'; + } + if (isOpen) { + return 'open'; + } + + // TODO: when real structure, this should be actually be unread not just existence + if (notifications.length > 0) { + return 'unread'; + } + + return 'empty'; +} + +type NotificationsLinkProps = Omit, 'to'> & { + navOpen: boolean; + notificationsOpen: boolean; + shouldDim: boolean; +}; + +export const NotificationsLink = ({ + navOpen, + notificationsOpen, + shouldDim +}: NotificationsLinkProps) => { + const unseen = useHarkStore((s) => s.unseen); + const state = getNotificationsState(notificationsOpen, unseen); + const select = useLeapStore((s) => s.select); + const clearSelection = useCallback(() => select(null), [select]); + + return ( + + {state === 'empty' && } + {state === 'unread' && Object.keys(unseen).length} + {state === 'attention-needed' && ( + + ! Attention needed + + )} + {state === 'open' && ( + <> + + Close + + )} + + ); +}; diff --git a/pkg/grid/src/nav/Search.tsx b/pkg/grid/src/nav/Search.tsx new file mode 100644 index 000000000..ebcd5f4ee --- /dev/null +++ b/pkg/grid/src/nav/Search.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { Route, RouteComponentProps, Switch } from 'react-router-dom'; +import { ErrorBoundary } from 'react-error-boundary'; +import { TreatyInfo } from './search/TreatyInfo'; +import { Apps } from './search/Apps'; +import { Home } from './search/Home'; +import { Providers } from './search/Providers'; +import { ErrorAlert } from '../components/ErrorAlert'; + +type SearchProps = RouteComponentProps<{ + query?: string; +}>; + +export const Search = ({ match, history }: SearchProps) => { + return ( + history.push('/leap/search')}> + + + + + + + + ); +}; diff --git a/pkg/grid/src/nav/SystemMenu.tsx b/pkg/grid/src/nav/SystemMenu.tsx new file mode 100644 index 000000000..d58c9ffb5 --- /dev/null +++ b/pkg/grid/src/nav/SystemMenu.tsx @@ -0,0 +1,156 @@ +import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; +import classNames from 'classnames'; +import clipboardCopy from 'clipboard-copy'; +import React, { HTMLAttributes, useCallback, useState } from 'react'; +import { Link, Route, useHistory } from 'react-router-dom'; +import { Vat } from '@urbit/api/hood'; +import { Adjust } from '../components/icons/Adjust'; +import { useVat } from '../state/kiln'; +import { disableDefault, handleDropdownLink } from '../state/util'; +import { useMedia } from '../logic/useMedia'; +import { Cross } from '../components/icons/Cross'; +import { useLeapStore } from './Nav'; + +type SystemMenuProps = HTMLAttributes & { + open: boolean; + subMenuOpen: boolean; + shouldDim: boolean; +}; + +function getHash(vat: Vat): string { + const parts = vat.hash.split('.'); + return parts[parts.length - 1]; +} + +export const SystemMenu = ({ className, open, subMenuOpen, shouldDim }: SystemMenuProps) => { + const { push } = useHistory(); + const [copied, setCopied] = useState(false); + const garden = useVat(window.desk); + const hash = garden ? getHash(garden) : null; + const isMobile = useMedia('(max-width: 639px)'); + const select = useLeapStore((s) => s.select); + const clearSelection = useCallback(() => select(null), [select]); + + const copyHash = useCallback( + (event: Event) => { + event.preventDefault(); + if (!hash) { + return; + } + + setCopied(true); + clipboardCopy(hash); + + setTimeout(() => { + setCopied(false); + }, 1250); + }, + [hash] + ); + + const preventFlash = useCallback((e) => { + const target = e.target as HTMLElement; + + if (target.id !== 'system-menu-overlay') { + e.preventDefault(); + } + }, []); + + return ( + <> +
+ setTimeout(() => !isOpen && push('/'), 15)} + > + + {!open && !subMenuOpen && ( + <> + + System Menu + + )} + {(open || subMenuOpen) && ( + <> + + Close + + )} + {/* trigger here just for anchoring the dropdown */} + + + + + + + + System Preferences + + + + Help and Support + + + + About + + {hash && ( + + Base Hash + + {!copied && {hash}} + {copied && 'copied!'} + + + )} + + + + +
+ +
+ + + ); +}; diff --git a/pkg/grid/src/nav/SystemPreferences.tsx b/pkg/grid/src/nav/SystemPreferences.tsx new file mode 100644 index 000000000..78ca87f4c --- /dev/null +++ b/pkg/grid/src/nav/SystemPreferences.tsx @@ -0,0 +1,145 @@ +import React, { PropsWithChildren, useCallback } from 'react'; +import { Link, Route, RouteComponentProps, Switch, useRouteMatch } from 'react-router-dom'; +import { ErrorBoundary } from 'react-error-boundary'; +import classNames from 'classnames'; +import { NotificationPrefs } from './preferences/NotificationPrefs'; +import { SystemUpdatePrefs } from './preferences/SystemUpdatePrefs'; +import { InterfacePrefs } from './preferences/InterfacePrefs'; +import { useCharges } from '../state/docket'; +import { AppPrefs } from './preferences/AppPrefs'; +import { DocketImage } from '../components/DocketImage'; +import { ErrorAlert } from '../components/ErrorAlert'; +import { useMedia } from '../logic/useMedia'; +import { LeftArrow } from '../components/icons/LeftArrow'; +import { System } from '../components/icons/System'; +import { Interface } from '../components/icons/Interface'; +import { Notifications } from '../components/icons/Notifications'; +import { getAppName } from '../state/util'; + +interface SystemPreferencesSectionProps { + url: string; + active: boolean; +} + +function SystemPreferencesSection({ + url, + active, + children +}: PropsWithChildren) { + return ( +
  • + + {children} + +
  • + ); +} + +export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }>) => { + const { match, history } = props; + const subMatch = useRouteMatch<{ submenu: string; desk?: string }>( + `${match.url}/:submenu/:desk?` + ); + const charges = useCharges(); + const filteredCharges = Object.values(charges).filter((charge) => charge.desk !== window.desk); + const isMobile = useMedia('(max-width: 639px)'); + const settingsPath = isMobile ? `${match.url}/:submenu` : '/'; + + const matchSub = useCallback( + (target: string, desk?: string) => { + if (isMobile) { + return false; + } + + if (!subMatch && target === 'notifications') { + return true; + } + + if (desk && subMatch?.params.desk !== desk) { + return false; + } + + return subMatch?.params.submenu === target; + }, + [match, subMatch] + ); + + const subUrl = useCallback((submenu: string) => `${match.url}/${submenu}`, [match]); + + return ( + history.push('/leap/system-preferences')} + > +
    + + + + +
    + + + + + + + + Back + +
    +
    +
    +
    + ); +}; diff --git a/pkg/grid/src/nav/notifications/BasicNotification.tsx b/pkg/grid/src/nav/notifications/BasicNotification.tsx new file mode 100644 index 000000000..94a6d5606 --- /dev/null +++ b/pkg/grid/src/nav/notifications/BasicNotification.tsx @@ -0,0 +1,102 @@ +import React from 'react'; +import cn from 'classnames'; +import { Notification, harkBinToId, HarkContent, HarkLid } from '@urbit/api'; +import { map, take } from 'lodash'; +import { useCharge } from '../../state/docket'; +import { Elbow } from '../../components/icons/Elbow'; +import { ShipName } from '../../components/ShipName'; +import { DeskLink } from '../../components/DeskLink'; +import { useHarkStore } from '../../state/hark'; +import { DocketImage } from '../../components/DocketImage'; +import { Button } from '../../components/Button'; + +interface BasicNotificationProps { + notification: Notification; + lid: HarkLid; +} + +const MAX_CONTENTS = 5; + +const NotificationText = ({ contents }: { contents: HarkContent[] }) => { + return ( + <> + {contents.map((content, idx) => { + if ('ship' in content) { + return ; + } + return content.text; + })} + + ); +}; + +export const BasicNotification = ({ notification, lid }: BasicNotificationProps) => { + const { desk } = notification.bin.place; + const binId = harkBinToId(notification.bin); + const id = `notif-${notification.time}-${binId}`; + + const charge = useCharge(desk); + const first = notification.body?.[0]; + if (!first || !charge) { + return null; + } + const contents = map(notification.body, 'content').filter((c) => c.length > 0); + const large = contents.length === 0; + const archive = () => { + useHarkStore.getState().archiveNote(notification.bin, lid); + }; + + const archiveNoFollow = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + archive(); + }; + + return ( + +
    + +
    {charge?.title || desk}
    + {!large ? : null} +

    + +

    + {!('time' in lid) ? ( +
    + +
    + ) : null} +
    + {contents.length > 0 ? ( +
    + {take(contents, MAX_CONTENTS).map((content) => ( +

    + +

    + ))} + {contents.length > MAX_CONTENTS ? ( +

    and {contents.length - MAX_CONTENTS} more

    + ) : null} +
    + ) : null} +
    + ); +}; diff --git a/pkg/grid/src/nav/notifications/Inbox.tsx b/pkg/grid/src/nav/notifications/Inbox.tsx new file mode 100644 index 000000000..66299772c --- /dev/null +++ b/pkg/grid/src/nav/notifications/Inbox.tsx @@ -0,0 +1,71 @@ +import React, { useEffect } from 'react'; +import { HarkLid, Notification } from '@urbit/api'; +import { BasicNotification } from './BasicNotification'; +import { BaseBlockedNotification, RuntimeLagNotification } from './SystemNotification'; +import { useNotifications } from '../../state/notifications'; +import { useHarkStore } from '../../state/hark'; +import { OnboardingNotification } from './OnboardingNotification'; + +function renderNotification(notification: Notification, key: string, lid: HarkLid) { + // Special casing + if (notification.bin.place.desk === window.desk) { + if (notification.bin.place.path === '/lag') { + return ; + } + if (notification.bin.place.path === '/blocked') { + return ; + } + if (notification.bin.place.path === '/onboard') { + return ; + } + } + return ; +} + +const Empty = () => ( +
    + All clear! +
    +); + +export const Inbox = ({ archived = false }) => { + const { unseen, seen } = useNotifications(); + const archive = useHarkStore((s) => s.archive); + + useEffect(() => { + useHarkStore.getState().getMore(); + }, [archived]); + + if (archived ? archive.size === 0 : Object.keys({ ...seen, ...unseen }).length === 0) { + return ; + } + + return ( +
    + {archived ? ( + Array.from(archive).map(([key, box]) => { + return Object.entries(box) + .sort(([, a], [, b]) => b.time - a.time) + .map(([binId, n]) => + renderNotification(n, `${key.toString()}-${binId}`, { time: key.toString() }) + ); + }) + ) : ( + <> +
    Unseen
    +
    + {Object.entries(unseen) + .sort(([, a], [, b]) => b.time - a.time) + .map(([binId, n]) => renderNotification(n, `unseen-${binId}`, { unseen: null }))} +
    +
    Seen
    +
    + {Object.entries(seen) + .sort(([, a], [, b]) => b.time - a.time) + .map(([binId, n]) => renderNotification(n, `seen-${binId}`, { seen: null }))} +
    + + )} +
    + ); +}; diff --git a/pkg/grid/src/nav/notifications/NotificationButton.tsx b/pkg/grid/src/nav/notifications/NotificationButton.tsx new file mode 100644 index 000000000..d8c27c999 --- /dev/null +++ b/pkg/grid/src/nav/notifications/NotificationButton.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import type * as Polymorphic from '@radix-ui/react-polymorphic'; +import classNames from 'classnames'; + +type NotificationButtonVariant = 'primary' | 'secondary' | 'destructive'; + +type PolymorphicButton = Polymorphic.ForwardRefComponent< + 'button', + { + variant?: NotificationButtonVariant; + } +>; + +const variants: Record = { + primary: 'text-blue bg-white', + secondary: 'text-black bg-white', + destructive: 'text-red-500 bg-white' +}; + +export const NotificationButton = React.forwardRef( + ({ as: Comp = 'button', variant = 'primary', children, className, ...props }, ref) => { + return ( + + {children} + + ); + } +) as PolymorphicButton; diff --git a/pkg/grid/src/nav/notifications/OnboardingNotification.tsx b/pkg/grid/src/nav/notifications/OnboardingNotification.tsx new file mode 100644 index 000000000..57b16fda4 --- /dev/null +++ b/pkg/grid/src/nav/notifications/OnboardingNotification.tsx @@ -0,0 +1,152 @@ +import React from 'react'; +import cn from 'classnames'; +import { Link } from 'react-router-dom'; +import { HarkLid, Vats, getVatPublisher } from '@urbit/api'; +import { Button } from '../../components/Button'; +import { useCurrentTheme, useProtocolHandling } from '../../state/local'; +import { getDarkColor } from '../../state/util'; +import useKilnState from '../../state/kiln'; +import {useHarkStore} from '../../state/hark'; + +const getCards = (vats: Vats, protocol: boolean): OnboardingCardProps[] => { + const cards = [ + { + title: 'Terminal', + body: "A web interface to your Urbit's command line (the dojo).", + button: 'Install', + color: '#9CA4B1', + href: '/leap/search/direct/apps/~mister-dister-dozzod-dozzod/webterm', + ship: '~mister-dister-dozzod-dozzod', + desk: 'webterm' + }, + { + title: 'Groups', + body: 'A suite of applications to communicate on Urbit', + button: 'Install', + color: '#D1DDD3', + href: '/leap/search/direct/apps/~lander-dister-dozzod-dozzod/landscape', + ship: '~lander-dister-dozzod-dozzod', + desk: 'landscape' + }, + { + title: 'Bitcoin', + body: ' A Bitcoin Wallet that lets you send and receive Bitcoin directly to and from other Urbit users', + button: 'Install', + color: '#F6EBDB', + href: '/leap/search/direct/apps/~mister-dister-dozzod-dozzod/bitcoin', + ship: '~mister-dister-dozzod-dozzod', + desk: 'bitcoin' + } + // Commenting out until we have something real + // { + // title: 'Debug', + // body: "Install a debugger. You can inspect your ship's internals using this interface", + // button: 'Install', + // color: '#E5E5E5', + // href: '/leap/search/direct/apps/~zod/debug' + // } + // { + // title: 'Build an app', + // body: 'You can instantly get started building new things on Urbit. Just right click your Landscape and select “New App”', + // button: 'Learn more', + // color: '#82A6CA' + // } + ]; + if('registerProtocolHandler' in window.navigator && !protocol) { + cards.push({ + title: 'Open Urbit-Native Links', + body: 'Enable your Urbit to open links you find in the wild', + button: 'Enable Link Handler', + color: '#82A6CA', + href: '/leap/system-preferences/interface', + desk: '', + ship: '' + }); + } + + + return cards.filter(card => { + return !Object.values(vats).find(vat => getVatPublisher(vat) == card.ship && vat?.arak?.rail?.desk === card.desk); + }); +}; + +if ('registerProtocolHandler' in window.navigator) { +} + +interface OnboardingCardProps { + title: string; + button: string; + href: string; + body: string; + color: string; + ship: string; + desk: string; +} + +const OnboardingCard = ({ title, button, href, body, color }: OnboardingCardProps) => ( +
    +
    +

    {title}

    +

    {body}

    +
    + +
    +); + +interface OnboardingNotificationProps { + unread?: boolean; + lid: HarkLid; +} + +export const OnboardingNotification = ({ unread = false, lid }: OnboardingNotificationProps) => { + const theme = useCurrentTheme(); + const vats = useKilnState((s) => s.vats); + const protocolHandling = useProtocolHandling(); + const cards = getCards(vats, protocolHandling); + + if(cards.length === 0 && !('time' in lid)) { + useHarkStore.getState().archiveNote({ + path: '/', + place: { + path: '/onboard', + desk: window.desk + } + }, lid); + return null; + + } + + return ( +
    +
    +
    + + System +
    +
    +

    Hello there, and welcome!

    +
    +
    +
    + { + /* eslint-disable-next-line react/no-array-index-key */ + cards.map((card, i) => ( + + )) + } +
    +
    + ); +}; diff --git a/pkg/grid/src/nav/notifications/SystemNotification.tsx b/pkg/grid/src/nav/notifications/SystemNotification.tsx new file mode 100644 index 000000000..accb6a95c --- /dev/null +++ b/pkg/grid/src/nav/notifications/SystemNotification.tsx @@ -0,0 +1,139 @@ +import { pick } from 'lodash'; +import React, { useCallback } from 'react'; +import { kilnBump } from '@urbit/api/hood'; +import { AppList } from '../../components/AppList'; +import { Button } from '../../components/Button'; +import { Dialog, DialogClose, DialogContent, DialogTrigger } from '../../components/Dialog'; +import { Elbow } from '../../components/icons/Elbow'; +import api from '../../state/api'; +import { useCharges } from '../../state/docket'; + +import { NotificationButton } from './NotificationButton'; +import { disableDefault } from '../../state/util'; + +export const RuntimeLagNotification = () => ( +
    +
    +
    + + System +
    +
    + +

    The runtime blocked a System Update

    +
    +
    +
    +

    + In order to proceed with the System Update, you’ll need to upgrade the runtime. If you are + using a hosted ship, you should contact your hosting provider. +

    +
    +
    +); + +export const BaseBlockedNotification = () => { + const desks: string[] = []; + const charges = useCharges(); + const blockedCharges = Object.values(pick(charges, desks)); + const count = blockedCharges.length; + + const handlePauseOTAs = useCallback(() => {}, []); + + const handleArchiveApps = useCallback(async () => { + api.poke(kilnBump(true)); + }, []); + + return ( +
    +
    +
    + + System +
    +
    + +

    The following ({count}) apps blocked a System Update:

    +
    +
    + +
    +

    + In order to proceed with the System Update, you’ll need to temporarily archive these apps, + which will render them unusable, but with data intact. +

    +

    + Archived apps will automatically un-archive and resume operation when their developer + provides an app update. +

    +
    +
    + + Dismiss + +

    Skip System Update

    +

    + Skipping the application fo an incoming System Update will grant you the ability to + continue using incompatible apps at the cost of an urbit that's not up to date. +

    +

    + You can choose to apply System Updates from System Preferences any time.{' '} + + Learn More + +

    +
    + + Cancel + + + Pause OTAs + +
    +
    +
    + + + Archive ({count}) apps and Apply System Update + + +

    Archive ({count}) Apps and Apply System Update

    +

    + The following apps will be archived until their developer provides a compatible update + to your system. +

    + +
    + + Cancel + + + Archive Apps + +
    +
    +
    +
    +
    + ); +}; diff --git a/pkg/grid/src/nav/preferences/AppPrefs.tsx b/pkg/grid/src/nav/preferences/AppPrefs.tsx new file mode 100644 index 000000000..51910f776 --- /dev/null +++ b/pkg/grid/src/nav/preferences/AppPrefs.tsx @@ -0,0 +1,39 @@ +import React, { useCallback } from 'react'; +import { RouteComponentProps } from 'react-router-dom'; +import { Setting } from '../../components/Setting'; +import { ShipName } from '../../components/ShipName'; +import { useCharge } from '../../state/docket'; +import useKilnState, { useVat } from '../../state/kiln'; +import { getAppName } from '../../state/util'; + +export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => { + const { desk } = match.params; + const charge = useCharge(desk); + const vat = useVat(desk); + const tracking = !!vat?.arak.rail; + const otasEnabled = !vat?.arak.rail?.paused; + const otaSource = vat?.arak.rail?.ship; + const toggleOTAs = useKilnState((s) => s.toggleOTAs); + + const toggleUpdates = useCallback((on: boolean) => toggleOTAs(desk, on), [desk, toggleOTAs]); + + return ( + <> +

    {getAppName(charge)} Settings

    +
    + {tracking ? ( + +

    Automatically download and apply updates to keep {getAppName(charge)} up to date.

    + {otaSource && ( +

    + OTA Source: +

    + )} +
    + ) : ( +

    No settings

    + )} +
    + + ); +}; diff --git a/pkg/grid/src/nav/preferences/InterfacePrefs.tsx b/pkg/grid/src/nav/preferences/InterfacePrefs.tsx new file mode 100644 index 000000000..d07b6d9de --- /dev/null +++ b/pkg/grid/src/nav/preferences/InterfacePrefs.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { Setting } from '../../components/Setting'; +import { useProtocolHandling, setLocalState } from '../../state/local'; + +export function InterfacePrefs() { + const protocolHandling = useProtocolHandling(); + const secure = window.location.protocol === 'https:' || window.location.hostname === 'localhost'; + const linkHandlingAllowed = secure && 'registerProtocolHandler' in window.navigator; + const toggleProtoHandling = async () => { + if (!protocolHandling && window?.navigator?.registerProtocolHandler) { + try { + window.navigator.registerProtocolHandler( + 'web+urbitgraph', + '/apps/grid/perma?ext=%s', + 'Urbit Links' + ); + setLocalState((draft) => { + draft.protocolHandling = true; + }); + } catch (e) { + console.error(e); + } + } else if (protocolHandling && window.navigator?.unregisterProtocolHandler) { + try { + window.navigator.unregisterProtocolHandler('web+urbitgraph', '/apps/grid/perma?ext=%s'); + setLocalState((draft) => { + draft.protocolHandling = false; + }); + } catch (e) { + console.error(e); + } + } + }; + + return ( + <> +

    Interface Settings

    + +

    + Automatically open urbit links with this urbit + {!linkHandlingAllowed && ( + <> + , requires HTTPS + + )} +

    +
    + + ); +} diff --git a/pkg/grid/src/nav/preferences/NotificationPrefs.tsx b/pkg/grid/src/nav/preferences/NotificationPrefs.tsx new file mode 100644 index 000000000..f7ca7b702 --- /dev/null +++ b/pkg/grid/src/nav/preferences/NotificationPrefs.tsx @@ -0,0 +1,59 @@ +import { setMentions } from '@urbit/api/dist'; +import React from 'react'; +import { Setting } from '../../components/Setting'; +import { pokeOptimisticallyN } from '../../state/base'; +import { HarkState, reduceGraph, useHarkStore } from '../../state/hark'; +import { useSettingsState, SettingsState } from '../../state/settings'; + +const selDnd = (s: SettingsState) => s.display.doNotDisturb; +async function toggleDnd() { + const state = useSettingsState.getState(); + const curr = selDnd(state); + if (curr) { + Notification.requestPermission(); + } + await state.putEntry('display', 'doNotDisturb', !curr); +} + +const selMentions = (s: HarkState) => s.notificationsGraphConfig.mentions; +async function toggleMentions() { + const state = useHarkStore.getState(); + await pokeOptimisticallyN(useHarkStore, setMentions(!selMentions(state)), reduceGraph); +} + +export const NotificationPrefs = () => { + const doNotDisturb = useSettingsState(selDnd); + const mentions = useHarkStore(selMentions); + const secure = window.location.protocol === 'https:' || window.location.hostname === 'localhost'; + + return ( + <> +

    Notifications

    +
    + +

    + Block visual desktop notifications whenever Urbit software produces a notification + badge. +

    +

    + Turning this "off" will prompt your browser to ask if you'd like to + enable notifications + {!secure && ( + <> + , requires HTTPS + + )} +

    +
    + +

    Notify me if someone mentions my @p in a channel I've joined

    +
    +
    + + ); +}; diff --git a/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx b/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx new file mode 100644 index 000000000..4a8eafc55 --- /dev/null +++ b/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx @@ -0,0 +1,88 @@ +import _ from 'lodash'; +import React, { ChangeEvent, FormEvent, useCallback, useEffect, useState } from 'react'; +import { Button } from '../../components/Button'; +import { Setting } from '../../components/Setting'; +import { ShipName } from '../../components/ShipName'; +import { Spinner } from '../../components/Spinner'; +import { useAsyncCall } from '../../logic/useAsyncCall'; +import useKilnState, { useVat } from '../../state/kiln'; + +export const SystemUpdatePrefs = () => { + const { changeOTASource, toggleOTAs } = useKilnState((s) => + _.pick(s, ['toggleOTAs', 'changeOTASource']) + ); + const base = useVat('base'); + const otasEnabled = base && !(base.arak?.rail?.paused ?? true); + const otaSource = base && base.arak.rail?.ship; + + const toggleBase = useCallback((on: boolean) => toggleOTAs('base', on), [toggleOTAs]); + + const [source, setSource] = useState(''); + const sourceDirty = source !== otaSource; + const { status: sourceStatus, call: setOTA } = useAsyncCall(changeOTASource); + + useEffect(() => { + if (otaSource) { + setSource(otaSource); + } + }, [otaSource]); + + const handleSourceChange = useCallback((e: ChangeEvent) => { + const { target } = e; + const value = target.value.trim(); + setSource(value.startsWith('~') ? value : `~${value}`); + }, []); + + const onSubmit = useCallback( + (e: FormEvent) => { + e.preventDefault(); + setOTA(source); + }, + [source] + ); + + return ( + <> +

    System Updates

    +
    + +

    Automatically download and apply system updates to keep your Urbit up to date.

    + {otaSource && ( +

    + OTA Source: +

    + )} +
    +
    + +

    + Enter a valid urbit name into this form to change who you receive OTA updates from. Be + sure to select a reliable urbit! +

    +
    + + {sourceDirty && ( + + )} +
    +
    +
    + + ); +}; diff --git a/pkg/grid/src/nav/search/Apps.tsx b/pkg/grid/src/nav/search/Apps.tsx new file mode 100644 index 000000000..c020390ff --- /dev/null +++ b/pkg/grid/src/nav/search/Apps.tsx @@ -0,0 +1,118 @@ +import React, { useCallback, useEffect, useMemo } from 'react'; +import { RouteComponentProps } from 'react-router-dom'; +import fuzzy from 'fuzzy'; +import { Treaty } from '@urbit/api'; +import { ShipName } from '../../components/ShipName'; +import useDocketState, { useAllyTreaties, useAllies } from '../../state/docket'; +import { useLeapStore } from '../Nav'; +import { AppList } from '../../components/AppList'; +import { addRecentDev } from './Home'; +import { Spinner } from '../../components/Spinner'; + +type AppsProps = RouteComponentProps<{ ship: string }>; + +export const Apps = ({ match }: AppsProps) => { + const { searchInput, selectedMatch, select } = useLeapStore((state) => ({ + searchInput: state.searchInput, + select: state.select, + selectedMatch: state.selectedMatch + })); + const provider = match?.params.ship; + const { treaties, status } = useAllyTreaties(provider); + const allies = useAllies(); + const isAllied = provider in allies; + + useEffect(() => { + if (Object.keys(allies).length > 0 && !isAllied) { + useDocketState.getState().addAlly(provider); + } + }, [allies, isAllied, provider]); + + const results = useMemo(() => { + if (!treaties) { + return undefined; + } + const values = Object.values(treaties); + return fuzzy + .filter( + searchInput, + values.map((v) => v.title) + ) + .sort((a, b) => { + const left = a.string.startsWith(searchInput) ? a.score + 1 : a.score; + const right = b.string.startsWith(searchInput) ? b.score + 1 : b.score; + + return right - left; + }) + .map((result) => values[result.index]); + }, [treaties, searchInput]); + const count = results?.length; + + const getAppPath = useCallback( + (app: Treaty) => `${match?.path.replace(':ship', provider)}/${app.ship}/${app.desk}`, + [match] + ); + + useEffect(() => { + select( + <> + Apps by + + ); + }, [provider]); + + useEffect(() => { + if (results) { + useLeapStore.setState({ + matches: results.map((r) => ({ + url: getAppPath(r), + openInNewTab: false, + value: r.desk, + display: r.title + })) + }); + } + }, [results]); + + useEffect(() => { + if (provider) { + useDocketState.getState().fetchAllyTreaties(provider); + addRecentDev(provider); + } + }, [provider]); + + return ( +
    + {status === 'loading' && ( + + Finding software... + + )} + {results && results.length > 0 && ( + <> +
    +

    + Software developed by +

    +

    + {count} result{count === 1 ? '' : 's'} +

    +
    + +

    That's it!

    + + )} + {status === 'error' || + ((status === 'success' || status === 'initial') && results?.length === 0 && ( +

    + Unable to find software developed by +

    + ))} +
    + ); +}; diff --git a/pkg/grid/src/nav/search/Home.tsx b/pkg/grid/src/nav/search/Home.tsx new file mode 100644 index 000000000..a5db6b462 --- /dev/null +++ b/pkg/grid/src/nav/search/Home.tsx @@ -0,0 +1,169 @@ +import produce from 'immer'; +import create from 'zustand'; +import _ from 'lodash'; +import React, { useEffect } from 'react'; +import { persist } from 'zustand/middleware'; +import { MatchItem, useLeapStore } from '../Nav'; +import { providerMatch } from './Providers'; +import { AppList } from '../../components/AppList'; +import { ProviderList } from '../../components/ProviderList'; +import { AppLink } from '../../components/AppLink'; +import { ShipName } from '../../components/ShipName'; +import { ProviderLink } from '../../components/ProviderLink'; +import useDocketState, { ChargesWithDesks, useCharges } from '../../state/docket'; +import { + clearStorageMigration, + createStorageKey, + getAppHref, + storageVersion +} from '../../state/util'; +import useContactState from '../../state/contact'; + +export interface RecentsStore { + recentApps: string[]; + recentDevs: string[]; + addRecentApp: (desk: string) => void; + addRecentDev: (ship: string) => void; + removeRecentApp: (desk: string) => void; +} + +export const useRecentsStore = create( + persist( + (set) => ({ + recentApps: [], + recentDevs: [], + addRecentApp: (desk: string) => { + set( + produce((draft: RecentsStore) => { + const hasApp = draft.recentApps.find((testDesk) => testDesk === desk); + if (!hasApp) { + draft.recentApps.unshift(desk); + } + + draft.recentApps = _.take(draft.recentApps, 3); + }) + ); + }, + addRecentDev: (dev) => { + set( + produce((draft: RecentsStore) => { + const hasDev = draft.recentDevs.includes(dev); + if (!hasDev) { + draft.recentDevs.unshift(dev); + } + + draft.recentDevs = _.take(draft.recentDevs, 3); + }) + ); + }, + removeRecentApp: (desk: string) => { + set( + produce((draft: RecentsStore) => { + _.remove(draft.recentApps, (test) => test === desk); + }) + ); + } + }), + { + whitelist: ['recentApps', 'recentDevs'], + name: createStorageKey('recents-store'), + version: storageVersion, + migrate: clearStorageMigration + } + ) +); + +window.recents = useRecentsStore.getState; + +export function addRecentDev(dev: string) { + return useRecentsStore.getState().addRecentDev(dev); +} + +export function addRecentApp(app: string) { + return useRecentsStore.getState().addRecentApp(app); +} + +function getApps(desks: string[], charges: ChargesWithDesks) { + return desks.filter((desk) => desk in charges).map((desk) => charges[desk]); +} + +export const Home = () => { + const selectedMatch = useLeapStore((state) => state.selectedMatch); + const { recentApps, recentDevs } = useRecentsStore(); + const charges = useCharges(); + const groups = charges?.landscape; + const contacts = useContactState((s) => s.contacts); + const defaultAlly = useDocketState((s) => + s.defaultAlly ? { shipName: s.defaultAlly, ...contacts[s.defaultAlly] } : null + ); + const providerList = recentDevs.map((d) => ({ shipName: d, ...contacts[d] })); + const apps = getApps(recentApps, charges); + + useEffect(() => { + const appMatches = apps.map((app) => ({ + url: getAppHref(app.href), + openInNewTab: true, + value: app.desk, + display: app.title + })); + const devs = recentDevs.map(providerMatch); + + useLeapStore.setState({ + matches: ([] as MatchItem[]).concat(appMatches, devs) + }); + }, [recentApps, recentDevs]); + + return ( +
    +

    + Recent Apps +

    + {apps.length === 0 && ( +
    +

    Apps you use will be listed here, in the order you used them.

    +

    You can click/tap/keyboard on a listed app to open it.

    + {groups && ( + addRecentApp('groups')} + /> + )} +
    + )} + {apps.length > 0 && ( + + )} +
    +

    + Recent Developers +

    + {recentDevs.length === 0 && ( +
    +

    Urbit app developers you search for will be listed here.

    + {defaultAlly && ( + <> +

    + Try out app discovery by visiting below. +

    + addRecentDev(defaultAlly.shipName)} + /> + + )} +
    + )} + {recentDevs.length > 0 && ( + + )} +
    + ); +}; diff --git a/pkg/grid/src/nav/search/Providers.tsx b/pkg/grid/src/nav/search/Providers.tsx new file mode 100644 index 000000000..5c32e36bd --- /dev/null +++ b/pkg/grid/src/nav/search/Providers.tsx @@ -0,0 +1,160 @@ +import React, { useEffect, useMemo } from 'react'; +import { RouteComponentProps } from 'react-router-dom'; +import fuzzy from 'fuzzy'; +import { Provider, deSig } from '@urbit/api'; +import * as ob from 'urbit-ob'; +import { MatchItem, useLeapStore } from '../Nav'; +import { useAllies, useCharges } from '../../state/docket'; +import { ProviderList } from '../../components/ProviderList'; +import useContactState from '../../state/contact'; +import { AppList } from '../../components/AppList'; +import { getAppHref } from '../../state/util'; + +type ProvidersProps = RouteComponentProps<{ ship: string }>; + +export function providerMatch(provider: Provider | string): MatchItem { + const value = typeof provider === 'string' ? provider : provider.shipName; + const display = typeof provider === 'string' ? undefined : provider.nickname; + + return { + value, + display, + url: `/leap/search/${value}/apps`, + openInNewTab: false + }; +} + +function fuzzySort(search: string) { + return (a: fuzzy.FilterResult, b: fuzzy.FilterResult): number => { + const left = a.string.startsWith(search) ? a.score + 1 : a.score; + const right = b.string.startsWith(search) ? b.score + 1 : b.score; + + return right - left; + }; +} + +export const Providers = ({ match }: ProvidersProps) => { + const selectedMatch = useLeapStore((state) => state.selectedMatch); + const provider = match?.params.ship; + const contacts = useContactState((s) => s.contacts); + const charges = useCharges(); + const allies = useAllies(); + const search = provider || ''; + const chargeArray = Object.entries(charges); + const appResults = useMemo( + () => + charges + ? fuzzy + .filter( + search, + chargeArray.map(([desk, charge]) => charge.title + desk) + ) + .sort(fuzzySort(search)) + .map((el) => chargeArray[el.index][1]) + : [], + [charges, search] + ); + + const patp = `~${deSig(search) || ''}`; + const isValidPatp = ob.isValidPatp(patp); + + const results = useMemo(() => { + if (!allies) { + return []; + } + const exact = + isValidPatp && !Object.keys(allies).includes(patp) + ? [ + { + shipName: patp, + ...contacts[patp] + } + ] + : []; + return [ + ...exact, + ...fuzzy + .filter( + search, + Object.entries(allies).map(([ship]) => ship) + ) + .sort(fuzzySort(search)) + .map((el) => ({ shipName: el.original, ...contacts[el.original] })) + ]; + }, [allies, search, contacts]); + + const count = results?.length; + + useEffect(() => { + if (search) { + useLeapStore.setState({ rawInput: search }); + } + }, []); + + useEffect(() => { + if (results) { + const providerMatches = results ? results.map(providerMatch) : []; + const appMatches = appResults + ? appResults.map((app) => ({ + url: getAppHref(app.href), + openInNewTab: true, + value: app.desk, + display: app.title + })) + : []; + + const newProviderMatches = isValidPatp + ? [ + { + url: `/leap/search/${patp}/apps`, + value: patp, + display: patp, + openInNewTab: false + } + ] + : []; + + useLeapStore.setState({ + matches: ([] as MatchItem[]).concat(appMatches, providerMatches, newProviderMatches) + }); + } + }, [results, patp, isValidPatp]); + + return ( +
    + {appResults && !(results?.length > 0 && appResults.length === 0) && ( +
    +

    + Installed Apps +

    + +
    + )} + {results && !(appResults?.length > 0 && results.length === 0) && ( +
    +
    +

    Searching Software Providers

    +

    + {count} result{count === 1 ? '' : 's'} +

    +
    + +
    + )} +

    That's it!

    +
    + ); +}; diff --git a/pkg/grid/src/nav/search/TreatyInfo.tsx b/pkg/grid/src/nav/search/TreatyInfo.tsx new file mode 100644 index 000000000..a6c78feec --- /dev/null +++ b/pkg/grid/src/nav/search/TreatyInfo.tsx @@ -0,0 +1,38 @@ +import React, { useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { AppInfo } from '../../components/AppInfo'; +import { Spinner } from '../../components/Spinner'; +import useDocketState, { useCharge, useTreaty } from '../../state/docket'; +import { useVat } from '../../state/kiln'; +import { getAppName } from '../../state/util'; +import { useLeapStore } from '../Nav'; + +export const TreatyInfo = () => { + const select = useLeapStore((state) => state.select); + const { host, desk } = useParams<{ host: string; desk: string }>(); + const treaty = useTreaty(host, desk); + const vat = useVat(desk); + const charge = useCharge(desk); + const name = getAppName(treaty); + + useEffect(() => { + if (!charge) { + useDocketState.getState().requestTreaty(host, desk); + } + }, [host, desk]); + + useEffect(() => { + select(<>{name}); + useLeapStore.setState({ matches: [] }); + }, [name]); + + if (!treaty) { + // TODO: maybe replace spinner with skeletons + return ( +
    + +
    + ); + } + return ; +}; diff --git a/pkg/grid/src/pages/Grid.tsx b/pkg/grid/src/pages/Grid.tsx new file mode 100644 index 000000000..1ad02a9cc --- /dev/null +++ b/pkg/grid/src/pages/Grid.tsx @@ -0,0 +1,51 @@ +import { map, omit } from 'lodash'; +import React, { FunctionComponent } from 'react'; +import { ErrorBoundary } from 'react-error-boundary'; +import { Route, RouteComponentProps } from 'react-router-dom'; +import { ErrorAlert } from '../components/ErrorAlert'; +import { MenuState, Nav } from '../nav/Nav'; +import { useCharges } from '../state/docket'; +import { RemoveApp } from '../tiles/RemoveApp'; +import { SuspendApp } from '../tiles/SuspendApp'; +import { Tile } from '../tiles/Tile'; +import { TileInfo } from '../tiles/TileInfo'; + +type GridProps = RouteComponentProps<{ + menu?: MenuState; +}>; + +export const Grid: FunctionComponent = ({ match, history }) => { + const charges = useCharges(); + const chargesLoaded = Object.keys(charges).length > 0; + + return ( +
    +
    +
    + +
    + {!chargesLoaded && Loading...} + {chargesLoaded && ( +
    + {charges && + map(omit(charges, window.desk), (charge, desk) => ( + + ))} +
    + )} + history.push('/')}> + + + + + + + + + + +
    +
    + ); +}; diff --git a/pkg/grid/src/pages/PermalinkRoutes.tsx b/pkg/grid/src/pages/PermalinkRoutes.tsx new file mode 100644 index 000000000..c1fefda0d --- /dev/null +++ b/pkg/grid/src/pages/PermalinkRoutes.tsx @@ -0,0 +1,97 @@ +import React, { useEffect } from 'react'; +import { Switch, Route, Redirect, RouteComponentProps } from 'react-router-dom'; +import { Spinner } from '../components/Spinner'; +import { useQuery } from '../logic/useQuery'; +import { useCharge } from '../state/docket'; +import useKilnState, { useKilnLoaded } from '../state/kiln'; +import { getAppHref } from '../state/util'; + +function getDeskByForeignRef(ship: string, desk: string): string | undefined { + const { vats } = useKilnState.getState(); + const found = Object.entries(vats).find( + ([, vat]) => vat.arak.rail?.ship === ship && vat.arak.rail?.desk === desk + ); + return found ? found[0] : undefined; +} + +type AppLinkProps = RouteComponentProps<{ + ship: string; + desk: string; + link: string; +}>; + +function AppLink({ match, history, location }: AppLinkProps) { + const { ship, desk, link = '' } = match.params; + const ourDesk = getDeskByForeignRef(ship, desk); + console.log(ourDesk); + + if (ourDesk) { + return ; + } + return ; +} + +function AppLinkNotFound({ match }: AppLinkProps) { + const { ship, desk } = match.params; + return ; +} + +function AppLinkInvalid() { + return ( +
    +

    Link was malformed

    +

    The link you tried to follow was invalid

    +
    + ); +} +function AppLinkRedirect({ desk, link }: { desk: string; link: string }) { + const charge = useCharge(desk); + + useEffect(() => { + if (!charge) { + return; + } + + const query = new URLSearchParams({ + 'grid-link': encodeURIComponent(`/${link}`) + }); + + const url = `${getAppHref(charge.href)}?${query.toString()}`; + window.open(url, desk); + }, [charge]); + + return ; +} + +const LANDSCAPE_DESK = 'landscape'; +const LANDSCAPE_HOST = '~lander-dister-dozzod-dozzod'; + +function LandscapeLink({ match }: RouteComponentProps<{ link: string }>) { + const { link } = match.params; + + return ; +} + +export function PermalinkRoutes() { + const loaded = useKilnLoaded(); + + const { query } = useQuery(); + + if (query.has('ext')) { + const ext = query.get('ext')!; + const url = `/perma${ext.slice(16)}`; + return ; + } + + if (!loaded) { + return ; + } + + return ( + + + + + + ); +} diff --git a/pkg/grid/src/state/api.ts b/pkg/grid/src/state/api.ts new file mode 100644 index 000000000..2e4058fa8 --- /dev/null +++ b/pkg/grid/src/state/api.ts @@ -0,0 +1,24 @@ +import Urbit from '@urbit/http-api'; +import { useMockData } from './util'; + +declare global { + interface Window { + ship: string; + } +} + +const api = useMockData + ? ({ + poke: async () => {}, + subscribe: async () => {}, + subscribeOnce: async () => {}, + ship: '', + scry: async () => {} + } as unknown as Urbit) + : new Urbit('', ''); +if (import.meta.env.DEV || useMockData) { + api.verbose = true; +} +api.ship = useMockData ? 'dopzod' : window.ship; + +export default api; diff --git a/pkg/grid/src/state/base.ts b/pkg/grid/src/state/base.ts new file mode 100644 index 000000000..9c2efe232 --- /dev/null +++ b/pkg/grid/src/state/base.ts @@ -0,0 +1,194 @@ +/* eslint-disable no-param-reassign */ +import { applyPatches, Patch, produceWithPatches, setAutoFreeze, enablePatches } from 'immer'; +import { compose } from 'lodash/fp'; +import _ from 'lodash'; +import create, { GetState, SetState, UseStore } from 'zustand'; +import { persist } from 'zustand/middleware'; +import Urbit, { SubscriptionRequestInterface } from '@urbit/http-api'; +import { Poke } from '@urbit/api'; +import api from './api'; +import { clearStorageMigration, createStorageKey, storageVersion, useMockData } from './util'; + +setAutoFreeze(false); +enablePatches(); + +export const stateSetter = >( + fn: (state: Readonly>) => void, + set: (newState: T & BaseState) => void, + get: () => T & BaseState +): void => { + const old = get(); + const [state] = produceWithPatches(old, fn) as readonly [T & BaseState, any, Patch[]]; + // console.log(patches); + set(state); +}; + +export const optStateSetter = >( + fn: (state: T & BaseState) => void, + set: (newState: T & BaseState) => void, + get: () => T & BaseState +): string => { + const old = get(); + const id = _.uniqueId(); + const [state, , patches] = produceWithPatches(old, fn) as readonly [ + T & BaseState, + any, + Patch[] + ]; + set({ ...state, patches: { ...state.patches, [id]: patches } }); + return id; +}; + +export const reduceState = , U>( + state: UseStore>, + data: U, + reducers: ((data: U, state: S & BaseState) => S & BaseState)[] +): void => { + const reducer = compose(reducers.map((r) => (sta) => r(data, sta))); + state.getState().set((s) => { + reducer(s); + }); +}; + +export const reduceStateN = , U>( + state: S & BaseState, + data: U, + reducers: ((data: U, state: S & BaseState) => S & BaseState)[] +): void => { + const reducer = compose(reducers.map((r) => (sta) => r(data, sta))); + state.set(reducer); +}; + +export const optReduceState = , U>( + state: UseStore>, + data: U, + reducers: ((data: U, state: S & BaseState) => BaseState & S)[] +): string => { + const reducer = compose(reducers.map((r) => (sta) => r(data, sta))); + return state.getState().optSet((s) => { + reducer(s); + }); +}; + +/* eslint-disable-next-line import/no-mutable-exports */ +export let stateStorageKeys: string[] = []; + +export const stateStorageKey = (stateName: string): string => { + const key = createStorageKey(`${stateName}State`); + stateStorageKeys = [...new Set([...stateStorageKeys, key])]; + return key; +}; + +(window as any).clearStates = () => { + stateStorageKeys.forEach((key) => { + localStorage.removeItem(key); + }); +}; + +export interface BaseState> { + rollback: (id: string) => void; + patches: { + [id: string]: Patch[]; + }; + set: (fn: (state: StateType & BaseState) => void) => void; + addPatch: (id: string, ...patch: Patch[]) => void; + removePatch: (id: string) => void; + optSet: (fn: (state: StateType & BaseState) => void) => string; + initialize: (api: Urbit) => Promise; +} + +export function createSubscription( + app: string, + path: string, + e: (data: any) => void +): SubscriptionRequestInterface { + const request = { + app, + path, + event: e, + err: () => {}, + quit: () => {} + }; + // TODO: err, quit handling (resubscribe?) + return request; +} + +export const createState = >( + name: string, + properties: T | ((set: SetState>, get: GetState>) => T), + blacklist: (keyof BaseState | keyof T)[] = [], + subscriptions: (( + set: SetState>, + get: GetState> + ) => SubscriptionRequestInterface)[] = [] +): UseStore> => + create>( + persist>( + (set, get) => ({ + initialize: async (airlock: Urbit) => { + await Promise.all(subscriptions.map((sub) => airlock.subscribe(sub(set, get)))); + }, + set: (fn) => stateSetter(fn, set, get), + optSet: (fn) => { + return optStateSetter(fn, set, get); + }, + patches: {}, + addPatch: (id: string, patch: Patch[]) => { + set((s) => ({ ...s, patches: { ...s.patches, [id]: patch } })); + }, + removePatch: (id: string) => { + set((s) => ({ ...s, patches: _.omit(s.patches, id) })); + }, + rollback: (id: string) => { + set((state) => { + const applying = state.patches[id]; + return { ...applyPatches(state, applying), patches: _.omit(state.patches, id) }; + }); + }, + ...(typeof properties === 'function' ? (properties as any)(set, get) : properties) + }), + { + blacklist, + name: stateStorageKey(name), + version: storageVersion, + migrate: clearStorageMigration + } + ) + ); + +export async function doOptimistically>( + state: UseStore>, + action: A, + call: (a: A) => Promise, + reduce: ((a: A, fn: S & BaseState) => S & BaseState)[] +) { + let num: string | undefined; + try { + num = optReduceState(state, action, reduce); + await call(action); + state.getState().removePatch(num); + } catch (e) { + console.error(e); + if (num) { + state.getState().rollback(num); + } + } +} + +export async function pokeOptimisticallyN>( + state: UseStore>, + poke: Poke, + reduce: ((a: A, fn: S & BaseState) => S & BaseState)[] +) { + let num: string | undefined; + try { + num = optReduceState(state, poke.json, reduce); + await (useMockData ? new Promise((res) => setTimeout(res, 500)) : api.poke(poke)); + state.getState().removePatch(num); + } catch (e) { + console.error(e); + if (num) { + state.getState().rollback(num); + } + } +} diff --git a/pkg/grid/src/state/contact.ts b/pkg/grid/src/state/contact.ts new file mode 100644 index 000000000..40bf49bdb --- /dev/null +++ b/pkg/grid/src/state/contact.ts @@ -0,0 +1,134 @@ +/* eslint-disable no-param-reassign */ +import { Contact, ContactEditFieldPrim, ContactUpdate, deSig, Patp, Rolodex } from '@urbit/api'; +import { useCallback } from 'react'; +import _ from 'lodash'; +import { BaseState, createState, createSubscription, reduceStateN } from './base'; +import { useMockData } from './util'; +import { mockContacts } from './mock-data'; + +export interface BaseContactState { + contacts: Rolodex; + isContactPublic: boolean; + nackedContacts: Set; + [ref: string]: unknown; +} + +type ContactState = BaseContactState & BaseState; + +const initial = (json: ContactUpdate, state: ContactState): ContactState => { + const data = _.get(json, 'initial', false); + if (data) { + state.contacts = data.rolodex; + state.isContactPublic = data['is-public']; + } + return state; +}; + +const add = (json: ContactUpdate, state: ContactState): ContactState => { + const data = _.get(json, 'add', false); + if (data) { + state.contacts[data.ship] = data.contact; + } + return state; +}; + +const remove = (json: ContactUpdate, state: ContactState): ContactState => { + const data = _.get(json, 'remove', false); + if (data && data.ship in state.contacts) { + delete state.contacts[data.ship]; + } + return state; +}; + +export const edit = (json: ContactUpdate, state: ContactState): ContactState => { + const data = _.get(json, 'edit', false); + const ship = `~${deSig(data.ship)}`; + if (data && ship in state.contacts) { + const [field] = Object.keys(data['edit-field']); + if (!field) { + return state; + } + + const value = data['edit-field'][field]; + if (field === 'add-group') { + if (typeof value !== 'string') { + state.contacts[ship].groups.push(`/ship/${Object.values(value).join('/')}`); + } else if (!state.contacts[ship].groups.includes(value)) { + state.contacts[ship].groups.push(value); + } + } else if (field === 'remove-group') { + if (typeof value !== 'string') { + state.contacts[ship].groups = state.contacts[ship].groups.filter( + (g) => g !== `/ship/${Object.values(value).join('/')}` + ); + } else { + state.contacts[ship].groups = state.contacts[ship].groups.filter((g) => g !== value); + } + } else { + const k = field as ContactEditFieldPrim; + state.contacts[ship][k] = value; + } + } + return state; +}; + +const setPublic = (json: ContactUpdate, state: ContactState): ContactState => { + const data = _.get(json, 'set-public', state.isContactPublic); + state.isContactPublic = data; + return state; +}; + +export const reduceNacks = ( + json: { resource?: { res: string } }, + state: ContactState +): ContactState => { + const data = json?.resource; + if (data) { + state.nackedContacts.add(`~${data.res}`); + } + return state; +}; + +export const reduce = [initial, add, remove, edit, setPublic]; + +const useContactState = createState( + 'Contact', + { + contacts: {}, + nackedContacts: new Set(), + isContactPublic: false + }, + ['nackedContacts'], + [ + (set, get) => + createSubscription('contact-pull-hook', '/nacks', (e) => { + const data = e?.resource; + if (data) { + reduceStateN(get(), data, [reduceNacks]); + } + }), + (set, get) => + createSubscription('contact-store', '/all', (e) => { + const data = _.get(e, 'contact-update', false); + if (data) { + reduceStateN(get(), data, reduce); + } + }) + ] +); + +if (useMockData) { + useContactState.setState({ contacts: mockContacts }); +} + +export function useContact(ship: string) { + return useContactState( + useCallback((s) => s.contacts[`~${deSig(ship)}`] as Contact | null, [ship]) + ); +} + +export function useOurContact() { + return useContact(`~${window.ship}`); +} + +export default useContactState; diff --git a/pkg/grid/src/state/docket.ts b/pkg/grid/src/state/docket.ts new file mode 100644 index 000000000..c94cec3ea --- /dev/null +++ b/pkg/grid/src/state/docket.ts @@ -0,0 +1,326 @@ +import create, { SetState } from 'zustand'; +import produce from 'immer'; +import { useCallback, useEffect } from 'react'; +import { omit, pick } from 'lodash'; +import { + Allies, + Charge, + ChargeUpdateInitial, + scryAllies, + scryAllyTreaties, + scryCharges, + scryDefaultAlly, + Treaty, + Docket, + Treaties, + chadIsRunning, + AllyUpdateIni, + AllyUpdateNew, + TreatyUpdateIni, + TreatyUpdate, + docketInstall, + ChargeUpdate, + kilnRevive, + kilnSuspend, + allyShip +} from '@urbit/api'; +import api from './api'; +import { mockAllies, mockCharges, mockTreaties } from './mock-data'; +import { fakeRequest, normalizeUrbitColor, useMockData } from './util'; +import { useAsyncCall } from '../logic/useAsyncCall'; + +export interface ChargeWithDesk extends Charge { + desk: string; +} + +export interface ChargesWithDesks { + [ref: string]: ChargeWithDesk; +} + +export interface DocketWithDesk extends Docket { + desk: string; +} + +interface DocketState { + charges: ChargesWithDesks; + treaties: Treaties; + allies: Allies; + defaultAlly: string | null; + fetchCharges: () => Promise; + fetchDefaultAlly: () => Promise; + requestTreaty: (ship: string, desk: string) => Promise; + fetchAllies: () => Promise; + fetchAllyTreaties: (ally: string) => Promise; + toggleDocket: (desk: string) => Promise; + installDocket: (ship: string, desk: string) => Promise; + uninstallDocket: (desk: string) => Promise; + // + addAlly: (ship: string) => Promise; + set: SetState; +} + +const useDocketState = create((set, get) => ({ + defaultAlly: useMockData ? '~zod' : null, + fetchDefaultAlly: async () => { + const defaultAlly = await api.scry(scryDefaultAlly); + set({ defaultAlly }); + }, + fetchCharges: async () => { + const charg = useMockData + ? await fakeRequest(mockCharges) + : (await api.scry(scryCharges)).initial; + + const charges = Object.entries(charg).reduce((obj: ChargesWithDesks, [key, value]) => { + // eslint-disable-next-line no-param-reassign + obj[key] = normalizeDocket(value as ChargeWithDesk, key); + return obj; + }, {}); + + set({ charges }); + }, + fetchAllies: async () => { + const allies = useMockData ? mockAllies : (await api.scry(scryAllies)).ini; + set({ allies }); + return allies; + }, + fetchAllyTreaties: async (ally: string) => { + let treaties = useMockData + ? mockTreaties + : (await api.scry(scryAllyTreaties(ally))).ini; + treaties = normalizeDockets(treaties); + set((s) => ({ treaties: { ...s.treaties, ...treaties } })); + return treaties; + }, + requestTreaty: async (ship: string, desk: string) => { + const { treaties } = get(); + if (useMockData) { + set({ treaties: await fakeRequest(treaties) }); + return treaties[desk]; + } + + const key = `${ship}/${desk}`; + if (key in treaties) { + return treaties[key]; + } + + const result = await api.subscribeOnce('treaty', `/treaty/${key}`, 20000); + const treaty = { ...normalizeDocket(result, desk), ship }; + set((state) => ({ + treaties: { ...state.treaties, [key]: treaty } + })); + return treaty; + }, + installDocket: async (ship: string, desk: string) => { + const treaty = get().treaties[`${ship}/${desk}`]; + if (!treaty) { + throw new Error('Bad install'); + } + set((state) => addCharge(state, desk, { ...treaty, chad: { install: null } })); + if (useMockData) { + await new Promise((res) => setTimeout(() => res(), 10000)); + set((state) => addCharge(state, desk, { ...treaty, chad: { glob: null } })); + } + + return api.poke(docketInstall(ship, desk)); + }, + uninstallDocket: async (desk: string) => { + set((state) => delCharge(state, desk)); + if (useMockData) { + return; + } + await api.poke({ + app: 'docket', + mark: 'docket-uninstall', + json: desk + }); + }, + toggleDocket: async (desk: string) => { + if (useMockData) { + set( + produce((draft) => { + const charge = draft.charges[desk]; + charge.chad = chadIsRunning(charge.chad) ? { suspend: null } : { glob: null }; + }) + ); + } + const { charges } = get(); + const charge = charges[desk]; + if (!charge) { + return; + } + const suspended = 'suspend' in charge.chad; + if (suspended) { + await api.poke(kilnRevive(desk)); + } else { + await api.poke(kilnSuspend(desk)); + } + }, + treaties: useMockData ? normalizeDockets(mockTreaties) : {}, + charges: {}, + allies: useMockData ? mockAllies : {}, + addAlly: async (ship) => { + set((draft) => { + draft.allies[ship] = []; + }); + + return api.poke(allyShip(ship)); + }, + set +})); + +function normalizeDocket(docket: T, desk: string): T { + return { + ...docket, + desk, + color: normalizeUrbitColor(docket.color) + }; +} + +function normalizeDockets(dockets: Record): Record { + return Object.entries(dockets).reduce((obj: Record, [key, value]) => { + const [, desk] = key.split('/'); + // eslint-disable-next-line no-param-reassign + obj[key] = normalizeDocket(value, desk); + return obj; + }, {}); +} + +function addCharge(state: DocketState, desk: string, charge: Charge) { + return { charges: { ...state.charges, [desk]: normalizeDocket(charge as ChargeWithDesk, desk) } }; +} + +function delCharge(state: DocketState, desk: string) { + return { charges: omit(state.charges, desk) }; +} + +api.subscribe({ + app: 'docket', + path: '/charges', + event: (data: ChargeUpdate) => { + useDocketState.setState((state) => { + if ('add-charge' in data) { + const { desk, charge } = data['add-charge']; + return addCharge(state, desk, charge); + } + + if ('del-charge' in data) { + const desk = data['del-charge']; + return delCharge(state, desk); + } + + return { charges: state.charges }; + }); + } +}); + +api.subscribe({ + app: 'treaty', + path: '/treaties', + event: (data: TreatyUpdate) => { + useDocketState.getState().set((draft) => { + if ('add' in data) { + const { ship, desk } = data.add; + const treaty = normalizeDocket(data.add, desk); + draft.treaties[`${ship}/${desk}`] = treaty; + } + + if ('ini' in data) { + const treaties = normalizeDockets(data.ini); + draft.treaties = { ...draft.treaties, ...treaties }; + } + }); + } +}); + +api.subscribe({ + app: 'treaty', + path: '/allies', + event: (data: AllyUpdateNew) => { + useDocketState.getState().set((draft) => { + if ('new' in data) { + const { ship, alliance } = data.new; + draft.allies[ship] = alliance; + } + }); + } +}); + +const selCharges = (s: DocketState) => { + return s.charges; +}; + +export function useCharges() { + return useDocketState(selCharges); +} + +export function useCharge(desk: string) { + return useDocketState(useCallback((state) => state.charges[desk], [desk])); +} + +const selRequest = (s: DocketState) => s.requestTreaty; +export function useRequestDocket() { + return useDocketState(selRequest); +} + +const selAllies = (s: DocketState) => s.allies; +export function useAllies() { + return useDocketState(selAllies); +} + +export function useAllyTreaties(ship: string) { + const allies = useAllies(); + const { call: fetchTreaties, status } = useAsyncCall(() => + useDocketState.getState().fetchAllyTreaties(ship) + ); + + useEffect(() => { + if (ship in allies) { + fetchTreaties(); + } + }, [ship, allies]); + + const treaties = useDocketState( + useCallback( + (s) => { + const charter = s.allies[ship]; + return pick(s.treaties, ...(charter || [])); + }, + [ship] + ) + ); + + return { + treaties, + status + }; +} + +export function useTreaty(host: string, desk: string) { + return useDocketState( + useCallback( + (s) => { + const ref = `${host}/${desk}`; + return s.treaties[ref]; + }, + [host, desk] + ) + ); +} + +export function allyForTreaty(ship: string, desk: string) { + const ref = `${ship}/${desk}`; + const { allies } = useDocketState.getState(); + const ally = Object.entries(allies).find(([, allied]) => allied.includes(ref))?.[0]; + return ally; +} + +export const landscapeTreatyHost = import.meta.env.LANDSCAPE_HOST as string; + +// xx useful for debugging +window.docket = useDocketState.getState; + +if (useMockData) { + window.desk = 'garden'; +} + +export default useDocketState; diff --git a/pkg/grid/src/state/hark-types.ts b/pkg/grid/src/state/hark-types.ts new file mode 100644 index 000000000..e9d54636f --- /dev/null +++ b/pkg/grid/src/state/hark-types.ts @@ -0,0 +1,22 @@ +/** + * I know this doesn't match our current hark type scheme, but since we're talking + * about changing that I decided to just throw something together to at least test + * this flow for updates. + */ + +export interface RuntimeLagNotification { + type: 'runtime-lag'; +} + +export interface BaseBlockedNotification { + type: 'system-updates-blocked'; + desks: string[]; +} + +export interface BasicNotification { + type: 'basic'; + time: string; + message: string; +} + +export type Notification = BasicNotification | BaseBlockedNotification | RuntimeLagNotification; diff --git a/pkg/grid/src/state/hark.ts b/pkg/grid/src/state/hark.ts new file mode 100644 index 000000000..9bea900fa --- /dev/null +++ b/pkg/grid/src/state/hark.ts @@ -0,0 +1,258 @@ +/* eslint-disable no-param-reassign */ +import { + makePatDa, + decToUd, + unixToDa, + Timebox, + harkBinToId, + opened, + HarkBin, + HarkLid, + archive, + HarkContent, + NotificationGraphConfig, + archiveAll +} from '@urbit/api'; +import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; +/* eslint-disable-next-line camelcase */ +import { unstable_batchedUpdates } from 'react-dom'; +import produce from 'immer'; +import _ from 'lodash'; +import api from './api'; +import { useSettingsState } from './settings'; +import { BaseState, createState, createSubscription, reduceStateN } from './base'; +import { mockNotifications } from './mock-data'; +import { useMockData } from './util'; + +export interface HarkState { + seen: Timebox; + unseen: Timebox; + archive: BigIntOrderedMap; + set: (f: (s: HarkState) => void) => void; + opened: () => Promise; + notificationsGraphConfig: NotificationGraphConfig; + archiveAll: () => Promise; + archiveNote: (bin: HarkBin, lid: HarkLid) => Promise; + getMore: () => Promise; + webNotes: { + [binId: string]: Notification[]; + }; + [ref: string]: unknown; +} + +type BaseHarkState = BaseState & HarkState; + +function updateState( + key: string, + transform: (state: BaseHarkState, data: any) => void +): (json: any, state: BaseHarkState) => BaseHarkState { + return (json: any, state: BaseHarkState) => { + if (_.has(json, key)) { + transform(state, _.get(json, key, undefined)); + } + return state; + }; +} + +export const reduceGraph = [ + updateState('initial', (draft, data) => { + draft.notificationsGraphConfig = data; + }), + updateState('set-mentions', (draft, data) => { + draft.notificationsGraphConfig.mentions = data; + }) +]; + +export const useHarkStore = createState( + 'Hark', + (set, get) => ({ + seen: {}, + unseen: useMockData ? mockNotifications : {}, + archive: new BigIntOrderedMap(), + webNotes: {}, + notificationsGraphConfig: { + watchOnSelf: false, + mentions: false, + watching: [] + }, + + set: (f) => { + const newState = produce(get(), f); + set(newState); + }, + archiveAll: async () => { + get().set((draft) => { + draft.unseen = {}; + draft.seen = {}; + }); + await api.poke(archiveAll); + }, + archiveNote: async (bin, lid) => { + get().set((draft) => { + const seen = 'seen' in lid ? 'seen' : 'unseen'; + const binId = harkBinToId(bin); + delete draft[seen][binId]; + }); + if (useMockData) { + return; + } + await api.poke(archive(bin, lid)); + }, + opened: async () => { + reduceHark({ opened: null }); + + await api.poke(opened); + }, + getMore: async () => { + const { archive: arch } = get(); + const idx = decToUd((arch?.peekSmallest()?.[0] || unixToDa(Date.now() * 1000)).toString()); + const update = await api.scry({ + app: 'hark-store', + path: `/recent/inbox/${idx}/5` + }); + reduceHark(update); + } + }), + ['archive', 'unseen', 'seen'], + [ + (set, get) => + createSubscription('hark-graph-hook', '/updates', (j) => { + const graphHookData = _.get(j, 'hark-graph-hook-update', false); + if (graphHookData) { + reduceStateN(get(), graphHookData, reduceGraph); + } + }), + () => + createSubscription('hark-store', '/updates', (u) => { + /* eslint-ignore-next-line camelcase */ + unstable_batchedUpdates(() => { + reduceHark(u); + }); + }) + ] +); + +function reduceHark(u: any) { + const { set } = useHarkStore.getState(); + if (!u) { + return; + } + if ('more' in u) { + u.more.forEach((upd: any) => { + reduceHark(upd); + }); + } else if ('all-stats' in u) { + // TODO: probably ignore? + } else if ('added' in u) { + set((draft) => { + const { bin } = u.added; + const binId = harkBinToId(bin); + draft.unseen[binId] = u.added; + }); + } else if ('timebox' in u) { + const { timebox } = u; + const { lid, notifications } = timebox; + if ('archive' in lid) { + set((draft) => { + const time = makePatDa(lid.archive); + const old = draft.archive.get(time) || {}; + notifications.forEach((note: any) => { + const binId = harkBinToId(note.bin); + old[binId] = note; + }); + draft.archive = draft.archive.set(time, old); + }); + } else { + set((draft) => { + const seen = 'seen' in lid ? 'seen' : 'unseen'; + notifications.forEach((note: any) => { + const binId = harkBinToId(note.bin); + draft[seen][binId] = note; + }); + }); + } + } else if ('archived' in u) { + const { lid, notification } = u.archived; + set((draft) => { + const seen = 'seen' in lid ? 'seen' : 'unseen'; + const binId = harkBinToId(notification.bin); + delete draft[seen][binId]; + const time = makePatDa(u.archived.time); + const timebox = draft.archive?.get(time) || {}; + timebox[binId] = notification; + draft.archive = draft.archive.set(time, timebox); + }); + } else if ('opened' in u) { + set((draft) => { + const bins = Object.keys(draft.unseen); + bins.forEach((bin) => { + const old = draft.seen[bin]; + const curr = draft.unseen[bin]; + curr.body = [...curr.body, ...(old?.body || [])]; + draft.seen[bin] = curr; + delete draft.unseen[bin]; + }); + }); + } else if ('del-place' in u) { + const { path, desk } = u['del-place']; + const pathId = `${desk}${path}`; + const wipeBox = (t: Timebox) => { + Object.keys(t).forEach((bin) => { + if (bin.startsWith(pathId)) { + delete t[bin]; + } + }); + }; + set((draft) => { + wipeBox(draft.unseen); + wipeBox(draft.seen); + draft.archive.keys().forEach((key) => { + wipeBox(draft.archive.get(key)!); + }); + }); + } +} + +api.subscribe({ + app: 'hark-store', + path: '/updates', + event: (u: any) => { + /* eslint-ignore-next-line camelcase */ + unstable_batchedUpdates(() => { + reduceHark(u); + }); + } +}); + +function harkContentsToPlainText(contents: HarkContent[]) { + return contents + .map((c) => { + if ('ship' in c) { + return c.ship; + } + return c.text; + }) + .join(''); +} + +api.subscribe({ + app: 'hark-store', + path: '/notes', + event: (u: any) => { + if ('add-note' in u) { + if (useSettingsState.getState().display.doNotDisturb) { + return; + } + const { bin, body } = u['add-note']; + const binId = harkBinToId(bin); + const { title, content } = body; + + const note = new Notification(harkContentsToPlainText(title), { + body: harkContentsToPlainText(content), + tag: binId, + renotify: true + }); + note.onclick = () => {}; + } + } +}); diff --git a/pkg/grid/src/state/kiln.ts b/pkg/grid/src/state/kiln.ts new file mode 100644 index 000000000..40222b6ed --- /dev/null +++ b/pkg/grid/src/state/kiln.ts @@ -0,0 +1,101 @@ +import { getVats, Vats, scryLag, getBlockers, Vat, kilnInstall } from '@urbit/api'; +import { kilnPause, kilnResume } from '@urbit/api/hood'; +import create from 'zustand'; +import produce from 'immer'; +import { useCallback } from 'react'; +import api from './api'; +import { fakeRequest, useMockData } from './util'; +import { mockVats } from './mock-data'; + +interface KilnState { + vats: Vats; + loaded: boolean; + fetchVats: () => Promise; + lag: boolean; + fetchLag: () => Promise; + changeOTASource: (ship: string) => Promise; + toggleOTAs: (desk: string, on: boolean) => Promise; + set: (s: KilnState) => void; +} +const useKilnState = create((set, get) => ({ + vats: useMockData ? mockVats : {}, + lag: !!useMockData, + loaded: false, + fetchVats: async () => { + if (useMockData) { + await fakeRequest({}, 500); + set({ loaded: true }); + return; + } + const vats = await api.scry(getVats); + set({ vats, loaded: true }); + }, + fetchLag: async () => { + const lag = await api.scry(scryLag); + set({ lag }); + }, + changeOTASource: async (ship: string) => { + if (useMockData) { + await fakeRequest(''); + set( + produce((draft: KilnState) => { + if (!draft.vats.base.arak.rail) { + return; + } + draft.vats.base.arak.rail.ship = ship; + }) + ); + return; + } + + await api.poke(kilnInstall(ship, 'kids', 'base')); + }, + toggleOTAs: async (desk: string, on: boolean) => { + set( + produce((draft: KilnState) => { + const { arak } = draft.vats[desk]; + if (!arak.rail) { + return; + } + if (on) { + arak.rail.paused = false; + } else { + arak.rail.paused = true; + } + }) + ); + + await (useMockData ? fakeRequest('') : api.poke(on ? kilnResume(desk) : kilnPause(desk))); + await get().fetchVats(); // refresh vat state + }, + set: produce(set) +})); + +api.subscribe({ + app: 'hood', + path: '/kiln/vats', + event: () => { + useKilnState.getState().fetchVats(); + } +}); + +const selBlockers = (s: KilnState) => getBlockers(s.vats); +export function useBlockers() { + return useKilnState(selBlockers); +} + +export function useVat(desk: string): Vat | undefined { + return useKilnState(useCallback((s) => s.vats[desk], [desk])); +} + +const selLag = (s: KilnState) => s.lag; +export function useLag() { + return useKilnState(selLag); +} + +const selLoaded = (s: KilnState) => s.loaded; +export function useKilnLoaded() { + return useKilnState(selLoaded); +} + +export default useKilnState; diff --git a/pkg/grid/src/state/local.ts b/pkg/grid/src/state/local.ts new file mode 100644 index 000000000..c8285b77b --- /dev/null +++ b/pkg/grid/src/state/local.ts @@ -0,0 +1,37 @@ +import create from 'zustand'; +import { persist } from 'zustand/middleware'; +import produce from 'immer'; +import { clearStorageMigration, createStorageKey, storageVersion } from './util'; + +interface LocalState { + protocolHandling: boolean; + currentTheme: 'light' | 'dark'; + set: (f: (s: LocalState) => void) => void; +} + +export const useLocalState = create( + persist( + (set, get) => ({ + set: (f) => set(produce(get(), f)), + currentTheme: 'light', + protocolHandling: false + }), + { + name: createStorageKey('local'), + version: storageVersion, + migrate: clearStorageMigration + } + ) +); + +const selProtocolHandling = (s: LocalState) => s.protocolHandling; +export function useProtocolHandling() { + return useLocalState(selProtocolHandling); +} + +const selCurrentTheme = (s: LocalState) => s.currentTheme; +export function useCurrentTheme() { + return useLocalState(selCurrentTheme); +} + +export const setLocalState = (f: (s: LocalState) => void) => useLocalState.getState().set(f); diff --git a/pkg/grid/src/state/mock-data.ts b/pkg/grid/src/state/mock-data.ts new file mode 100644 index 000000000..44240b3f3 --- /dev/null +++ b/pkg/grid/src/state/mock-data.ts @@ -0,0 +1,367 @@ +import { + Vat, + Vats, + Allies, + Charges, + DocketHrefGlob, + Treaties, + Treaty, + Notification, + HarkContent, + HarkBody, + unixToDa, + Contact, + Contacts, + Timebox, + harkBinToId +} from '@urbit/api'; +import _ from 'lodash'; +import systemUrl from '../assets/system.png'; + +export const appMetaData: Pick = { + cass: { + da: '~2021.9.13..05.41.04..ae65', + ud: 1 + }, + hash: '0v6.nj6ls.l7unh.l9bhk.d839n.n8nlq.m2dmc.fj80i.pvqun.uhg6g.1kk0h', + website: 'https://tlon.io', + license: 'MIT', + version: '2.0.1' +}; + +const makeHref = (base: string): DocketHrefGlob => ({ glob: { base } }); + +export const mockTreaties: Treaties = { + '~zod/garden': { + ship: '~zod', + desk: 'garden', + title: 'System', + info: 'Your Urbit Home', + href: makeHref('garden'), + color: '#E2C050', + ...appMetaData + }, + '~zod/groups': { + ship: '~zod', + desk: 'groups', + title: 'Groups', + info: 'Simple Software for Community Assembly', + href: makeHref('groups'), + color: '#CDE7EF', + ...appMetaData + }, + '~zod/messages': { + title: 'Messages', + ship: '~zod', + desk: 'messages', + href: makeHref('messages'), + info: 'A lengthier description of the app down here', + color: '#8BE789', + ...appMetaData + }, + '~zod/calls': { + title: 'Calls', + ship: '~zod', + desk: 'calls', + href: makeHref('calls'), + info: 'A lengthier description of the app down here', + color: '#C2D6BE', + ...appMetaData + }, + '~zod/bitcoin-wallet': { + title: 'Bitcoin Wallet', + ship: '~zod', + desk: 'bitcoin-wallet', + href: makeHref('bitcoin-wallet'), + info: 'A lengthier description of the app down here', + color: '#F0AE70', + ...appMetaData + }, + '~zod/system': { + title: 'System', + ship: '~zod', + desk: 'system', + href: makeHref('system'), + info: 'A lengthier description of the app down here', + color: '#2D0118', + image: systemUrl, + ...appMetaData + }, + '~zod/my-apps': { + title: 'My Apps', + ship: '~zod', + desk: 'my-apps', + href: makeHref('my-apps'), + info: 'A lengthier description of the app down here', + color: '#D8B14E', + ...appMetaData + }, + '~zod/go': { + title: 'Go', + ship: '~zod', + desk: 'go', + href: makeHref('go'), + info: 'A lengthier description of the app down here', + color: '#A58E52', + ...appMetaData + }, + '~zod/terminal': { + title: 'Terminal', + ship: '~zod', + desk: 'terminal', + href: makeHref('terminal'), + info: 'A lengthier description of the app down here', + color: '#2D382B', + ...appMetaData + }, + '~zod/pomodoro': { + title: 'Pomodoro', + ship: '~zod', + desk: 'pomodoro', + href: makeHref('pomodoro'), + info: 'A lengthier description of the app down here', + color: '#EE5432', + ...appMetaData + }, + '~zod/clocks': { + title: 'Clocks', + ship: '~zod', + desk: 'clocks', + href: makeHref('clocks'), + info: 'A lengthier description of the app down here', + color: '#DCDCDC', + ...appMetaData + }, + '~zod/uniswap': { + title: 'Uniswap', + ship: '~zod', + desk: 'uniswap', + href: makeHref('uniswap'), + info: 'A lengthier description of the app down here', + color: '#FDA1FF', + ...appMetaData + }, + '~zod/inbox': { + title: 'Inbox', + ship: '~zod', + desk: 'inbox', + href: makeHref('inbox'), + color: '#FEFFBA', + ...appMetaData + } +}; + +export const mockCharges: Charges = _.reduce( + mockTreaties, + (acc, val, key) => { + const [, desk] = key.split('/'); + const chad = { glob: null }; + if (desk === 'inbox') { + return acc; + } + + if (desk === 'calls') { + return { ...acc, [desk]: { ...val, chad: { hung: 'glob failed' } } }; + } + + if (desk === 'messages') { + return { ...acc, [desk]: { ...val, chad: { install: null } } }; + } + + return { ...acc, [desk]: { ...val, chad } }; + }, + {} as Charges +); + +const charter = Object.keys(mockTreaties); + +export const mockAllies: Allies = [ + '~zod', + '~nocsyx-lassul', + '~nachus-hollyn', + '~nalbel_litzod', + '~litmus^ritten', + '~nalput_litzod', + '~nalrex_bannus', + '~nalrys' +].reduce((acc, val) => ({ ...acc, [val]: charter }), {}); + +function ship(s: string) { + return { ship: s }; +} + +function text(t: string) { + return { text: t }; +} + +function createDmNotification(...content: HarkContent[]): HarkBody { + return { + title: [ship('~hastuc-dibtux'), text(' messaged you')], + time: unixToDa(Date.now() - 3_600).toString(), + content, + binned: '/', + link: '/' + }; +} + +function createBitcoinNotif(amount: string) { + return { + title: [ship('~silnem'), text(` sent you ${amount}`)], + time: unixToDa(Date.now() - 3_600).toString(), + content: [], + binned: '/', + link: '/' + }; +} + +function createGroupNotif(to: string): HarkBody { + return { + title: [ship('~ridlur-figbud'), text(` invited you to ${to}`)], + content: [], + time: unixToDa(Date.now() - 3_600).toString(), + binned: '/', + link: '/' + }; +} + +window.desk = window.desk || 'garden'; + +function createMockSysNotification(path: string, body: HarkBody[] = []) { + return { + bin: { + place: { + desk: window.desk, + path + }, + path: '/' + }, + time: Date.now() - 3_600, + body + }; +} + +const lag = createMockSysNotification('/lag'); +const blocked = createMockSysNotification('/blocked'); +const onboard = createMockSysNotification('/onboard'); + +const updateNotification = createMockSysNotification('/desk/bitcoin', [ + { + title: [{ text: 'App "Bitcoin" updated to version 1.0.1' }], + time: '', + content: [], + link: '/desk/bitcoin', + binned: '/' + } +]); + +export function createMockNotification(desk: string, body: HarkBody[]): Notification { + return { + bin: { + place: { + desk, + path: '/' + }, + path: '/' + }, + time: Date.now() - 3_600, + body + }; +} + +export const mockNotifications: Timebox = _.keyBy( + [ + lag, + blocked, + onboard, + updateNotification, + createMockNotification('groups', [ + createDmNotification(text('ie the hook agent responsible for marking the notifications')), + createDmNotification(ship('~hastuc-dibtux'), text(' sent a link')) + ]), + createMockNotification('bitcoin-wallet', [createBitcoinNotif('0.025 BTC')]), + createMockNotification('groups', [createGroupNotif('a Group: Tlon Corporation')]) + ], + (not) => harkBinToId(not.bin) +); + +const contact: Contact = { + nickname: '', + bio: '', + status: '', + color: '#000000', + avatar: null, + cover: null, + groups: [], + 'last-updated': 0 +}; + +export const mockContacts: Contacts = { + '~zod': { + ...contact, + nickname: 'Tlon Corporation' + }, + '~nocsyx-lassul': { + ...contact, + status: 'technomancing an electron wrapper for urbit', + color: '#4c00ff' + }, + '~nachus-hollyn': { + ...contact, + avatar: 'https://i.pinimg.com/originals/20/62/59/2062590a440f717a2ae1065ad8e8a4c7.gif' + }, + '~nalbel_litzod': { + ...contact, + nickname: 'Queen', + color: '#0a1b0a' + }, + '~litmus^ritten': { + ...contact + }, + '~nalput_litzod': { + ...contact + }, + '~nalrex_bannus': { + ...contact, + status: 'Script, command and inspect your Urbit. Use TUI applications' + }, + '~nalrys': { + ...contact, + status: 'hosting coming soon', + color: '#130c06' + } +}; + +export const mockVat = (desk: string, blockers?: boolean): Vat => ({ + cass: { + da: '~2021.9.13..05.41.04..ae65', + ud: 1 + }, + desk, + arak: { + rein: { + sub: [], + add: [] + }, + rail: + desk === 'uniswap' + ? null + : { + aeon: 3, + desk, + publisher: '~zod', + next: blockers ? [{ aeon: 3, weft: { name: 'zuse', kelvin: 419 } }] : [], + ship: '~zod', + paused: desk === 'groups' + } + }, + hash: '0vh.lhfn6.julg1.fs52d.g2lqj.q5kp0.2o7j3.2bljl.jdm34.hd46v.9uv5v' +}); + +const badVats = ['inbox', 'system', 'terminal', 'base']; +export const mockVats = _.reduce( + mockCharges, + (vats, charge, desk) => { + return { ...vats, [desk]: mockVat(desk, !badVats.includes(desk)) }; + }, + { base: mockVat('base', true) } as Vats +); diff --git a/pkg/grid/src/state/notifications.ts b/pkg/grid/src/state/notifications.ts new file mode 100644 index 000000000..95bf5ec4d --- /dev/null +++ b/pkg/grid/src/state/notifications.ts @@ -0,0 +1,13 @@ +import shallow from 'zustand/shallow'; +import { useHarkStore } from './hark'; + +export const useNotifications = () => { + const [unseen, seen] = useHarkStore((s) => [s.unseen, s.seen], shallow); + const hasAnyNotifications = Object.keys(seen).length > 0 || Object.keys(unseen).length > 0; + + return { + unseen, + seen, + hasAnyNotifications + }; +}; diff --git a/pkg/grid/src/state/settings.ts b/pkg/grid/src/state/settings.ts new file mode 100644 index 000000000..2ca2388ae --- /dev/null +++ b/pkg/grid/src/state/settings.ts @@ -0,0 +1,103 @@ +/* eslint-disable no-param-reassign */ +import { + SettingsUpdate, + Value, + putEntry as doPutEntry, + getDeskSettings, + DeskData +} from '@urbit/api/settings'; +import _ from 'lodash'; +import { + BaseState, + createState, + createSubscription, + pokeOptimisticallyN, + reduceStateN +} from './base'; +import api from './api'; + +interface BaseSettingsState { + display: { + theme: 'light' | 'dark' | 'auto'; + doNotDisturb: boolean; + }; + putEntry: (bucket: string, key: string, value: Value) => Promise; + [ref: string]: unknown; +} + +export type SettingsState = BaseSettingsState & BaseState; + +function putBucket(json: SettingsUpdate, state: SettingsState): SettingsState { + const data = _.get(json, 'put-bucket', false); + if (data) { + state[data['bucket-key']] = data.bucket; + } + return state; +} + +function delBucket(json: SettingsUpdate, state: SettingsState): SettingsState { + const data = _.get(json, 'del-bucket', false); + if (data) { + delete state[data['bucket-key']]; + } + return state; +} + +function putEntry(json: SettingsUpdate, state: any): SettingsState { + const data: Record = _.get(json, 'put-entry', false); + if (data) { + if (!state[data['bucket-key']]) { + state[data['bucket-key']] = {}; + } + state[data['bucket-key']][data['entry-key']] = data.value; + } + return state; +} + +function delEntry(json: SettingsUpdate, state: any): SettingsState { + const data = _.get(json, 'del-entry', false); + if (data) { + delete state[data['bucket-key']][data['entry-key']]; + } + return state; +} + +export const reduceUpdate = [putBucket, delBucket, putEntry, delEntry]; + +export const useSettingsState = createState( + 'Settings', + (set, get) => ({ + display: { + theme: 'auto', + doNotDisturb: true + }, + loaded: false, + putEntry: async (bucket, key, val) => { + const poke = doPutEntry(window.desk, bucket, key, val); + await pokeOptimisticallyN(useSettingsState, poke, reduceUpdate); + }, + fetchAll: async () => { + const result = (await api.scry(getDeskSettings(window.desk))).desk; + const newState = { + loaded: true, + ..._.mergeWith(get(), result, (obj, src) => (_.isArray(src) ? src : undefined)) + }; + set(newState); + } + }), + [], + [ + (set, get) => + createSubscription('settings-store', `/desk/${window.desk}`, (e) => { + const data = _.get(e, 'settings-event', false); + if (data) { + reduceStateN(get(), data, reduceUpdate); + } + }) + ] +); + +const selTheme = (s: SettingsState) => s.display.theme; +export function useTheme() { + return useSettingsState(selTheme); +} diff --git a/pkg/grid/src/state/util.ts b/pkg/grid/src/state/util.ts new file mode 100644 index 000000000..a6375bbf0 --- /dev/null +++ b/pkg/grid/src/state/util.ts @@ -0,0 +1,71 @@ +import { Docket, DocketHref, Treaty } from '@urbit/api/docket'; +import { hsla, parseToHsla } from 'color2k'; +import _ from 'lodash'; + +export const useMockData = import.meta.env.MODE === 'mock'; + +export async function fakeRequest(data: T, time = 300): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(data); + }, time); + }); +} + +export function getAppHref(href: DocketHref) { + return 'site' in href ? href.site : `/apps/${href.glob.base}/`; +} + +export function getAppName(app: (Docket & { desk: string }) | Treaty | undefined): string { + if (!app) { + return ''; + } + + return app.title || app.desk; +} + +export function disableDefault(e: T): void { + e.preventDefault(); +} + +// hack until radix-ui fixes this behavior +export function handleDropdownLink(setOpen?: (open: boolean) => void): (e: Event) => void { + return (e: Event) => { + e.stopPropagation(); + e.preventDefault(); + setTimeout(() => setOpen?.(false), 15); + }; +} + +export function deSig(ship: string): string { + if (!ship) { + return ''; + } + return ship.replace('~', ''); +} + +export function normalizeUrbitColor(color: string): string { + if (color.startsWith('#')) { + return color; + } + + const colorString = color.slice(2).replace('.', '').toUpperCase(); + const lengthAdjustedColor = _.padEnd(colorString, 6, _.last(colorString)); + return `#${lengthAdjustedColor}`; +} + +export function getDarkColor(color: string): string { + const hslaColor = parseToHsla(color); + return hsla(hslaColor[0], hslaColor[1], 1 - hslaColor[2], 1); +} + +export function createStorageKey(name: string): string { + return `~${window.ship}/${window.desk}/${name}`; +} + +// for purging storage with version updates +export function clearStorageMigration() { + return {} as T; +} + +export const storageVersion = parseInt(import.meta.env.VITE_STORAGE_VERSION, 10); diff --git a/pkg/grid/src/storage-wipe.ts b/pkg/grid/src/storage-wipe.ts new file mode 100644 index 000000000..a1d0d6b16 --- /dev/null +++ b/pkg/grid/src/storage-wipe.ts @@ -0,0 +1,12 @@ +import { createStorageKey } from './state/util'; + +const key = createStorageKey(`storage-wipe-${import.meta.env.VITE_LAST_WIPE}`); +const wiped = localStorage.getItem(key); + +// Loaded before everything, this clears local storage just once. +// Change VITE_LAST_WIPE in .env to date of wipe + +if (!wiped) { + localStorage.clear(); + localStorage.setItem(key, 'true'); +} diff --git a/pkg/grid/src/styles/base.css b/pkg/grid/src/styles/base.css new file mode 100644 index 000000000..b48a6d8d3 --- /dev/null +++ b/pkg/grid/src/styles/base.css @@ -0,0 +1,42 @@ +body { + scrollbar-width: thin; + scrollbar-color: #e5e5e5 transparent; +} + +body::-webkit-scrollbar-thumb { + background-color: #e5e5e5; +} + +body::-webkit-scrollbar-track { + background: transparent; +} + +@media (prefers-color-scheme: dark) { + body { + scrollbar-color: #333333 transparent; + } + + body::-webkit-scrollbar-thumb { + background-color: #333333; + } +} + +.h1 { + @apply text-2xl sm:text-3xl font-bold leading-relaxed tracking-tighter; +} + +.h2 { + @apply text-xl sm:text-2xl font-semibold leading-snug tracking-tight; +} + +.h3 { + @apply text-lg sm:text-xl font-semibold leading-relaxed tracking-tight; +} + +.h4 { + @apply text-sm sm:text-base font-semibold leading-normal tracking-tight; +} + +.default-ring { + @apply focus-visible:ring-2 ring-blue-400 ring-opacity-80 focus-visible:outline-none; +} diff --git a/pkg/grid/src/styles/components.css b/pkg/grid/src/styles/components.css new file mode 100644 index 000000000..b0cebc598 --- /dev/null +++ b/pkg/grid/src/styles/components.css @@ -0,0 +1,39 @@ +.circle-button { + @apply inline-flex items-center justify-center h-12 w-12 font-semibold rounded-full; +} + +.button { + @apply inline-flex items-center justify-center px-4 py-2 font-semibold text-base tracking-tight rounded-lg cursor-pointer; +} + +.dialog-container { + @apply fixed z-40 top-1/2 left-1/2 p-4 transform -translate-x-1/2 -translate-y-1/2; +} + +.dialog { + @apply relative max-h-[calc(100vh-2rem)] max-w-[calc(100vw-2rem)] p-5 sm:p-8 bg-white rounded-3xl overflow-auto; +} + +.dialog-inner-container { + @apply h-full p-4 md:p-8 space-y-8 overflow-y-auto; +} + +.dropdown { + @apply min-w-52 p-4 rounded-xl; +} + +.inner-section { + @apply p-3 bg-gray-50 rounded-xl; +} + +.input { + @apply px-4 py-2 w-full text-base sm:text-sm bg-white rounded-xl; +} + +.notification { + @apply p-4 bg-gray-50 rounded-xl; +} + +.spinner { + @apply inline-flex items-center w-6 h-6 animate-spin; +} diff --git a/pkg/grid/src/styles/grids.css b/pkg/grid/src/styles/grids.css new file mode 100644 index 000000000..6ec24acc7 --- /dev/null +++ b/pkg/grid/src/styles/grids.css @@ -0,0 +1,65 @@ +.note-grid-content { + display: grid; + grid-template-columns: 1.5rem 1fr 4rem; + grid-template-rows: 1.5rem 1.5rem; + grid-gap: 0.5rem; + padding: 1rem; + grid-template-areas: + 'icon title actions ' + 'arrow head head' + '. body body'; +} + +.note-grid-no-content { + display: grid; + width: 100%; + padding: 1rem; + grid-template-columns: 3.5rem 1fr 4rem; + grid-column-gap: 0.75rem; + align-items: center; + grid-template-areas: + 'icon title actions' + 'icon head head'; +} +.note-grid-title { + grid-area: title; +} + +.note-grid-icon { + grid-area: icon; +} + +.note-grid-body { + grid-area: body; +} + +.note-grid-head { + grid-area: head; +} + +.note-grid-arrow { + grid-area: arrow; +} + +.note-grid-actions { + grid-area: actions; +} + +@media (min-width: 640px) { + .note-grid-content { + grid-template-columns: 1.5rem 1fr 6rem; + grid-template-rows: 1.5rem 1.5rem; + grid-template-areas: + 'icon title actions ' + 'arrow head actions' + '. body actions'; + } + + .note-grid-no-content { + grid-template-rows: 1.75rem 1.75rem; + grid-template-columns: 3.5rem 1fr 6rem; + grid-template-areas: + 'icon title actions' + 'icon head actions'; + } +} diff --git a/pkg/grid/src/styles/index.css b/pkg/grid/src/styles/index.css new file mode 100644 index 000000000..419a82058 --- /dev/null +++ b/pkg/grid/src/styles/index.css @@ -0,0 +1,10 @@ +@import 'tailwindcss/base'; +@import './base.css'; + +@import 'tailwindcss/components'; +@import './components.css'; + +@import 'tailwindcss/utilities'; +@import './utilities.css'; + +@import './grids.css'; diff --git a/pkg/grid/src/styles/utilities.css b/pkg/grid/src/styles/utilities.css new file mode 100644 index 000000000..ddbe64ce6 --- /dev/null +++ b/pkg/grid/src/styles/utilities.css @@ -0,0 +1,7 @@ +.scroll-full-width { + width: calc(100% - var(--removed-body-scroll-bar-size)); +} + +.scroll-left-50 { + left: calc(50% - (var(--removed-body-scroll-bar-size) / 2)); +} diff --git a/pkg/grid/src/tiles/RemoveApp.tsx b/pkg/grid/src/tiles/RemoveApp.tsx new file mode 100644 index 000000000..a2357d03d --- /dev/null +++ b/pkg/grid/src/tiles/RemoveApp.tsx @@ -0,0 +1,43 @@ +import React, { useCallback } from 'react'; +import { useHistory, useParams } from 'react-router-dom'; +import { Button } from '../components/Button'; +import { Dialog, DialogClose, DialogContent } from '../components/Dialog'; +import { useRecentsStore } from '../nav/search/Home'; +import useDocketState, { useCharges } from '../state/docket'; +import { getAppName } from '../state/util'; + +export const RemoveApp = () => { + const history = useHistory(); + const { desk } = useParams<{ desk: string }>(); + const charges = useCharges(); + const docket = charges[desk]; + const uninstallDocket = useDocketState((s) => s.uninstallDocket); + + // TODO: add optimistic updates + const handleRemoveApp = useCallback(() => { + uninstallDocket(desk); + useRecentsStore.getState().removeRecentApp(desk); + }, [desk]); + + return ( + !open && history.push('/')}> + +

    Uninstall “{getAppName(docket)}”?

    +

    + The app tile will be removed from Landscape, all processes will be stopped and their data archived, and the app will stop receiving updates. +

    +

    + If the app is reinstalled, the archived data will be restored and you'll be able to pick up where you left off. +

    +
    + + Cancel + + + Uninstall + +
    +
    +
    + ); +}; diff --git a/pkg/grid/src/tiles/SuspendApp.tsx b/pkg/grid/src/tiles/SuspendApp.tsx new file mode 100644 index 000000000..a31c65cfd --- /dev/null +++ b/pkg/grid/src/tiles/SuspendApp.tsx @@ -0,0 +1,46 @@ +import React, { useCallback } from 'react'; +import { Redirect, useHistory, useParams } from 'react-router-dom'; +import { Button } from '../components/Button'; +import { Dialog, DialogClose, DialogContent } from '../components/Dialog'; +import { useRecentsStore } from '../nav/search/Home'; +import useDocketState, { useCharges } from '../state/docket'; +import { getAppName } from '../state/util'; + +export const SuspendApp = () => { + const history = useHistory(); + const { desk } = useParams<{ desk: string }>(); + const charges = useCharges(); + const charge = charges[desk]; + + // TODO: add optimistic updates + const handleSuspendApp = useCallback(() => { + useDocketState.getState().toggleDocket(desk); + useRecentsStore.getState().removeRecentApp(desk); + }, [desk]); + + if ('suspend' in charge.chad) { + return ; + } + + return ( + !open && history.push('/')}> + +

    Suspend “{getAppName(charge)}”

    +

    + All processes will be stopped and data archived. The app will continue to receive updates from its publisher. +

    +

    + When unsuspended, archived data will be loaded and all processes will resume running, so you can pick up where you left off. +

    +
    + + Cancel + + + Suspend + +
    +
    +
    + ); +}; diff --git a/pkg/grid/src/tiles/Tile.tsx b/pkg/grid/src/tiles/Tile.tsx new file mode 100644 index 000000000..45280d70f --- /dev/null +++ b/pkg/grid/src/tiles/Tile.tsx @@ -0,0 +1,81 @@ +import classNames from 'classnames'; +import React, { FunctionComponent } from 'react'; +import { chadIsRunning } from '@urbit/api'; +import { TileMenu } from './TileMenu'; +import { Spinner } from '../components/Spinner'; +import { getAppHref } from '../state/util'; +import { useRecentsStore } from '../nav/search/Home'; +import { ChargeWithDesk } from '../state/docket'; +import { useTileColor } from './useTileColor'; +import { useVat } from '../state/kiln'; +import { Bullet } from '../components/icons/Bullet'; + +type TileProps = { + charge: ChargeWithDesk; + desk: string; +}; + +export const Tile: FunctionComponent = ({ charge, desk }) => { + const addRecentApp = useRecentsStore((state) => state.addRecentApp); + const { title, image, color, chad, href } = charge; + const vat = useVat(desk); + const { lightText, tileColor, menuColor, suspendColor, suspendMenuColor } = useTileColor(color); + const loading = 'install' in chad; + const suspended = 'suspend' in chad; + const hung = 'hung' in chad; + const active = chadIsRunning(chad); + const link = getAppHref(href); + const backgroundColor = active ? tileColor || 'purple' : suspendColor; + + return ( + addRecentApp(desk)} + onAuxClick={() => addRecentApp(desk)} + > +
    +
    + {!active && ( + <> + {loading && } + + {suspended && 'Suspended'} + {loading && 'Installing'} + {hung && 'Errored'} + + + )} +
    + {vat?.arak.rail?.paused && ( + + )} + + {title && ( +
    +

    {title}

    +
    + )} + {image && !loading && ( + + )} +
    +
    + ); +}; diff --git a/pkg/grid/src/tiles/TileInfo.tsx b/pkg/grid/src/tiles/TileInfo.tsx new file mode 100644 index 000000000..f95c04664 --- /dev/null +++ b/pkg/grid/src/tiles/TileInfo.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { useHistory, useParams } from 'react-router-dom'; +import { Dialog, DialogContent } from '../components/Dialog'; +import { AppInfo } from '../components/AppInfo'; +import { useCharge } from '../state/docket'; +import { useVat } from '../state/kiln'; + +export const TileInfo = () => { + const { desk } = useParams<{ desk: string }>(); + const { push } = useHistory(); + const charge = useCharge(desk); + const vat = useVat(desk); + + if (!charge) { + return null; + } + + return ( + !open && push('/')}> + + + + + ); +}; diff --git a/pkg/grid/src/tiles/TileMenu.tsx b/pkg/grid/src/tiles/TileMenu.tsx new file mode 100644 index 000000000..5a811301a --- /dev/null +++ b/pkg/grid/src/tiles/TileMenu.tsx @@ -0,0 +1,95 @@ +import React, { useCallback, useState } from 'react'; +import type * as Polymorphic from '@radix-ui/react-polymorphic'; +import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; +import classNames from 'classnames'; +import { Link } from 'react-router-dom'; +import { Chad, chadIsRunning } from '@urbit/api'; +import useDocketState from '../state/docket'; +import { disableDefault, handleDropdownLink } from '../state/util'; + +export interface TileMenuProps { + desk: string; + lightText: boolean; + menuColor: string; + chad: Chad; + className?: string; +} + +const MenuIcon = ({ className }: { className: string }) => ( + + + + + +); + +type ItemComponent = Polymorphic.ForwardRefComponent< + Polymorphic.IntrinsicElement, + Polymorphic.OwnProps +>; + +const Item = React.forwardRef(({ children, ...props }, ref) => ( + + {children} + +)) as ItemComponent; + +export const TileMenu = ({ desk, chad, menuColor, lightText, className }: TileMenuProps) => { + const [open, setOpen] = useState(false); + const toggleDocket = useDocketState((s) => s.toggleDocket); + const menuBg = { backgroundColor: menuColor }; + const linkOnSelect = useCallback(handleDropdownLink(setOpen), []); + const active = chadIsRunning(chad); + const suspended = 'suspend' in chad; + + return ( + setOpen(isOpen)}> + queryClient.setQueryData(['apps', name], app)} + > + + Menu + + + + + + App Info + + + + + {active && ( + + Suspend App + + )} + {suspended && toggleDocket(desk)}>Resume App} + + Uninstall App + + + + + + ); +}; diff --git a/pkg/grid/src/tiles/useTileColor.tsx b/pkg/grid/src/tiles/useTileColor.tsx new file mode 100644 index 000000000..a9320c336 --- /dev/null +++ b/pkg/grid/src/tiles/useTileColor.tsx @@ -0,0 +1,39 @@ +import { darken, hsla, lighten, parseToHsla, readableColorIsBlack } from 'color2k'; +import { useCurrentTheme } from '../state/local'; +import { getDarkColor } from '../state/util'; + +function bgAdjustedColor(color: string, darkBg: boolean): string { + return darkBg ? lighten(color, 0.1) : darken(color, 0.1); +} + +function getMenuColor(color: string, darkBg: boolean): string { + const hslaColor = parseToHsla(color); + const satAdjustedColor = hsla(hslaColor[0], Math.max(0.2, hslaColor[1]), hslaColor[2], 1); + + return bgAdjustedColor(satAdjustedColor, darkBg); +} + +// makes tiles look broken because they blend into BG +function disallowWhiteTiles(color: string): string { + const hslaColor = parseToHsla(color); + return hslaColor[2] >= 0.95 ? darken(color, hslaColor[2] - 0.95) : color; +} + +export const useTileColor = (color: string) => { + const theme = useCurrentTheme(); + const darkTheme = theme === 'dark'; + const allowedColor = disallowWhiteTiles(color); + const tileColor = darkTheme ? getDarkColor(allowedColor) : allowedColor; + const darkBg = !readableColorIsBlack(tileColor); + const lightText = darkBg !== darkTheme; // if not same, light text + const suspendColor = darkTheme ? 'rgb(26,26,26)' : 'rgb(220,220,220)'; + + return { + theme, + tileColor, + menuColor: getMenuColor(tileColor, darkBg), + suspendColor, + suspendMenuColor: bgAdjustedColor(suspendColor, darkTheme), + lightText + }; +}; diff --git a/pkg/grid/src/vite-env.d.ts b/pkg/grid/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/pkg/grid/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/pkg/grid/src/window.ts b/pkg/grid/src/window.ts new file mode 100644 index 000000000..9a6993bc1 --- /dev/null +++ b/pkg/grid/src/window.ts @@ -0,0 +1,15 @@ +import { useLeapStore } from './nav/Nav'; +import { useRecentsStore } from './nav/search/Home'; +import useDocketState from './state/docket'; + +declare global { + interface Window { + ship: string; + desk: string; + recents: typeof useRecentsStore.getState; + docket: typeof useDocketState.getState; + leap: typeof useLeapStore.getState; + } +} + +export {}; diff --git a/pkg/grid/tailwind.config.js b/pkg/grid/tailwind.config.js new file mode 100644 index 000000000..218adbecd --- /dev/null +++ b/pkg/grid/tailwind.config.js @@ -0,0 +1,215 @@ +const defaultTheme = require('tailwindcss/defaultTheme'); +const resolveConfig = require('tailwindcss/resolveConfig'); +const { Theme, ThemeManager } = require('tailwindcss-theming/api'); + +const themableProperties = [ + 'spacing', + 'fontFamily', + //'fontSize', would require change in tailwindcss-theming + 'fontWeight', + 'letterSpacing', + 'lineHeight', + 'borderRadius', + 'borderWidth', + 'boxShadow' +]; + +function variablizeTheme(themeConfig, theme) { + themableProperties.forEach((prop) => { + const propSet = themeConfig[prop]; + Object.entries(propSet).forEach(([key, value]) => { + theme.setVariable(key, value, prop, prop); + }); + }); +} + +const config = resolveConfig({ + theme: { + fontFamily: { + sans: [ + 'Inter', + 'Inter UI', + '-apple-system', + 'BlinkMacSystemFont', + 'San Francisco', + 'Helvetica Neue', + 'Arial', + 'sans-serif' + ], + mono: ['Source Code Pro', 'Roboto mono', 'Courier New', 'monospace'] + }, + extend: { + lineHeight: { + tight: 1.2, + snug: 1.33334, + relaxed: 1.66667 + } + } + } +}); + +const base = new Theme().addColors({ + transparent: 'transparent', + white: '#FFFFFF', + black: '#000000', + gray: { + 50: '#F2F2F2', + 100: '#E5E5E5', + 200: '#CCCCCC', + 300: '#B3B3B3', + 400: '#999999', + 500: '#808080', + 600: '#666666', + 700: '#4D4D4D', + 800: '#333333', + 900: '#1A1A1A' + }, + blue: { + 50: '#EFF9FF', + 100: '#C8EDFF', + 200: '#A0E1FF', + 300: '#5FBFFF', + 400: '#219DFF', + 500: '#0F75D8', + 600: '#0252B2', + 700: '#00388B', + 800: '#002364', + 900: '#00133E' + }, + red: { + 50: '#FFF4F2', + 100: '#FFDED6', + 200: '#FFC8B9', + 300: '#FC9B84', + 400: '#F57456', + 500: '#EE5432', + 600: '#D03B22', + 700: '#B12918', + 800: '#931C13', + 900: '#751410' + }, + orange: { + 50: '#FFF4EF', + 100: '#FFE2CE', + 200: '#FFCEAB', + 300: '#FFA56F', + 400: '#FF7E36', + 500: '#D85E1E', + 600: '#B2420C', + 700: '#8B2B00', + 800: '#641E00', + 900: '#3E1100' + }, + green: { + 100: '#E6F5F0', + 200: '#B3E2D1', + 300: '#009F65' + }, + yellow: { + 100: '#FFF9E6', + 200: '#FFEEB3', + 300: '#FFDD66', + 400: '#FFC700' + } +}); +variablizeTheme(config.theme, base); + +const dark = new Theme() + .setName('dark') + .targetable() + .addColors({ + transparent: 'transparent', + white: '#000000', + black: '#FFFFFF', + gray: { + 50: '#1A1A1A', + 100: '#333333', + 200: '#4D4D4D', + 300: '#666666', + 400: '#808080', + 500: '#999999', + 600: '#B3B3B3', + 700: '#CCCCCC', + 800: '#E5E5E5', + 900: '#F2F2F2' + }, + red: { + 50: '#751410', + 100: '#931C13', + 200: '#B12918', + 300: '#D03B22', + 400: '#EE5432', + 500: '#F57456', + 600: '#FC9B84', + 700: '#FFC8B9', + 800: '#FFDED6', + 900: '#FFF4F2' + }, + blue: { + 50: '#00133E', + 100: '#002364', + 200: '#00388B', + 300: '#0252B2', + 400: '#0F75D8', + 500: '#219DFF', + 600: '#5FBFFF', + 700: '#A0E1FF', + 800: '#C8EDFF', + 900: '#EFF9FF' + }, + orange: { + 50: '#3E1100', + 100: '#641E00', + 200: '#8B2B00', + 300: '#B2420C', + 400: '#D85E1E', + 500: '#FF7E36', + 600: '#FFA56F', + 700: '#FFCEAB', + 800: '#FFE2CE', + 900: '#FFF4EF' + }, + green: { + 100: '#182722', + 200: '#134231', + 300: '#009F65' + }, + yellow: { + 100: '#312B18', + 200: '#5F4E13', + 300: '#A4820B', + 400: '#FFC700' + } + }); + +const themes = new ThemeManager().setDefaultTheme(base).addTheme(dark); + +module.exports = { + mode: 'jit', + purge: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], + darkMode: 'class', // or 'media' or 'class' + theme: { + extend: { + minWidth: (theme) => theme('spacing') + } + }, + screens: { + ...defaultTheme.screens, + xl: '1440px', + '2xl': '2200px' + }, + variants: { + extend: { + opacity: ['hover-none'], + display: ['group-hover'] + } + }, + plugins: [ + require('@tailwindcss/aspect-ratio'), + require('tailwindcss-touch')(), + require('tailwindcss-theming')({ + themes, + strategy: 'class' + }) + ] +}; diff --git a/pkg/grid/tsconfig.json b/pkg/grid/tsconfig.json new file mode 100644 index 000000000..013e6c54f --- /dev/null +++ b/pkg/grid/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + }, + "include": ["./src"] +} diff --git a/pkg/grid/vite.config.ts b/pkg/grid/vite.config.ts new file mode 100644 index 000000000..45c862692 --- /dev/null +++ b/pkg/grid/vite.config.ts @@ -0,0 +1,37 @@ +import { loadEnv, defineConfig } from 'vite'; +import analyze from 'rollup-plugin-analyzer'; +import { visualizer } from 'rollup-plugin-visualizer'; +import reactRefresh from '@vitejs/plugin-react-refresh'; +import { urbitPlugin } from '@urbit/vite-plugin-urbit'; +import { execSync } from 'child_process'; + +// https://vitejs.dev/config/ +export default ({ mode }) => { + process.env.VITE_STORAGE_VERSION = Date.now().toString(); + + Object.assign(process.env, loadEnv(mode, process.cwd())); + const SHIP_URL = process.env.SHIP_URL || process.env.VITE_SHIP_URL || 'http://localhost:8080'; + console.log(SHIP_URL); + + return defineConfig({ + base: mode === 'mock' ? undefined : '/apps/grid/', + server: mode === 'mock' ? undefined : { https: true }, + build: + mode !== 'profile' + ? undefined + : { + rollupOptions: { + plugins: [ + analyze({ + limit: 20 + }), + visualizer() + ] + } + }, + plugins: + mode === 'mock' + ? [] + : [urbitPlugin({ base: 'grid', target: SHIP_URL, secure: false }), reactRefresh()] + }); +}; diff --git a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs index 7a65674f1..d2f316a53 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Arvo/Event.hs @@ -134,7 +134,7 @@ data Feed | Feed1 Germs deriving (Eq, Show) ---NOTE reify type environment +-- NOTE reify type environment $(pure []) instance ToNoun Feed where @@ -270,7 +270,7 @@ data BoatEv deriveNoun ''BoatEv --- Boat Events ----------------------------------------------------------------- +-- Jael Events ----------------------------------------------------------------- data JaelEv = JaelEvRekey () (Life, Ring) diff --git a/pkg/hs/urbit-king/lib/Urbit/King/Main.hs b/pkg/hs/urbit-king/lib/Urbit/King/Main.hs index e278f33a0..d7ae6d392 100644 --- a/pkg/hs/urbit-king/lib/Urbit/King/Main.hs +++ b/pkg/hs/urbit-king/lib/Urbit/King/Main.hs @@ -506,7 +506,7 @@ newShip CLI.New{..} opts = do let seed = mineComet (Set.fromList starList) eny putStrLn ("boot: found comet " ++ renderShip (sShip seed)) putStrLn ("code: " ++ (tshow $ deriveCode $ sRing seed)) - bootFromSeed pill $ Feed0 seed + bootFromFeed pill $ Feed0 seed CLI.BootFake name -> do pill <- pillFrom nPillSource @@ -526,7 +526,7 @@ newShip CLI.New{..} opts = do pill <- pillFrom nPillSource - bootFromSeed pill feed + bootFromFeed pill feed where shipFrom :: Text -> RIO HostEnv Ship @@ -547,8 +547,8 @@ newShip CLI.New{..} opts = do Nothing -> error "Urbit.ob didn't produce string with ~" Just x -> pure x - bootFromSeed :: Pill -> Feed -> RIO HostEnv () - bootFromSeed pill feed = do + bootFromFeed :: Pill -> Feed -> RIO HostEnv () + bootFromFeed pill feed = do ethReturn <- dawnVent nEthNode feed case ethReturn of diff --git a/pkg/hs/urbit-king/lib/Urbit/Vere/Dawn.hs b/pkg/hs/urbit-king/lib/Urbit/Vere/Dawn.hs index 61faa380b..9d1475749 100644 --- a/pkg/hs/urbit-king/lib/Urbit/Vere/Dawn.hs +++ b/pkg/hs/urbit-king/lib/Urbit/Vere/Dawn.hs @@ -310,29 +310,29 @@ validateFeedAndGetSponsor endpoint = \case Left _ -> validateGerms $ Germs gShip f Right r -> pure (seed, r) - validateSeed (Seed ship life ring oaf) = + validateSeed (Seed ship life ring oaf) = do case clanFromShip ship of - Ob.Comet -> validateComet - Ob.Moon -> validateMoon + Ob.Comet -> pure validateComet + Ob.Moon -> pure validateMoon _ -> validateRest where - validateComet = do + cometFromPass = cometFingerprint $ ringToPass ring + validateComet -- A comet address is the fingerprint of the keypair - let shipFromPass = cometFingerprint $ ringToPass ring - if (ship /= shipFromPass) then - pure $ Left ("comet name doesn't match fingerprint " <> + | (ship /= cometFromPass) = + Left ("comet name doesn't match fingerprint " <> show ship <> " vs " <> - show shipFromPass) - else if (life /= 1) then - pure $ Left "comet can never be re-keyed" - else - pure $ Right (shipSein ship) + show cometFromPass) + | (life /= 1) = + Left "comet can never be re-keyed" + | otherwise = + Right (shipSein ship) - validateMoon = do + validateMoon = -- TODO: The current code in zuse does nothing, but we should be able -- to try to validate the oath against the current as exists planet -- on chain. - pure $ Right $ shipSein ship + Right $ shipSein ship validateRest = do putStrLn ("boot: retrieving " <> renderShip ship <> "'s public keys") diff --git a/pkg/hs/urbit-king/package.yaml b/pkg/hs/urbit-king/package.yaml index 472b15605..dd4655e4c 100644 --- a/pkg/hs/urbit-king/package.yaml +++ b/pkg/hs/urbit-king/package.yaml @@ -1,5 +1,5 @@ name: urbit-king -version: 1.5 +version: 1.7 license: MIT license-file: LICENSE data-files: diff --git a/pkg/interface/.eslintrc.js b/pkg/interface/.eslintrc.js index bcdb06a01..09212671c 100644 --- a/pkg/interface/.eslintrc.js +++ b/pkg/interface/.eslintrc.js @@ -2,5 +2,11 @@ module.exports = { extends: '@urbit', env: { 'jest': true + }, + rules: { + // Because we use styled system, and use + // the convention of each prop on a new line + // we probably shouldn't keep this on + 'max-lines-per-function': ['off', {}] } }; diff --git a/pkg/interface/.husky/post-checkout b/pkg/interface/.husky/post-checkout deleted file mode 100755 index cab40f264..000000000 --- a/pkg/interface/.husky/post-checkout +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-checkout.\n"; exit 2; } -git lfs post-checkout "$@" diff --git a/pkg/interface/.husky/post-commit b/pkg/interface/.husky/post-commit deleted file mode 100755 index 9443f4161..000000000 --- a/pkg/interface/.husky/post-commit +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-commit.\n"; exit 2; } -git lfs post-commit "$@" diff --git a/pkg/interface/.husky/post-merge b/pkg/interface/.husky/post-merge deleted file mode 100755 index 828b70891..000000000 --- a/pkg/interface/.husky/post-merge +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-merge.\n"; exit 2; } -git lfs post-merge "$@" diff --git a/pkg/interface/.husky/pre-push b/pkg/interface/.husky/pre-push deleted file mode 100755 index 81a9cc639..000000000 --- a/pkg/interface/.husky/pre-push +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; } -git lfs pre-push "$@" diff --git a/pkg/interface/.storybook/preview.js b/pkg/interface/.storybook/preview.js index 250a80233..4968246d2 100644 --- a/pkg/interface/.storybook/preview.js +++ b/pkg/interface/.storybook/preview.js @@ -36,8 +36,34 @@ export const globalTypes = { export const decorators = [ (Story, context) => { + window.ship = 'sampel-palnet'; const theme = context.globals.theme === 'light' ? light : dark; + useContactState.setState({ + contacts: { + '~ridlur-figbud': { + status: 'please like and subscribe', + 'last-updated': 1616609090555, + avatar: null, + cover: null, + bio: '', + nickname: 'Gav', + color: '0x26.3e0f', + groups: [], + }, + '~sampel-palnet': { + status: 'A test status', + 'last-updated': 1616609090555, + avatar: null, + cover: null, + bio: '', + nickname: 'You', + color: '0x26.3e0f', + groups: [], + }, + }, + }); + useMetadataState.setState({ associations: { groups: { @@ -66,6 +92,25 @@ export const decorators = [ }, }, graph: { + '/ship/~bitbet-bolbel/links': { + metadata: { + preview: false, + vip: '', + title: 'Link Collection', + description: '', + creator: '~darrux-landes', + picture: '', + hidden: false, + config: { + graph: 'link', + }, + 'date-created': '~2020.4.6..21.53.30..dc68', + color: '0x0', + }, + 'app-name': 'graph', + resource: '/ship/~bitbet-bolbel/links', + group: '/ship/~bitbet-bolbel/urbit-community', + }, '/ship/~darrux-landes/development': { metadata: { preview: false, @@ -88,6 +133,47 @@ export const decorators = [ }, }, }, + previews: { + '/ship/~bollug-worlus/urbit-index': { + group: '/ship/~bollug-worlus/urbit-index', + channels: { + '/ship/~darrux-landes/index-weekly': { + metadata: { + preview: false, + vip: '', + title: 'Index Weekly', + description: '', + creator: '~bollug-worlus', + picture: '', + hidden: false, + config: { + graph: 'publish', + }, + 'date-created': '~2020.4.6..21.53.30..dc68', + color: '0x0', + }, + 'app-name': 'graph', + resource: '/ship/~bollug-worlus/index-weekly', + group: '/ship/~bollug-worlus/urbit-index', + }, + }, + members: 1237, + metadata: { + preview: false, + vip: '', + title: 'Urbit Index', + description: '', + creator: '~bollug-worlus', + picture: '', + hidden: false, + config: { + group: null, + }, + 'date-created': '~2020.4.6..21.53.30..dc68', + color: '0x0', + }, + }, + }, }); useContactState.setState({ diff --git a/pkg/interface/CONTRIBUTING.md b/pkg/interface/CONTRIBUTING.md index f3bfbb5a0..9ee37c2a4 100644 --- a/pkg/interface/CONTRIBUTING.md +++ b/pkg/interface/CONTRIBUTING.md @@ -28,12 +28,13 @@ module.exports = { ``` Change the URL to your livenet ship (if making front-end changes) or keep it the -same (if [developing on a local development ship][local]). Then, from -'pkg/interface': +same (if [developing on a local development ship][local]). Then, from the root +of the repository -``` -npm ci -npm run start +```bash +npm i +npm run bootstrap +cd pkg/interface && npm run start ``` The dev server will start at `http://localhost:9000`. Sign in as you would diff --git a/pkg/interface/config/webpack.dev.js b/pkg/interface/config/webpack.dev.js index 27c5e4e63..699cc4cd3 100644 --- a/pkg/interface/config/webpack.dev.js +++ b/pkg/interface/config/webpack.dev.js @@ -1,57 +1,23 @@ const path = require('path'); const webpack = require('webpack'); -// const HtmlWebpackPlugin = require('html-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); // const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const urbitrc = require('./urbitrc'); -const fs = require('fs'); -const util = require('util'); const _ = require('lodash'); const { execSync } = require('child_process'); const GIT_DESC = execSync('git describe --always', { encoding: 'utf8' }).trim(); - -function copyFile(src,dest) { - return new Promise((res,rej) => - fs.copyFile(src,dest, err => err ? rej(err) : res())); -} - -class UrbitShipPlugin { - constructor(urbitrc) { - this.piers = urbitrc.URBIT_PIERS; - this.herb = urbitrc.herb || false; - } - - apply(compiler) { - compiler.hooks.afterEmit.tapPromise( - 'UrbitShipPlugin', - async (compilation) => { - const src = path.resolve(compiler.options.output.path, 'index.js'); - // uncomment to copy into all piers - // - // return Promise.all(this.piers.map(pier => { - // const dst = path.resolve(pier, 'app/landscape/js/index.js'); - // copyFile(src, dst).then(() => { - // if(!this.herb) { - // return; - // } - // pier = pier.split('/'); - // const desk = pier.pop(); - // return exec(`herb -p hood -d '+hood/commit %${desk}' ${pier.join('/')}`); - // }); - // })); - } - ); - } -} - let devServer = { - contentBase: path.join(__dirname, '../dist'), + contentBase: path.join(__dirname, '../public'), hot: true, port: 9000, host: '0.0.0.0', disableHostCheck: true, - historyApiFallback: true + historyApiFallback: { + disableDotRule: true + }, + publicPath: '/apps/landscape/' }; const router = _.mapKeys(urbitrc.FLEET || {}, (value, key) => `${key}.localhost:9000`); @@ -59,35 +25,31 @@ const router = _.mapKeys(urbitrc.FLEET || {}, (value, key) => `${key}.localhost if(urbitrc.URL) { devServer = { ...devServer, - index: '', - proxy: { - '/~landscape/js/bundle/index.*.js': { - target: 'http://localhost:9000', - pathRewrite: (req, path) => { - return '/index.js' - } - }, - // '/~landscape/js/serviceworker.js': { - // target: 'http://localhost:9000', - // pathRewrite: (req, path) => { - // return '/serviceworker.js' - // } - // }, - '**': { + index: 'index.html', + // headers: { + // 'Service-Worker-Allowed': '/' + // }, + proxy: [ + { + context: (path) => { + console.log(path); + if(path === '/apps/landscape/desk.js') { + return true; + } + return !path.startsWith('/apps/landscape'); + }, changeOrigin: true, target: urbitrc.URL, - router, - // ensure proxy doesn't timeout channels - proxyTimeout: 0, + router } - } + ] }; } module.exports = { mode: 'development', entry: { - app: './src/index.js', + app: './src/index.js' // serviceworker: './src/serviceworker.js' }, module: { @@ -100,7 +62,7 @@ module.exports = { presets: ['@babel/preset-env', '@babel/typescript', ['@babel/preset-react', { runtime: 'automatic', development: true, - importSource: '@welldone-software/why-did-you-render', + importSource: '@welldone-software/why-did-you-render' }]], plugins: [ '@babel/transform-runtime', @@ -123,7 +85,20 @@ module.exports = { // Compiles Sass to CSS 'sass-loader' ] + }, + { + test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, + use: [ + { + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/' + } + } + ] } + ] }, resolve: { @@ -132,21 +107,17 @@ module.exports = { devtool: 'inline-source-map', devServer: devServer, plugins: [ - new UrbitShipPlugin(urbitrc), new webpack.DefinePlugin({ 'process.env.LANDSCAPE_SHORTHASH': JSON.stringify(GIT_DESC), - 'process.env.TUTORIAL_HOST': JSON.stringify('~difmex-passed'), - 'process.env.TUTORIAL_GROUP': JSON.stringify('beginner-island'), - 'process.env.TUTORIAL_CHAT': JSON.stringify('introduce-yourself-7010'), - 'process.env.TUTORIAL_BOOK': JSON.stringify('guides-9684'), - 'process.env.TUTORIAL_LINKS': JSON.stringify('community-articles-2143'), - }) + 'process.env.LANDSCAPE_STORAGE_VERSION': JSON.stringify(Date.now()), + 'process.env.LANDSCAPE_LAST_WIPE': JSON.stringify('2021-10-20'), + }), // new CleanWebpackPlugin(), - // new HtmlWebpackPlugin({ - // title: 'Hot Module Replacement', - // template: './public/index.html', - // }), + new HtmlWebpackPlugin({ + title: 'Groups', + template: './public/index.html' + }) ], watch: true, output: { @@ -155,7 +126,7 @@ module.exports = { }, chunkFilename: '[name].js', path: path.resolve(__dirname, '../dist'), - publicPath: '/', + publicPath: '/apps/landscape/', globalObject: 'this' }, optimization: { diff --git a/pkg/interface/config/webpack.prod.js b/pkg/interface/config/webpack.prod.js index e8f080c93..42f99c463 100644 --- a/pkg/interface/config/webpack.prod.js +++ b/pkg/interface/config/webpack.prod.js @@ -1,5 +1,5 @@ const path = require('path'); -// const HtmlWebpackPlugin = require('html-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const MomentLocalesPlugin = require('moment-locales-webpack-plugin'); const webpack = require('webpack'); @@ -42,6 +42,18 @@ module.exports = { // Compiles Sass to CSS 'sass-loader' ] + }, + { + test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, + use: [ + { + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/' + } + } + ] } ] }, @@ -61,23 +73,21 @@ module.exports = { new webpack.DefinePlugin({ 'process.env.LANDSCAPE_STREAM': JSON.stringify(process.env.LANDSCAPE_STREAM), 'process.env.LANDSCAPE_SHORTHASH': JSON.stringify(GIT_DESC), - 'process.env.TUTORIAL_HOST': JSON.stringify('~difmex-passed'), - 'process.env.TUTORIAL_GROUP': JSON.stringify('beginner-island'), - 'process.env.TUTORIAL_CHAT': JSON.stringify('introduce-yourself-7010'), - 'process.env.TUTORIAL_BOOK': JSON.stringify('guides-9684'), - 'process.env.TUTORIAL_LINKS': JSON.stringify('community-articles-2143'), + 'process.env.LANDSCAPE_STORAGE_VERSION': Date.now().toString(), + 'process.env.LANDSCAPE_LAST_WIPE': '2021-10-20', }), - // new HtmlWebpackPlugin({ - // title: 'Hot Module Replacement', - // template: './public/index.html', - // }), + new HtmlWebpackPlugin({ + title: 'Groups', + template: './public/index.html', + favicon: './src/assets/img/Favicon.png' + }) ], output: { filename: (pathData) => { return pathData.chunk.name === 'app' ? 'index.[contenthash].js' : '[name].js'; }, - path: path.resolve(__dirname, '../../arvo/app/landscape/js/bundle'), - publicPath: '/' + path: path.resolve(__dirname, '../dist'), + publicPath: '/apps/landscape/' }, optimization: { minimize: true, diff --git a/pkg/interface/package-lock.json b/pkg/interface/package-lock.json index 0d756ff69..37680d5a2 100644 --- a/pkg/interface/package-lock.json +++ b/pkg/interface/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@actions/core": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.3.0.tgz", - "integrity": "sha512-xxtX0Cwdhb8LcgatfJkokqT8KzPvcIbwL9xpLU09nOwBzaStbfm0dNncsP0M4us+EpoPdWy7vbzU5vSOH7K6pg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", + "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==", "dev": true }, "@actions/github": { @@ -32,57 +32,51 @@ } }, "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.14.5" } }, "@babel/compat-data": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", - "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", "dev": true }, "@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "dependencies": { "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -92,11 +86,11 @@ } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.14.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -109,81 +103,63 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", - "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz", + "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-explode-assignable-expression": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-compilation-targets": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", - "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", "dev": true, "requires": { - "@babel/compat-data": "^7.12.5", - "@babel/helper-validator-option": "^7.12.1", - "browserslist": "^4.14.5", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", - "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", + "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", - "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", + "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.14.5", "regexpu-core": "^4.7.1" } }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" - } - }, "@babel/helper-define-polyfill-provider": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", - "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.13.0", @@ -194,683 +170,377 @@ "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", "semver": "^6.1.2" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/compat-data": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", - "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", - "dev": true - }, - "@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", - "dev": true, - "requires": { - "@babel/types": "^7.14.2", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - } - }, - "@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "dev": true, - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", - "dev": true - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/helper-explode-assignable-expression": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", - "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz", + "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.14.5" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" } }, "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", - "dev": true, + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.14.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" } }, "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", - "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz", + "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/types": "^7.12.1" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-wrap-function": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.14.5" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", - "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", + "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.14.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" }, "@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", - "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz", + "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-function-name": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", - "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz", + "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", - "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz", + "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.14.2.tgz", - "integrity": "sha512-LauAqDd/VjQDtae58QgBcEOE42NNP+jB2OE+XeC3KBI/E+BhhRjtr5viCIrj1hmu1YvrguLipIPRJZmS5yUcFw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.14.5.tgz", + "integrity": "sha512-LYz5nvQcvYeRVjui1Ykn28i+3aUiXwQ/3MGoEy0InTaz1pJo/lAzmIDXX+BQny/oufgHzJ6vnEEiXQ8KZjEVFg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.14.2", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-decorators": "^7.12.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", - "dev": true, - "requires": { - "@babel/types": "^7.14.2", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.3.tgz", - "integrity": "sha512-BnEfi5+6J2Lte9LeiL6TxLWdIlEv9Woacc1qXzXBgbikcOzMRM2Oya5XGg/f/ngotv1ej2A/b+3iJH8wbS1+lQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.14.3", - "@babel/helper-split-export-declaration": "^7.12.13" - } - }, - "@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "dev": true, - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz", - "integrity": "sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.14.2", - "@babel/types": "^7.14.2" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", - "dev": true - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-decorators": "^7.14.5" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-default-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.12.13.tgz", - "integrity": "sha512-idIsBT+DGXdOHL82U+8bwX4goHm/z10g8sGGrQroh+HCRcm7mDv/luaGdWJQMTuCX2FsdXS7X0Nyyzp4znAPJA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", + "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/plugin-syntax-export-default-from": "^7.12.13" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-default-from": "^7.14.5" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", - "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", - "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", - "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", - "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", - "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz", + "integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "@babel/compat-data": "^7.14.7", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.14.5" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", - "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", + "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", - "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", - "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", - "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", + "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-async-generators": { @@ -892,29 +562,30 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-decorators": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz", - "integrity": "sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.12.13" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - } + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.14.5.tgz", + "integrity": "sha512-c4sZMRWL4GSvP1EXy0woIP7m4jkVcEuG8R1TOZxPBPtp4FSM/kiPZub9UIs/Jrb5ZAOzvTUSGYrWsrSu1JvoPw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-dynamic-import": { @@ -927,20 +598,12 @@ } }, "@babel/plugin-syntax-export-default-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.12.13.tgz", - "integrity": "sha512-gVry0zqoums0hA+EniCYK3gABhjYSLX1dVuwYpPw9DrLNA4/GovXySHVg4FGRsZht09ON/5C2NVx3keq+qqVGQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", + "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-export-namespace-from": { @@ -953,20 +616,12 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz", - "integrity": "sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", + "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-import-meta": { @@ -988,12 +643,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", + "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -1050,531 +705,511 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-typescript": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz", - "integrity": "sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", - "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", - "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", + "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", - "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", - "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz", + "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-classes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", - "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz", + "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", - "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-destructuring": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", - "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", + "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", - "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", + "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", - "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", + "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", - "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", + "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.13.0.tgz", - "integrity": "sha512-EXAGFMJgSX8gxWD7PZtW/P6M+z74jpx3wm/+9pn+c2dOawPpBkUX7BrfyPvo6ZpXbgRIEuwgwDb/MGlKvu2pOg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", + "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-flow": "^7.12.13" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-flow": "^7.14.5" } }, "@babel/plugin-transform-for-of": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", - "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", + "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-function-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", - "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", - "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", - "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", - "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", + "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", - "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz", + "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", - "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz", + "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", - "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", + "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", - "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz", + "integrity": "sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1" + "@babel/helper-create-regexp-features-plugin": "^7.14.5" } }, "@babel/plugin-transform-new-target": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", - "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", + "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-object-super": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", - "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" } }, "@babel/plugin-transform-parameters": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", - "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", + "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", - "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", - "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.5.tgz", + "integrity": "sha512-07aqY1ChoPgIxsuDviptRpVkWCSbXWmzQqcgy65C6YSFOfPFvb/DX3bBRHh7pCd/PMEEYHYWUTSVkCbkVainYQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz", - "integrity": "sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.5.tgz", + "integrity": "sha512-7RylxNeDnxc1OleDm0F5Q/BSL+whYRbOAR+bwgCxIr0L32v7UFh/pz1DLMZideAUxKT6eMoS2zQH6fyODLEi8Q==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.12.10", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.12.1", - "@babel/types": "^7.12.12" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/plugin-transform-react-jsx-development": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz", - "integrity": "sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.14.5.tgz", + "integrity": "sha512-rdwG/9jC6QybWxVe2UVOa7q6cnTpw8JRRHOxntG/h6g/guAOe6AhtQHJuJh5FwmnXIT1bdm5vC2/5huV8ZOorQ==", "dev": true, "requires": { - "@babel/plugin-transform-react-jsx": "^7.12.12" + "@babel/plugin-transform-react-jsx": "^7.14.5" } }, "@babel/plugin-transform-react-pure-annotations": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz", - "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.14.5.tgz", + "integrity": "sha512-3X4HpBJimNxW4rhUy/SONPyNQHp5YRr0HhJdT2OH1BRp0of7u3Dkirc7x9FRJMKMqTBI079VZ1hzv7Ouuz///g==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-regenerator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", - "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", + "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", - "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", + "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-runtime": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz", - "integrity": "sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz", + "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "semver": "^5.5.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "semver": "^6.3.0" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", - "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", - "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", + "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", - "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", + "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-template-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", - "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", - "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", + "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-typescript": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz", - "integrity": "sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz", + "integrity": "sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-typescript": "^7.12.1" + "@babel/helper-create-class-features-plugin": "^7.14.6", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", - "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", + "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", - "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", + "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/preset-env": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", - "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz", + "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==", "dev": true, "requires": { - "@babel/compat-data": "^7.12.7", - "@babel/helper-compilation-targets": "^7.12.5", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.11", - "@babel/plugin-proposal-async-generator-functions": "^7.12.1", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", - "@babel/plugin-proposal-export-namespace-from": "^7.12.1", - "@babel/plugin-proposal-json-strings": "^7.12.1", - "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.7", - "@babel/plugin-proposal-object-rest-spread": "^7.12.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.7", - "@babel/plugin-proposal-private-methods": "^7.12.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.12.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/compat-data": "^7.14.7", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-async-generator-functions": "^7.14.7", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.14.5", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.14.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.14.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.12.1", - "@babel/plugin-transform-arrow-functions": "^7.12.1", - "@babel/plugin-transform-async-to-generator": "^7.12.1", - "@babel/plugin-transform-block-scoped-functions": "^7.12.1", - "@babel/plugin-transform-block-scoping": "^7.12.11", - "@babel/plugin-transform-classes": "^7.12.1", - "@babel/plugin-transform-computed-properties": "^7.12.1", - "@babel/plugin-transform-destructuring": "^7.12.1", - "@babel/plugin-transform-dotall-regex": "^7.12.1", - "@babel/plugin-transform-duplicate-keys": "^7.12.1", - "@babel/plugin-transform-exponentiation-operator": "^7.12.1", - "@babel/plugin-transform-for-of": "^7.12.1", - "@babel/plugin-transform-function-name": "^7.12.1", - "@babel/plugin-transform-literals": "^7.12.1", - "@babel/plugin-transform-member-expression-literals": "^7.12.1", - "@babel/plugin-transform-modules-amd": "^7.12.1", - "@babel/plugin-transform-modules-commonjs": "^7.12.1", - "@babel/plugin-transform-modules-systemjs": "^7.12.1", - "@babel/plugin-transform-modules-umd": "^7.12.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", - "@babel/plugin-transform-new-target": "^7.12.1", - "@babel/plugin-transform-object-super": "^7.12.1", - "@babel/plugin-transform-parameters": "^7.12.1", - "@babel/plugin-transform-property-literals": "^7.12.1", - "@babel/plugin-transform-regenerator": "^7.12.1", - "@babel/plugin-transform-reserved-words": "^7.12.1", - "@babel/plugin-transform-shorthand-properties": "^7.12.1", - "@babel/plugin-transform-spread": "^7.12.1", - "@babel/plugin-transform-sticky-regex": "^7.12.7", - "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/plugin-transform-typeof-symbol": "^7.12.10", - "@babel/plugin-transform-unicode-escapes": "^7.12.1", - "@babel/plugin-transform-unicode-regex": "^7.12.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.11", - "core-js-compat": "^3.8.0", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.14.5", + "@babel/plugin-transform-classes": "^7.14.5", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.7", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.14.5", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.14.5", + "@babel/plugin-transform-modules-systemjs": "^7.14.5", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.14.5", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.14.6", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.15.0", + "semver": "^6.3.0" } }, "@babel/preset-flow": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.13.13.tgz", - "integrity": "sha512-MDtwtamMifqq3R2mC7l3A3uFalUb3NH5TIBQWjN/epEPlZktcLq4se3J+ivckKrLMGsR7H9LW8+pYuIUN9tsKg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", + "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-option": "^7.12.17", - "@babel/plugin-transform-flow-strip-types": "^7.13.0" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-flow-strip-types": "^7.14.5" } }, "@babel/preset-modules": { @@ -1591,33 +1226,34 @@ } }, "@babel/preset-react": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.10.tgz", - "integrity": "sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.14.5.tgz", + "integrity": "sha512-XFxBkjyObLvBaAvkx1Ie95Iaq4S/GUEIrejyrntQ/VCMKUYvKLoyKxOBzJ2kjA3b6rC9/KL6KXfDC2GqvLiNqQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.12.1", - "@babel/plugin-transform-react-jsx": "^7.12.10", - "@babel/plugin-transform-react-jsx-development": "^7.12.7", - "@babel/plugin-transform-react-pure-annotations": "^7.12.1" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-react-display-name": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.5", + "@babel/plugin-transform-react-jsx-development": "^7.14.5", + "@babel/plugin-transform-react-pure-annotations": "^7.14.5" } }, "@babel/preset-typescript": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz", - "integrity": "sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz", + "integrity": "sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.1", - "@babel/plugin-transform-typescript": "^7.12.1" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.14.5" } }, "@babel/register": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.16.tgz", - "integrity": "sha512-dh2t11ysujTwByQjXNgJ48QZ2zcXKQVdV8s0TbeMI0flmtGWCdTwK9tJiACHXPLmncm5+ktNn/diojA45JE4jg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.14.5.tgz", + "integrity": "sha512-TjJpGz/aDjFGWsItRBQMOFTrmTI9tr79CHOK+KIvLeCkbxuOAk2M5QHjvruIMGoo9OuccMh5euplPzc5FjAKGg==", "dev": true, "requires": { "clone-deep": "^4.0.1", @@ -1625,121 +1261,48 @@ "make-dir": "^2.1.0", "pirates": "^4.0.0", "source-map-support": "^0.5.16" - }, - "dependencies": { - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", + "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" } }, @@ -1767,87 +1330,14 @@ "yargs": "16.2.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "color-convert": "^2.0.1" + "ms": "2.1.2" } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", - "dev": true } } }, @@ -1989,15 +1479,15 @@ "dev": true }, "@eslint/eslintrc": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz", - "integrity": "sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", - "globals": "^12.1.0", + "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", @@ -2006,12 +1496,12 @@ }, "dependencies": { "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" } }, "ignore": { @@ -2019,9 +1509,34 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, + "@figspec/components": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@figspec/components/-/components-0.1.9.tgz", + "integrity": "sha512-u6nKNCwRNFKlVofX91PmRyDj35bB7raRFWHOgoXiJNS4hR5qsJiz7tKXg8tx4W/qQsI/CmJTRZBdn6auGG3DWA==", + "dev": true, + "requires": { + "copy-to-clipboard": "^3.0.0", + "lit-element": "^2.4.0" + } + }, + "@figspec/react": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@figspec/react/-/react-0.1.6.tgz", + "integrity": "sha512-oi0JL8uIXgJ+PWRl4LDxJ7WWa80E3jdYmi6wsHAFDq1vT0rKuyhqimEJzCezIrHHz4fXKpNRO98TO7ccma6hjw==", + "dev": true, + "requires": { + "@figspec/components": "^0.1.1" + } + }, "@hapi/hoek": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", @@ -2029,14 +1544,31 @@ "dev": true }, "@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dev": true, "requires": { "@hapi/hoek": "^9.0.0" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2048,14 +1580,6 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, "@istanbuljs/schema": { @@ -2165,6 +1689,21 @@ "strip-ansi": "^6.0.0" }, "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2205,22 +1744,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2247,6 +1770,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true } } }, @@ -2360,25 +1889,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2387,6 +1897,25 @@ "requires": { "has-flag": "^4.0.0" } + }, + "v8-to-istanbul": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", + "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } } } }, @@ -2489,22 +2018,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2691,31 +2204,6 @@ "@loki/core": "^0.28.0", "aws-sdk": "^2.840.0", "debug": "^4.1.1" - }, - "dependencies": { - "aws-sdk": { - "version": "2.909.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.909.0.tgz", - "integrity": "sha512-aRr61EoW8FOLKwrPpfobyO4VuYVp0SmPXgZ1O4IOlN01k9cTdRmgZSbfhB3iECge9NMHoO5AqGPGS8dXY1BYLg==", - "dev": true, - "requires": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.15.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "uuid": "3.3.2", - "xml2js": "0.4.19" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - } } }, "@loki/target-chrome-core": { @@ -2746,10 +2234,21 @@ "wait-on": "^5.2.1" }, "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -2769,6 +2268,12 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -2783,6 +2288,36 @@ "requires": { "path-key": "^3.0.0" } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -2808,14 +2343,6 @@ "@loki/core": "^0.28.0", "debug": "^4.1.1", "ws": "^7.2.0" - }, - "dependencies": { - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "dev": true - } } }, "@loki/target-native-ios-simulator": { @@ -2915,6 +2442,15 @@ "source-map": "^0.5.0" } }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -3098,28 +2634,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -3160,14 +2696,14 @@ } }, "@octokit/core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.4.0.tgz", - "integrity": "sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.4.12", + "@octokit/request": "^5.6.0", "@octokit/request-error": "^2.0.5", "@octokit/types": "^6.0.3", "before-after-hook": "^2.2.0", @@ -3175,9 +2711,9 @@ } }, "@octokit/endpoint": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz", - "integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", "dev": true, "requires": { "@octokit/types": "^6.0.3", @@ -3194,29 +2730,29 @@ } }, "@octokit/graphql": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.2.tgz", - "integrity": "sha512-WmsIR1OzOr/3IqfG9JIczI8gMJUMzzyx5j0XXQ4YihHtKlQc+u35VpVoOXhlKAlaBntvry1WpAzPl/a+s3n89Q==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", "dev": true, "requires": { - "@octokit/request": "^5.3.0", + "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", "universal-user-agent": "^6.0.0" } }, "@octokit/openapi-types": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.2.1.tgz", - "integrity": "sha512-IHQJpLciwzwDvciLxiFj3IEV5VYn7lSVcj5cu0jbTwMfK4IG6/g8SPrVp3Le1VRzIiYSRcBzm1dA7vgWelYP3Q==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", + "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.13.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz", - "integrity": "sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", + "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", "dev": true, "requires": { - "@octokit/types": "^6.11.0" + "@octokit/types": "^6.18.0" } }, "@octokit/plugin-rest-endpoint-methods": { @@ -3230,14 +2766,14 @@ } }, "@octokit/request": { - "version": "5.4.15", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz", - "integrity": "sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.0.0", - "@octokit/types": "^6.7.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.1", "universal-user-agent": "^6.0.0" @@ -3252,9 +2788,9 @@ } }, "@octokit/request-error": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz", - "integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", "dev": true, "requires": { "@octokit/types": "^6.0.3", @@ -3263,12 +2799,12 @@ } }, "@octokit/types": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.16.0.tgz", - "integrity": "sha512-EktqSNq8EKXE82a7Vw33ozOEhFXIRik+rZHJTHAgVZRm/p2K5r5ecn5fVpRkLCm3CAVFwchRvt3yvtmfbt2LCQ==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", + "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", "dev": true, "requires": { - "@octokit/openapi-types": "^7.2.0" + "@octokit/openapi-types": "^8.2.1" } }, "@pmmmwh/react-refresh-webpack-plugin": { @@ -3299,6 +2835,215 @@ "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", "dev": true }, + "@radix-ui/primitive": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-0.1.0.tgz", + "integrity": "sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-compose-refs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz", + "integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-context": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.0.tgz", + "integrity": "sha512-o8h7SP6ePEBLC33BsHiuFqW898c+wiyBiY2ZC2xFJUUnHj1Z6XrQdZCNjm3/VuhljMkPrIA5xC4swVWBo/gzOA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-dialog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-0.1.0.tgz", + "integrity": "sha512-yy833v6mSkqlhdDR7R0+sZJZd5OyEzsjeJfAuJoWRMSW2/2S78vTUgk1sRTXzT+6unoQOQ9teevURNjwAfX0Ug==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "0.1.0", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-context": "0.1.0", + "@radix-ui/react-dismissable-layer": "0.1.0", + "@radix-ui/react-focus-guards": "0.1.0", + "@radix-ui/react-focus-scope": "0.1.0", + "@radix-ui/react-id": "0.1.0", + "@radix-ui/react-portal": "0.1.0", + "@radix-ui/react-presence": "0.1.0", + "@radix-ui/react-primitive": "0.1.0", + "@radix-ui/react-use-controllable-state": "0.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.4.0" + }, + "dependencies": { + "react-remove-scroll": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.4.3.tgz", + "integrity": "sha512-lGWYXfV6jykJwbFpsuPdexKKzp96f3RbvGapDSIdcyGvHb7/eqyn46C7/6h+rUzYar1j5mdU+XECITHXCKBk9Q==", + "requires": { + "react-remove-scroll-bar": "^2.1.0", + "react-style-singleton": "^2.1.0", + "tslib": "^1.0.0", + "use-callback-ref": "^1.2.3", + "use-sidecar": "^1.0.1" + } + }, + "react-remove-scroll-bar": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz", + "integrity": "sha512-UU9ZBP1wdMR8qoUs7owiVcpaPwsQxUDC2lypP6mmixaGlARZa7ZIBx1jcuObLdhMOvCsnZcvetOho0wzPa9PYg==", + "requires": { + "react-style-singleton": "^2.1.0", + "tslib": "^1.0.0" + } + }, + "react-style-singleton": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.1.1.tgz", + "integrity": "sha512-jNRp07Jza6CBqdRKNgGhT3u9umWvils1xsuMOjZlghBDH2MU0PL2WZor4PGYjXpnRCa9DQSlHMs/xnABWOwYbA==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^1.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "use-callback-ref": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", + "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==" + } + } + }, + "@radix-ui/react-dismissable-layer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.0.tgz", + "integrity": "sha512-xQSXEP7rHkAe0sY1Ggd9CS0IuYXhjks0e+mtPu6LgJBXhlOTDVj4MeJC8fKAP+H1sKMygcrEEagb6M5GXEDvzg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "0.1.0", + "@radix-ui/react-primitive": "0.1.0", + "@radix-ui/react-use-body-pointer-events": "0.1.0", + "@radix-ui/react-use-callback-ref": "0.1.0", + "@radix-ui/react-use-escape-keydown": "0.1.0" + } + }, + "@radix-ui/react-focus-guards": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-0.1.0.tgz", + "integrity": "sha512-kRx/swAjEfBpQ3ns7J3H4uxpXuWCqN7MpALiSDOXiyo2vkWv0L9sxvbpZeTulINuE3CGMzicVMuNc/VWXjFKOg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-focus-scope": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-0.1.0.tgz", + "integrity": "sha512-lquiYfEnkpqLDR9oO/h78OAY73jedZHVlBHJi2RZeSg3YM1UyyyGx+adZD+VWNphA/oEQG/RE5b7DteF4hhG8Q==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-primitive": "0.1.0", + "@radix-ui/react-use-callback-ref": "0.1.0" + } + }, + "@radix-ui/react-id": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-0.1.0.tgz", + "integrity": "sha512-SubMSz7rAtl6w8qZ9YBRbDe9GjW36JugBsc6aYqng8tFydvNtkuBMj86zN/x5QiomMo+r8ylBVvuWzRkS0WbBA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-portal": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-0.1.0.tgz", + "integrity": "sha512-HiSDaQVlhoZWvp5Wy0JPPojqo31Z3efs890oyYkpKgRDWDdMYHzEWYZxC7pB60a6c6yM5JzjJc0bP7o6bye+/Q==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "0.1.0", + "@radix-ui/react-use-layout-effect": "0.1.0" + } + }, + "@radix-ui/react-presence": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-0.1.0.tgz", + "integrity": "sha512-MIj5dywsSB1mWi7f9EqsxNoR5hfIScquYANbMdRmzxqNQzq2UrO8GEhOMXPo99YssdfpK9d0Pc9nLNwsFyq5Eg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0", + "@radix-ui/react-use-layout-effect": "0.1.0" + } + }, + "@radix-ui/react-primitive": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.0.tgz", + "integrity": "sha512-ydO24k5Cvry5RCMfm5OJNnIwvxSIUuUZ3Kf6bu1GaSsDfBKiv5JeuQkipURW28KlX7I85Jr/I02JlE+Ec4HmWA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "0.1.0" + } + }, + "@radix-ui/react-slot": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.0.tgz", + "integrity": "sha512-ZuvAUhSK9EAE42b3+K7k7w4nF1uF+Wd4bFj2OCE1aSiW3tgiu7ZU+J61m2+RIDps0WLu95PUx6eZrnpfqBXFRg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "0.1.0" + } + }, + "@radix-ui/react-use-body-pointer-events": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-body-pointer-events/-/react-use-body-pointer-events-0.1.0.tgz", + "integrity": "sha512-svPyoHCcwOq/vpWNEvdH/yD91vN9p8BtiozNQbjVmJRxQ/vS12zqk70AxTGWe+2ZKHq2sggpEQNTv1JHyVFlnQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "0.1.0" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz", + "integrity": "sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-controllable-state": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz", + "integrity": "sha512-zv7CX/PgsRl46a52Tl45TwqwVJdmqnlQEQhaYMz/yBOD2sx2gCkCFSoF/z9mpnYWmS6DTLNTg5lIps3fV6EnXg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "0.1.0" + } + }, + "@radix-ui/react-use-escape-keydown": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.0.tgz", + "integrity": "sha512-tDLZbTGFmvXaazUXXv8kYbiCcbAE8yKgng9s95d8fCO+Eundv0Jngbn/hKPhDDs4jj9ChwRX5cDDnlaN+ugYYQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "0.1.0" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz", + "integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, "@reach/auto-id": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.10.5.tgz", @@ -3412,47 +3157,52 @@ } }, "@react-spring/animated": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.1.1.tgz", - "integrity": "sha512-u8Assg5uySwqyoeb1f7eBAUSl8sleJTewdfhVi1EtcM9ngU2Snhcp6snF8NGxvf4gZp5z7v+Dfx3KdB2V8NnXQ==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.2.3.tgz", + "integrity": "sha512-xxYOxxrk4r+yy218lVnkR027GXGvHcadDnnXRW0l6atcL+1AGYwimMwIuvzlvnsVnyoK0YUABEeGjk9ENOrVMQ==", "requires": { - "@react-spring/shared": "~9.1.1", - "@react-spring/types": "~9.1.1" + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" } }, "@react-spring/core": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.1.1.tgz", - "integrity": "sha512-flHeLN56idxQ1YIpUYY1m3r2ZAM2xg7Zb/pHBFSCbnOKP7TtlhAAOfmrabERqaThmrqkFKiq9FjyF76d3OjE5g==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.2.3.tgz", + "integrity": "sha512-8qJbj0xjjoYGVqdmNd2bVaFzKSAwrMVLweHkaYJiTY6p0g7LhSdt5KSl1MjYA4Rj6S4wO1KgefAPK6mH6MtGtA==", "requires": { - "@react-spring/animated": "~9.1.1", - "@react-spring/shared": "~9.1.1", - "@react-spring/types": "~9.1.1" + "@react-spring/animated": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" } }, + "@react-spring/rafz": { + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.2.3.tgz", + "integrity": "sha512-ThBI3HWp1Y82uRSFVpoykwgM3M9s3SJD6ilKKp9C2OTPcGhWiRGt1IMjzKPwB+F1NX3psbPTt30Bev8WzA/DQQ==" + }, "@react-spring/shared": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.1.1.tgz", - "integrity": "sha512-GA9A9l5JxC50eDTDPu5IDUMhQ4MiBrXd3ZdlI6/wUCgAsZ1wPx77sxaccomxlUomRet0IUcXCEKcL1Flax7ZMQ==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.2.3.tgz", + "integrity": "sha512-MehdmKao1oUAwSEJo8BXOz1OGgsSav/dimD1Vz920hirShj9s/I4zKnWtkdK92xQ4n35D/xD3hATHkXbt/WSvg==", "requires": { - "@react-spring/types": "~9.1.1", - "rafz": "^0.1.14" + "@react-spring/rafz": "~9.2.0", + "@react-spring/types": "~9.2.0" } }, "@react-spring/types": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.1.1.tgz", - "integrity": "sha512-GaesYowey+nmDw/yhZ5jErEH2UaDl4jxax8aQtW5h3OpNu/QS8swoEn/jxQgffLb0n6gjsER7QyIx/dmZIWlyw==" + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.2.3.tgz", + "integrity": "sha512-G7AWUJavwsvvvprnYmqUXE5N1XKINktc8V72ipvkFTE3DD3GApYpX/ORNmieJljKJYvBSBzpRSIzk2qELUs30Q==" }, "@react-spring/web": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.1.1.tgz", - "integrity": "sha512-py4c/Agqz9Unf+Apame29XYTLqHnKXSwJA6Q44jcNtHRFMuRjIpCyhS13C1ZI5PcJT0g9b8CvtMQFiShne8wNQ==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.2.3.tgz", + "integrity": "sha512-dWRcgVDbO2UI9I03n/HVmCx9tY++Na+RwRzkzXv3E53BcFsjvnWGArnpj+xE/XgXiaII3ep2RmUj5jyYoukqGg==", "requires": { - "@react-spring/animated": "~9.1.1", - "@react-spring/core": "~9.1.1", - "@react-spring/shared": "~9.1.1", - "@react-spring/types": "~9.1.1" + "@react-spring/animated": "~9.2.0", + "@react-spring/core": "~9.2.0", + "@react-spring/shared": "~9.2.0", + "@react-spring/types": "~9.2.0" } }, "@samverschueren/stream-to-observable": { @@ -3504,17 +3254,17 @@ } }, "@storybook/addon-actions": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.2.9.tgz", - "integrity": "sha512-CkUYSMt+fvuHfWvtDzlhhaeQBCWlUo99xdL88JTsTml05P43bIHZNIRv2QJ8DwhHuxdIPeHKLmz9y/ymOagOnw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.3.3.tgz", + "integrity": "sha512-eanTjj3ww5kXD4l6ENmrsQCrnqiZOzvUpAr03dpoWgSGpYUbad33W2exBaj9qCDGp49a3SBnU2lsucnuZLYA/Q==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/client-api": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/core-events": "6.2.9", - "@storybook/theming": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/client-api": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/core-events": "6.3.3", + "@storybook/theming": "6.3.3", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", "global": "^4.4.0", @@ -3529,17 +3279,17 @@ } }, "@storybook/addon-backgrounds": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-6.2.9.tgz", - "integrity": "sha512-oPSdeoUuvaXshY5sQRagbYXpr6ZEVUuLhGYBnZTlvm19QMeNCXQE+rdlgzcgyafq4mc1FI/udE2MpJ1dhfS6pQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-6.3.3.tgz", + "integrity": "sha512-8bSv3bCz+gS4lSsICbvEpxubkOPdZK/4/oOsY6neyoAKXBm6A+PHB1PJosrmK3vZVey0d4CuKUZdpA2Q/pl9Fw==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/core-events": "6.2.9", - "@storybook/theming": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/core-events": "6.3.3", + "@storybook/theming": "6.3.3", "core-js": "^3.8.2", "global": "^4.4.0", "memoizerific": "^1.11.3", @@ -3549,25 +3299,25 @@ } }, "@storybook/addon-controls": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-6.2.9.tgz", - "integrity": "sha512-NvXAJ7I5U4CLxv4wL3/Ne9rehJlgnSmQlLIG/z6dg5zm7JIb48LT4IY6GzjlUP5LkjmO9KJ8gJC249uRt2iPBQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-6.3.3.tgz", + "integrity": "sha512-6oSl7hLvm2nWjv83JM4iU1sIJmaBIHJvWo1rKkyxknm/CUMZNs9YTh/TBQ5LjRemgIzO+Fq4ImJkBPY9oQbSWg==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/client-api": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/node-logger": "6.2.9", - "@storybook/theming": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/client-api": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/node-logger": "6.3.3", + "@storybook/theming": "6.3.3", "core-js": "^3.8.2", "ts-dedent": "^2.0.0" } }, "@storybook/addon-docs": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-6.2.9.tgz", - "integrity": "sha512-qOtwgiqI3LMqT0eXYNV6ykp7qSu0LQGeXxy3wOBGuDDqAizfgnAjomYEWGFcyKp5ahV7HCRCjxbixAklFPUmyw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-6.3.3.tgz", + "integrity": "sha512-8+Q+SmH4yR7sAClw1Zqh4lBm545j8OS8dTbcibXDyQV2hNBer0Mw6ANb8kG+zU5k+vVY3gerGGCyQhDROk2qoQ==", "dev": true, "requires": { "@babel/core": "^7.12.10", @@ -3579,19 +3329,20 @@ "@mdx-js/loader": "^1.6.22", "@mdx-js/mdx": "^1.6.22", "@mdx-js/react": "^1.6.22", - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/builder-webpack4": "6.2.9", - "@storybook/client-api": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/core": "6.2.9", - "@storybook/core-events": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/builder-webpack4": "6.3.3", + "@storybook/client-api": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/core": "6.3.3", + "@storybook/core-events": "6.3.3", "@storybook/csf": "0.0.1", - "@storybook/node-logger": "6.2.9", - "@storybook/postinstall": "6.2.9", - "@storybook/source-loader": "6.2.9", - "@storybook/theming": "6.2.9", + "@storybook/csf-tools": "6.3.3", + "@storybook/node-logger": "6.3.3", + "@storybook/postinstall": "6.3.3", + "@storybook/source-loader": "6.3.3", + "@storybook/theming": "6.3.3", "acorn": "^7.4.1", "acorn-jsx": "^5.3.1", "acorn-walk": "^7.2.0", @@ -3604,6 +3355,7 @@ "js-string-escape": "^1.0.1", "loader-utils": "^2.0.0", "lodash": "^4.17.20", + "p-limit": "^3.1.0", "prettier": "~2.2.1", "prop-types": "^15.7.2", "react-element-to-jsx-string": "^14.3.2", @@ -3614,15 +3366,6 @@ "util-deprecate": "^1.0.2" }, "dependencies": { - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -3642,40 +3385,51 @@ "emojis-list": "^3.0.0", "json5": "^2.1.2" } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } } } }, "@storybook/addon-essentials": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-6.2.9.tgz", - "integrity": "sha512-zXsV4e1TCkHyDwi7hew4h9eJfDW++f2BNKzTif+DAcjPUVFDp7yC17gLjS5IhOjcQk+db0UUlFSx/OrTxhy7Xw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-6.3.3.tgz", + "integrity": "sha512-ENwziIGaI0VLUFkqZ1Au0UsAKnRs6vRsjj9UcOpifTu6D1/u4dIsu6eyPmaKXm7rhe4z2+GObGasGJwlAyd8Ow==", "dev": true, "requires": { - "@storybook/addon-actions": "6.2.9", - "@storybook/addon-backgrounds": "6.2.9", - "@storybook/addon-controls": "6.2.9", - "@storybook/addon-docs": "6.2.9", - "@storybook/addon-toolbars": "6.2.9", - "@storybook/addon-viewport": "6.2.9", - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/node-logger": "6.2.9", + "@storybook/addon-actions": "6.3.3", + "@storybook/addon-backgrounds": "6.3.3", + "@storybook/addon-controls": "6.3.3", + "@storybook/addon-docs": "6.3.3", + "@storybook/addon-measure": "^2.0.0", + "@storybook/addon-toolbars": "6.3.3", + "@storybook/addon-viewport": "6.3.3", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/node-logger": "6.3.3", "core-js": "^3.8.2", "regenerator-runtime": "^0.13.7", + "storybook-addon-outline": "^1.4.1", "ts-dedent": "^2.0.0" } }, "@storybook/addon-links": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.2.9.tgz", - "integrity": "sha512-pBiL6EUZI3c9qtCqnGx3RXF46kAxGMdo4xDC2y3mM132W//DzxkzLZRe4ZhxxGwaLzTNlNrypZ6Li6WyIaPZ/w==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.3.3.tgz", + "integrity": "sha512-wBPSVJ/XBJ7UH2T8FdIHMw1GVlF39GaOIdfP1mhsEAYIUTUbUNXstZTPETaO1ggSp8eSRkUO1fVI0vOWPzUT3w==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/core-events": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/core-events": "6.3.3", "@storybook/csf": "0.0.1", - "@storybook/router": "6.2.9", + "@storybook/router": "6.3.3", "@types/qs": "^6.9.5", "core-js": "^3.8.2", "global": "^4.4.0", @@ -3683,44 +3437,41 @@ "qs": "^6.10.0", "regenerator-runtime": "^0.13.7", "ts-dedent": "^2.0.0" - }, - "dependencies": { - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } } }, + "@storybook/addon-measure": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-2.0.0.tgz", + "integrity": "sha512-ZhdT++cX+L9LwjhGYggvYUUVQH/MGn2rwbrAwCMzA/f2QTFvkjxzX8nDgMxIhaLCDC+gHIxfJG2wrWN0jkBr3g==", + "dev": true + }, "@storybook/addon-toolbars": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-6.2.9.tgz", - "integrity": "sha512-4WjIofN5npBPNZ8v1UhzPeATB9RnAWRH/y1AVS1HB+zl6Ku92o7aOMqVxs8zR1oSSmtkHh/rcUcpATFKjuofdw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-6.3.3.tgz", + "integrity": "sha512-y8TGt+S+qaxvesLDCFca4CfxwV+iGrETrMYATEG2gdWtQ66tZ7/JLUvaaJPyMMRj3aMiSQKQ9BCI8L4XRv5asA==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/client-api": "6.2.9", - "@storybook/components": "6.2.9", - "core-js": "^3.8.2" + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/client-api": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/theming": "6.3.3", + "core-js": "^3.8.2", + "regenerator-runtime": "^0.13.7" } }, "@storybook/addon-viewport": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-6.2.9.tgz", - "integrity": "sha512-IK2mu5njmfcAT967SJtBOY2B6NPMikySZga9QuaLdSpQxPd3vXKNMVG1CjnduMLeDaAoUlvlJISeEPbYGuE+1A==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-6.3.3.tgz", + "integrity": "sha512-i1i//FsNcGxDfo+gspC/CrBj1S552QSoNFyP5Qy1+nx1HFC3AXdMFOCL+GRVSvcd21snzllRe2oPFKsDtGMZ0g==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/core-events": "6.2.9", - "@storybook/theming": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/core-events": "6.3.3", + "@storybook/theming": "6.3.3", "core-js": "^3.8.2", "global": "^4.4.0", "memoizerific": "^1.11.3", @@ -3729,36 +3480,36 @@ } }, "@storybook/addons": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.2.9.tgz", - "integrity": "sha512-GnmEKbJwiN1jncN9NSA8CuR1i2XAlasPcl/Zn0jkfV9WitQeczVcJCPw86SGH84AD+tTBCyF2i9UC0KaOV1YBQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.3.3.tgz", + "integrity": "sha512-EAT/MXZcAsjt9zQ15oHCyjoOVSbeas/y8+tHXFAcJKF1leZzRamg4X0hFjJWDtm0+HZWfC9qX8Rl57bIwgMRmQ==", "dev": true, "requires": { - "@storybook/api": "6.2.9", - "@storybook/channels": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/core-events": "6.2.9", - "@storybook/router": "6.2.9", - "@storybook/theming": "6.2.9", + "@storybook/api": "6.3.3", + "@storybook/channels": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/core-events": "6.3.3", + "@storybook/router": "6.3.3", + "@storybook/theming": "6.3.3", "core-js": "^3.8.2", "global": "^4.4.0", "regenerator-runtime": "^0.13.7" } }, "@storybook/api": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.2.9.tgz", - "integrity": "sha512-okkA3HAScE9tGnYBrjTOcgzT+L1lRHNoEh3ZfGgh1u/XNEyHGNkj4grvkd6nX7BzRcYQ/l2VkcKCqmOjUnSkVQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.3.3.tgz", + "integrity": "sha512-Q8LxULCZF/ZUalamvNXLbT7x3bmH2She5TZFTyEINJF7W1UX5wluWnJ6RonAFxAK7GvLTf0wSHS7wzritJGMjg==", "dev": true, "requires": { "@reach/router": "^1.3.4", - "@storybook/channels": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/core-events": "6.2.9", + "@storybook/channels": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/core-events": "6.3.3", "@storybook/csf": "0.0.1", - "@storybook/router": "6.2.9", + "@storybook/router": "6.3.3", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.2.9", + "@storybook/theming": "6.3.3", "@types/reach__router": "^1.3.7", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", @@ -3768,7 +3519,7 @@ "qs": "^6.10.0", "regenerator-runtime": "^0.13.7", "store2": "^2.12.0", - "telejson": "^5.1.0", + "telejson": "^5.3.2", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" }, @@ -3782,22 +3533,13 @@ "core-js": "^3.6.5", "find-up": "^4.1.0" } - }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } } } }, "@storybook/builder-webpack4": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack4/-/builder-webpack4-6.2.9.tgz", - "integrity": "sha512-swECic1huVdj+B+iRJIQ8ds59HuPVE4fmhI+j/nhw0CQCsgAEKqDlOQVYEimW6nZX8GO4WxNm6tiiRzxixejbw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack4/-/builder-webpack4-6.3.3.tgz", + "integrity": "sha512-E/UAPwR/H4t77CNIKy4xHBZ8bJ/01dAGoXknRX8RKIhD+kS97R1IUDeTqxFa4raj9n1/FV+24no4Etf6+BJCfA==", "dev": true, "requires": { "@babel/core": "^7.12.10", @@ -3821,20 +3563,20 @@ "@babel/preset-env": "^7.12.11", "@babel/preset-react": "^7.12.10", "@babel/preset-typescript": "^7.12.7", - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/channel-postmessage": "6.2.9", - "@storybook/channels": "6.2.9", - "@storybook/client-api": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/core-common": "6.2.9", - "@storybook/core-events": "6.2.9", - "@storybook/node-logger": "6.2.9", - "@storybook/router": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/channel-postmessage": "6.3.3", + "@storybook/channels": "6.3.3", + "@storybook/client-api": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/core-common": "6.3.3", + "@storybook/core-events": "6.3.3", + "@storybook/node-logger": "6.3.3", + "@storybook/router": "6.3.3", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.2.9", - "@storybook/ui": "6.2.9", + "@storybook/theming": "6.3.3", + "@storybook/ui": "6.3.3", "@types/node": "^14.0.10", "@types/webpack": "^4.41.26", "autoprefixer": "^9.8.6", @@ -3854,14 +3596,14 @@ "global": "^4.4.0", "html-webpack-plugin": "^4.0.0", "pnp-webpack-plugin": "1.6.4", - "postcss": "^7.0.35", + "postcss": "^7.0.36", "postcss-flexbugs-fixes": "^4.2.1", "postcss-loader": "^4.2.0", "raw-loader": "^4.0.2", "react-dev-utils": "^11.0.3", "stable": "^0.1.8", "style-loader": "^1.3.0", - "terser-webpack-plugin": "^3.1.0", + "terser-webpack-plugin": "^4.2.3", "ts-dedent": "^2.0.0", "url-loader": "^4.1.1", "util-deprecate": "^1.0.2", @@ -3872,6 +3614,22 @@ "webpack-virtual-modules": "^0.2.2" }, "dependencies": { + "@babel/helper-define-polyfill-provider": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", + "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, "@storybook/semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", @@ -3894,37 +3652,22 @@ } } }, - "cacache": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.6.tgz", - "integrity": "sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==", + "@types/node": { + "version": "14.17.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", + "dev": true + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", + "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", "dev": true, "requires": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" + "@babel/helper-define-polyfill-provider": "^0.1.5", + "core-js-compat": "^3.8.1" } }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3946,12 +3689,6 @@ } } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3969,83 +3706,28 @@ "requires": { "p-limit": "^3.0.2" } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "terser-webpack-plugin": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz", - "integrity": "sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA==", - "dev": true, - "requires": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.2.1", - "p-limit": "^3.0.2", - "schema-utils": "^2.6.6", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.8.0", - "webpack-sources": "^1.4.3" - } } } }, "@storybook/channel-postmessage": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.2.9.tgz", - "integrity": "sha512-OqV+gLeeCHR0KExsIz0B7gD17Cjd9D+I75qnBsLWM9inWO5kc/WZ5svw8Bvjlcm6snWpvxUaT8L+svuqcPSmww==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.3.3.tgz", + "integrity": "sha512-IGDUMpq+nLTeVottYPwXyaeto/Li5VBpU6jZaiGMMaggwxAeLxjKyovv/cnKBQr/HXNO8xWl+SZfptonrS9abw==", "dev": true, "requires": { - "@storybook/channels": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/core-events": "6.2.9", + "@storybook/channels": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/core-events": "6.3.3", "core-js": "^3.8.2", "global": "^4.4.0", "qs": "^6.10.0", - "telejson": "^5.1.0" - }, - "dependencies": { - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } + "telejson": "^5.3.2" } }, "@storybook/channels": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.2.9.tgz", - "integrity": "sha512-6dC8Fb2ipNyOQXnUZMDeEUaJGH5DMLzyHlGLhVyDtrO5WR6bO8mQdkzf4+5dSKXgCBNX0BSkssXth4pDjn18rg==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.3.3.tgz", + "integrity": "sha512-S20bQKlQv7Fwq+1qM4ZoBN921NvuPF3HVPKemS3REN0gSoVPjN1Ur+kRLh7Q7mAo4AWFirD+2yqA2tU5ClTGMw==", "dev": true, "requires": { "core-js": "^3.8.2", @@ -4054,16 +3736,16 @@ } }, "@storybook/client-api": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.2.9.tgz", - "integrity": "sha512-aLvEUVkbvv6Qo/2mF4rFCecdqi2CGOUDdsV1a6EFIVS/9gXFdpirsOwKHo9qNjacGdWPlBYGCUcbrw+DvNaSFA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.3.3.tgz", + "integrity": "sha512-oKku+viz+fgxdLCBEYT31yM9khyLvrmicnQHA33MyMXUzhEwFlKO5aXHD4TF5ZeaGxZ8M1NSLAIz53O8QpPizg==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/channel-postmessage": "6.2.9", - "@storybook/channels": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/core-events": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/channel-postmessage": "6.3.3", + "@storybook/channels": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/core-events": "6.3.3", "@storybook/csf": "0.0.1", "@types/qs": "^6.9.5", "@types/webpack-env": "^1.16.0", @@ -4077,23 +3759,12 @@ "store2": "^2.12.0", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" - }, - "dependencies": { - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } } }, "@storybook/client-logger": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.2.9.tgz", - "integrity": "sha512-IfOQZuvpjh66qBInQCJOb9S0dTGpzZ/Cxlcvokp+PYt95KztaWN3mPm+HaDQCeRsrWNe0Bpm1zuickcJ6dBOXg==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.3.3.tgz", + "integrity": "sha512-eckaVBPYOLh5ZFWrcCS+JqXkIQMESpiR2IfmEBHpZFq8lHZRq/dpmfLnDM2HrGiRR5EvPn9/Hl9jIKLaVx3Yng==", "dev": true, "requires": { "core-js": "^3.8.2", @@ -4101,15 +3772,15 @@ } }, "@storybook/components": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.2.9.tgz", - "integrity": "sha512-hnV1MI2aB2g1sJ7NJphpxi7TwrMZQ/tpCJeHnkjmzyC6ez1MXqcBXGrEEdSXzRfAxjQTOEpu6H1mnns0xMP0Ag==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.3.3.tgz", + "integrity": "sha512-45XDLRTXdG2bfEILwMkENdknkyVLQrqchcVh7qm+wtZEXhbtIGoTxlXYPUST+xB6MF5AXZ0c8UTm2YMgV3v3FQ==", "dev": true, "requires": { "@popperjs/core": "^2.6.0", - "@storybook/client-logger": "6.2.9", + "@storybook/client-logger": "6.3.3", "@storybook/csf": "0.0.1", - "@storybook/theming": "6.2.9", + "@storybook/theming": "6.3.3", "@types/color-convert": "^2.0.0", "@types/overlayscrollbars": "^1.12.0", "@types/react-syntax-highlighter": "11.0.5", @@ -4118,12 +3789,12 @@ "fast-deep-equal": "^3.1.3", "global": "^4.4.0", "lodash": "^4.17.20", - "markdown-to-jsx": "^7.1.0", + "markdown-to-jsx": "^7.1.3", "memoizerific": "^1.11.3", "overlayscrollbars": "^1.13.1", "polished": "^4.0.5", "prop-types": "^15.7.2", - "react-colorful": "^5.0.1", + "react-colorful": "^5.1.2", "react-popper-tooltip": "^3.1.1", "react-syntax-highlighter": "^13.5.3", "react-textarea-autosize": "^8.3.0", @@ -4150,28 +3821,29 @@ } }, "@storybook/core": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-6.2.9.tgz", - "integrity": "sha512-pzbyjWvj0t8m0kR2pC9GQne4sZn7Y/zfcbm6/31CL+yhzOQjfJEj3n4ZFUlxikXqQJPg1aWfypfyaeaLL0QyuA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-6.3.3.tgz", + "integrity": "sha512-aJaix3DLQrGEUovSU0Ry64ZS+E66IgM/MqrlEjiKHU3ahDbZ35Ol9P1sl3saUUPkBozbid+/+zCN9Hw7vF6RdA==", "dev": true, "requires": { - "@storybook/core-client": "6.2.9", - "@storybook/core-server": "6.2.9" + "@storybook/core-client": "6.3.3", + "@storybook/core-server": "6.3.3" } }, "@storybook/core-client": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-6.2.9.tgz", - "integrity": "sha512-jW841J5lCe1Ub5ZMtzYPgCy/OUddFxxVYeHLZyuNxlH5RoiQQxbDpuFlzuZMYGuIzD6eZw+ANE4w5vW/y5oBfA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-6.3.3.tgz", + "integrity": "sha512-AP9LoHJSXwxLWtwJ9xcanhXaI74ehu4UG3HLqe4FdN7tjYR9IgS3nMzSVfN7WyuI4ixUeLUlRgrak0Ic54F0ng==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/channel-postmessage": "6.2.9", - "@storybook/client-api": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/core-events": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/channel-postmessage": "6.3.3", + "@storybook/client-api": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/core-events": "6.3.3", "@storybook/csf": "0.0.1", - "@storybook/ui": "6.2.9", + "@storybook/ui": "6.3.3", + "airbnb-js-shims": "^2.2.1", "ansi-to-html": "^0.6.11", "core-js": "^3.8.2", "global": "^4.4.0", @@ -4181,23 +3853,12 @@ "ts-dedent": "^2.0.0", "unfetch": "^4.2.0", "util-deprecate": "^1.0.2" - }, - "dependencies": { - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } } }, "@storybook/core-common": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.2.9.tgz", - "integrity": "sha512-ve0Qb4EMit8jGibfZBprmaU2i4LtpB4vSMIzD9nB1YeBmw2cGhHubtmayZ0TwcV3fPQhtYH9wwRWuWyzzHyQyw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.3.3.tgz", + "integrity": "sha512-LZrZW8MgNHg6jxSFZZ29za2JFN/TjKHuo+iu2iRZUnmgQJmdkSUloasrJDq/s3CHt7wjcsYMEMTE9HqUAvMhOw==", "dev": true, "requires": { "@babel/core": "^7.12.10", @@ -4221,7 +3882,7 @@ "@babel/preset-react": "^7.12.10", "@babel/preset-typescript": "^7.12.7", "@babel/register": "^7.12.1", - "@storybook/node-logger": "6.2.9", + "@storybook/node-logger": "6.3.3", "@storybook/semver": "^7.3.2", "@types/glob-base": "^0.3.0", "@types/micromatch": "^4.0.1", @@ -4250,6 +3911,22 @@ "webpack": "4" }, "dependencies": { + "@babel/helper-define-polyfill-provider": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", + "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, "@storybook/semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", @@ -4272,6 +3949,12 @@ } } }, + "@types/node": { + "version": "14.17.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4292,6 +3975,16 @@ "resolve": "^1.19.0" } }, + "babel-plugin-polyfill-corejs3": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", + "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.1.5", + "core-js-compat": "^3.8.1" + } + }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -4358,9 +4051,9 @@ } }, "fork-ts-checker-webpack-plugin": { - "version": "6.2.10", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.2.10.tgz", - "integrity": "sha512-HveFCHWSH2WlYU1tU3PkrupvW8lNFMTfH3Jk0TfC2mtktE9ibHGcifhCsCFvj+kqlDfNIlwmNLiNqR9jnSA7OQ==", + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.2.12.tgz", + "integrity": "sha512-BzXGIfM47q1WFwXsNLl22dQVMFwSBgldL07lvqRJFxgrhT76QQ3nri5PX01Rxfa2RYvv/hqACULO8K5gT8fFuA==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", @@ -4408,12 +4101,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -4423,16 +4110,6 @@ "minimist": "^1.2.5" } }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4451,27 +4128,6 @@ "p-limit": "^3.0.2" } }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, "schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", @@ -4495,73 +4151,53 @@ } }, "@storybook/core-events": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.2.9.tgz", - "integrity": "sha512-xQmbX/oYQK1QsAGN8hriXX5SUKOoTUe3L4dVaVHxJqy7MReRWJpprJmCpbAPJzWS6WCbDFfCM5kVEexHLOzJlQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.3.3.tgz", + "integrity": "sha512-Ym/Xna7GrCF0CbTkbejzuAw7LunZ158AT2AvGYMZujGBzunYG7MlfXVoS6YjUUt8vEmGHi8g6PdD6uij4IBY8A==", "dev": true, "requires": { "core-js": "^3.8.2" } }, "@storybook/core-server": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-6.2.9.tgz", - "integrity": "sha512-DzihO73pj1Ro0Y4tq9hjw2mLMUYeSRPrx7CndCOBxcTHCKQ8Kd7Dee3wJ49t5/19V7TW1+4lYR59GAy73FeOAQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-6.3.3.tgz", + "integrity": "sha512-NfT7627eO0thpfTOwJyMCoJtCVQIgzvjnZGjUpdT7onKYh3w8cB7w85HQAvAKaAQIPidciXR5RrwAZOKPfDA5g==", "dev": true, "requires": { - "@babel/core": "^7.12.10", - "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/preset-react": "^7.12.10", - "@storybook/addons": "6.2.9", - "@storybook/builder-webpack4": "6.2.9", - "@storybook/core-client": "6.2.9", - "@storybook/core-common": "6.2.9", - "@storybook/node-logger": "6.2.9", + "@storybook/builder-webpack4": "6.3.3", + "@storybook/core-client": "6.3.3", + "@storybook/core-common": "6.3.3", + "@storybook/csf-tools": "6.3.3", + "@storybook/manager-webpack4": "6.3.3", + "@storybook/node-logger": "6.3.3", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.2.9", - "@storybook/ui": "6.2.9", "@types/node": "^14.0.10", "@types/node-fetch": "^2.5.7", "@types/pretty-hrtime": "^1.0.0", "@types/webpack": "^4.41.26", - "airbnb-js-shims": "^2.2.1", - "babel-loader": "^8.2.2", "better-opn": "^2.1.1", "boxen": "^4.2.0", - "case-sensitive-paths-webpack-plugin": "^2.3.0", "chalk": "^4.1.0", "cli-table3": "0.6.0", "commander": "^6.2.1", + "compression": "^1.7.4", "core-js": "^3.8.2", "cpy": "^8.1.1", - "css-loader": "^3.6.0", "detect-port": "^1.3.0", - "dotenv-webpack": "^1.8.0", "express": "^4.17.1", - "file-loader": "^6.2.0", "file-system-cache": "^1.0.5", - "find-up": "^5.0.0", "fs-extra": "^9.0.1", - "global": "^4.4.0", - "html-webpack-plugin": "^4.0.0", + "globby": "^11.0.2", "ip": "^1.1.5", "node-fetch": "^2.6.1", - "pnp-webpack-plugin": "1.6.4", "pretty-hrtime": "^1.0.3", "prompts": "^2.4.0", - "read-pkg-up": "^7.0.1", "regenerator-runtime": "^0.13.7", - "resolve-from": "^5.0.0", "serve-favicon": "^2.5.0", - "style-loader": "^1.3.0", - "telejson": "^5.1.0", - "terser-webpack-plugin": "^3.1.0", "ts-dedent": "^2.0.0", - "url-loader": "^4.1.1", "util-deprecate": "^1.0.2", - "webpack": "4", - "webpack-dev-middleware": "^3.7.3", - "webpack-virtual-modules": "^0.2.2" + "webpack": "4" }, "dependencies": { "@storybook/semver": { @@ -4572,20 +4208,14 @@ "requires": { "core-js": "^3.6.5", "find-up": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - } } }, + "@types/node": { + "version": "14.17.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4595,31 +4225,6 @@ "color-convert": "^2.0.1" } }, - "cacache": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.6.tgz", - "integrity": "sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==", - "dev": true, - "requires": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -4630,12 +4235,6 @@ "supports-color": "^7.1.0" } }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4676,25 +4275,18 @@ "debug": "^2.6.0" } }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "dependencies": { - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - } + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" } }, "has-flag": { @@ -4703,18 +4295,164 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "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" + } + } + } + }, + "@storybook/csf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", + "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "@storybook/csf-tools": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.3.3.tgz", + "integrity": "sha512-w2BAkUjS1Wr8nuoppvkesgJ4H+qfxBIGogKuMDny4V9R5bCFT361p02ZCNsDEjtFWaeOire2vBm3bE7eUCvwMA==", + "dev": true, + "requires": { + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@babel/traverse": "^7.12.11", + "@babel/types": "^7.12.11", + "@mdx-js/mdx": "^1.6.22", + "@storybook/csf": "^0.0.1", + "core-js": "^3.8.2", + "fs-extra": "^9.0.1", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.20", + "prettier": "~2.2.1", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/manager-webpack4": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.3.3.tgz", + "integrity": "sha512-IUuC1SpcnE/IRPtJkFalbJdOa8gHvOkccxZW/DhJZi2QgfOvnwmErz8unX1VHkpcqHfoUWcjLYUbYVeYo0shfw==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/preset-react": "^7.12.10", + "@storybook/addons": "6.3.3", + "@storybook/core-client": "6.3.3", + "@storybook/core-common": "6.3.3", + "@storybook/node-logger": "6.3.3", + "@storybook/theming": "6.3.3", + "@storybook/ui": "6.3.3", + "@types/node": "^14.0.10", + "@types/webpack": "^4.41.26", + "babel-loader": "^8.2.2", + "case-sensitive-paths-webpack-plugin": "^2.3.0", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "css-loader": "^3.6.0", + "dotenv-webpack": "^1.8.0", + "express": "^4.17.1", + "file-loader": "^6.2.0", + "file-system-cache": "^1.0.5", + "find-up": "^5.0.0", + "fs-extra": "^9.0.1", + "html-webpack-plugin": "^4.0.0", + "node-fetch": "^2.6.1", + "pnp-webpack-plugin": "1.6.4", + "read-pkg-up": "^7.0.1", + "regenerator-runtime": "^0.13.7", + "resolve-from": "^5.0.0", + "style-loader": "^1.3.0", + "telejson": "^5.3.2", + "terser-webpack-plugin": "^4.2.3", + "ts-dedent": "^2.0.0", + "url-loader": "^4.1.1", + "util-deprecate": "^1.0.2", + "webpack": "4", + "webpack-dev-middleware": "^3.7.3", + "webpack-virtual-modules": "^0.2.2" + }, + "dependencies": { + "@types/node": { + "version": "14.17.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "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 + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4733,39 +4471,6 @@ "p-limit": "^3.0.2" } }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4774,39 +4479,13 @@ "requires": { "has-flag": "^4.0.0" } - }, - "terser-webpack-plugin": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz", - "integrity": "sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA==", - "dev": true, - "requires": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.2.1", - "p-limit": "^3.0.2", - "schema-utils": "^2.6.6", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.8.0", - "webpack-sources": "^1.4.3" - } } } }, - "@storybook/csf": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", - "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, "@storybook/node-logger": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.2.9.tgz", - "integrity": "sha512-ryRBChWZf1A5hOVONErJZosS25IdMweoMVFAUAcj91iC0ynoSA6YL2jmoE71jQchxEXEgkDeRkX9lR/GlqFGZQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.3.3.tgz", + "integrity": "sha512-YmH8jZok49HPHuG/fkKgYTrHd1jxwwjhyy/cJvzW+gr3V+4rTLv0EqVe45j2LEB8+9hEw6NyMTNzn9j1eEZvIg==", "dev": true, "requires": { "@types/npmlog": "^4.1.2", @@ -4868,27 +4547,28 @@ } }, "@storybook/postinstall": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-6.2.9.tgz", - "integrity": "sha512-HjAjXZV+WItonC7lVrfrUsQuRFZNz1g1lE0GgsEK2LdC5rAcD/JwJxjiWREwY+RGxKL9rpWgqyxVQajpIJRjhA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-6.3.3.tgz", + "integrity": "sha512-J0r3haDjCRjj6jCYqTokOzXP6Udyq45HGXvjb9usY4sOH6c18fuAarcD2VmfdYJ3LqOl15U0p8zCW1QDnpvwXw==", "dev": true, "requires": { "core-js": "^3.8.2" } }, "@storybook/react": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-6.2.9.tgz", - "integrity": "sha512-glvw+o/Vek2oapYIXCYDK6gm3cuSnx0XdOpiJVcXk3KLb8JfLbdzGYYp6dcWUbyOBqGcGFRpXIgMmkcwgn+fvQ==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-6.3.3.tgz", + "integrity": "sha512-dJjEugouMw0TdL/4R/lRKA6kdmS3NUmK5LfZeNyO9s/iygYwIdHowh1x5vzQO2ZUaaTKnI4OZ3GNxs+ULjUEPg==", "dev": true, "requires": { "@babel/preset-flow": "^7.12.1", "@babel/preset-react": "^7.12.10", "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", - "@storybook/addons": "6.2.9", - "@storybook/core": "6.2.9", - "@storybook/core-common": "6.2.9", - "@storybook/node-logger": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/core": "6.3.3", + "@storybook/core-common": "6.3.3", + "@storybook/node-logger": "6.3.3", + "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", "@storybook/semver": "^7.3.2", "@types/webpack-env": "^1.16.0", "babel-plugin-add-react-displayname": "^0.0.5", @@ -4899,7 +4579,6 @@ "lodash": "^4.17.20", "prop-types": "^15.7.2", "react-dev-utils": "^11.0.3", - "react-docgen-typescript-plugin": "^0.6.2", "react-refresh": "^0.8.3", "read-pkg-up": "^7.0.1", "regenerator-runtime": "^0.13.7", @@ -4919,14 +4598,60 @@ } } }, + "@storybook/react-docgen-typescript-plugin": { + "version": "1.0.2-canary.253f8c1.0", + "resolved": "https://registry.npmjs.org/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.253f8c1.0.tgz", + "integrity": "sha512-mmoRG/rNzAiTbh+vGP8d57dfcR2aP+5/Ll03KKFyfy5FqWFm/Gh7u27ikx1I3LmVMI8n6jh5SdWMkMKon7/tDw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "endent": "^2.0.1", + "find-cache-dir": "^3.3.1", + "flat-cache": "^3.0.4", + "micromatch": "^4.0.2", + "react-docgen-typescript": "^2.0.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, "@storybook/router": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.2.9.tgz", - "integrity": "sha512-7Bn1OFoItCl8whXRT8N1qp1Lky7kzXJ3aslWp5E8HcM8rxh4OYXfbaeiyJEJxBTGC5zxgY+tAEXHFjsAviFROg==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.3.3.tgz", + "integrity": "sha512-vS04DWSod9YvFIVSxvWbSc7Bkn/1kwpg+mnOeCSZxs50e6LflZ+5tXqAvnobeEnceTH/rjtbQBVvarx0ZfDD3g==", "dev": true, "requires": { "@reach/router": "^1.3.4", - "@storybook/client-logger": "6.2.9", + "@storybook/client-logger": "6.3.3", "@types/reach__router": "^1.3.7", "core-js": "^3.8.2", "fast-deep-equal": "^3.1.3", @@ -4935,27 +4660,16 @@ "memoizerific": "^1.11.3", "qs": "^6.10.0", "ts-dedent": "^2.0.0" - }, - "dependencies": { - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } } }, "@storybook/source-loader": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.2.9.tgz", - "integrity": "sha512-cx499g7BG2oeXvRFx45r0W0p2gKEy/e88WsUFnqqfMKZBJ8K0R/lx5DI0l1hq+TzSrE6uGe0/uPlaLkJNIro7g==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.3.3.tgz", + "integrity": "sha512-J8ZscrKcuXPnw4HL/NYxnM5EZmv6IO1WyRAUEd7FCNlcA2E0AxuZH1WB8/l8mL5Pdsj4gISdRG3vbOFa9CwsEQ==", "dev": true, "requires": { - "@storybook/addons": "6.2.9", - "@storybook/client-logger": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/client-logger": "6.3.3", "@storybook/csf": "0.0.1", "core-js": "^3.8.2", "estraverse": "^5.2.0", @@ -4995,15 +4709,15 @@ } }, "@storybook/theming": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.2.9.tgz", - "integrity": "sha512-183oJW7AD7Fhqg5NT4ct3GJntwteAb9jZnQ6yhf9JSdY+fk8OhxRbPf7ov0au2gYACcGrWDd9K5pYQsvWlP5gA==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.3.3.tgz", + "integrity": "sha512-+V6aDZhzesYgiRe5hb8AAmLIh2GzIDTU6N2ssVuJQkujv6XE9uiL2hfORRChVm/dKPgTr84vX2jnJ+1317iCEg==", "dev": true, "requires": { "@emotion/core": "^10.1.1", "@emotion/is-prop-valid": "^0.8.6", "@emotion/styled": "^10.0.27", - "@storybook/client-logger": "6.2.9", + "@storybook/client-logger": "6.3.3", "core-js": "^3.8.2", "deep-object-diff": "^1.1.0", "emotion-theming": "^10.0.27", @@ -5012,32 +4726,24 @@ "polished": "^4.0.5", "resolve-from": "^5.0.0", "ts-dedent": "^2.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, "@storybook/ui": { - "version": "6.2.9", - "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-6.2.9.tgz", - "integrity": "sha512-jq2xmw3reIqik/6ibUSbNKGR+Xvr9wkAEwexiOl+5WQ5BeYJpw4dmDmsFQf+SQuWaSEUUPolbzkakRQM778Kdg==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-6.3.3.tgz", + "integrity": "sha512-zDWR8TEjnuGwVMEb1rFZ3XCAMApb00VBR1PIxN23yemizk6hWLfJvOGYGWEyqjiknS10eF/iMVv936V35Pr9Qw==", "dev": true, "requires": { "@emotion/core": "^10.1.1", - "@storybook/addons": "6.2.9", - "@storybook/api": "6.2.9", - "@storybook/channels": "6.2.9", - "@storybook/client-logger": "6.2.9", - "@storybook/components": "6.2.9", - "@storybook/core-events": "6.2.9", - "@storybook/router": "6.2.9", + "@storybook/addons": "6.3.3", + "@storybook/api": "6.3.3", + "@storybook/channels": "6.3.3", + "@storybook/client-logger": "6.3.3", + "@storybook/components": "6.3.3", + "@storybook/core-events": "6.3.3", + "@storybook/router": "6.3.3", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.2.9", + "@storybook/theming": "6.3.3", "@types/markdown-to-jsx": "^6.11.3", "copy-to-clipboard": "^3.3.1", "core-js": "^3.8.2", @@ -5078,21 +4784,6 @@ "prop-types": "^15.6.2", "unquote": "^1.1.0" } - }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true } } }, @@ -5201,1933 +4892,33 @@ "@tlon/indigo-dark": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@tlon/indigo-dark/-/indigo-dark-1.0.6.tgz", - "integrity": "sha512-/c+3/aC+gSnLHiLwTdje7pYS84ZAR3zyMJhp2mT9BIPtk7ek/EGsrrugZjVJxeKXqy+mQpFD5TXktgAEh0Ko1A==", - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", - "requires": { - "@babel/types": "^7.14.2", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.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==", - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - }, - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "requires": { - "@emotion/memoize": "0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" - }, - "@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "@types/react": { - "version": "17.0.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.6.tgz", - "integrity": "sha512-u/TtPoF/hrvb63LdukET6ncaplYsvCvmkceasx8oG84/ZCsoLxz9Z/raPBP4lTAiWW1Jb889Y9svHmv8R26dWw==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - }, - "dependencies": { - "csstype": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" - } - } - }, - "@types/react-native": { - "version": "0.64.5", - "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.64.5.tgz", - "integrity": "sha512-k0r8MnQX7UFboZDvMKLov26gFLXKrNgLhCfSVhjaZ6wMUofKijxvee7/wgfAqtT2zS5FR4an4+qn0r72SCbw3g==", - "requires": { - "@types/react": "*" - } - }, - "@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" - }, - "@types/styled-components": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-4.4.3.tgz", - "integrity": "sha512-U0udeNOZBfUkJycmGJwmzun0FBt11rZy08weVQmE2xfUNAbX8AGOEWxWna2d+qAUKxKgMlcG+TZT0+K2FfDcnQ==", - "requires": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "@types/react-native": "*", - "csstype": "^2.2.0" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" - }, - "babel-plugin-styled-components": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", - "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-module-imports": "^7.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" - }, - "css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "csstype": { - "version": "2.6.17", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", - "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "esbuild": { - "version": "0.6.34", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.6.34.tgz", - "integrity": "sha512-InRdL/Q96pUucPqovJzvuLhquZr6jOn81FDVwFjCKz1rYKIm9OdOC+7Fs4vr6x48vKBl5LzKgtjU39BUpO636A==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "requires": { - "semver-regex": "^3.1.2" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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==" - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, - "npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "requires": { - "path-key": "^3.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "requires": { - "find-up": "^5.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "requires": { - "semver-compare": "^1.0.0" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==" - }, - "pretty-quick": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.2.tgz", - "integrity": "sha512-aLb6vtOTEfJDwi1w+MBTeE20GwPVUYyn6IqNg6TtGpiOB1W3y6vKcsGFjqGeaaEtQgMLSPXTWONqh33UBuwG8A==", - "requires": { - "chalk": "^2.4.2", - "execa": "^2.1.0", - "find-up": "^4.1.0", - "ignore": "^5.1.4", - "mri": "^1.1.4", - "multimatch": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.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==", - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.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==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "styled-components": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.0.tgz", - "integrity": "sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - } - } + "integrity": "sha512-/c+3/aC+gSnLHiLwTdje7pYS84ZAR3zyMJhp2mT9BIPtk7ek/EGsrrugZjVJxeKXqy+mQpFD5TXktgAEh0Ko1A==" }, "@tlon/indigo-light": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@tlon/indigo-light/-/indigo-light-1.0.7.tgz", - "integrity": "sha512-xO8hj2Ak6cEYe2QCM3w7UuaSB8ubg6G0G6/OkPVMVrz6b5ztccZmkbmYCYJ/Ot6976lGzKFsWFKRUhwRgCHfHQ==", - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", - "requires": { - "@babel/types": "^7.14.2", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "requires": { - "@babel/types": "^7.13.12" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.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==", - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - }, - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "requires": { - "@emotion/memoize": "0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" - }, - "@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "@types/react": { - "version": "17.0.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.6.tgz", - "integrity": "sha512-u/TtPoF/hrvb63LdukET6ncaplYsvCvmkceasx8oG84/ZCsoLxz9Z/raPBP4lTAiWW1Jb889Y9svHmv8R26dWw==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - }, - "dependencies": { - "csstype": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" - } - } - }, - "@types/react-native": { - "version": "0.64.5", - "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.64.5.tgz", - "integrity": "sha512-k0r8MnQX7UFboZDvMKLov26gFLXKrNgLhCfSVhjaZ6wMUofKijxvee7/wgfAqtT2zS5FR4an4+qn0r72SCbw3g==", - "requires": { - "@types/react": "*" - } - }, - "@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" - }, - "@types/styled-components": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-4.4.3.tgz", - "integrity": "sha512-U0udeNOZBfUkJycmGJwmzun0FBt11rZy08weVQmE2xfUNAbX8AGOEWxWna2d+qAUKxKgMlcG+TZT0+K2FfDcnQ==", - "requires": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "@types/react-native": "*", - "csstype": "^2.2.0" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" - }, - "babel-plugin-styled-components": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", - "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.0.0", - "@babel/helper-module-imports": "^7.0.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" - }, - "css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "csstype": { - "version": "2.6.17", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", - "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "esbuild": { - "version": "0.6.34", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.6.34.tgz", - "integrity": "sha512-InRdL/Q96pUucPqovJzvuLhquZr6jOn81FDVwFjCKz1rYKIm9OdOC+7Fs4vr6x48vKBl5LzKgtjU39BUpO636A==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "requires": { - "semver-regex": "^3.1.2" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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==" - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mri": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", - "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, - "npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "requires": { - "path-key": "^3.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==" - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "requires": { - "find-up": "^5.0.0" - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "requires": { - "semver-compare": "^1.0.0" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==" - }, - "pretty-quick": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.2.tgz", - "integrity": "sha512-aLb6vtOTEfJDwi1w+MBTeE20GwPVUYyn6IqNg6TtGpiOB1W3y6vKcsGFjqGeaaEtQgMLSPXTWONqh33UBuwG8A==", - "requires": { - "chalk": "^2.4.2", - "execa": "^2.1.0", - "find-up": "^4.1.0", - "ignore": "^5.1.4", - "mri": "^1.1.4", - "multimatch": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.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==", - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.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==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "semver-regex": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz", - "integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==" - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "styled-components": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.0.tgz", - "integrity": "sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - } - } + "integrity": "sha512-xO8hj2Ak6cEYe2QCM3w7UuaSB8ubg6G0G6/OkPVMVrz6b5ztccZmkbmYCYJ/Ot6976lGzKFsWFKRUhwRgCHfHQ==" }, "@tlon/indigo-react": { - "version": "1.2.23", - "resolved": "https://registry.npmjs.org/@tlon/indigo-react/-/indigo-react-1.2.23.tgz", - "integrity": "sha512-RH9106bWwRjLm91vnVRmdtPeXNg0YujsaBNwPt7Wsezj1IKVJKabGu50dRY7bovfBbiE5JhBZzA3lw3LABfj/w==", + "version": "1.2.25", + "resolved": "https://registry.npmjs.org/@tlon/indigo-react/-/indigo-react-1.2.25.tgz", + "integrity": "sha512-4K0MeGqDK6OnqEDq2AHGHNhX4+owqCzhDFCzd81HPwyYy9x6wZB+z+iI36xl+P6Fwhl0I2fIKMG9ioiA1vbiLQ==", "requires": { "@reach/menu-button": "^0.10.5", "react": "^16.13.1", "tslib": "^2.0.1" + }, + "dependencies": { + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + } } }, "@tlon/sigil-js": { @@ -7146,16 +4937,10 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, "@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "version": "7.1.15", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", + "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -7166,18 +4951,18 @@ } }, "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -7185,18 +4970,18 @@ } }, "@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.1.tgz", + "integrity": "sha512-DomsDK/nX3XXHs6jlQ8/YYE6jZAuhmoGAFfcYi1h1jbBNGS7Efdx74FKLTO3HCCyLqQyLlNbql87xqa7C3M/FQ==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, "@types/braces": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz", - "integrity": "sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.1.tgz", + "integrity": "sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==", "dev": true }, "@types/color-convert": { @@ -7215,9 +5000,9 @@ "dev": true }, "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, "requires": { "@types/minimatch": "*", @@ -7240,18 +5025,18 @@ } }, "@types/hast": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz", - "integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.2.tgz", + "integrity": "sha512-Op5W7jYgZI7AWKY5wQ0/QNMzQM7dGQPyW1rXKNiymVCy5iTfdPuGu4HhYNOM2sIv8gUfIuIdcYlXmAepwaowow==", "dev": true, "requires": { "@types/unist": "*" } }, "@types/history": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", - "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", + "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==", "dev": true }, "@types/hoist-non-react-statics": { @@ -7265,9 +5050,9 @@ } }, "@types/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz", + "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==", "dev": true }, "@types/is-function": { @@ -7292,23 +5077,23 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" } }, "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" }, "@types/lodash": { - "version": "4.14.168", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", - "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", "dev": true }, "@types/markdown-to-jsx": { @@ -7321,45 +5106,45 @@ } }, "@types/mdast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", - "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.4.tgz", + "integrity": "sha512-gIdhbLDFlspL53xzol2hVzrXAbzt71erJHoOwQZWssjaiouOotf03lNtMmFm9VfFkvnLWccSVjUAZGQ5Kqw+jA==", "dev": true, "requires": { "@types/unist": "*" } }, "@types/micromatch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/micromatch/-/micromatch-4.0.1.tgz", - "integrity": "sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==", "dev": true, "requires": { "@types/braces": "*" } }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, "@types/minimist": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", - "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, "@types/node": { - "version": "14.14.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", - "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.0.tgz", + "integrity": "sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg==", "dev": true }, "@types/node-fetch": { - "version": "2.5.10", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz", - "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==", + "version": "2.5.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.11.tgz", + "integrity": "sha512-2upCKaqVZETDRb8A2VTaRymqFBEgH8u6yr96b/u3+1uQEPDRo3mJLEiPk7vdXBHRtjwkjqzFYMJXrt0Z9QsYjQ==", "dev": true, "requires": { "@types/node": "*", @@ -7397,9 +5182,9 @@ "dev": true }, "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.1.tgz", + "integrity": "sha512-NVkb4p4YjI8E3O6+1m8I+8JlMpFZwfSbPGdaw0wXuyPRTEz0SLKwBUWNSO7Maoi8tQMPC8JLZNWkrcKPI7/sLA==", "dev": true }, "@types/pretty-hrtime": { @@ -7421,37 +5206,38 @@ "dev": true }, "@types/reach__router": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.7.tgz", - "integrity": "sha512-cyBEb8Ef3SJNH5NYEIDGPoMMmYUxROatuxbICusVRQIqZUB85UCt6R2Ok60tKS/TABJsJYaHyNTW3kqbpxlMjg==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.8.tgz", + "integrity": "sha512-cjjT0FPdwuvhLWpCDt2WCh4sdBqNzJe3XhxXmRQGsY3IvT58M8sE4E7A0QaFYuJs3ar+McSJTiJxdYKWAXbBhw==", "dev": true, "requires": { "@types/react": "*" } }, "@types/react": { - "version": "16.14.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.2.tgz", - "integrity": "sha512-BzzcAlyDxXl2nANlabtT4thtvbbnhee8hMmH/CcJrISDBVcJS1iOsP1f0OAgSdGE0MsY9tqcrb9YoZcOFv9dbQ==", + "version": "16.14.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.10.tgz", + "integrity": "sha512-QadBsMyF6ldjEAXEhsmEW/L0uBDJT8yw7Qoe5sRnEKVrzMkiYoJwqoL5TKJOlArsn/wvIJM/XdVzkdL6+AS64Q==", "dev": true, "requires": { "@types/prop-types": "*", + "@types/scheduler": "*", "csstype": "^3.0.2" } }, "@types/react-dom": { - "version": "16.9.10", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.10.tgz", - "integrity": "sha512-ItatOrnXDMAYpv6G8UCk2VhbYVTjZT9aorLtA/OzDN9XJ2GKcfam68jutoAcILdRjsRUO8qb7AmyObF77Q8QFw==", + "version": "16.9.13", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.13.tgz", + "integrity": "sha512-34Hr3XnmUSJbUVDxIw/e7dhQn2BJZhJmlAaPyPwfTQyuVS9mV/CeyghFcXyvkJXxI7notQJz8mF8FeCVvloJrA==", "dev": true, "requires": { "@types/react": "^16" } }, "@types/react-router": { - "version": "5.1.11", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.11.tgz", - "integrity": "sha512-ofHbZMlp0Y2baOHgsWBQ4K3AttxY61bDMkwTiBOkPg7U6C/3UwwB5WaIx28JmSVi/eX3uFEMRo61BV22fDQIvg==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.15.tgz", + "integrity": "sha512-z3UlMG/x91SFEVmmvykk9FLTliDvfdIUky4k2rCfXWQ0NKbrP8o9BTCaCTPuYsB8gDkUnUmkcA2vYlm2DR+HAA==", "dev": true, "requires": { "@types/history": "*", @@ -7478,6 +5264,12 @@ "@types/react": "*" } }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -7485,15 +5277,15 @@ "dev": true }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/styled-components": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.7.tgz", - "integrity": "sha512-BJzPhFygYspyefAGFZTZ/8lCEY4Tk+Iqktvnko3xmJf9LrLqs3+grxPeU3O0zLl6yjbYBopD0/VikbHgXDbJtA==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.11.tgz", + "integrity": "sha512-u8g3bSw9KUiZY+S++gh+LlURGraqBe3MC5I5dygrNjGDHWWQfsmZZRTJ9K9oHU2CqWtxChWmJkDI/gp+TZPQMw==", "dev": true, "requires": { "@types/hoist-non-react-statics": "*", @@ -7502,33 +5294,33 @@ } }, "@types/styled-system": { - "version": "5.1.10", - "resolved": "https://registry.npmjs.org/@types/styled-system/-/styled-system-5.1.10.tgz", - "integrity": "sha512-OmVjC9OzyUckAgdavJBc+t5oCJrNXTlzWl9vo2x47leqpX1REq2qJC49SEtzbu1OnWSzcD68Uq3Aj8TeX+Kvtg==", + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@types/styled-system/-/styled-system-5.1.12.tgz", + "integrity": "sha512-7x4BYKKfK9QewfsFC2x5r9BK/OrfX+JF/1P21jKPMHruawDw9gvG7bTZgTVk6YkzDO2JUlsk4i8hdiAepAhD0g==", "dev": true, "requires": { "csstype": "^3.0.2" } }, "@types/tapable": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz", - "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", + "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==", "dev": true }, "@types/uglify-js": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.1.tgz", - "integrity": "sha512-7npvPKV+jINLu1SpSYVWG8KvyJBhBa8tmzMMdDoVc2pWUYHN8KIXlPJhjJ4LT97c4dXJA2SHL/q6ADbDriZN+Q==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", + "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", "dev": true, "requires": { "source-map": "^0.6.1" } }, "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==" }, "@types/warning": { "version": "3.0.0", @@ -7536,29 +5328,29 @@ "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=" }, "@types/webpack": { - "version": "4.41.26", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz", - "integrity": "sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA==", + "version": "4.41.30", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.30.tgz", + "integrity": "sha512-GUHyY+pfuQ6haAfzu4S14F+R5iGRwN6b2FRNJY7U0NilmFAqbsOfK6j1HwuLBAqwRIT+pVdNDJGJ6e8rpp0KHA==", "dev": true, "requires": { - "@types/anymatch": "*", "@types/node": "*", - "@types/tapable": "*", + "@types/tapable": "^1", "@types/uglify-js": "*", "@types/webpack-sources": "*", + "anymatch": "^3.0.0", "source-map": "^0.6.0" } }, "@types/webpack-env": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.0.tgz", - "integrity": "sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.2.tgz", + "integrity": "sha512-vKx7WNQNZDyJveYcHAm9ZxhqSGLYwoyLhrHjLBOkw3a7cT76sTdjgtwyijhk1MaHyRIuSztcVwrUOO/NEu68Dw==", "dev": true }, "@types/webpack-sources": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", - "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz", + "integrity": "sha512-MjM1R6iuw8XaVbtkCBz0N349cyqBjJHCbQiOeppe3VBeFvxqs74RKHAVt9LkxTnUWc7YLZOEsUfPUnmK6SBPKQ==", "dev": true, "requires": { "@types/node": "*", @@ -7575,18 +5367,18 @@ } }, "@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@types/yoga-layout": { @@ -7596,31 +5388,30 @@ "dev": true }, "@types/yup": { - "version": "0.29.11", - "resolved": "https://registry.npmjs.org/@types/yup/-/yup-0.29.11.tgz", - "integrity": "sha512-9cwk3c87qQKZrT251EDoibiYRILjCmxBvvcb4meofCmx1vdnNcR9gyildy5vOHASpOKMsn42CugxUvcwK5eu1g==", + "version": "0.29.12", + "resolved": "https://registry.npmjs.org/@types/yup/-/yup-0.29.12.tgz", + "integrity": "sha512-fA7bXyBzWEAgOwX2SD/5/iaZY/4In0EvJEzFmBWzaGNF4vxr8d5iOFUMFBpL4cMEmlSx2wW9ginJNnoZjE/vOg==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.0.tgz", - "integrity": "sha512-DJgdGZW+8CFUTz5C/dnn4ONcUm2h2T0itWD85Ob5/V27Ndie8hUoX5HKyGssvR8sUMkAIlUc/AMK67Lqa3kBIQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz", + "integrity": "sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.15.0", - "@typescript-eslint/scope-manager": "4.15.0", - "debug": "^4.1.1", + "@typescript-eslint/experimental-utils": "4.28.2", + "@typescript-eslint/scope-manager": "4.28.2", + "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "dependencies": { "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -7629,88 +5420,78 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.0.tgz", - "integrity": "sha512-V4vaDWvxA2zgesg4KPgEGiomWEBpJXvY4ZX34Y3qxK8LUm5I87L+qGIOTd9tHZOARXNRt9pLbblSKiYBlGMawg==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", + "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.15.0", - "@typescript-eslint/types": "4.15.0", - "@typescript-eslint/typescript-estree": "4.15.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + } } }, "@typescript-eslint/parser": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.24.0.tgz", - "integrity": "sha512-dj1ZIh/4QKeECLb2f/QjRwMmDArcwc2WorWPRlB8UNTZlY1KpTVsbX7e3ZZdphfRw29aTFUSNuGB8w9X5sS97w==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", + "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.24.0", - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/typescript-estree": "4.24.0", - "debug": "^4.1.1" + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" + } + }, + "@typescript-eslint/types": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz", - "integrity": "sha512-9+WYJGDnuC9VtYLqBhcSuM7du75fyCS/ypC8c5g7Sdw7pGL4NDTbeH38eJPfzIydCHZDoOgjloxSAA3+4l/zsA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0" - } - }, - "@typescript-eslint/types": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.24.0.tgz", - "integrity": "sha512-tkZUBgDQKdvfs8L47LaqxojKDE+mIUmOzdz7r+u+U54l3GDkTpEbQ1Jp3cNqqAU9vMUCBA1fitsIhm7yN0vx9Q==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.24.0.tgz", - "integrity": "sha512-kBDitL/by/HK7g8CYLT7aKpAwlR8doshfWz8d71j97n5kUa5caHWvY0RvEUEanL/EqBJoANev8Xc/mQ6LLwXGA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.24.0.tgz", - "integrity": "sha512-4ox1sjmGHIxjEDBnMCtWFFhErXtKA1Ec0sBpuz0fqf3P+g3JFGyTxxbF06byw0FRsPnnbq44cKivH7Ks1/0s6g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.24.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -7732,1321 +5513,14 @@ } } }, - "@typescript-eslint/scope-manager": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz", - "integrity": "sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "@typescript-eslint/visitor-keys": "4.15.0" - } - }, - "@typescript-eslint/types": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.0.tgz", - "integrity": "sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.0.tgz", - "integrity": "sha512-jG6xTmcNbi6xzZq0SdWh7wQ9cMb2pqXaUp6bUZOMsIlu5aOlxGxgE/t6L/gPybybQGvdguajXGkZKSndZJpksA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.15.0", - "@typescript-eslint/visitor-keys": "4.15.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "@typescript-eslint/visitor-keys": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz", - "integrity": "sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", "dev": true, "requires": { - "@typescript-eslint/types": "4.15.0", + "@typescript-eslint/types": "4.28.2", "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "dev": true - } - } - }, - "@urbit/api": { - "version": "file:../npm/api", - "requires": { - "@babel/runtime": "^7.12.5", - "@types/lodash": "^4.14.168", - "@urbit/eslint-config": "^1.0.0", - "big-integer": "^1.6.48", - "immer": "^9.0.1", - "lodash": "^4.17.20" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@blakeembrey/deque": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz", - "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==" - }, - "@blakeembrey/template": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@blakeembrey/template/-/template-1.0.0.tgz", - "integrity": "sha512-J6WGZqCLdRMHUkyRG6fBSIFJ0rL60/nsQNh5rQvsYZ5u0PsKw6XQcJcA3DWvd9cN3j/IQx5yB1fexhCafwwUUw==" - }, - "@types/lodash": { - "version": "4.14.169", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz", - "integrity": "sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw==" - }, - "@urbit/eslint-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@urbit/eslint-config/-/eslint-config-1.0.0.tgz", - "integrity": "sha512-Xmzb6MvM7KorlPJEq/hURZZ4BHSVy/7CoQXWogsBSTv5MOZnMqwNKw6yt24k2AO/2UpHwjGptimaNLqFfesJbw==" - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "big-integer": { - "version": "1.6.48", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "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==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "immer": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.2.tgz", - "integrity": "sha512-mkcmzLtIfSp40vAqteRr1MbWNSoI7JE+/PB36FNPoSfJ9RQRmNKuTYCjKkyXyuq3Dgn07HuJBrwJd4ZSk2yUbw==" - }, - "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==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "onchange": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/onchange/-/onchange-7.1.0.tgz", - "integrity": "sha512-ZJcqsPiWUAUpvmnJri5TPBooqJOPmC0ttN65juhN15Q8xA+Nbg3BaxBHXQ45EistKKlKElb0edmbPWnKSBkvMg==", - "requires": { - "@blakeembrey/deque": "^1.0.5", - "@blakeembrey/template": "^1.0.0", - "arg": "^4.1.3", - "chokidar": "^3.3.1", - "cross-spawn": "^7.0.1", - "ignore": "^5.1.4", - "tree-kill": "^1.2.2" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "@urbit/eslint-config": { - "version": "file:../npm/eslint-config", - "dev": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", - "requires": { - "@babel/types": "^7.14.2", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "requires": { - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==" - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.0", - "to-fast-properties": "^2.0.0" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.24.0.tgz", - "integrity": "sha512-qbCgkPM7DWTsYQGjx9RTuQGswi+bEt0isqDBeo+CKV0953zqI0Tp7CZ7Fi9ipgFA6mcQqF4NOVNwS/f2r6xShw==", - "requires": { - "@typescript-eslint/experimental-utils": "4.24.0", - "@typescript-eslint/scope-manager": "4.24.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.24.0.tgz", - "integrity": "sha512-IwTT2VNDKH1h8RZseMH4CcYBz6lTvRoOLDuuqNZZoThvfHEhOiZPQCow+5El3PtyxJ1iDr6UXZwYtE3yZQjhcw==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.24.0", - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/typescript-estree": "4.24.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.24.0.tgz", - "integrity": "sha512-dj1ZIh/4QKeECLb2f/QjRwMmDArcwc2WorWPRlB8UNTZlY1KpTVsbX7e3ZZdphfRw29aTFUSNuGB8w9X5sS97w==", - "requires": { - "@typescript-eslint/scope-manager": "4.24.0", - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/typescript-estree": "4.24.0", - "debug": "^4.1.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz", - "integrity": "sha512-9+WYJGDnuC9VtYLqBhcSuM7du75fyCS/ypC8c5g7Sdw7pGL4NDTbeH38eJPfzIydCHZDoOgjloxSAA3+4l/zsA==", - "requires": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0" - } - }, - "@typescript-eslint/types": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.24.0.tgz", - "integrity": "sha512-tkZUBgDQKdvfs8L47LaqxojKDE+mIUmOzdz7r+u+U54l3GDkTpEbQ1Jp3cNqqAU9vMUCBA1fitsIhm7yN0vx9Q==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.24.0.tgz", - "integrity": "sha512-kBDitL/by/HK7g8CYLT7aKpAwlR8doshfWz8d71j97n5kUa5caHWvY0RvEUEanL/EqBJoANev8Xc/mQ6LLwXGA==", - "requires": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.24.0.tgz", - "integrity": "sha512-4ox1sjmGHIxjEDBnMCtWFFhErXtKA1Ec0sBpuz0fqf3P+g3JFGyTxxbF06byw0FRsPnnbq44cKivH7Ks1/0s6g==", - "requires": { - "@typescript-eslint/types": "4.24.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - } - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "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==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.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==", - "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "requires": { - "esutils": "^2.0.2" - } - }, - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint-plugin-react": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz", - "integrity": "sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw==", - "requires": { - "array-includes": "^3.1.3", - "array.prototype.flatmap": "^1.2.4", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", - "object.entries": "^1.1.3", - "object.fromentries": "^2.0.4", - "object.values": "^1.1.3", - "prop-types": "^15.7.2", - "resolve": "^2.0.0-next.3", - "string.prototype.matchall": "^4.0.4" - }, - "dependencies": { - "resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "requires": { - "reusify": "^1.0.4" - } - }, - "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==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", - "requires": { - "array-includes": "^3.1.2", - "object.assign": "^4.1.2" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - } - }, - "object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - } - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "string.prototype.matchall": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz", - "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "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==", - "requires": { - "is-number": "^7.0.0" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } } }, "@webassemblyjs/ast": { @@ -9225,9 +5699,9 @@ } }, "@welldone-software/why-did-you-render": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@welldone-software/why-did-you-render/-/why-did-you-render-6.1.0.tgz", - "integrity": "sha512-0s+PuKQ4v9VV1SZSM6iS7d2T7X288T3DF+K8yfkFAhI31HhJGGH1SY1ssVm+LqjSMyrVWT60ZF5r0qUsO0Z9Lw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@welldone-software/why-did-you-render/-/why-did-you-render-6.2.0.tgz", + "integrity": "sha512-ViwaE09Vgb0yXzyZuGTWCmWy/nBRAEGyztMdFYuxIgmL8yoXX5TVMCfieiJGdRQQPiDUznlYmcu0lu8kN1lwtQ==", "dev": true, "requires": { "lodash": "^4" @@ -9370,10 +5844,10 @@ "string-width": "^3.0.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "is-fullwidth-code-point": { @@ -9392,6 +5866,15 @@ "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } } }, @@ -9402,21 +5885,10 @@ "dev": true }, "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true }, "ansi-html": { "version": "0.0.7", @@ -9425,9 +5897,9 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { @@ -9459,9 +5931,9 @@ "dev": true }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "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", @@ -9488,32 +5960,6 @@ "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "argparse": { @@ -9525,6 +5971,21 @@ "sprintf-js": "~1.0.2" } }, + "aria-hidden": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.1.3.tgz", + "integrity": "sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==", + "requires": { + "tslib": "^1.0.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -9544,21 +6005,21 @@ "dev": true }, "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, "array-includes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", - "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "get-intrinsic": "^1.0.1", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, @@ -9575,13 +6036,10 @@ "dev": true }, "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, "array-uniq": { "version": "1.0.3", @@ -9713,13 +6171,10 @@ "dev": true }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "dev": true }, "async-each": { "version": "1.0.3", @@ -9782,9 +6237,9 @@ } }, "aws-sdk": { - "version": "2.831.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.831.0.tgz", - "integrity": "sha512-lrOjbGFpjk2xpESyUx2PGsTZgptCy5xycZazPeakNbFO19cOoxjHx3xyxOHsMCYb3pQwns35UvChQT60B4u6cw==", + "version": "2.940.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.940.0.tgz", + "integrity": "sha512-3m3CglRKuSULo2bPBWUYeE6ugmNHVIw6pFru6bRy/s/em7+4GEZmB4TnlqACgds/X0NyQTKDhPUz0P237dGGmA==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -9837,6 +6292,14 @@ "@babel/types": "^7.7.0", "eslint-visitor-keys": "^1.0.0", "resolve": "^1.12.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "babel-jest": { @@ -9916,6 +6379,37 @@ "loader-utils": "^1.4.0", "make-dir": "^3.1.0", "schema-utils": "^2.6.5" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } } }, "babel-plugin-add-react-displayname": { @@ -9932,6 +6426,14 @@ "requires": { "@babel/helper-plugin-utils": "7.10.4", "@mdx-js/util": "1.6.22" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } } }, "babel-plugin-dynamic-import-node": { @@ -9976,6 +6478,14 @@ "dev": true, "requires": { "@babel/helper-plugin-utils": "7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } } }, "babel-plugin-istanbul": { @@ -10033,14 +6543,34 @@ "integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==", "dev": true }, - "babel-plugin-polyfill-corejs3": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", - "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", + "babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.1.5", - "core-js-compat": "^3.8.1" + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz", + "integrity": "sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.14.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2" } }, "babel-plugin-react-docgen": { @@ -10064,9 +6594,9 @@ } }, "babel-plugin-styled-components": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz", - "integrity": "sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.1.tgz", + "integrity": "sha512-iY11g5orsdBnvWtXKCFBzDyTxZ9jvmkcYCCs5ONlvASYltDRhieCVzeDC7Do0fSW7psAL0zfVoXB3FHz2CkUSg==", "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-module-imports": "^7.0.0", @@ -10115,9 +6645,9 @@ "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base": { @@ -10208,9 +6738,9 @@ } }, "before-after-hook": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz", - "integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", "dev": true }, "better-opn": { @@ -10255,9 +6785,9 @@ "dev": true }, "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "body-parser": { "version": "1.19.0", @@ -10277,12 +6807,6 @@ "type-is": "~1.6.17" }, "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -10297,6 +6821,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true } } }, @@ -10312,6 +6842,14 @@ "dns-txt": "^2.0.2", "multicast-dns": "^6.0.1", "multicast-dns-service-types": "^1.1.0" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + } } }, "boolbase": { @@ -10336,6 +6874,12 @@ "widest-line": "^3.1.0" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -10370,12 +6914,44 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "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 }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10466,9 +7042,9 @@ }, "dependencies": { "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", "dev": true } } @@ -10491,11 +7067,22 @@ }, "dependencies": { "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", "dev": true }, + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -10514,16 +7101,16 @@ } }, "browserslist": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", - "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001173", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.634", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.69" + "node-releases": "^1.1.71" } }, "bser": { @@ -10570,15 +7157,15 @@ "dev": true }, "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, "c8": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/c8/-/c8-7.7.2.tgz", - "integrity": "sha512-8AqNnUMxB3hsgYCYso2GJjlwnaNPlrEEbYbCQb7N76V1nrOgCKXiTcE3gXU18rIj0FeduPywROrIBMC7XAKApg==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.7.3.tgz", + "integrity": "sha512-ZyA7n3w8i4ETV25tVYMHwJxCSnaOf/LfA8vOcuZOPbonuQfD7tBT/gMWZy7eczRpCDuHcvMXwoqAemg6R0p3+A==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", @@ -10590,46 +7177,11 @@ "istanbul-reports": "^3.0.2", "rimraf": "^3.0.0", "test-exclude": "^6.0.0", - "v8-to-istanbul": "^7.1.0", + "v8-to-istanbul": "^8.0.0", "yargs": "^16.2.0", "yargs-parser": "^20.2.7" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -10675,53 +7227,6 @@ "requires": { "glob": "^7.1.3" } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", - "dev": true } } }, @@ -10960,9 +7465,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-lite": { - "version": "1.0.30001179", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz", - "integrity": "sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==", + "version": "1.0.30001243", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz", + "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==", "dev": true }, "capture-exit": { @@ -11038,19 +7543,19 @@ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "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.5.0" + "readdirp": "~3.6.0" } }, "chownr": { @@ -11060,9 +7565,9 @@ "dev": true }, "chromatic": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-5.8.3.tgz", - "integrity": "sha512-zTLQGhlGO/bz7LNbEv2qXtarE93aG7vz5CnYNPukhyE1LK2LZaPdzTgaWU5Ah+7ZFPQGFMMAmJ6I6fU4WCUnYA==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/chromatic/-/chromatic-5.9.2.tgz", + "integrity": "sha512-h7+LPo5j2yHUaQIpaJzM7SXfkdEE9I7/rI6TWSeURwCrUggptVjj/+T4X2rmuqD5TfCp9HyHvtRObRl4PVWfNw==", "dev": true, "requires": { "@actions/core": "^1.2.4", @@ -11079,6 +7584,7 @@ "execa": "^5.0.0", "fake-tag": "^2.0.0", "fs-extra": "^9.1.0", + "https-proxy-agent": "^5.0.0", "jsonfile": "^6.0.1", "junit-report-builder": "2.1.0", "listr": "0.14.3", @@ -11103,14 +7609,11 @@ "yarn-or-npm": "^3.0.1" }, "dependencies": { - "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", @@ -11146,10 +7649,21 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -11175,6 +7689,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -11209,6 +7729,18 @@ "yocto-queue": "^0.1.0" } }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -11218,6 +7750,21 @@ "lru-cache": "^6.0.0" } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -11247,6 +7794,15 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -11299,31 +7855,14 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "dev": true } } }, "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true }, "ci-info": { "version": "2.0.0", @@ -11371,9 +7910,9 @@ } }, "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "clean-css": { "version": "4.2.3", @@ -11407,12 +7946,12 @@ "dev": true }, "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^2.0.0" } }, "cli-table3": { @@ -11424,99 +7963,105 @@ "colors": "^1.1.2", "object-assign": "^4.1.0", "string-width": "^4.2.0" - } - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "slice-ansi": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" } } } }, - "clipboard": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", - "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", "dev": true, - "optional": true, "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" } }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" } } } @@ -11567,9 +8112,9 @@ "dev": true }, "codemirror": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.59.2.tgz", - "integrity": "sha512-/D5PcsKyzthtSy2NNKCyJi3b+htRkoKv3idswR/tR6UAvMNKA7SrmyZy6fOONJxSRs1JlUWEDAbxqfdArbK8iA==" + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.0.tgz", + "integrity": "sha512-Xnl3304iCc8nyVZuRkzDVVwc794uc9QNX0UcPGeNic1fbzkSrO4l4GVXho9tRNKBgPYZXgocUqXyfIv3BILhCQ==" }, "collapse-white-space": { "version": "1.0.6", @@ -11612,9 +8157,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, "colors": { @@ -11640,9 +8185,9 @@ "dev": true }, "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "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==", "dev": true }, "commondir": { @@ -11681,6 +8226,12 @@ "vary": "~1.1.2" }, "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -11720,32 +8271,6 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "connect-history-api-fallback": { @@ -11788,9 +8313,9 @@ "dev": true }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -11844,18 +8369,18 @@ } }, "core-js": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz", - "integrity": "sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", "dev": true }, "core-js-compat": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", - "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz", + "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==", "dev": true, "requires": { - "browserslist": "^4.16.1", + "browserslist": "^4.16.6", "semver": "7.0.0" }, "dependencies": { @@ -11868,9 +8393,9 @@ } }, "core-js-pure": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.12.1.tgz", - "integrity": "sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.2.tgz", + "integrity": "sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA==", "dev": true }, "core-util-is": { @@ -11902,6 +8427,17 @@ "make-dir": "^3.0.0", "nested-error-stacks": "^2.0.0", "p-event": "^4.1.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + } } }, "cpy": { @@ -11927,6 +8463,44 @@ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "dir-glob": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", @@ -11950,6 +8524,29 @@ "micromatch": "^3.1.10" } }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -11993,6 +8590,53 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, "p-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", @@ -12024,6 +8668,16 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -12081,17 +8735,70 @@ "dev": true, "requires": { "cross-spawn": "^7.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "crypto-browserify": { @@ -12145,49 +8852,25 @@ } }, "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", "dev": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" }, "dependencies": { - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", "dev": true, "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", - "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "domelementtype": "^2.2.0" } } } @@ -12203,9 +8886,9 @@ } }, "css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", "dev": true }, "cssesc": { @@ -12237,9 +8920,9 @@ } }, "csstype": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz", - "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", "dev": true }, "cyclist": { @@ -12281,9 +8964,9 @@ "dev": true }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { "ms": "2.1.2" } @@ -12313,9 +8996,9 @@ } }, "decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "decode-uri-component": { @@ -12449,6 +9132,44 @@ "p-map": "^2.0.0", "pify": "^4.0.1", "rimraf": "^2.6.3" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } } }, "delayed-stream": { @@ -12457,13 +9178,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "dev": true, - "optional": true - }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -12520,11 +9234,16 @@ "dev": true }, "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "detect-port-alt": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", @@ -12585,9 +9304,9 @@ "dev": true }, "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "dev": true, "requires": { "ip": "^1.1.0", @@ -12604,9 +9323,9 @@ } }, "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -12622,21 +9341,21 @@ } }, "dom-serializer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", - "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "requires": { "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", + "domhandler": "^4.2.0", "entities": "^2.0.0" }, "dependencies": { "domhandler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", - "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", "requires": { - "domelementtype": "^2.1.0" + "domelementtype": "^2.2.0" } } } @@ -12654,9 +9373,9 @@ "dev": true }, "domelementtype": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", - "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" }, "domexception": { "version": "2.0.1", @@ -12684,21 +9403,21 @@ } }, "domutils": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz", - "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz", + "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==", "requires": { "dom-serializer": "^1.0.1", - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0" + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" }, "dependencies": { "domhandler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", - "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", "requires": { - "domelementtype": "^2.1.0" + "domelementtype": "^2.2.0" } } } @@ -12763,15 +9482,6 @@ "react-is": "^17.0.2" }, "dependencies": { - "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -12796,32 +9506,6 @@ "inherits": "^2.0.1", "readable-stream": "^2.0.0", "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "ecc-jsbn": { @@ -12841,9 +9525,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.643", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.643.tgz", - "integrity": "sha512-TGomM4gj8adt/uqRgPbu9F0yhUVAR1deww5X0fvbQgpGr9suSMjLgc4IwQ9YKGkp1t03cDbZum20OfAkiTYjAg==", + "version": "1.3.769", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.769.tgz", + "integrity": "sha512-B+3hW8D76/uoTPSobWI3D/CFn2S4jPn88dVJ+BkD88Lz6LijQpL+hfdzIFJGTQK4KdE0XwmNbjUQFH1OQVwKdQ==", "dev": true }, "elegant-spinner": { @@ -12853,9 +9537,9 @@ "dev": true }, "element-resize-detector": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.2.tgz", - "integrity": "sha512-+LOXRkCJc4I5WhEJxIDjhmE3raF8jtOMBDqSCgZTMz2TX3oXAX5pE2+MDeopJlGdXzP7KzPbBJaUGfNaP9HG4A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.3.tgz", + "integrity": "sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ==", "dev": true, "requires": { "batch-processor": "1.0.0" @@ -12883,9 +9567,9 @@ "dev": true }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "emojis-list": { @@ -12920,14 +9604,14 @@ } }, "endent": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/endent/-/endent-2.0.1.tgz", - "integrity": "sha512-mADztvcC+vCk4XEZaCz6xIPO2NHQuprv5CAEjuVAu6aZwqAj7nVNlMyl1goPFYqCCpS2OJV9jwpumJLkotZrNw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", + "integrity": "sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==", "dev": true, "requires": { "dedent": "^0.7.0", "fast-json-parse": "^1.0.3", - "objectorarray": "^1.0.4" + "objectorarray": "^1.0.5" } }, "enhanced-resolve": { @@ -12950,30 +9634,6 @@ "errno": "^0.1.3", "readable-stream": "^2.0.1" } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } } } }, @@ -12995,9 +9655,9 @@ } }, "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "env-ci": { "version": "5.0.2", @@ -13009,6 +9669,17 @@ "java-properties": "^1.0.0" }, "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "execa": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", @@ -13035,12 +9706,6 @@ "pump": "^3.0.0" } }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -13055,6 +9720,36 @@ "requires": { "path-key": "^3.0.0" } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -13085,25 +9780,27 @@ } }, "es-abstract": { - "version": "1.18.0-next.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", - "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.1", - "object-inspect": "^1.9.0", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.3", - "string.prototype.trimstart": "^1.0.3" + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-array-method-boxes-properly": { @@ -13128,17 +9825,6 @@ "isarray": "^2.0.5" }, "dependencies": { - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -13205,71 +9891,35 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } } } }, "eslint": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.26.0.tgz", - "integrity": "sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.1", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", + "glob-parent": "^5.1.2", "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", @@ -13278,7 +9928,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.21", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -13287,11 +9937,26 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^6.0.4", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -13326,25 +9991,54 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "esutils": "^2.0.2" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, "globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -13362,6 +10056,42 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -13371,6 +10101,21 @@ "lru-cache": "^6.0.0" } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -13389,56 +10134,96 @@ "has-flag": "^4.0.0" } }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "eslint-plugin-react": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", - "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz", + "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", "doctrine": "^2.1.0", "has": "^1.0.3", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.4", "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + } } }, "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { - "esrecurse": "^4.3.0", + "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" } }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "esm": { @@ -13456,6 +10241,14 @@ "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "esprima": { @@ -13538,9 +10331,9 @@ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", + "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", "dev": true, "requires": { "original": "^1.0.0" @@ -13575,57 +10368,6 @@ "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "exit": { @@ -13771,12 +10513,6 @@ "vary": "~1.1.2" }, "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -13797,6 +10533,12 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true } } }, @@ -13915,29 +10657,16 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "dependencies": { - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - } + "micromatch": "^4.0.4" } }, "fast-json-parse": { @@ -13958,9 +10687,9 @@ "dev": true }, "fastq": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.1.tgz", - "integrity": "sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -13976,9 +10705,9 @@ } }, "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -14000,12 +10729,13 @@ "dev": true }, "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" } }, "file-entry-cache": { @@ -14028,9 +10758,9 @@ }, "dependencies": { "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -14048,12 +10778,12 @@ } }, "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", + "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", "dev": true, "requires": { - "@types/json-schema": "^7.0.6", + "@types/json-schema": "^7.0.7", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } @@ -14152,14 +10882,59 @@ } }, "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } } }, "find-root": { @@ -14188,6 +10963,117 @@ "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "flat-cache": { @@ -14212,9 +11098,9 @@ } }, "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", "dev": true }, "flush-write-stream": { @@ -14225,32 +11111,6 @@ "requires": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "fn-name": { @@ -14259,9 +11119,9 @@ "integrity": "sha512-eNMNr5exLoavuAMhIUVsOKF79SWd/zG104ef6sxBTSw+cZc6BXdQXDvYcGvp0VbxVVSp1XDUNoz7mg1xMtSznA==" }, "follow-redirects": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", - "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", "dev": true }, "for-in": { @@ -14278,6 +11138,49 @@ "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "forever-agent": { @@ -14301,11 +11204,120 @@ "worker-rpc": "^0.1.0" }, "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -14327,29 +11339,19 @@ "dev": true }, "formik": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.1.5.tgz", - "integrity": "sha512-bWpo3PiqVDYslvrRjTq0Isrm0mFXHiO33D8MS6t6dWcqSFGeYF52nlpCM2xwOJ6tRVRznDkL+zz/iHPL4LDuvQ==", + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", + "integrity": "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==", "requires": { "deepmerge": "^2.1.1", "hoist-non-react-statics": "^3.3.0", - "lodash": "^4.17.14", - "lodash-es": "^4.17.14", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "react-fast-compare": "^2.0.1", - "scheduler": "^0.18.0", "tiny-warning": "^1.0.2", "tslib": "^1.10.0" }, "dependencies": { - "scheduler": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", - "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -14358,9 +11360,9 @@ } }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true }, "fragment-cache": { @@ -14386,32 +11388,6 @@ "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "fs-extra": { @@ -14463,32 +11439,6 @@ "iferr": "^0.1.5", "imurmurhash": "^0.1.4", "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "fs.realpath": { @@ -14498,9 +11448,9 @@ "dev": true }, "fsevents": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", - "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", + "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 }, @@ -14554,43 +11504,6 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } } }, "gensync": { @@ -14606,9 +11519,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -14616,6 +11529,11 @@ "has-symbols": "^1.0.1" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -14675,9 +11593,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -14725,9 +11643,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "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" @@ -14765,57 +11683,24 @@ "dev": true, "requires": { "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" }, "dependencies": { - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, @@ -14834,24 +11719,17 @@ } }, "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" } }, "gm": { @@ -14895,15 +11773,6 @@ "yallist": "^2.1.2" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -14912,20 +11781,10 @@ } } }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "dev": true, - "optional": true, - "requires": { - "delegate": "^3.1.2" - } - }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "growly": { @@ -14995,14 +11854,6 @@ "dev": true, "requires": { "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } } }, "has-bigints": { @@ -15037,9 +11888,9 @@ } }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, "has-unicode": { @@ -15084,6 +11935,17 @@ "safe-buffer": "^5.2.0" }, "dependencies": { + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -15280,9 +12142,9 @@ "dev": true }, "highlight.js": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", - "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true }, "history": { @@ -15342,32 +12204,6 @@ "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "html-encoding-sniffer": { @@ -15404,6 +12240,14 @@ "param-case": "^3.0.3", "relateurl": "^0.2.7", "terser": "^4.6.3" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + } } }, "html-tags": { @@ -15430,9 +12274,9 @@ "dev": true }, "html-webpack-plugin": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.1.tgz", - "integrity": "sha512-yzK7RQZwv9xB+pcdHNTjcqbaaDZ+5L0zJHXfi89iWIZmb/FtzxhLk0635rmJihcQbs3ZUF27Xp4oWGx6EK56zg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz", + "integrity": "sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==", "dev": true, "requires": { "@types/html-minifier-terser": "^5.0.0", @@ -15530,6 +12374,117 @@ "is-glob": "^4.0.0", "lodash": "^4.17.11", "micromatch": "^3.1.10" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "http-signature": { @@ -15560,9 +12515,9 @@ } }, "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, "husky": { @@ -15606,9 +12561,9 @@ "dev": true }, "immer": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.2.tgz", - "integrity": "sha512-mkcmzLtIfSp40vAqteRr1MbWNSoI7JE+/PB36FNPoSfJ9RQRmNKuTYCjKkyXyuq3Dgn07HuJBrwJd4ZSk2yUbw==" + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.5.tgz", + "integrity": "sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ==" }, "import-fresh": { "version": "3.3.0", @@ -15618,6 +12573,14 @@ "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } } }, "import-jsx": { @@ -15637,6 +12600,35 @@ "rimraf": "^3.0.0" }, "dependencies": { + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -15655,56 +12647,22 @@ } }, "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dev": true, "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" }, "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "find-up": "^3.0.0" + "find-up": "^4.0.0" } } } @@ -15721,11 +12679,6 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -15784,6 +12737,29 @@ "yoga-layout-prebuilt": "^1.9.6" }, "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15803,6 +12779,25 @@ "supports-color": "^7.1.0" } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -15818,12 +12813,34 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "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 }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "scheduler": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", @@ -15845,6 +12862,50 @@ "is-fullwidth-code-point": "^3.0.0" } }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -15879,12 +12940,6 @@ "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } - }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "dev": true } } }, @@ -15913,25 +12968,12 @@ "get-intrinsic": "^1.1.0", "has": "^1.0.3", "side-channel": "^1.0.4" - }, - "dependencies": { - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - } } }, "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, "invariant": { @@ -16039,9 +13081,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-ci": { @@ -16054,9 +13096,9 @@ } }, "is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "requires": { "has": "^1.0.3" @@ -16072,9 +13114,9 @@ } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", "dev": true }, "is-decimal": { @@ -16130,10 +13172,13 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-function": { "version": "1.0.2", @@ -16256,12 +13301,13 @@ "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" } }, "is-regexp": { @@ -16289,18 +13335,18 @@ "dev": true }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", "dev": true }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" } }, "is-typedarray": { @@ -16400,6 +13446,15 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -16465,6 +13520,12 @@ "jest-cli": "^26.6.3" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16510,21 +13571,23 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "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 }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "jest-cli": { "version": "26.6.3", @@ -16547,21 +13610,17 @@ "yargs": "^15.4.1" } }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "resolve-from": "^5.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -16633,6 +13692,17 @@ "throat": "^5.0.0" }, "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "execa": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", @@ -16659,12 +13729,6 @@ "pump": "^3.0.0" } }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -16679,6 +13743,36 @@ "requires": { "path-key": "^3.0.0" } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -16754,22 +13848,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -16972,24 +14050,6 @@ "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" - }, - "dependencies": { - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true - } } }, "jest-jasmine2": { @@ -17199,22 +14259,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -17440,6 +14484,12 @@ "yargs": "^15.4.1" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -17485,12 +14535,35 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "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 }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -17699,22 +14772,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -17812,6 +14869,15 @@ "string-length": "^4.0.1" }, "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -17852,25 +14918,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -17879,6 +14926,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true } } }, @@ -17991,15 +15044,32 @@ }, "dependencies": { "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true }, - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true } } @@ -18185,13 +15255,13 @@ "dev": true }, "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "lighthouse-logger": { @@ -18250,6 +15320,12 @@ "stringify-object": "^3.3.0" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -18269,6 +15345,16 @@ "supports-color": "^7.1.0" } }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -18303,10 +15389,27 @@ "yaml": "^1.10.0" } }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", @@ -18332,20 +15435,32 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, "npm-run-path": { @@ -18357,12 +15472,58 @@ "path-key": "^3.0.0" } }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18371,6 +15532,15 @@ "requires": { "has-flag": "^4.0.0" } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -18389,6 +15559,14 @@ "listr-verbose-renderer": "^0.5.0", "p-map": "^2.0.0", "rxjs": "^6.3.3" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } } }, "listr-silent-renderer": { @@ -18413,18 +15591,6 @@ "strip-ansi": "^3.0.1" }, "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -18444,169 +15610,17 @@ "supports-color": "^2.0.0" } }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, "indent-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - }, - "log-update": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", - "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "cli-cursor": "^2.0.0", - "wrap-ansi": "^3.0.1" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true - }, - "wrap-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", - "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } } } }, @@ -18622,15 +15636,6 @@ "figures": "^2.0.0" }, "dependencies": { - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -18639,44 +15644,17 @@ "requires": { "escape-string-regexp": "^1.0.5" } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } } } }, "listr2": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.8.2.tgz", - "integrity": "sha512-E28Fw7Zd3HQlCJKzb9a8C8M0HtFWQeucE+S8YrSrqZObuCLPRHMRrR8gNmYt65cU9orXYHwvN5agXC36lYt7VQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.10.0.tgz", + "integrity": "sha512-eP40ZHihu70sSmqFNbNy2NL1YwImmlMmPh9WO5sLmPDleurMHt3n+SwEWNu2kzKScexZnkyFtc1VI0z/TGlmpw==", "dev": true, "requires": { - "chalk": "^4.1.1", "cli-truncate": "^2.1.0", - "figures": "^3.2.0", - "indent-string": "^4.0.0", + "colorette": "^1.2.2", "log-update": "^4.0.0", "p-map": "^4.0.0", "rxjs": "^6.6.7", @@ -18684,6 +15662,21 @@ "wrap-ansi": "^7.0.0" }, "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -18693,14 +15686,23 @@ "color-convert": "^2.0.1" } }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" } }, "color-convert": { @@ -18718,19 +15720,84 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "p-map": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "log-update": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, "requires": { - "aggregate-error": "^3.0.0" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { @@ -18742,28 +15809,29 @@ "ansi-regex": "^5.0.0" } }, - "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" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true } } }, + "lit-element": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.5.1.tgz", + "integrity": "sha512-ogu7PiJTA33bEK0xGu1dmaX5vhcRjBXCFexPja0e7P7jqLhTpNKYRPmE+GmiCaRVAbiQKGkUgkh/i6+bh++dPQ==", + "dev": true, + "requires": { + "lit-html": "^1.1.1" + } + }, + "lit-html": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.4.1.tgz", + "integrity": "sha512-B9btcSgPYb1q4oSOb/PrOT6Z/H+r6xuNzfH4lFli/AWhYwdtrgQkQWBbIc6mdnf6E2IL3gDXdkkqNktpU0OZQA==", + "dev": true + }, "loader-runner": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", @@ -18795,9 +15863,9 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz", - "integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "lodash.camelcase": { "version": "4.3.0", @@ -18832,6 +15900,12 @@ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -18845,120 +15919,91 @@ "dev": true }, "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "chalk": "^1.0.0" }, "dependencies": { "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "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" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", "dev": true, "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" } }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" } } } @@ -19022,12 +16067,6 @@ "color-convert": "^2.0.1" } }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", - "dev": true - }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -19072,6 +16111,17 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -19138,12 +16188,21 @@ } }, "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { - "semver": "^6.0.0" + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "makeerror": { @@ -19196,9 +16255,9 @@ } }, "markdown-to-jsx": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.2.tgz", - "integrity": "sha512-O8DMCl32V34RrD+ZHxcAPc2+kYytuDIoQYjY36RVdsLK7uHjgNVvFec4yv0X6LgB4YEZgSvK5QtFi5YVqEpoMA==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.3.tgz", + "integrity": "sha512-jtQ6VyT7rMT5tPV0g2EJakEnXLiPksnvlYtwQsVVZ611JsWGN8bQ1tVSDX4s6JllfEH6wmsYxNjTUAMrPmNA8w==", "dev": true }, "marky": { @@ -19396,32 +16455,6 @@ "requires": { "errno": "^0.1.3", "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "meow": { @@ -19464,16 +16497,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -19488,12 +16511,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", - "dev": true } } }, @@ -19528,114 +16545,13 @@ "dev": true }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } + "braces": "^3.0.1", + "picomatch": "^2.2.3" } }, "miller-rabin": { @@ -19655,18 +16571,18 @@ "dev": true }, "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", "dev": true }, "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "dev": true, "requires": { - "mime-db": "1.45.0" + "mime-db": "1.48.0" } }, "mimic-fn": { @@ -20050,36 +16966,16 @@ }, "dependencies": { "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true }, "url": { "version": "0.11.0", @@ -20089,14 +16985,6 @@ "requires": { "punycode": "1.3.2", "querystring": "0.2.0" - }, - "dependencies": { - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - } } } } @@ -20159,13 +17047,23 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "node-releases": { - "version": "1.1.70", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", - "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "normalize-package-data": { @@ -20211,14 +17109,6 @@ "dev": true, "requires": { "path-key": "^2.0.0" - }, - "dependencies": { - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - } } }, "npmlog": { @@ -20234,12 +17124,12 @@ } }, "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", "dev": true, "requires": { - "boolbase": "~1.0.0" + "boolbase": "^1.0.0" } }, "num2fraction": { @@ -20294,18 +17184,18 @@ } }, "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", "dev": true }, "object-is": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz", - "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, @@ -20337,38 +17227,37 @@ } }, "object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "object.fromentries": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", - "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" } }, "object.getownpropertydescriptors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz", - "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.18.0-next.2" } }, "object.pick": { @@ -20381,21 +17270,20 @@ } }, "object.values": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", - "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "objectorarray": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.4.tgz", - "integrity": "sha512-91k8bjcldstRz1bG6zJo8lWD7c6QXcB4nTDUqiEvIL1xAsLoZlOOZZG+nd6YPz+V7zY1580J4Xxh1vZtyv4i/w==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.5.tgz", + "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==", "dev": true }, "obuf": { @@ -20405,9 +17293,9 @@ "dev": true }, "oembed-parser": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/oembed-parser/-/oembed-parser-1.4.5.tgz", - "integrity": "sha512-CTrwqBizddDtlKDZ66JXYiSKCGePLiY5mSTx7oZohbyuG3WwuJnP1D8ZCR7BJhgDBpvJwyZqpPHD5a7pRVYPOg==", + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/oembed-parser/-/oembed-parser-1.4.7.tgz", + "integrity": "sha512-XtitoQKGBDE167OK6JuUchMXtl8CTeJhfHVifCZO0MnkmUAzRPNbtvtOZafNn/qYr37QHOzUDxhElT9O8/+iGA==", "requires": { "node-fetch": "^2.6.1" } @@ -20491,17 +17379,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" } }, "original": { @@ -20580,30 +17468,6 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -20625,6 +17489,14 @@ "dev": true, "requires": { "p-map": "^2.0.0" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } } }, "p-each-series": { @@ -20649,6 +17521,14 @@ "dev": true, "requires": { "p-map": "^2.0.0" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } } }, "p-finally": { @@ -20676,10 +17556,13 @@ } }, "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } }, "p-retry": { "version": "3.0.1", @@ -20720,32 +17603,6 @@ "cyclist": "^1.0.1", "inherits": "^2.0.3", "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "param-case": { @@ -20893,15 +17750,15 @@ "dev": true }, "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "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 }, "path-to-regexp": { @@ -20926,9 +17783,9 @@ "dev": true }, "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -20945,9 +17802,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { @@ -20998,12 +17855,51 @@ } }, "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", "dev": true, "requires": { - "find-up": "^4.0.0" + "find-up": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + } } }, "pkg-up": { @@ -21082,23 +17978,12 @@ } }, "polished": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.1.2.tgz", - "integrity": "sha512-jq4t3PJUpVRcveC53nnbEX35VyQI05x3tniwp26WFdm1dwaNUBHAi5awa/roBlwQxx1uRhwNSYeAi/aMbfiJCQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.1.3.tgz", + "integrity": "sha512-ocPAcVBUOryJEKe0z2KLd1l9EBa1r5mSwlKpExmrLzsnIzJo4axsoU9O2BjOTkDGDT4mZ0WFE5XKTlR3nLnZOA==", "dev": true, "requires": { - "@babel/runtime": "^7.13.17" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - } + "@babel/runtime": "^7.14.0" } }, "portfinder": { @@ -21112,6 +17997,15 @@ "mkdirp": "^0.5.5" }, "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -21130,9 +18024,9 @@ "dev": true }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -21195,12 +18089,12 @@ } }, "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", + "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", "dev": true, "requires": { - "@types/json-schema": "^7.0.6", + "@types/json-schema": "^7.0.7", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } @@ -21254,9 +18148,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz", - "integrity": "sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -21268,9 +18162,9 @@ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" }, "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "prettier": { @@ -21301,6 +18195,12 @@ "react-is": "^17.0.1" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -21340,13 +18240,10 @@ "dev": true }, "prismjs": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", - "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", - "dev": true, - "requires": { - "clipboard": "^2.0.0" - } + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz", + "integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow==", + "dev": true }, "process": { "version": "0.11.10", @@ -21405,85 +18302,6 @@ "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.0", "function-bind": "^1.1.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - } - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - } } }, "prompts": { @@ -21521,12 +18339,12 @@ } }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -21601,10 +18419,13 @@ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } }, "querystring": { "version": "0.2.1", @@ -21624,9 +18445,9 @@ "dev": true }, "queue-microtask": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", - "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "quick-lru": { @@ -21635,11 +18456,6 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, - "rafz": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/rafz/-/rafz-0.1.14.tgz", - "integrity": "sha512-YiQkedSt1urYtYbvHhTQR3l67M8SZbUvga5eJFM/v4vx/GmDdtXlE2hjJIyRjhhO/PjcdGC+CXCYOUA4onit8w==" - }, "ramda": { "version": "0.27.1", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", @@ -21680,14 +18496,6 @@ "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } } }, "raw-loader": { @@ -21721,12 +18529,12 @@ } }, "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", + "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", "dev": true, "requires": { - "@types/json-schema": "^7.0.6", + "@types/json-schema": "^7.0.7", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } @@ -21734,13 +18542,12 @@ } }, "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" + "object-assign": "^4.1.1" } }, "react-codemirror2": { @@ -21749,9 +18556,9 @@ "integrity": "sha512-rutEKVgvFhWcy/GeVA1hFbqrO89qLqgqdhUr7YhYgIzdyICdlRQv+ztuNvOFQMXrO0fLt0VkaYOdMdYdQgsSUA==" }, "react-colorful": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.2.0.tgz", - "integrity": "sha512-SJXywyc9oew0rOp7xjmtStiJ5N4Mk2RYc/1OptlaEnbuCz9PvILmRotoHfowdmO142HASUSgKdngL4WOHo/TnQ==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.2.3.tgz", + "integrity": "sha512-lAge4syxosZg9SX8fJiwOLd9ZJSW3poPBtypnz1aMiFoHsRnK5G3+INGGx9DGtsrso4h5uFYbiFpjAfWyK3Kag==", "dev": true }, "react-dev-utils": { @@ -21795,10 +18602,10 @@ "@babel/highlight": "^7.10.4" } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "browserslist": { @@ -21813,26 +18620,23 @@ "node-releases": "^1.1.61" } }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, "immer": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", @@ -21859,6 +18663,27 @@ "json5": "^2.1.2" } }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -21867,25 +18692,26 @@ "requires": { "ansi-regex": "^5.0.0" } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "react-devtools-core": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.13.2.tgz", - "integrity": "sha512-/lA5FVLMhUHrkQwtEf5wZNCKsXmc2RBZMNS/kkq3WlXPg2Y7COUGMh0Lmz34jjMpM0kvLMDuj+DqsPT/jSADbw==", + "version": "4.13.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.13.5.tgz", + "integrity": "sha512-k+P5VSKM6P22Go9IQ8dJmjj9fbztvKt1iRDI/4wS5oTvd1EnytIJMYB59wZt+D3kgp64jklNX/MRmY42xAQ08g==", "dev": true, "requires": { "shell-quote": "^1.6.1", "ws": "^7" - }, - "dependencies": { - "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "dev": true - } } }, "react-docgen": { @@ -21904,71 +18730,22 @@ "neo-async": "^2.6.1", "node-dir": "^0.1.10", "strip-indent": "^3.0.0" - }, - "dependencies": { - "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==", - "dev": true - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } } }, "react-docgen-typescript": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-1.22.0.tgz", - "integrity": "sha512-MPLbF8vzRwAG3GcjdL+OHQlhgtWsLTXs+7uJiHfEeT3Ur7IsZaNYqRTLQ9sj2nB6M6jylcPCeCmH7qbszJmecg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.0.0.tgz", + "integrity": "sha512-lPf+KJKAo6a9klKyK4y8WwgaX+6t5/HkVjHOpJDMbmaXfXcV7zP0QgWtnEOc3ccEUXKvlHMGUMIS9f6Zgo1BSw==", "dev": true }, - "react-docgen-typescript-plugin": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.6.3.tgz", - "integrity": "sha512-av1S/fmWBNFGgNa4qtkidFjjOz23eEi6EdCtwSWo9WNhGzUMyMygbD/DosMWoeFlZpk9R3MXPkRE7PDH6j5GMQ==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "endent": "^2.0.1", - "micromatch": "^4.0.2", - "react-docgen-typescript": "^1.20.5", - "tslib": "^2.0.0" - }, - "dependencies": { - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true - } - } - }, "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" + "scheduler": "^0.20.2" } }, "react-draggable": { @@ -22257,9 +19034,9 @@ } }, "react-textarea-autosize": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz", - "integrity": "sha512-JrMWVgQSaExQByP3ggI1eA8zF4mF0+ddVuX7acUeK2V7bmrpjVOY72vmLz2IXFJSAXoY3D80nEzrn0GWajWK3Q==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", "dev": true, "requires": { "@babel/runtime": "^7.10.2", @@ -22328,20 +19105,24 @@ } }, "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==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "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" @@ -22376,14 +19157,14 @@ } }, "refractor": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.3.1.tgz", - "integrity": "sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.4.0.tgz", + "integrity": "sha512-dBeD02lC5eytm9Gld2Mx0cMcnR+zhSnsTfPpWqFaMgUMJfC9A6bcN3Br/NaXrnBJcuxnLFR90k1jrkaSyV8umg==", "dev": true, "requires": { "hastscript": "^6.0.0", "parse-entities": "^2.0.0", - "prismjs": "~1.23.0" + "prismjs": "~1.24.0" }, "dependencies": { "parse-entities": { @@ -22452,9 +19233,9 @@ } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "regexpu-core": { @@ -22478,9 +19259,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.6.tgz", - "integrity": "sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -22766,6 +19547,32 @@ "source-map": "^0.5.0" } }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.12.1" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -23045,108 +19852,45 @@ "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==" }, "renderkid": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", - "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", "dev": true, "requires": { - "css-select": "^2.0.2", - "dom-converter": "^0.2", - "htmlparser2": "^3.10.1", - "lodash": "^4.17.20", - "strip-ansi": "^3.0.0" + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "dev": true, "requires": { "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", - "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", - "dev": true - }, - "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" } } } }, "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true }, "repeat-string": { @@ -23198,27 +19942,11 @@ "mime-types": "^2.1.12" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } } } }, @@ -23258,30 +19986,22 @@ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { - "is-core-module": "^2.1.0", + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } + "resolve-from": "^5.0.0" } }, "resolve-dir": { @@ -23304,13 +20024,26 @@ "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } } } }, "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, "resolve-pathname": { @@ -23325,13 +20058,30 @@ "dev": true }, "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "onetime": "^5.1.0", + "onetime": "^2.0.0", "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } } }, "ret": { @@ -23460,6 +20210,105 @@ "normalize-path": "^2.1.1" } }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -23468,16 +20317,26 @@ "requires": { "remove-trailing-separator": "^1.0.1" } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, "sass": { - "version": "1.32.5", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.5.tgz", - "integrity": "sha512-kU1yJ5zUAmPxr7f3q0YXTAd1oZjSR1g3tYyv+xu0HZSl5JiNOaE987eiz7wCUvbm4I9fGWGU2TgApTtcP4GMNQ==", + "version": "1.35.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.35.1.tgz", + "integrity": "sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==", "dev": true, "requires": { - "chokidar": ">=2.0.0 <4.0.0" + "chokidar": ">=3.0.0 <4.0.0" } }, "sass-loader": { @@ -23508,9 +20367,9 @@ } }, "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -23526,13 +20385,6 @@ "ajv-keywords": "^3.5.2" } }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "dev": true, - "optional": true - }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -23540,9 +20392,9 @@ "dev": true }, "selfsigned": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", - "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", + "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", "dev": true, "requires": { "node-forge": "^0.10.0" @@ -23783,18 +20635,18 @@ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "^3.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "shell-quote": { @@ -23812,6 +20664,14 @@ "glob": "^7.0.0", "interpret": "^1.0.0", "rechoir": "^0.6.2" + }, + "dependencies": { + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + } } }, "shellwords": { @@ -23851,41 +20711,10 @@ "dev": true }, "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true }, "snapdragon": { "version": "0.8.2", @@ -24030,9 +20859,9 @@ } }, "sockjs-client": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz", - "integrity": "sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", + "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", "dev": true, "requires": { "debug": "^3.2.6", @@ -24040,7 +20869,7 @@ "faye-websocket": "^0.11.3", "inherits": "^2.0.4", "json3": "^3.3.3", - "url-parse": "^1.4.7" + "url-parse": "^1.5.1" }, "dependencies": { "debug": { @@ -24089,9 +20918,9 @@ } }, "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, "space-separated-tokens": { @@ -24127,9 +20956,9 @@ } }, "spdx-license-ids": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", - "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "spdy": { @@ -24157,6 +20986,19 @@ "obuf": "^1.1.2", "readable-stream": "^3.0.6", "wbuf": "^1.7.3" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, "speedometer": { @@ -24306,6 +21148,28 @@ "integrity": "sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw==", "dev": true }, + "storybook-addon-designs": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/storybook-addon-designs/-/storybook-addon-designs-6.0.1.tgz", + "integrity": "sha512-BVoh8a1UoXz3xUuUeP5F+V95xGqmHlGR+K9vgZfwnpFLB7IWkRFUmW9a+bF+tl94b3PvcncI33qUnQeBn5KlqA==", + "dev": true, + "requires": { + "@figspec/react": "^0.1.6" + } + }, + "storybook-addon-outline": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/storybook-addon-outline/-/storybook-addon-outline-1.4.1.tgz", + "integrity": "sha512-Qvv9X86CoONbi+kYY78zQcTGmCgFaewYnOVR6WL7aOFJoW7TrLiIc/O4hH5X9PsEPZFqjfXEPUPENWVUQim6yw==", + "dev": true, + "requires": { + "@storybook/addons": "^6.3.0", + "@storybook/api": "^6.3.0", + "@storybook/components": "^6.3.0", + "@storybook/core-events": "^6.3.0", + "ts-dedent": "^2.1.1" + } + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -24314,32 +21178,6 @@ "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "stream-each": { @@ -24363,32 +21201,6 @@ "readable-stream": "^2.3.6", "to-arraybuffer": "^1.0.0", "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "stream-shift": { @@ -24404,34 +21216,21 @@ "dev": true }, "string-length": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", - "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" - }, - "dependencies": { - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - } - } - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", + "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -24443,19 +21242,31 @@ } } }, - "string.prototype.matchall": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", - "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "call-bind": "^1.0.0", + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3" + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" } }, "string.prototype.padend": { @@ -24481,40 +21292,32 @@ } }, "string.prototype.trimend": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", - "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", - "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "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==", - "dev": true - } + "safe-buffer": "~5.1.0" } }, "stringify-entities": { @@ -24539,20 +21342,12 @@ } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -24598,9 +21393,9 @@ }, "dependencies": { "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "requires": { "minimist": "^1.2.5" } @@ -24627,16 +21422,16 @@ } }, "styled-components": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.2.1.tgz", - "integrity": "sha512-sBdgLWrCFTKtmZm/9x7jkIabjFNVzCUeKfoQsM6R3saImkUnjx0QYdLwJHBjY9ifEcmjDamJDVfknWm1yxZPxQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.0.tgz", + "integrity": "sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", "@emotion/is-prop-valid": "^0.8.8", "@emotion/stylis": "^0.8.4", "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1", + "babel-plugin-styled-components": ">= 1.12.0", "css-to-react-native": "^3.0.0", "hoist-non-react-statics": "^3.0.0", "shallowequal": "^1.1.0", @@ -24745,19 +21540,6 @@ "es-abstract": "^1.18.0-next.2", "has-symbols": "^1.0.1", "object.getownpropertydescriptors": "^2.1.2" - }, - "dependencies": { - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - } - } } }, "synchronous-promise": { @@ -24785,9 +21567,9 @@ }, "dependencies": { "ajv": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.4.0.tgz", - "integrity": "sha512-7QD2l6+KBSLwf+7MuYocbWvRPdOu63/trReTLu2KFwkgctnub1auoF+Y1WYcm09CTM7quuscrzqmASaLHC/K4Q==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -24796,12 +21578,76 @@ "uri-js": "^4.2.2" } }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -24848,9 +21694,9 @@ } }, "telejson": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.3.2.tgz", - "integrity": "sha512-lvtKMZ2ONxgwcMrhUs2W6zT9Z/IwUY8ZZ6D4DvUtLMl7txBNmtY0GnbMBCQ3JevQpkwxYZ5Zu0a+AR7xCzJJnQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.3.3.tgz", + "integrity": "sha512-PjqkJZpzEggA9TBpVtJi1LVptP7tYtXB6rEubwlHap76AMjzvOdKX41CxyaW7ahhzDU1aftXnMCx5kAPDZTQBA==", "dev": true, "requires": { "@types/is-function": "^1.0.0", @@ -24863,22 +21709,6 @@ "memoizerific": "^1.11.3" }, "dependencies": { - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, "isobject": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", @@ -24916,12 +21746,6 @@ "unique-string": "^2.0.0" }, "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, "del": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", @@ -24938,20 +21762,6 @@ "slash": "^3.0.0" } }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -24964,15 +21774,6 @@ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -25010,6 +21811,23 @@ "requires": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, "terser": { @@ -25021,113 +21839,156 @@ "commander": "^2.20.0", "source-map": "~0.6.1", "source-map-support": "~0.5.12" - }, - "dependencies": { - "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==", - "dev": true - } } }, "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", + "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", "dev": true, "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", + "cacache": "^15.0.5", + "find-cache-dir": "^3.3.1", + "jest-worker": "^26.5.0", + "p-limit": "^3.0.2", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" + "terser": "^5.3.4", + "webpack-sources": "^1.4.3" }, "dependencies": { + "cacache": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "find-up": "^3.0.0" + "yocto-queue": "^0.1.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" } }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", + "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.7", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } }, - "semver": { + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "terser": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", + "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } } } }, @@ -25174,32 +22035,6 @@ "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "thunky": { @@ -25217,13 +22052,6 @@ "setimmediate": "^1.0.4" } }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true, - "optional": true - }, "tiny-invariant": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", @@ -25328,14 +22156,13 @@ "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=" }, "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "dependencies": { "punycode": { @@ -25343,12 +22170,6 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true } } }, @@ -25381,90 +22202,6 @@ "dev": true, "requires": { "yargs": "^16.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", - "dev": true - } } }, "tree-kill": { @@ -25479,9 +22216,9 @@ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" }, "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "trim-trailing-lines": { @@ -25523,14 +22260,14 @@ "dev": true }, "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, "tsutils": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", - "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -25572,12 +22309,12 @@ "dev": true }, "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "^1.2.1" + "prelude-ls": "~1.1.2" } }, "type-detect": { @@ -25618,9 +22355,9 @@ } }, "typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true }, "unbox-primitive": { @@ -25633,14 +22370,6 @@ "has-bigints": "^1.0.1", "has-symbols": "^1.0.2", "which-boxed-primitive": "^1.0.2" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - } } }, "unfetch": { @@ -25810,9 +22539,9 @@ "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" }, "unist-util-visit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.0.1.tgz", - "integrity": "sha512-DHyYg2LPkrzcdlhs2CJTWB1TWRRvah+CLiGjw5Ul9k13xPSEi+bK5EMFHVgSiyFNH2AS2/EinkWGZ05HKcXM1w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", + "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", @@ -25820,14 +22549,14 @@ }, "dependencies": { "unist-util-is": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.0.0.tgz", - "integrity": "sha512-G4p13DhfdUNmlnJxd0uy5Skx1FG58LSDhX8h1xgpeSq0omOQ4ZN5BO54ToFlNX55NDTbRHMdwTOJXqAieInSEA==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.0.tgz", + "integrity": "sha512-pWspZ+AvTqYbC+xWeRmzGqbcY8Na08Eowlfs2xchWTYot8vBBAq+syrE/LWS0bw1D/JOu4lwzDbEb6Mz13tK+g==" }, "unist-util-visit-parents": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.0.0.tgz", - "integrity": "sha512-QyATSx30wHguIzI82+GVeuXGnFlh3AUVcyeZPOo5Paz2Z52zfRe3/0WLlBv6XlMWcr5xEdFqox6PteUL6hzEFA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", + "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -25958,12 +22687,12 @@ } }, "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", + "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", "dev": true, "requires": { - "@types/json-schema": "^7.0.6", + "@types/json-schema": "^7.0.7", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } @@ -26010,6 +22739,22 @@ "use-isomorphic-layout-effect": "^1.0.0" } }, + "use-sidecar": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz", + "integrity": "sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -26066,15 +22811,15 @@ "dev": true }, "v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz", + "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -26269,6 +23014,18 @@ "snapdragon-node": "^2.0.1", "split-string": "^3.0.2", "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "chokidar": { @@ -26292,16 +23049,6 @@ "upath": "^1.1.1" } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -26313,6 +23060,18 @@ "is-number": "^3.0.0", "repeat-string": "^1.6.1", "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "fsevents": { @@ -26367,22 +23126,47 @@ "optional": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "optional": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "readdirp": { @@ -26397,16 +23181,6 @@ "readable-stream": "^2.0.2" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", @@ -26478,14 +23252,103 @@ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "schema-utils": { @@ -26498,6 +23361,33 @@ "ajv-errors": "^1.0.0", "ajv-keywords": "^3.1.0" } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -26520,53 +23410,160 @@ "yargs": "^13.3.2" }, "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "locate-path": "^3.0.0" } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -26585,9 +23582,9 @@ }, "dependencies": { "mime": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", - "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "dev": true } } @@ -26634,9 +23631,9 @@ }, "dependencies": { "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "anymatch": { @@ -26682,6 +23679,17 @@ "snapdragon-node": "^2.0.1", "split-string": "^3.0.2", "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "chokidar": { @@ -26704,13 +23712,26 @@ "upath": "^1.1.1" } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, "fill-range": { @@ -26723,6 +23744,26 @@ "is-number": "^3.0.0", "repeat-string": "^1.6.1", "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" } }, "fsevents": { @@ -26757,6 +23798,16 @@ } } }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -26766,6 +23817,12 @@ "binary-extensions": "^1.0.0" } }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -26773,23 +23830,86 @@ "dev": true, "requires": { "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -26801,6 +23921,21 @@ "readable-stream": "^2.0.2" } }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -26812,22 +23947,26 @@ "ajv-keywords": "^3.1.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, "to-regex-range": { @@ -26848,15 +23987,66 @@ "requires": { "punycode": "1.3.2", "querystring": "0.2.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "dependencies": { - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, @@ -26876,23 +24066,6 @@ "html-entities": "^1.2.0", "querystring": "^0.2.0", "strip-ansi": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } } }, "webpack-log": { @@ -26968,20 +24141,20 @@ "dev": true }, "whatwg-url": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", - "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { "lodash": "^4.7.0", - "tr46": "^2.0.2", + "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" } }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -27013,39 +24186,6 @@ "dev": true, "requires": { "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "widest-line": { @@ -27055,6 +24195,46 @@ "dev": true, "requires": { "string-width": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "word-wrap": { @@ -27064,63 +24244,63 @@ "dev": true }, "workbox-cacheable-response": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.0.2.tgz", - "integrity": "sha512-OrgFiYWkmFXDIbNRYSu+fchcfoZqyJ4yZbdc8WKUjr9v/MghKHfR9u7UI077xBkjno5J3YNpbwx73/no3HkrzA==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.1.5.tgz", + "integrity": "sha512-x8DC71lO/JCgiaJ194l9le8wc8lFPLgUpDkLhp2si7mXV6S/wZO+8Osvw1LLgYa8YYTWGbhbFhFTXIkEMknIIA==", "requires": { - "workbox-core": "^6.0.2" + "workbox-core": "^6.1.5" } }, "workbox-core": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.0.2.tgz", - "integrity": "sha512-Ksl6qeikGb+BOCILoCUJGxwlEQOeeqdpOnpOr9UDt3NtacPYbfYBmpYpKArw5DFWK+5geBsFqgUUlXThlCYfKQ==" + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.1.5.tgz", + "integrity": "sha512-9SOEle7YcJzg3njC0xMSmrPIiFjfsFm9WjwGd5enXmI8Lwk8wLdy63B0nzu5LXoibEmS9k+aWF8EzaKtOWjNSA==" }, "workbox-expiration": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.0.2.tgz", - "integrity": "sha512-6+nbR18cklAdI3BPT675ytftXPwnVbXGR8mPWNWTJtl5y2urRYv56ZOJLD7FBFVkZ8EjWiRhNP/A0fkxgdKtWQ==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.1.5.tgz", + "integrity": "sha512-6cN+FVbh8fNq56LFKPMchGNKCJeyboHsDuGBqmhDUPvD4uDjsegQpDQzn52VaE0cpywbSIsDF/BSq9E9Yjh5oQ==", "requires": { - "workbox-core": "^6.0.2" + "workbox-core": "^6.1.5" } }, "workbox-precaching": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.0.2.tgz", - "integrity": "sha512-sqKWL2emzmGnfJpna+9RjUkUiqQO++AKfwljCbgkHg8wBbVLy/rnui3eelKgAI7D8R31LJFfiZkY/kXmwkjtlQ==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.1.5.tgz", + "integrity": "sha512-yhm1kb6wgi141JeM5X7z42XJxCry53tbMLB3NgrxktrZbwbrJF8JILzYy+RFKC9tHC6u2bPmL789GPLT2NCDzw==", "requires": { - "workbox-core": "^6.0.2", - "workbox-routing": "^6.0.2", - "workbox-strategies": "^6.0.2" + "workbox-core": "^6.1.5", + "workbox-routing": "^6.1.5", + "workbox-strategies": "^6.1.5" } }, "workbox-recipes": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.0.2.tgz", - "integrity": "sha512-ewZIHO4jYE6bnEeUIYS6joQy3l+MydpOsVr2F6EpE8ps++z1ScbSdLtJU+yu6WuO3lH44HFZLeFxYQqYm50QAA==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.1.5.tgz", + "integrity": "sha512-MD1yabHca6O/oj1hrRdfj9cRwhKA5zqIE53rWOAg/dKMMzWQsf9nyRbXRgzK3a13iQvYKuQzURU4Cx58tdnR+Q==", "requires": { - "workbox-cacheable-response": "^6.0.2", - "workbox-core": "^6.0.2", - "workbox-expiration": "^6.0.2", - "workbox-precaching": "^6.0.2", - "workbox-routing": "^6.0.2", - "workbox-strategies": "^6.0.2" + "workbox-cacheable-response": "^6.1.5", + "workbox-core": "^6.1.5", + "workbox-expiration": "^6.1.5", + "workbox-precaching": "^6.1.5", + "workbox-routing": "^6.1.5", + "workbox-strategies": "^6.1.5" } }, "workbox-routing": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.0.2.tgz", - "integrity": "sha512-iQ9ch3fL1YpztDLfHNURaHQ0ispgPCdzWmZZhtSHUyy/+YkTlIiDVTbOQCIpHIrWlKQiim6X3K2ItIy1FW9+wA==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.1.5.tgz", + "integrity": "sha512-uC/Ctz+4GXGL42h1WxUNKxqKRik/38uS0NZ6VY/EHqL2F1ObLFqMHUZ4ZYvyQsKdyI82cxusvhJZHOrY0a2fIQ==", "requires": { - "workbox-core": "^6.0.2" + "workbox-core": "^6.1.5" } }, "workbox-strategies": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.0.2.tgz", - "integrity": "sha512-HjLnYCVS60U7OKhl5NIq8NAQXrotJQRDakmIONnRlQIlP2If/kAiQSUP3QCHMq4EeXGiF+/CdlR1/bhYBHZzZg==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.1.5.tgz", + "integrity": "sha512-QhiOn9KT9YGBdbfWOmJT6pXZOIAxaVrs6J6AMYzRpkUegBTEcv36+ZhE/cfHoT0u2fxVtthHnskOQ/snEzaXQw==", "requires": { - "workbox-core": "^6.0.2" + "workbox-core": "^6.1.5" } }, "worker-farm": { @@ -27142,37 +24322,76 @@ } }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" } } } @@ -27196,13 +24415,10 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz", + "integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==", + "dev": true }, "x-is-string": { "version": "0.1.0", @@ -27258,9 +24474,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { @@ -27276,91 +24492,71 @@ "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true } } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true }, "yarn-or-npm": { "version": "3.0.1", @@ -27372,53 +24568,13 @@ "pkg-dir": "^4.2.0" }, "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" + "find-up": "^4.0.0" } } } @@ -27453,9 +24609,9 @@ } }, "zustand": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.5.1.tgz", - "integrity": "sha512-7J56Ve814z4zap71iaKFD+t65LFI//jEq/Vf55BTSVqJZCm+w9rov8OMBg+YSwIPQk54bfoIWHTrOWuAbpEDMw==" + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.5.5.tgz", + "integrity": "sha512-iTiJoxzYFtiD7DhscgwK2P4Kft1JcZEI2U7mG8IxiOFM4KpBAiJZfFop3r/3wbCuyltXI6ph1Fx90e4j/S43XA==" }, "zwitch": { "version": "1.0.5", diff --git a/pkg/interface/package.json b/pkg/interface/package.json index dd5eee050..60b0b0961 100644 --- a/pkg/interface/package.json +++ b/pkg/interface/package.json @@ -3,8 +3,10 @@ "version": "1.0.0", "description": "", "main": "index.js", + "private": true, "dependencies": { "@babel/runtime": "^7.12.5", + "@radix-ui/react-dialog": "^0.1.0", "@reach/disclosure": "^0.10.5", "@reach/menu-button": "^0.10.5", "@reach/tabs": "^0.10.5", @@ -13,7 +15,8 @@ "@tlon/indigo-light": "^1.0.7", "@tlon/indigo-react": "^1.2.23", "@tlon/sigil-js": "^1.4.3", - "@urbit/api": "file:../npm/api", + "@urbit/api": "^1.1.1", + "@urbit/http-api": "^1.2.1", "any-ascii": "^0.1.7", "aws-sdk": "^2.830.0", "big-integer": "^1.6.48", @@ -31,9 +34,9 @@ "oembed-parser": "^1.4.5", "prop-types": "^15.7.2", "querystring": "^0.2.0", - "react": "^16.14.0", + "react": "^17.0.2", "react-codemirror2": "^6.0.1", - "react-dom": "^16.14.0", + "react-dom": "^17.0.2", "react-helmet": "^6.1.0", "react-markdown": "^4.3.1", "react-oembed-container": "^1.0.0", @@ -80,7 +83,7 @@ "@types/yup": "^0.29.11", "@typescript-eslint/eslint-plugin": "^4.15.0", "@typescript-eslint/parser": "^4.24.0", - "@urbit/eslint-config": "file:../npm/eslint-config", + "@urbit/eslint-config": "^1.0.0", "@welldone-software/why-did-you-render": "^6.1.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", @@ -102,6 +105,7 @@ "react-hot-loader": "^4.13.0", "sass": "^1.32.5", "sass-loader": "^8.0.2", + "storybook-addon-designs": "^6.0.0", "ts-mdast": "^1.0.0", "typescript": "^4.2.4", "webpack": "^4.46.0", @@ -113,15 +117,15 @@ "lint-file": "eslint", "tsc": "tsc", "tsc:watch": "tsc --watch", - "preinstall": "./preinstall.sh", "build:dev": "cross-env NODE_ENV=development webpack --config config/webpack.dev.js", - "build:prod": "cd ../npm/api && npm ci && cd ../../interface && cross-env NODE_ENV=production webpack --config config/webpack.prod.js", + "build:prod": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js", "start": "webpack-dev-server --config config/webpack.dev.js", - "test": "jest", - "prepare": "cd ../.. && husky install pkg/interface/.husky", + "test": "tsc && jest", + "jest": "jest", "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook", - "chromatic": "chromatic --exit-zero-on-changes" + "chromatic": "chromatic --exit-zero-on-changes", + "hook-lint": "eslint --cache --fix" }, "author": "", "license": "MIT", diff --git a/pkg/interface/preinstall.sh b/pkg/interface/preinstall.sh index 4f35cfc0f..0fcf27d52 100755 --- a/pkg/interface/preinstall.sh +++ b/pkg/interface/preinstall.sh @@ -9,4 +9,6 @@ for i in $(find . -type d -maxdepth 1) ; do npm ci cd .. fi -done \ No newline at end of file +done +cd http-api +npm run build diff --git a/pkg/interface/public/index.html b/pkg/interface/public/index.html index 4a2da1bf3..976a5201b 100644 --- a/pkg/interface/public/index.html +++ b/pkg/interface/public/index.html @@ -1,24 +1,26 @@ - - + + + Groups - - - - - - Landscape + + + + + + + - - -
    - +
    diff --git a/pkg/arvo/app/landscape/fonts/inter-bold.woff2 b/pkg/interface/src/assets/fonts/inter-bold.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/inter-bold.woff2 rename to pkg/interface/src/assets/fonts/inter-bold.woff2 diff --git a/pkg/arvo/app/landscape/fonts/inter-bolditalic.woff2 b/pkg/interface/src/assets/fonts/inter-bolditalic.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/inter-bolditalic.woff2 rename to pkg/interface/src/assets/fonts/inter-bolditalic.woff2 diff --git a/pkg/arvo/app/landscape/fonts/inter-italic.woff2 b/pkg/interface/src/assets/fonts/inter-italic.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/inter-italic.woff2 rename to pkg/interface/src/assets/fonts/inter-italic.woff2 diff --git a/pkg/arvo/app/landscape/fonts/inter-regular.woff2 b/pkg/interface/src/assets/fonts/inter-regular.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/inter-regular.woff2 rename to pkg/interface/src/assets/fonts/inter-regular.woff2 diff --git a/pkg/arvo/app/landscape/fonts/sourcecodepro-bold.woff2 b/pkg/interface/src/assets/fonts/sourcecodepro-bold.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/sourcecodepro-bold.woff2 rename to pkg/interface/src/assets/fonts/sourcecodepro-bold.woff2 diff --git a/pkg/arvo/app/landscape/fonts/sourcecodepro-extralight.woff2 b/pkg/interface/src/assets/fonts/sourcecodepro-extralight.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/sourcecodepro-extralight.woff2 rename to pkg/interface/src/assets/fonts/sourcecodepro-extralight.woff2 diff --git a/pkg/arvo/app/landscape/fonts/sourcecodepro-light.woff2 b/pkg/interface/src/assets/fonts/sourcecodepro-light.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/sourcecodepro-light.woff2 rename to pkg/interface/src/assets/fonts/sourcecodepro-light.woff2 diff --git a/pkg/arvo/app/landscape/fonts/sourcecodepro-medium.woff2 b/pkg/interface/src/assets/fonts/sourcecodepro-medium.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/sourcecodepro-medium.woff2 rename to pkg/interface/src/assets/fonts/sourcecodepro-medium.woff2 diff --git a/pkg/arvo/app/landscape/fonts/sourcecodepro-regular.woff2 b/pkg/interface/src/assets/fonts/sourcecodepro-regular.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/sourcecodepro-regular.woff2 rename to pkg/interface/src/assets/fonts/sourcecodepro-regular.woff2 diff --git a/pkg/arvo/app/landscape/fonts/sourcecodepro-semibold.woff2 b/pkg/interface/src/assets/fonts/sourcecodepro-semibold.woff2 similarity index 100% rename from pkg/arvo/app/landscape/fonts/sourcecodepro-semibold.woff2 rename to pkg/interface/src/assets/fonts/sourcecodepro-semibold.woff2 diff --git a/pkg/arvo/app/landscape/img/favicon.png b/pkg/interface/src/assets/img/favicon.png similarity index 100% rename from pkg/arvo/app/landscape/img/favicon.png rename to pkg/interface/src/assets/img/favicon.png diff --git a/pkg/arvo/app/landscape/img/imageupload.png b/pkg/interface/src/assets/img/imageupload.png similarity index 100% rename from pkg/arvo/app/landscape/img/imageupload.png rename to pkg/interface/src/assets/img/imageupload.png diff --git a/pkg/arvo/app/landscape/img/touch_icon.png b/pkg/interface/src/assets/img/touch_icon.png similarity index 100% rename from pkg/arvo/app/landscape/img/touch_icon.png rename to pkg/interface/src/assets/img/touch_icon.png diff --git a/pkg/interface/src/index.js b/pkg/interface/src/index.js index 7d908cd50..afde2c28f 100644 --- a/pkg/interface/src/index.js +++ b/pkg/interface/src/index.js @@ -1,6 +1,7 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './register-sw'; +import './storage-wipe'; import App from './views/App'; import './wdyr'; diff --git a/pkg/interface/src/logic/api/base.ts b/pkg/interface/src/logic/api/base.ts deleted file mode 100644 index a5d021131..000000000 --- a/pkg/interface/src/logic/api/base.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Path, Patp } from '@urbit/api'; -import _ from 'lodash'; -import BaseStore from '../store/base'; - -export default class BaseApi { - bindPaths: Path[] = []; - constructor(public ship: Patp, public channel: any, public store: BaseStore) {} - - unsubscribe(id: number) { - this.channel.unsubscribe(id); - } - - subscribe(path: Path, method, ship = this.ship, app: string, success, fail, quit, queue = false) { - this.bindPaths = _.uniq([...this.bindPaths, path]); - - return this.channel.subscribe( - this.ship, - app, - path, - (err) => { - fail(err); - }, - (event) => { - success({ - data: event, - from: { - ship, - path - } - }); - }, - (qui) => { - quit(qui); - }, - () => {}, - queue - ); - } - - action( - appl: string, - mark: string, - data: any, - ship = (window as any).ship - ): Promise { - return new Promise((resolve, reject) => { - this.channel.poke( - ship, - appl, - mark, - data, - (json) => { - resolve(json); -}, - (err) => { - reject(err); -} - ); - }); - } - - scry(app: string, path: Path): Promise { - return fetch(`/~/scry/${app}${path}.json`).then(r => r.json() as Promise); - } - - async spider(inputMark: string, outputMark: string, threadName: string, body: any): Promise { - const res = await fetch(`/spider/${inputMark}/${threadName}/${outputMark}.json`, { - method: 'POST', - body: JSON.stringify(body) - }); - - return res.json(); - } -} diff --git a/pkg/interface/src/logic/api/bootstrap.ts b/pkg/interface/src/logic/api/bootstrap.ts new file mode 100644 index 000000000..3ee84bdb0 --- /dev/null +++ b/pkg/interface/src/logic/api/bootstrap.ts @@ -0,0 +1,50 @@ +import airlock from '~/logic/api'; +import useHarkState from '~/logic/state/hark'; +import useMetadataState from '~/logic/state/metadata'; +import useContactState from '../state/contact'; +import useGraphState from '../state/graph'; +import useGroupState from '../state/group'; +import useInviteState from '../state/invite'; +import useLaunchState from '../state/launch'; +import useSettingsState from '../state/settings'; +import useLocalState from '../state/local'; +import useStorageState from '../state/storage'; + +export async function bootstrapApi() { + airlock.onError = (e) => { + (async () => { + const { reconnect } = useLocalState.getState(); + try { + await reconnect(); + } catch (e) { + console.log(e); + console.log('onError'); + } + })(); + }; + + airlock.onRetry = () => { + useLocalState.setState({ subscription: 'reconnecting' }); + }; + + airlock.onOpen = () => { + useLocalState.setState({ subscription: 'connected' }); + }; + + [useGraphState].map(s => s.getState()?.clear?.()); + useGraphState.getState().getShallowChildren(`~${window.ship}`, 'dm-inbox'); + + const promises = [ + useHarkState, + useMetadataState, + useGroupState, + useContactState, + useSettingsState, + useLaunchState, + useInviteState, + useGraphState, + useStorageState + ].map(state => state.getState().initialize(airlock)); + await Promise.all(promises); +} + diff --git a/pkg/interface/src/logic/api/contacts.ts b/pkg/interface/src/logic/api/contacts.ts deleted file mode 100644 index c0be49902..000000000 --- a/pkg/interface/src/logic/api/contacts.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Patp } from '@urbit/api'; -import { ContactEditField } from '@urbit/api/contacts'; -import _ from 'lodash'; -import {edit} from '../reducers/contact-update'; -import {doOptimistically} from '../state/base'; -import useContactState from '../state/contact'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class ContactsApi extends BaseApi { - add(ship: Patp, contact: any) { - contact['last-updated'] = Date.now(); - return this.storeAction({ add: { ship, contact } }); - } - - remove(ship: Patp) { - return this.storeAction({ remove: { ship } }); - } - - edit(ship: Patp, editField: ContactEditField) { - /* editField can be... - {nickname: ''} - {email: ''} - {phone: ''} - {website: ''} - {color: 'fff'} // with no 0x prefix - {avatar: null} - {avatar: ''} - {add-group: {ship, name}} - {remove-group: {ship, name}} - */ - const action = { - edit: { - ship, - 'edit-field': editField, - timestamp: Date.now() - } - } - doOptimistically(useContactState, action, this.storeAction.bind(this), [edit]) - } - - allowShips(ships: Patp[]) { - return this.storeAction({ - allow: { - ships - } - }); - } - - allowGroup(ship: string, name: string) { - const group = { ship, name }; - return this.storeAction({ - allow: { - group - } - }); - } - - setPublic(setPublic: any) { - return this.storeAction({ - 'set-public': setPublic - }); - } - - share(recipient: Patp) { - return this.action( - 'contact-push-hook', - 'contact-share', - { share: recipient } - ); - } - - fetchIsAllowed(entity, name, ship, personal) { - const isPersonal = personal ? 'true' : 'false'; - return this.scry( - 'contact-store', - `/is-allowed/${entity}/${name}/${ship}/${isPersonal}` - ); - } - - async disallowedShipsForOurContact(ships: string[]): Promise { - return _.compact( - await Promise.all( - ships.map( - async (s) => { - const ship = `~${s}`; - if(s === window.ship) { - return null; - } - const allowed = await this.fetchIsAllowed( - `~${window.ship}`, - 'personal', - ship, - true - ); - return allowed ? null : ship; - } - ) - ) - ); - } - - retrieve(ship: string) { - const resource = { ship, name: '' }; - return this.action('contact-pull-hook', 'pull-hook-action', { - add: { - resource, - ship - } - }); - } - - private storeAction(action: any): Promise { - return this.action('contact-store', 'contact-update-0', action); - } - - private viewAction(threadName: string, action: any) { - return this.spider('contact-view-action', 'json', threadName, action); - } - - private hookAction(ship: Patp, action: any): Promise { - return this.action('contact-push-hook', 'contact-update-0', action); - } -} diff --git a/pkg/interface/src/logic/api/gcp.ts b/pkg/interface/src/logic/api/gcp.ts deleted file mode 100644 index f8a72d666..000000000 --- a/pkg/interface/src/logic/api/gcp.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class GcpApi extends BaseApi { - // Does not touch the store; use the value manually. - async isConfigured(): Promise { - return this.spider('noun', 'json', 'gcp-is-configured', {}); - } - - // Does not return the token; read it out of the store. - async getToken(): Promise { - return this.spider('noun', 'gcp-token', 'gcp-get-token', {}) - .then((token) => { - this.store.handleEvent({ - data: token - }); - }); - } -} diff --git a/pkg/interface/src/logic/api/global.ts b/pkg/interface/src/logic/api/global.ts deleted file mode 100644 index e4db67a1a..000000000 --- a/pkg/interface/src/logic/api/global.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Patp } from '@urbit/api'; -import GlobalStore from '../store/store'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; -import ContactsApi from './contacts'; -import GcpApi from './gcp'; -import GraphApi from './graph'; -import GroupsApi from './groups'; -import { HarkApi } from './hark'; -import InviteApi from './invite'; -import LaunchApi from './launch'; -import LocalApi from './local'; -import MetadataApi from './metadata'; -import S3Api from './s3'; -import SettingsApi from './settings'; - -export default class GlobalApi extends BaseApi { - local = new LocalApi(this.ship, this.channel, this.store); - invite = new InviteApi(this.ship, this.channel, this.store); - metadata = new MetadataApi(this.ship, this.channel, this.store); - contacts = new ContactsApi(this.ship, this.channel, this.store); - groups = new GroupsApi(this.ship, this.channel, this.store); - launch = new LaunchApi(this.ship, this.channel, this.store); - gcp = new GcpApi(this.ship, this.channel, this.store); - s3 = new S3Api(this.ship, this.channel, this.store); - graph = new GraphApi(this.ship, this.channel, this.store); - hark = new HarkApi(this.ship, this.channel, this.store); - settings = new SettingsApi(this.ship, this.channel, this.store); - - constructor( - public ship: Patp, - public channel: any, - public store: GlobalStore - ) { - super(ship, channel, store); - } -} - diff --git a/pkg/interface/src/logic/api/graph.ts b/pkg/interface/src/logic/api/graph.ts deleted file mode 100644 index 13094f0c1..000000000 --- a/pkg/interface/src/logic/api/graph.ts +++ /dev/null @@ -1,456 +0,0 @@ -import { patp2dec } from 'urbit-ob'; -import { Content, Enc, GraphNode, GroupPolicy, Path, Patp, Post, Resource } from '@urbit/api'; -import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; -import _ from 'lodash'; -import { decToUd, deSig, resourceAsPath, unixToDa } from '~/logic/lib/util'; -import { makeResource, resourceFromPath } from '../lib/group'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export const createBlankNodeWithChildPost = ( - parentIndex = '', - childIndex = '', - contents: Content[] -): GraphNode => { - const date = unixToDa(Date.now()).toString(); - const nodeIndex = parentIndex + '/' + date; - - const childGraph = {}; - childGraph[childIndex] = { - post: { - author: `~${window.ship}`, - index: nodeIndex + '/' + childIndex, - 'time-sent': Date.now(), - contents, - hash: null, - signatures: [] - }, - children: null - }; - - return { - post: { - author: `~${window.ship}`, - index: nodeIndex, - 'time-sent': Date.now(), - contents: [], - hash: null, - signatures: [] - }, - children: childGraph as BigIntOrderedMap - }; -}; - -function markPending(nodes: any) { - _.forEach(nodes, (node) => { - node.post.author = deSig(node.post.author); - node.post.pending = true; - markPending(node.children || {}); - }); -} - -export const createPost = ( - contents: Content[], - parentIndex = '', - childIndex = 'DATE_PLACEHOLDER' -) => { - if (childIndex === 'DATE_PLACEHOLDER') { - childIndex = unixToDa(Date.now()).toString(); - } - return { - author: `~${window.ship}`, - index: parentIndex + '/' + childIndex, - 'time-sent': Date.now(), - contents, - hash: null, - signatures: [] - }; -}; - -function moduleToMark(mod: string): string | undefined { - if(mod === 'link') { - return 'graph-validator-link'; - } - if(mod === 'publish') { - return 'graph-validator-publish'; - } - if(mod === 'chat') { - return 'graph-validator-chat'; - } - return undefined; -} - -export default class GraphApi extends BaseApi { - joiningGraphs = new Set(); - - private storeAction(action: any): Promise { - return this.action('graph-store', 'graph-update-2', action); - } - - private viewAction(threadName: string, action: any) { - return this.spider('graph-view-action', 'json', threadName, action); - } - - private hookAction(ship: Patp, action: any): Promise { - return this.action('graph-push-hook', 'graph-update-2', action); - } - - createManagedGraph( - name: string, - title: string, - description: string, - group: Path, - mod: string - ) { - const associated = { group: resourceFromPath(group) }; - const resource = makeResource(`~${window.ship}`, name); - - return this.viewAction('graph-create', { - 'create': { - resource, - title, - description, - associated, - 'module': mod, - mark: moduleToMark(mod) - } - }); - } - - createUnmanagedGraph( - name: string, - title: string, - description: string, - policy: Enc, - mod: string - ) { - const resource = makeResource(`~${window.ship}`, name); - - return this.viewAction('graph-create', { - 'create': { - resource, - title, - description, - associated: { policy }, - 'module': mod, - mark: moduleToMark(mod) - } - }); - } - - joinGraph(ship: Patp, name: string) { - const resource = makeResource(ship, name); - const rid = resourceAsPath(resource); - if(this.joiningGraphs.has(rid)) { - return Promise.resolve(); - } - this.joiningGraphs.add(rid); - return this.viewAction('graph-join', { - join: { - resource, - ship - } - }).then((res) => { - this.joiningGraphs.delete(rid); - return res; - }); - } - - deleteGraph(name: string) { - const resource = makeResource(`~${window.ship}`, name); - return this.viewAction('graph-delete', { - 'delete': { - resource - } - }); - } - - leaveGraph(ship: Patp, name: string) { - const resource = makeResource(ship, name); - return this.viewAction('graph-leave', { - 'leave': { - resource - } - }); - } - - groupifyGraph(ship: Patp, name: string, toPath?: string) { - const resource = makeResource(ship, name); - const to = toPath && resourceFromPath(toPath); - - return this.viewAction('graph-groupify', { - groupify: { - resource, - to - } - }); - } - - eval(cord: string): Promise { - return this.spider('graph-view-action', 'tang', 'graph-eval', { - eval: cord - }); - } - - addGraph(ship: Patp, name: string, graph: any, mark: any) { - return this.storeAction({ - 'add-graph': { - resource: { ship, name }, - graph, - mark - } - }); - } - - addDmMessage(ship: Patp, contents: Content[]) { - const post = createPost(contents, `/${patp2dec(ship)}`); - const action = { - 'add-nodes': { - resource: { ship: `~${window.ship}`, name: 'dm-inbox' }, - nodes: { - [post.index]: { - post, - children: null - } - } - } - }; - this.action('dm-hook', 'graph-update-2', action); - markPending(action['add-nodes'].nodes); - action['add-nodes'].resource.ship = - action['add-nodes'].resource.ship.slice(1); - this.store.handleEvent({ data: { - 'graph-update': action - } }); - } - - acceptDm(ship: Patp) { - return this.action('dm-hook', 'dm-hook-action', { 'accept' : ship }); - } - - declineDm(ship: Patp) { - return this.action('dm-hook', 'dm-hook-action', { 'decline' : ship }); - } - - setScreen(screen: boolean) { - return this.action('dm-hook', 'dm-hook-action', { screen }); - } - - addPost(ship: Patp, name: string, post: Post) { - const nodes = {}; - nodes[post.index] = { - post, - children: null - }; - return this.addNodes(ship, name, nodes); - } - - addNode(ship: Patp, name: string, node: GraphNode) { - const nodes = {}; - nodes[node.post.index] = node; - - return this.addNodes(ship, name, nodes); - } - - addNodes(ship: Patp, name: string, nodes: Object) { - const action = { - 'add-nodes': { - resource: { ship, name }, - nodes - } - }; - - const pendingPromise = this.spider( - 'graph-update-2', - 'graph-view-action', - 'graph-add-nodes', - action - ); - - markPending(action['add-nodes'].nodes); - action['add-nodes'].resource.ship = - action['add-nodes'].resource.ship.slice(1); - - this.store.handleEvent({ data: { - 'graph-update': action - } }); - - return pendingPromise; - /* TODO: stop lying to our users about pending states - return pendingPromise.then((pendingHashes) => { - for (let index in action['add-nodes'].nodes) { - action['add-nodes'].nodes[index].post.hash = - pendingHashes['pending-indices'][index] || null; - } - - this.store.handleEvent({ data: { - 'graph-update': { - 'pending-indices': pendingHashes['pending-indices'], - ...action - } - } }); - }); - */ - } - - async enableGroupFeed(group: Resource, vip: any = ''): Promise { - const { resource } = await this.spider( - 'graph-view-action', - 'resource', - 'graph-create-group-feed', - { - 'create-group-feed': { resource: group, vip } - } - ); - return resource; - } - - async disableGroupFeed(group: Resource): Promise { - await this.spider( - 'graph-view-action', - 'json', - 'graph-disable-group-feed', - { - 'disable-group-feed': { resource: group } - } - ); - } - - removePosts(ship: Patp, name: string, indices: string[]) { - return this.hookAction(ship, { - 'remove-posts': { - resource: { ship, name }, - indices - } - }); - } - - getKeys() { - return this.scry('graph-store', '/keys') - .then((keys) => { - this.store.handleEvent({ - data: keys - }); - }); - } - - getTags() { - return this.scry('graph-store', '/tags') - .then((tags) => { - this.store.handleEvent({ - data: tags - }); - }); - } - - getTagQueries() { - return this.scry('graph-store', '/tag-queries') - .then((tagQueries) => { - this.store.handleEvent({ - data: tagQueries - }); - }); - } - - getGraph(ship: string, resource: string) { - return this.scry('graph-store', `/graph/${ship}/${resource}`) - .then((graph) => { - this.store.handleEvent({ - data: graph - }); - }); - } - - async getNewest(ship: string, resource: string, count: number, index = '') { - const data = await this.scry('graph-store', `/newest/${ship}/${resource}/${count}${index}`); - data['graph-update'].fetch = true; - this.store.handleEvent({ data }); - } - - async getOlderSiblings(ship: string, resource: string, count: number, index = '') { - const idx = index.split('/').map(decToUd).join('/'); - const data = await this.scry('graph-store', - `/node-siblings/older/${ship}/${resource}/${count}${idx}` - ); - data['graph-update'].fetch = true; - this.store.handleEvent({ data }); - } - - async getYoungerSiblings(ship: string, resource: string, count: number, index = '') { - const idx = index.split('/').map(decToUd).join('/'); - const data = await this.scry('graph-store', - `/node-siblings/younger/${ship}/${resource}/${count}${idx}` - ); - data['graph-update'].fetch = true; - this.store.handleEvent({ data }); - } - - async getShallowChildren(ship: string, name: string, index = '') { - const idx = index.split('/').map(decToUd).join('/'); - const data = await this.scry('graph-store', - `/shallow-children/${ship}/${name}${idx}` - ); - data['graph-update'].fetch = true; - this.store.handleEvent({ data }); - } - - async getDeepOlderThan(ship: string, resource: string, startTime = null, count: number) { - const start = startTime ? decToUd(startTime) : 'null'; - const data = await this.scry('graph-store', - `/deep-nodes-older-than/${ship}/${resource}/${count}/${start}` - ); - data['graph-update'].fetch = true; - const node = data['graph-update']; - this.store.handleEvent({ - data: { - 'graph-update-flat': node, - 'graph-update': node - } - }); - } - - async getFirstborn(ship: string, resource: string, index = '') { - const idx = index.split('/').map(decToUd).join('/'); - const data = await this.scry('graph-store', - `/firstborn/${ship}/${resource}${idx}` - ); - data['graph-update'].fetch = true; - const node = data['graph-update']; - this.store.handleEvent({ - data: { - 'graph-update-thread': { - index, - ...node - }, - 'graph-update': node - } - }); - } - - getGraphSubset(ship: string, resource: string, start: string, end: string) { - return this.scry( - 'graph-store', - `/graph-subset/${ship}/${resource}/${end}/${start}` - ).then((subset) => { - this.store.handleEvent({ - data: subset - }); - }); - } - - async getNode(ship: string, resource: string, index: string) { - const idx = index.split('/').map(decToUd).join('/'); - const data = await this.scry( - 'graph-store', - `/node/${ship}/${resource}${idx}` - ); - data['graph-update'].fetch = true; - const node = data['graph-update']; - this.store.handleEvent({ - data: { - 'graph-update-loose': node - } - }); - } -} - diff --git a/pkg/interface/src/logic/api/groups.ts b/pkg/interface/src/logic/api/groups.ts deleted file mode 100644 index ee1807c51..000000000 --- a/pkg/interface/src/logic/api/groups.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Enc, Patp } from '@urbit/api'; -import { - GroupAction, - GroupPolicy, - - GroupPolicyDiff, Resource, - Tag -} from '@urbit/api/groups'; -import { makeResource } from '../lib/group'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class GroupsApi extends BaseApi { - remove(resource: Resource, ships: Patp[]) { - return this.proxyAction({ removeMembers: { resource, ships } }); - } - - addTag(resource: Resource, tag: Tag, ships: Patp[]) { - return this.proxyAction({ addTag: { resource, tag, ships } }); - } - - removeTag(resource: Resource, tag: Tag, ships: Patp[]) { - return this.proxyAction({ removeTag: { resource, tag, ships } }); - } - - add(resource: Resource, ships: Patp[]) { - return this.proxyAction({ addMembers: { resource, ships } }); - } - - removeGroup(resource: Resource) { - return this.storeAction({ removeGroup: { resource } }); - } - - changePolicy(resource: Resource, diff: Enc) { - return this.proxyAction({ changePolicy: { resource, diff } }); - } - - join(ship: string, name: string) { - const resource = makeResource(ship, name); - - return this.viewAction({ join: { resource, ship } }); - } - - create(name: string, policy: Enc, title: string, description: string) { - return this.viewThread('group-create', { - create: { - name, - policy, - title, - description - } - }); - } - - deleteGroup(ship: string, name: string) { - const resource = makeResource(ship, name); - - return this.viewThread('group-delete', { - remove: resource - }); - } - - leaveGroup(ship: string, name: string) { - const resource = makeResource(ship, name); - return this.viewThread('group-leave', { - leave: resource - }); - } - - invite(ship: string, name: string, ships: Patp[], description: string) { - const resource = makeResource(ship, name); - return this.viewThread('group-invite', { - invite: { - resource, - ships, - description - } - }); - } - - hide(resource: string) { - return this.viewAction({ hide: resource }); - } - - private proxyAction(action: GroupAction) { - return this.action('group-push-hook', 'group-update-0', action); - } - - private storeAction(action: GroupAction) { - return this.action('group-store', 'group-update-0', action); - } - - private viewThread(thread: string, action: any) { - return this.spider('group-view-action', 'json', thread, action); - } - - private viewAction(action: any) { - return this.action('group-view', 'group-view-action', action); - } -} diff --git a/pkg/interface/src/logic/api/hark.ts b/pkg/interface/src/logic/api/hark.ts deleted file mode 100644 index 396d4f85c..000000000 --- a/pkg/interface/src/logic/api/hark.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { Association, GraphNotifDescription, IndexedNotification, NotifIndex } from '@urbit/api'; -import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; -import { BigInteger } from 'big-integer'; -import { getParentIndex } from '../lib/notification'; -import { dateToDa, decToUd } from '../lib/util'; -import {reduce} from '../reducers/hark-update'; -import {doOptimistically, optReduceState} from '../state/base'; -import useHarkState from '../state/hark'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -function getHarkSize() { - return useHarkState.getState().notifications.size ?? 0; -} - -export class HarkApi extends BaseApi { - private harkAction(action: any): Promise { - return this.action('hark-store', 'hark-action', action); - } - - private graphHookAction(action: any) { - return this.action('hark-graph-hook', 'hark-graph-hook-action', action); - } - - private groupHookAction(action: any) { - return this.action('hark-group-hook', 'hark-group-hook-action', action); - } - - private actOnNotification(frond: string, intTime: BigInteger | undefined, index: NotifIndex) { - const time = intTime ? decToUd(intTime.toString()) : null; - return this.harkAction({ - [frond]: { - time, - index - } - }); - } - - async setMentions(mentions: boolean) { - await this.graphHookAction({ - 'set-mentions': mentions - }); - } - - setWatchOnSelf(watchSelf: boolean) { - return this.graphHookAction({ - 'set-watch-on-self': watchSelf - }); - } - - setDoNotDisturb(dnd: boolean) { - return this.harkAction({ - 'set-dnd': dnd - }); - } - - async archive(intTime: BigInteger, index: NotifIndex) { - const time = intTime ? decToUd(intTime.toString()) : null; - const action = { - archive: { - time, - index - } - }; - await doOptimistically(useHarkState, action, this.harkAction.bind(this), [reduce]) - } - - read(time: BigInteger, index: NotifIndex) { - return this.harkAction({ - 'read-note': index - }); - } - - readIndex(index: NotifIndex) { - return this.harkAction({ - 'read-index': index - }); - } - - unread(time: BigInteger, index: NotifIndex) { - return this.actOnNotification('unread-note', time, index); - } - - dismissReadCount(graph: string, index: string) { - return this.harkAction({ - 'read-count': { - graph: { - graph, - index - } - } - }); - } - - markCountAsRead(association: Association, parent: string, description: GraphNotifDescription) { - const action = { 'read-count': { - graph: { - graph: association.resource, - group: association.group, - description, - index: parent - } } - }; - doOptimistically(useHarkState, action, this.harkAction.bind(this), [reduce]); - } - - markEachAsRead(association: Association, parent: string, child: string, description: GraphNotifDescription, mod: string) { - return this.harkAction({ - 'read-each': { - index: - { graph: - { graph: association.resource, - group: association.group, - description, - module: mod, - index: parent - } - }, - target: child - } - }); - } - - dec(index: NotifIndex, ref: string) { - return this.harkAction({ - dec: { - index, - ref - } - }); - } - - seen() { - return this.harkAction({ seen: null }); - } - readAll() { - return this.harkAction({ 'read-all': null }); - } - - mute(notif: IndexedNotification) { - if('graph' in notif.index && 'graph' in notif.notification.contents) { - const { index } = notif; - const parentIndex = getParentIndex(index.graph, notif.notification.contents.graph); - if(!parentIndex) { - return Promise.resolve(); - } - return this.ignoreGraph(index.graph.graph, parentIndex); - } - if('group' in notif.index) { - const { group } = notif.index.group; - return this.ignoreGroup(group); - } - return Promise.resolve(); - } - - unmute(notif: IndexedNotification) { - if('graph' in notif.index && 'graph' in notif.notification.contents) { - const { index } = notif; - const parentIndex = getParentIndex(index.graph, notif.notification.contents.graph); - if(!parentIndex) { - return Promise.resolve(); - } - return this.listenGraph(index.graph.graph, parentIndex); - } - if('group' in notif.index) { - return this.listenGroup(notif.index.group.group); - } - return Promise.resolve(); - } - - ignoreGroup(group: string) { - return this.groupHookAction({ - ignore: group - }); - } - - ignoreGraph(graph: string, index: string) { - return this.graphHookAction({ - ignore: { - graph, - index - } - }); - } - - listenGroup(group: string) { - return this.groupHookAction({ - listen: group - }); - } - - listenGraph(graph: string, index: string) { - return this.graphHookAction({ - listen: { - graph, - index - } - }); - } - - async getMore(): Promise { - const offset = getHarkSize(); - const count = 3; - await this.getSubset(offset, count, false); - return offset === getHarkSize(); - } - - async getSubset(offset:number, count:number, isArchive: boolean) { - const where = isArchive ? 'archive' : 'inbox'; - const data = await this.scry('hark-store', `/recent/${where}/${offset}/${count}`); - this.store.handleEvent({ data }); - } - - async getTimeSubset(start?: Date, end?: Date) { - const s = start ? dateToDa(start) : '-'; - const e = end ? dateToDa(end) : '-'; - const result = await this.scry('hark-hook', `/recent/${s}/${e}`); - this.store.handleEvent({ - data: result - }); - } -} diff --git a/pkg/interface/src/logic/api/index.ts b/pkg/interface/src/logic/api/index.ts new file mode 100644 index 000000000..6679b8403 --- /dev/null +++ b/pkg/interface/src/logic/api/index.ts @@ -0,0 +1,8 @@ +import Urbit from '@urbit/http-api'; +const api = new Urbit('', '', (window as any).desk); +api.ship = window.ship; +// api.verbose = true; +// @ts-ignore TODO window typings +window.api = api; + +export default api; diff --git a/pkg/interface/src/logic/api/invite.ts b/pkg/interface/src/logic/api/invite.ts deleted file mode 100644 index 1588879fd..000000000 --- a/pkg/interface/src/logic/api/invite.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Serial } from '@urbit/api'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class InviteApi extends BaseApi { - accept(app: string, uid: Serial) { - return this.inviteAction({ - accept: { - term: app, - uid - } - }); - } - - decline(app: string, uid: Serial) { - return this.inviteAction({ - decline: { - term: app, - uid - } - }); - } - - private inviteAction(action) { - return this.action('invite-store', 'invite-action', action); - } -} diff --git a/pkg/interface/src/logic/api/launch.ts b/pkg/interface/src/logic/api/launch.ts deleted file mode 100644 index 013928188..000000000 --- a/pkg/interface/src/logic/api/launch.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class LaunchApi extends BaseApi { - add(name: string, tile = { basic : { title: '', linkedUrl: '', iconUrl: '' } }) { - return this.launchAction({ add: { name, tile } }); - } - - remove(name: string) { - return this.launchAction({ remove: name }); - } - - changeFirstTime(firstTime = true) { - return this.launchAction({ 'change-first-time': firstTime }); - } - - changeIsShown(name: string, isShown = true) { - return this.launchAction({ 'change-is-shown': { name, isShown } }); - } - - weather(location: string) { - return this.action('weather', 'json', location); - } - - private launchAction(data) { - return this.action('launch', 'launch-action', data); - } -} - diff --git a/pkg/interface/src/logic/api/local.ts b/pkg/interface/src/logic/api/local.ts deleted file mode 100644 index 240e2abd6..000000000 --- a/pkg/interface/src/logic/api/local.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class LocalApi extends BaseApi { - getBaseHash() { - this.scry('file-server', '/clay/base/hash').then((baseHash) => { - this.store.handleEvent({ data: { baseHash } }); - }); - } - - getRuntimeLag() { - return this.scry('launch', '/runtime-lag').then((runtimeLag) => { - this.store.handleEvent({ data: { runtimeLag } }); - }); - } -} diff --git a/pkg/interface/src/logic/api/metadata.ts b/pkg/interface/src/logic/api/metadata.ts deleted file mode 100644 index 97cb1471e..000000000 --- a/pkg/interface/src/logic/api/metadata.ts +++ /dev/null @@ -1,108 +0,0 @@ - -import { Association, Metadata, MetadataUpdatePreview, Path } from '@urbit/api'; -import { uxToHex } from '../lib/util'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class MetadataApi extends BaseApi { - metadataAdd(appName: string, resource: Path, group: Path, title: string, description: string, dateCreated: string, color: string, moduleName: string) { - const creator = `~${this.ship}`; - return this.metadataAction({ - add: { - group, - resource: { - resource, - 'app-name': appName - }, - metadata: { - title, - description, - color, - 'date-created': dateCreated, - creator, - config: { graph: moduleName }, - picture: '', - hidden: false, - preview: false, - vip: '' - } - } - }); - } - - remove(appName: string, resource: string, group: string) { - return this.metadataAction({ - remove: { - group, - resource: { - resource, - 'app-name': appName - } - } - }); - } - - update(association: Association, newMetadata: Partial) { - const metadata = { ...association.metadata, ...newMetadata }; - metadata.color = uxToHex(metadata.color); - return this.metadataAction({ - add: { - group: association.group, - resource: { - resource: association.resource, - 'app-name': association['app-name'] - }, - metadata - } - }); - } - - preview(group: string) { - return new Promise((resolve, reject) => { - const tempChannel: any = new (window as any).channel(); - let done = false; - - setTimeout(() => { - if(done) { - return; - } - done = true; - tempChannel.delete(); - reject(new Error('offline')); - }, 15000); - - tempChannel.subscribe(window.ship, 'metadata-pull-hook', `/preview${group}`, - (err) => { - console.error(err); - reject(err); - tempChannel.delete(); - }, - (ev: any) => { - if ('metadata-hook-update' in ev) { - done = true; - tempChannel.delete(); - const upd = ev['metadata-hook-update'].preview as MetadataUpdatePreview; - resolve(upd); - } else { - done = true; - tempChannel.delete(); - reject(new Error('no-permissions')); - } - }, - (quit) => { - tempChannel.delete(); - if(!done) { - reject(new Error('offline')); - } - }, - (a) => { - console.log(a); - } - ); - }); - } - - private metadataAction(data) { - return this.action('metadata-push-hook', 'metadata-update-1', data); - } -} diff --git a/pkg/interface/src/logic/api/s3.ts b/pkg/interface/src/logic/api/s3.ts deleted file mode 100644 index 14b998a14..000000000 --- a/pkg/interface/src/logic/api/s3.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class S3Api extends BaseApi { - setCurrentBucket(bucket: string) { - return this.s3Action({ 'set-current-bucket': bucket }); - } - - addBucket(bucket: string) { - return this.s3Action({ 'add-bucket': bucket }); - } - - removeBucket(bucket: string) { - return this.s3Action({ 'remove-bucket': bucket }); - } - - setEndpoint(endpoint: string) { - return this.s3Action({ 'set-endpoint': endpoint }); - } - - setAccessKeyId(accessKeyId: string) { - return this.s3Action({ 'set-access-key-id': accessKeyId }); - } - - setSecretAccessKey(secretAccessKey: string) { - return this.s3Action({ 'set-secret-access-key': secretAccessKey }); - } - - private s3Action(data: any) { - return this.action('s3-store', 's3-action', data); - } -} - diff --git a/pkg/interface/src/logic/api/settings.ts b/pkg/interface/src/logic/api/settings.ts deleted file mode 100644 index 47be601ad..000000000 --- a/pkg/interface/src/logic/api/settings.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { - Bucket, Key, - - SettingsUpdate, Value -} from '@urbit/api/settings'; -import { StoreState } from '../store/type'; -import BaseApi from './base'; - -export default class SettingsApi extends BaseApi { - private storeAction(action: SettingsUpdate): Promise { - return this.action('settings-store', 'settings-event', action); - } - - putBucket(key: Key, bucket: Bucket) { - return this.storeAction({ - 'put-bucket': { - 'bucket-key': key, - 'bucket': bucket - } - }); - } - - delBucket(key: Key) { - return this.storeAction({ - 'del-bucket': { - 'bucket-key': key - } - }); - } - - putEntry(buc: Key, key: Key, val: Value) { - return this.storeAction({ - 'put-entry': { - 'bucket-key': buc, - 'entry-key': key, - 'value': val - } - }); - } - - delEntry(buc: Key, key: Key) { - return this.storeAction({ - 'put-entry': { - 'bucket-key': buc, - 'entry-key': key - } - }); - } - - async getAll() { - const { all } = await this.scry('settings-store', '/all'); - this.store.handleEvent({ data: - { 'settings-data': { all } } - }); - } - - async getBucket(bucket: Key) { - const data: Record = await this.scry('settings-store', `/bucket/${bucket}`); - this.store.handleEvent({ data: { 'settings-data': { - 'bucket-key': bucket, - 'bucket': data.bucket - } } }); - } - - async getEntry(bucket: Key, entry: Key) { - const data: Record = await this.scry('settings-store', `/entry/${bucket}/${entry}`); - this.store.handleEvent({ data: { 'settings-data': { - 'bucket-key': bucket, - 'entry-key': entry, - 'entry': data.entry - } } }); - } -} diff --git a/pkg/interface/src/logic/lib/contact.ts b/pkg/interface/src/logic/lib/contact.ts new file mode 100644 index 000000000..b2f7e6c50 --- /dev/null +++ b/pkg/interface/src/logic/lib/contact.ts @@ -0,0 +1,25 @@ +import airlock from '~/logic/api'; +import _ from 'lodash'; +import { fetchIsAllowed } from '@urbit/api'; + +export async function disallowedShipsForOurContact( + ships: string[] +): Promise { + return _.compact( + await Promise.all( + ships.map(async (s) => { + const ship = `~${s}`; + if (s === window.ship) { + return null; + } + const allowed = await airlock.scry(fetchIsAllowed( + `~${window.ship}`, + 'personal', + ship, + true + )); + return allowed ? null : ship; + }) + ) + ); +} diff --git a/pkg/interface/src/logic/lib/fakeApi.test.js b/pkg/interface/src/logic/lib/fakeApi.test.js new file mode 100644 index 000000000..b8bb54b2a --- /dev/null +++ b/pkg/interface/src/logic/lib/fakeApi.test.js @@ -0,0 +1,16 @@ +import { newApi } from './fakeApi'; +describe('API shim', () => { + it('should allow deep accesses', () => { + const api = newApi(); + + expect(api.foo.bar.baz.toString()).toBe('[fakeApi]'); + }); + + it('should return promise on call', () => { + const api = newApi(); + const method = api.foo.bar.baz; + const res = method(); + + expect('then' in res).toBe(true); + }); +}); diff --git a/pkg/interface/src/logic/lib/fakeApi.ts b/pkg/interface/src/logic/lib/fakeApi.ts new file mode 100644 index 000000000..a58d48e13 --- /dev/null +++ b/pkg/interface/src/logic/lib/fakeApi.ts @@ -0,0 +1,22 @@ +export function newApi() { + const target = () => {}; + + const handler = { + apply: function (target, that, args) { + return Promise.resolve(); + }, + get: function (target, prop, receiver) { + const original = target[prop]; + if (prop === 'toString') { + return () => '[fakeApi]'; + } else if (typeof original === 'function') { + return target[prop].bind(target); + } else if (original) { + return target[prop]; + } + return newApi(); + } + }; + + return new Proxy(target, handler) as any; +} diff --git a/pkg/interface/src/logic/lib/fixtures.ts b/pkg/interface/src/logic/lib/fixtures.ts new file mode 100644 index 000000000..33b2c84ff --- /dev/null +++ b/pkg/interface/src/logic/lib/fixtures.ts @@ -0,0 +1,45 @@ +import { Content, GraphNode, unixToDa } from '@urbit/api'; +import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; +import bigInt, { BigInteger } from 'big-integer'; + +export const makeComment = ( + author: string, + time: number, + parentIndex: string, + contents: Content[] +): [BigInteger, GraphNode] => { + const da = unixToDa(time); + const index = `${parentIndex}/${da.toString()}`; + + const children = new BigIntOrderedMap().gas([ + [ + bigInt.one, + { + post: { + index: `${index}/1`, + author, + 'time-sent': time, + signatures: [], + contents: contents, + hash: null + }, + children: new BigIntOrderedMap() + } + ] + ]); + + return [ + da, + { + post: { + index, + author, + 'time-sent': time, + signatures: [], + contents: [], + hash: null + }, + children + } + ]; +}; diff --git a/pkg/interface/src/logic/lib/gcpManager.ts b/pkg/interface/src/logic/lib/gcpManager.ts index 9710e82d9..d74dc79d7 100644 --- a/pkg/interface/src/logic/lib/gcpManager.ts +++ b/pkg/interface/src/logic/lib/gcpManager.ts @@ -12,14 +12,10 @@ // intrinsic expiry. // // -import GlobalApi from '../api/global'; import useStorageState from '../state/storage'; class GcpManager { - #api: GlobalApi | null = null; - - configure(api: GlobalApi) { - this.#api = api; + configure() { } #running = false; @@ -30,10 +26,6 @@ class GcpManager { console.warn('GcpManager already running'); return; } - if (!this.#api) { - console.error('GcpManager must have api set'); - return; - } this.#running = true; this.refreshLoop(); } @@ -63,7 +55,7 @@ class GcpManager { private refreshLoop() { if (!this.#configured) { - this.#api!.gcp.isConfigured() + useStorageState.getState().gcp.isConfigured() .then((configured) => { if (configured === undefined) { throw new Error('can\'t check whether GCP is configured?'); @@ -82,7 +74,7 @@ class GcpManager { }); return; } - this.#api!.gcp.getToken() + useStorageState.getState().gcp.getToken() .then(() => { const token = useStorageState.getState().gcp.token; if (token) { diff --git a/pkg/interface/src/logic/lib/graph.ts b/pkg/interface/src/logic/lib/graph.ts new file mode 100644 index 000000000..194c308ac --- /dev/null +++ b/pkg/interface/src/logic/lib/graph.ts @@ -0,0 +1,27 @@ +import { Graph } from '@urbit/api'; +import { BigInteger } from 'big-integer'; +import _ from 'lodash'; +import useMetadataState from '~/logic/state/metadata'; + +export function getNodeFromGraph(graph: Graph, index: BigInteger[]) { + return _.reduce( + index.slice(1), + (acc, val) => { + return acc?.children?.get(val); + }, + graph.get(index[0]) + ); +} + +export function getPostRoute( + graph: string, + index: BigInteger[], + thread = false +) { + const association = useMetadataState.getState().associations.graph[graph]; + const segment = thread ? 'thread' : 'replies'; + + return `/~landscape${association.group}/feed/${segment}/${index + .map(i => i.toString()) + .join('/')}`; +} diff --git a/pkg/interface/src/logic/lib/group.ts b/pkg/interface/src/logic/lib/group.ts index 7268bcc0d..a0dcba8ab 100644 --- a/pkg/interface/src/logic/lib/group.ts +++ b/pkg/interface/src/logic/lib/group.ts @@ -1,4 +1,4 @@ -import { Path, PatpNoSig } from '@urbit/api'; +import { deSig, Path, PatpNoSig } from '@urbit/api'; import { Group, Resource, roleTags, RoleTags } from '@urbit/api/groups'; import _ from 'lodash'; @@ -36,7 +36,7 @@ export function isWriter(group: Group, resource: string) { } export function isChannelAdmin(group: Group, resource: string, ship = `~${window.ship}`) { - const role = roleForShip(group, ship.slice(1)); + const role = roleForShip(group, deSig(ship)); return ( isHost(resource, ship) || diff --git a/pkg/interface/src/logic/lib/hark.ts b/pkg/interface/src/logic/lib/hark.ts index 1faaf8ae1..6e10ec279 100644 --- a/pkg/interface/src/logic/lib/hark.ts +++ b/pkg/interface/src/logic/lib/hark.ts @@ -1,18 +1,13 @@ import { cite, - GraphNotifIndex, - GroupNotifIndex, - IndexedNotification, NotificationGraphConfig, Post, Unreads } from '@urbit/api'; -import { patp } from 'urbit-ob'; import bigInt, { BigInteger } from 'big-integer'; import _ from 'lodash'; import f from 'lodash/fp'; -import { pluralize } from './util'; -import useMetadataState from '../state/metadata'; +import { emptyHarkStats } from '../state/hark'; export function getLastSeen( unreads: Unreads, @@ -28,13 +23,16 @@ export function getLastSeen( ); } +export function getHarkStats(unreads: Unreads, path: string) { + return unreads?.[path] ?? emptyHarkStats(); +} + export function getUnreadCount( unreads: Unreads, - path: string, - index: string + path: string ): number { - const graphUnreads = unreads.graph?.[path]?.[index]?.unreads ?? 0; - return typeof graphUnreads === 'number' ? graphUnreads : graphUnreads.size; + const { count, each } = getHarkStats(unreads, path); + return count + each.length; } export function getNotificationCount(unreads: Unreads, path: string): number { @@ -56,94 +54,3 @@ export function isWatching( ); } -export function getNotificationKey( - time: BigInteger, - notification: IndexedNotification -): string { - const base = time.toString(); - if ('graph' in notification.index) { - const { graph, index, description } = notification.index.graph; - return `${base}-${graph}-${index}-${description}`; - } else if ('group' in notification.index) { - const { group } = notification.index.group; - return `${base}-${group}`; - } - return `${base}-unknown`; -} - -export function notificationReferent(not: IndexedNotification) { - if ('graph' in not.index) { - return not.index.graph.graph; - } else { - return not.index.group.group; - } -} -export function describeNotification(notification: IndexedNotification) { - function group(idx: GroupNotifIndex) { - switch (idx.description) { - case 'add-members': - return 'joined'; - case 'remove-members': - return 'left'; - default: - return idx.description; - } - } - function graph(idx: GraphNotifIndex, plural: boolean, singleAuthor: boolean) { - const isDm = idx.graph === `/ship/~${window.ship}/dm-inbox`; - if (isDm) { - return 'New DM from '; - } - switch (idx.description) { - case 'post': - return 'Your post received replies in'; - case 'link': - return `New link${plural ? 's' : ''} in`; - case 'comment': - return `New comment${plural ? 's' : ''} on`; - case 'note': - return `New Note${plural ? 's' : ''} in`; - // @ts-ignore need better types - case 'edit-note': - return `updated ${pluralize('note', plural)} in`; - case 'mention': - return 'You were mentioned in'; - case 'message': - if (isDm) { - return 'messaged you'; - } - return `New message${plural ? 's' : ''} in`; - default: return idx.description; - } - } - if ('group' in notification.index) { - return group(notification.index.group); - } else if ('graph' in notification.index) { - // @ts-ignore needs better type guard - const contents = notification.notification?.contents?.graph ?? ([] as Post[]); - return graph( - notification.index.graph, - contents.length > 1, - _.uniq(_.map(contents, 'author')).length === 1 - ); - } -} - -export function getReferent(notification: IndexedNotification) { - const meta = useMetadataState.getState(); - if ('graph' in notification.index) { - if (notification.index.graph.graph === `/ship/~${window.ship}/dm-inbox`) { - const [, ship] = notification.index.graph.index.split('/'); - return cite(patp(ship)); - } - return ( - meta.associations.graph[notification.index.graph.graph]?.metadata - ?.title ?? notification.index.graph - ); - } else if ('group' in notification.index) { - return ( - meta.associations.groups[notification.index.group.group]?.metadata?.title ?? - notification.index.group.group - ); - } -} diff --git a/pkg/interface/src/logic/lib/migrateSettings.ts b/pkg/interface/src/logic/lib/migrateSettings.ts deleted file mode 100644 index d35f6212b..000000000 --- a/pkg/interface/src/logic/lib/migrateSettings.ts +++ /dev/null @@ -1,68 +0,0 @@ -import useLocalState from '~/logic/state/local'; -import useSettingsState from '~/logic/state/settings'; -import { BackgroundConfig, RemoteContentPolicy } from '~/types'; -import GlobalApi from '../api/global'; - -const getBackgroundString = (bg: BackgroundConfig) => { - if (bg?.type === 'url') { - return bg.url; - } else if (bg?.type === 'color') { - return bg.color; - } else { - return ''; - } -}; - -export function useMigrateSettings(api: GlobalApi) { - const local = useLocalState(); - const { display, remoteContentPolicy, calm } = useSettingsState(); - - return async () => { - const promises: Promise[] = []; - - if (local.hideAvatars !== calm.hideAvatars) { - promises.push( - api.settings.putEntry('calm', 'hideAvatars', local.hideAvatars) - ); - } - - if (local.hideNicknames !== calm.hideNicknames) { - promises.push( - api.settings.putEntry('calm', 'hideNicknames', local.hideNicknames) - ); - } - - if ( - local?.background?.type && - display.background !== getBackgroundString(local.background) - ) { - promises.push( - api.settings.putEntry( - 'display', - 'background', - getBackgroundString(local.background) - ) - ); - promises.push( - api.settings.putEntry( - 'display', - 'backgroundType', - local.background?.type - ) - ); - } - - Object.keys(local.remoteContentPolicy).forEach((_key) => { - const key = _key as keyof RemoteContentPolicy; - const localVal = local.remoteContentPolicy[key]; - if (localVal !== remoteContentPolicy[key]) { - promises.push( - api.settings.putEntry('remoteContentPolicy', key, localVal) - ); - } - }); - - await Promise.all(promises); - localStorage.removeItem('localReducer'); - }; -} diff --git a/pkg/interface/src/logic/lib/notification.ts b/pkg/interface/src/logic/lib/notification.ts deleted file mode 100644 index 7514d1e0c..000000000 --- a/pkg/interface/src/logic/lib/notification.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { GraphNotificationContents, GraphNotifIndex } from '@urbit/api'; - -export function getParentIndex( - idx: GraphNotifIndex, - contents: GraphNotificationContents -) { - const origIndex = contents[0].index.slice(1).split('/'); - const ret = (i: string[]) => `/${i.join('/')}`; - switch (idx.description) { - case 'link': - return '/'; - case 'comment': - return ret(origIndex.slice(0, 1)); - case 'note': - return '/'; - case 'mention': - return undefined; - default: - return undefined; - } -} diff --git a/pkg/interface/src/logic/lib/notificationRedirects.ts b/pkg/interface/src/logic/lib/notificationRedirects.ts new file mode 100644 index 000000000..d6befab54 --- /dev/null +++ b/pkg/interface/src/logic/lib/notificationRedirects.ts @@ -0,0 +1,92 @@ +import useMetadataState from '../state/metadata'; +import ob from 'urbit-ob'; + +function getGroupResourceRedirect(key: string) { + const association = useMetadataState.getState().associations.graph[`/ship/${key}`]; + const { metadata } = association; + if(!association || !('graph' in metadata.config)) { + return ''; + } + + const section = association.group === association.resource ? '/messages' : association.group; + return `/~landscape${section}/resource/${metadata.config.graph}${association.resource}`; +} + +function getPostRedirect(key: string, segs: string[]) { + const association = useMetadataState.getState().associations.graph[`/ship/${key}`]; + const { metadata } = association; + if(!association || !('graph' in metadata.config)) { + return ''; + } + return `/~landscape${association.group}/feed/thread/${segs.slice(0, -1).join('/')}`; +} + +function getChatRedirect(chat: string, segs: string[]) { + const qs = segs.length > 0 ? `?msg=${segs[0]}` : ''; + return `${getGroupResourceRedirect(chat)}${qs}`; +} + +function getPublishRedirect(graphKey: string, segs: string[]) { + const base = getGroupResourceRedirect(graphKey); + if(segs.length === 3) { + return `${base}/note/${segs[0]}`; + } else if (segs.length === 4) { + return `${base}/note/${segs[0]}?selected=${segs[2]}`; + } + return base; +} + +function getLinkRedirect(graphKey: string, segs: string[]) { + const base = getGroupResourceRedirect(graphKey); + if(segs.length === 1) { + return `${base}/index/${segs[0]}`; + } else if (segs.length === 3) { + return `${base}/index/${segs[0]}?selected=${segs[1]}`; + } + return base; +} + +function getGraphRedirect(link: string) { + const [,mark, ship, name, ...rest] = link.split('/'); + const graphKey = `${ship}/${name}`; + switch(mark) { + case 'graph-validator-dm': + return `/~landscape/messages/dm/${ob.patp(rest[0])}`; + case 'graph-validator-chat': + return getChatRedirect(graphKey, rest); + case 'graph-validator-publish': + return getPublishRedirect(graphKey, rest); + case 'graph-validator-link': + return getLinkRedirect(graphKey, rest); + case 'graph-validator-post': + return getPostRedirect(graphKey, rest); + default: + return''; + } +} + +function getInviteRedirect(link: string) { + const [,,app,uid] = link.split('/'); + return `/invites/${app}/${uid}`; +} + +function getDmRedirect(link: string) { + const [,,ship] = link.split('/'); + return `/~landscape/messages/dm/${ship}`; +} +function getGroupRedirect(link: string) { + const [,,ship,name] = link.split('/'); + return `/~landscape/ship/${ship}/${name}`; +} + +export function getNotificationRedirect(link: string) { + if(link.startsWith('/graph-validator')) { + return getGraphRedirect(link); + } else if (link.startsWith('/invite')) { + return getInviteRedirect(link); + } else if (link.startsWith('/dm')) { + return getDmRedirect(link); + } else if (link.startsWith('/groups')) { + return getGroupRedirect(link); + } +} diff --git a/pkg/interface/src/logic/lib/omnibox.js b/pkg/interface/src/logic/lib/omnibox.ts similarity index 90% rename from pkg/interface/src/logic/lib/omnibox.js rename to pkg/interface/src/logic/lib/omnibox.ts index 1870db33f..9febb443f 100644 --- a/pkg/interface/src/logic/lib/omnibox.js +++ b/pkg/interface/src/logic/lib/omnibox.ts @@ -10,8 +10,18 @@ const makeIndexes = () => new Map([ ['other', []] ]); +export interface OmniboxItem { + title: string; + link: string; + app: string; + host: string; + description: string; + shiftLink: string; + shiftDescription: string; +} + // result schematic -const result = function(title, link, app, host, description = 'Open', shiftLink = null, shiftDescription = null) { +const result = function(title: string, link: string, app: string, host: string, description = 'Open', shiftLink = null as string | null, shiftDescription = null as string | null): OmniboxItem { return { 'title': title, 'link': link, @@ -78,12 +88,11 @@ const otherIndex = function(config) { const other = []; const idx = { mychannel: result('My Channels', '/~landscape/home', 'home', null), - updates: result('Notifications', '/~notifications', 'inbox', null), profile: result('Profile', `/~profile/~${window.ship}`, 'profile', null), + updates: result('Notifications', '/~notifications', 'notifications', null), messages: result('Messages', '/~landscape/messages', 'messages', null), logout: result('Log Out', '/~/logout', 'logout', null) }; - other.push(result('Tutorial', '/?tutorial=true', 'tutorial', null)); for(const cat of config.categories) { if(idx[cat]) { other.push(idx[cat]); @@ -93,7 +102,7 @@ const otherIndex = function(config) { return other; }; -export default function index(contacts, associations, apps, currentGroup, groups, hide) { +export default function index(contacts, associations, apps, currentGroup, groups, hide): Map { const indexes = makeIndexes(); indexes.set('ships', shipIndex(contacts)); // all metadata from all apps is indexed @@ -117,7 +126,7 @@ export default function index(contacts, associations, apps, currentGroup, groups let app = each['app-name']; if (each['app-name'] === 'contacts') { app = 'groups'; - }; + } if (each['app-name'] === 'graph') { app = each.metadata.config.graph; @@ -159,4 +168,4 @@ export default function index(contacts, associations, apps, currentGroup, groups indexes.set('other', otherIndex(hide)); return indexes; -}; +} diff --git a/pkg/interface/src/logic/lib/permalinks.ts b/pkg/interface/src/logic/lib/permalinks.ts index d225dc317..46d550e72 100644 --- a/pkg/interface/src/logic/lib/permalinks.ts +++ b/pkg/interface/src/logic/lib/permalinks.ts @@ -2,6 +2,8 @@ import { ReferenceContent, resourceFromPath } from '@urbit/api'; +import { isValidPatp } from 'urbit-ob'; +import _ from 'lodash'; export function getPermalinkForGraph( group: string, @@ -18,7 +20,15 @@ function getPermalinkForAssociatedGroup(group: string) { return `web+urbitgraph://group/${ship}/${name}`; } -type Permalink = GraphPermalink | GroupPermalink; +type Permalink = AppPermalink | GraphPermalink | GroupPermalink; + +export interface AppPermalink { + type: 'app'; + link: string; + ship: string; + desk: string; + path: string; +} export interface GroupPermalink { type: 'group'; @@ -54,20 +64,13 @@ function parseGraphPermalink( } export function permalinkToReference(link: Permalink): ReferenceContent { - if(link.type === 'graph') { - const reference = { - graph: { - graph: link.graph, - group: link.group, - index: link.index - } - }; - return { reference }; - } else { - const reference = { - group: link.group - }; - return { reference }; + switch (link.type) { + case 'graph': + return { reference: { graph: _.omit(link, ['type', 'link']) } }; + case 'group': + return { reference: { group: link.group } }; + case 'app': + return { reference: { app: _.omit(link, ['type', 'link']) } }; } } @@ -80,6 +83,15 @@ export function referenceToPermalink({ reference }: ReferenceContent): Permalink link, ...reference.graph }; + } else if ('app' in reference) { + const { ship, desk, path } = reference.app; + return { + type: 'app', + link: `web+urbitgraph://${ship}/${desk}${path}`, + ship, + desk, + path + }; } else { const link = `web+urbitgraph://group${reference.group.slice(5)}`; return { @@ -92,6 +104,7 @@ export function referenceToPermalink({ reference }: ReferenceContent): Permalink export function parsePermalink(url: string): Permalink | null { const [kind, ...rest] = url.slice(17).split('/'); + if (kind === 'group') { const [ship, name, ...graph] = rest; const group = `/ship/${ship}/${name}`; @@ -104,5 +117,18 @@ export function parsePermalink(url: string): Permalink | null { link: url.slice(11) }; } + + if (isValidPatp(kind)) { + const [desk, ...parts] = rest; + const path = '/' + parts.join('/'); + return { + type: 'app', + link: url, + ship: kind, + desk, + path + }; + } + return null; } diff --git a/pkg/interface/src/logic/lib/shortcutContext.tsx b/pkg/interface/src/logic/lib/shortcutContext.tsx index 4f14a86e8..f12eb3867 100644 --- a/pkg/interface/src/logic/lib/shortcutContext.tsx +++ b/pkg/interface/src/logic/lib/shortcutContext.tsx @@ -5,7 +5,7 @@ import React, { useEffect, useMemo, useRef, - useState, + useState } from 'react'; import _ from 'lodash'; import { getChord } from '~/logic/lib/util'; @@ -13,10 +13,9 @@ import { getChord } from '~/logic/lib/util'; type Handler = (e: KeyboardEvent) => void; const fallback: ShortcutContextProps = { add: () => {}, - remove: () => {}, + remove: () => {} }; - export const ShortcutContext = createContext(fallback); export interface ShortcutContextProps { add: (cb: (e: KeyboardEvent) => void, key: string) => void; @@ -27,19 +26,19 @@ export function ShortcutContextProvider({ children }) { const handlerRef = useRef(() => {}); const add = useCallback((cb: Handler, key: string) => { - setShortcuts((s) => ({ ...s, [key]: cb })); + setShortcuts(s => ({ ...s, [key]: cb })); }, []); const remove = useCallback((cb: Handler, key: string) => { - setShortcuts((s) => (key in s ? _.omit(s, key) : s)); + setShortcuts(s => (key in s ? _.omit(s, key) : s)); }, []); useEffect(() => { function onKeypress(e: KeyboardEvent) { handlerRef.current(e); } - document.addEventListener('keypress', onKeypress); + document.addEventListener('keydown', onKeypress); return () => { - document.removeEventListener('keypress', onKeypress); + document.removeEventListener('keydown', onKeypress); }; }, []); @@ -50,7 +49,7 @@ export function ShortcutContextProvider({ children }) { }; }, [shortcuts]); - const value = useMemo(() => ({ add, remove }), [add, remove]) + const value = useMemo(() => ({ add, remove }), [add, remove]); return ( diff --git a/pkg/interface/src/logic/lib/suspend.ts b/pkg/interface/src/logic/lib/suspend.ts new file mode 100644 index 000000000..1d6d5f468 --- /dev/null +++ b/pkg/interface/src/logic/lib/suspend.ts @@ -0,0 +1,38 @@ +export type SuspendState = 'result' | 'error' | 'pending'; + +export interface Suspender { + read: () => T; +} + +export function suspend(awaiting: Promise): Suspender { + let state: SuspendState = 'pending'; + let result: T | null = null; + + const promise = awaiting + .then((res) => { + state = 'result'; + result = res; + }) + .catch((e) => { + state = 'error'; + result = e; + }); + + return { + read: () => { + if (state === 'result') { + return result!; + } else if (state === 'error') { + throw result; + } else { + throw promise; + } + } + }; +} + +export function suspendWithResult(result: T): Suspender { + return { + read: () => result + }; +} diff --git a/pkg/interface/src/logic/lib/tokenizeMessage.js b/pkg/interface/src/logic/lib/tokenizeMessage.js index e2f46ad94..84c25492e 100644 --- a/pkg/interface/src/logic/lib/tokenizeMessage.js +++ b/pkg/interface/src/logic/lib/tokenizeMessage.js @@ -1,11 +1,11 @@ import urbitOb from 'urbit-ob'; import { parsePermalink, permalinkToReference } from '~/logic/lib/permalinks'; -const URL_REGEX = new RegExp(String(/^([^[\]]*?)(([\w\-\+]+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+[\w/])([\s\S]*)/.source)); +const URL_REGEX = new RegExp(String(/^([\s\S]*?)(([\w\-\+]+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+[-a-zA-Z0-9:@;?&=\/%\+\*!'\(\)\$_\{\}\^~\[\]`#|])([\s\S]*)/.source)); const PATP_REGEX = /^([\s\S]*?)(~[a-z_-]+)([\s\S]*)/; -const GROUP_REGEX = new RegExp(String(/^([\s\S ]*?)(~[-a-z_]+\/[-a-z]+)([\s\S]*)/.source)); +const GROUP_REGEX = new RegExp(String(/^([\s\S ]*?)(~[-a-z_]+\/[-a-z0-9]+)([\s\S]*)/.source)); const convertToGroupRef = group => `web+urbitgraph://group/${group}`; @@ -18,7 +18,15 @@ export const isUrl = (str) => { }; const raceRegexes = (str) => { - const link = str.match(URL_REGEX); + let link = str.match(URL_REGEX); + while(link?.[1]?.endsWith('(')) { + const resumePos = link[1].length + link[2].length; + const resume = str.slice(resumePos); + link = resume.match(URL_REGEX); + if(link) { + link[1] = str.slice(0, resumePos) + link[1]; + } + } const groupRef = str.match(GROUP_REGEX); const mention = str.match(PATP_REGEX); let pfix = str; @@ -33,9 +41,10 @@ const raceRegexes = (str) => { content = { url: link[2] }; } } - if(groupRef && groupRef[1].length < pfix?.length) { + const perma = parsePermalink(convertToGroupRef(groupRef?.[2])); + const [,,host] = perma?.group.split('/') ?? []; + if(groupRef && groupRef[1].length < pfix?.length && Boolean(perma) && urbitOb.isValidPatp(host)) { pfix = groupRef[1]; - const perma = parsePermalink(convertToGroupRef(groupRef[2])); content = permalinkToReference(perma); sfix = groupRef[3]; } diff --git a/pkg/interface/src/logic/lib/tokenizeMessage.test.js b/pkg/interface/src/logic/lib/tokenizeMessage.test.js index 98a4559e5..2ddb4c1f6 100644 --- a/pkg/interface/src/logic/lib/tokenizeMessage.test.js +++ b/pkg/interface/src/logic/lib/tokenizeMessage.test.js @@ -93,4 +93,49 @@ describe('tokenizeMessage', () => { expect(three).toEqual(' test '); expect(hastuc).toEqual('~hastuc-dibtux'); }); + it('should tokenize a url with a par', () => { + const example = 'test https://en.wikipedia.org/wiki/Turbo_(gastropod)'; + + const [{ text }, { url }] = tokenizeMessage(example); + expect(text).toBe('test '); + expect(url).toBe('https://en.wikipedia.org/wiki/Turbo_(gastropod)'); + }); + it('should ignore ending commas', () => { + const example = 'https://tlon.io/test, foo'; + const [{ url }, { text }] = tokenizeMessage(example); + expect(text).toBe(', foo'); + expect(url).toBe('https://tlon.io/test'); + }); + + it('should ignore ending dots', () => { + const example = 'https://tlon.io/test. foo'; + const [{ url }, { text }] = tokenizeMessage(example); + expect(text).toBe('. foo'); + expect(url).toBe('https://tlon.io/test'); + }); + + it('should ignore malformed group links', () => { + const example = 'test ~zoid/fakegroup'; + const [{ text }, ...rest] = tokenizeMessage(example); + expect(text).toBe(example); + expect(rest.length).toBe(0); + }); + it('should handle groups with numbers', () => { + const example = 'oh no, ~sampel/group-123-abc'; + + const [{ text }, { reference }] = tokenizeMessage(example); + expect(text).toBe('oh no, '); + expect(reference.group).toBe('/ship/~sampel/group-123-abc'); + }); + it('should handle permalinks after inline urls', () => { + const example = 'test [test](https://tlon.io) web+urbitgraph://group/~middev/the-forge/graph/~littel-wolfur/writs-7082/170141184505164612398001831549075456000/2/170141184505164722986064231401764421632'; + + const [{ text }, { reference: { graph } }] = tokenizeMessage(example); + + expect(text).toBe('test [test](https://tlon.io) '); + expect(graph.group).toBe('/ship/~middev/the-forge'); + expect(graph.graph).toBe('/ship/~littel-wolfur/writs-7082'); + expect(graph.index).toBe('/170141184505164612398001831549075456000/2/170141184505164722986064231401764421632'); + }); }); + diff --git a/pkg/interface/src/logic/lib/tutorialModal.ts b/pkg/interface/src/logic/lib/tutorialModal.ts deleted file mode 100644 index 81908f4ee..000000000 --- a/pkg/interface/src/logic/lib/tutorialModal.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { Associations } from '@urbit/api'; -import { AlignX, AlignY } from '~/logic/lib/relativePosition'; -import { TutorialProgress } from '~/types'; -import { Direction } from '~/views/components/Triangle'; - -export const MODAL_WIDTH = 256; -export const MODAL_HEIGHT = 256; -export const MODAL_WIDTH_PX = `${MODAL_WIDTH}px`; -export const MODAL_HEIGHT_PX = `${MODAL_HEIGHT}px`; - -export const TUTORIAL_HOST = process.env.TUTORIAL_HOST!; -export const TUTORIAL_GROUP = process.env.TUTORIAL_GROUP!; -export const TUTORIAL_CHAT = process.env.TUTORIAL_CHAT!; -export const TUTORIAL_BOOK = process.env.TUTORIAL_BOOK!; -export const TUTORIAL_LINKS = process.env.TUTORIAL_LINKS!; -export const TUTORIAL_GROUP_RESOURCE = `/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}` ; - -interface StepDetail { - title: string; - description: string; - url: string; - alignX: AlignX | AlignX[]; - alignY: AlignY | AlignY[]; - offsetX: number; - offsetY: number; - arrow?: Direction; -} - -export function hasTutorialGroup(props: { associations: Associations }) { - return ( - TUTORIAL_GROUP_RESOURCE in props.associations.groups - ); -} - -export const getTrianglePosition = (dir: Direction) => { - const midY = `${MODAL_HEIGHT / 2 - 8}px`; - const midX = `${MODAL_WIDTH / 2 - 8}px`; - switch(dir) { - case 'East': - return { - top: midY, - right: '-32px' - }; - case 'West': - return { - top: midY, - left: '-32px' - }; - case 'North': - return { - top: '-32px', - left: midX - }; - case 'South': - return { - bottom: '-32px', - left: midX - }; - } -}; - -export const progressDetails: Record = { - hidden: {} as any, - exit: {} as any, - done: { - title: 'End', - description: - 'This tutorial is finished. Would you like to leave Beginner Island?', - url: '/', - alignX: 'right', - alignY: 'top', - offsetX: MODAL_WIDTH + 8, - offsetY: 0 - }, - start: { - title: 'New Group added', - description: - 'We just added you to the Beginner island group to show you around. This group is public, but other groups can be private', - url: '/', - alignX: 'right', - alignY: 'top', - arrow: 'West', - offsetX: MODAL_WIDTH + 24, - offsetY: 64 - }, - 'group-desc': { - title: 'What\'s a group', - description: - 'A group contains members and tends to be centered around a topic or multiple topics.', - url: `/~landscape/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}`, - alignX: 'left', - alignY: 'top', - arrow: 'East', - offsetX: MODAL_WIDTH + 24, - offsetY: 80 - }, - channels: { - title: 'Channels', - description: - 'Inside a group you have three types of Channels: Chat, Collection, or Notebook. Mix and match these depending on your group context!', - url: `/~landscape/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}`, - alignY: 'top', - alignX: 'right', - arrow: 'West', - offsetX: MODAL_WIDTH + 24, - offsetY: -8 - }, - chat: { - title: 'Chat', - description: - 'Chat channels are for messaging within your group. Direct Messages can be accessed from Messages in the top right', - url: `/~landscape/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}/resource/chat/ship/${TUTORIAL_HOST}/${TUTORIAL_CHAT}`, - alignY: 'top', - arrow: 'North', - alignX: 'right', - offsetY: -56, - offsetX: -8 - }, - link: { - title: 'Collection', - description: - 'A collection is where you can share and view links, images, and other media within your group. Every item in a Collection can have it’s own comment thread.', - url: `/~landscape/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}/resource/link/ship/${TUTORIAL_HOST}/${TUTORIAL_LINKS}`, - alignY: 'top', - alignX: 'right', - arrow: 'North', - offsetX: -8, - offsetY: -56 - }, - publish: { - title: 'Notebook', - description: - 'Notebooks are for creating long-form content within your group. Use markdown to create rich posts with headers, lists and images.', - url: `/~landscape/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}/resource/publish/ship/${TUTORIAL_HOST}/${TUTORIAL_BOOK}`, - alignY: 'top', - alignX: 'right', - arrow: 'North', - offsetX: -8, - offsetY: -56 - }, - notifications: { - title: 'Notifications', - description: 'You will get updates from subscribed channels and mentions here. You can access Notifications through Leap.', - url: '/~notifications', - alignY: 'top', - alignX: 'left', - arrow: 'North', - offsetX: 0, - offsetY: -48 - }, - profile: { - title: 'Profile', - description: - 'Your profile is customizable and can be shared with other ships. Enter as much or as little information as you’d like.', - url: `/~profile/~${window.ship}`, - alignY: 'top', - alignX: 'right', - arrow: 'South', - offsetX: -300 + MODAL_WIDTH / 2, - offsetY: -4 - }, - leap: { - title: 'Leap', - description: - 'Leap allows you to go to a specific channel, message, collection, profile or group simply by typing in a command or selecting a shortcut from the dropdown menu.', - url: `/~profile/~${window.ship}`, - alignY: 'top', - alignX: 'left', - arrow: 'North', - offsetX: 76, - offsetY: -48 - } -}; diff --git a/pkg/interface/src/logic/lib/useDrag.ts b/pkg/interface/src/logic/lib/useDrag.ts index 706b9ddc9..58e14a9a2 100644 --- a/pkg/interface/src/logic/lib/useDrag.ts +++ b/pkg/interface/src/logic/lib/useDrag.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { DragEvent, useCallback, useEffect, useState, useMemo } from 'react'; function validateDragEvent(e: DragEvent): FileList | File[] | true | null { const files: File[] = []; @@ -37,17 +37,17 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi const [dragging, setDragging] = useState(false); const onDragEnter = useCallback( - (e: DragEvent) => { + (e: DragEvent) => { if (!validateDragEvent(e)) { return; } setDragging(true); }, - [setDragging] + [] ); const onDrop = useCallback( - (e: DragEvent) => { + (e: DragEvent) => { setDragging(false); const files = validateDragEvent(e); if (!files || files === true) { @@ -56,11 +56,11 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi e.preventDefault(); dragged(files, e); }, - [setDragging, dragged] + [dragged] ); const onDragOver = useCallback( - (e: DragEvent) => { + (e: DragEvent) => { if (!validateDragEvent(e)) { return; } @@ -77,7 +77,7 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi setDragging(false); } }, - [setDragging] + [] ); useEffect(() => { @@ -92,12 +92,12 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi }; }, []); - const bind = { + const bind = useMemo(() => ({ onDragLeave, onDragOver, onDrop, onDragEnter - }; + }), [onDragEnter, onDragOver, onDrop, onDragEnter]); - return { bind, dragging }; + return useMemo(() => ({ bind, dragging }), [bind, dragging]); } diff --git a/pkg/interface/src/logic/lib/useFileUpload.ts b/pkg/interface/src/logic/lib/useFileUpload.ts new file mode 100644 index 000000000..0ce14f912 --- /dev/null +++ b/pkg/interface/src/logic/lib/useFileUpload.ts @@ -0,0 +1,77 @@ +import _ from 'lodash'; +import { useState, ClipboardEvent } from 'react'; +import { useFileDrag } from './useDrag'; +import useStorage, { IuseStorage } from './useStorage'; + +export type FileUploadSource = 'drag' | 'paste' | 'direct'; + +interface FileUploadEventHandlers { + onSuccess: (url: string, source: FileUploadSource) => void; + onError?: (error: Error) => void; +} + +interface FileUploadHandler { + onFiles: ( + files: FileList | File[], + storage?: IuseStorage, + uploadSource?: FileUploadSource + ) => void | Promise; +} + +function isFileUploadHandler(obj: any): obj is FileUploadHandler { + return typeof obj.onFiles === 'function'; +} + +type useFileUploadParams = { + multiple?: boolean; +} & (FileUploadEventHandlers | FileUploadHandler) + +export function useFileUpload({ multiple = true, ...params }: useFileUploadParams) { + const storage = useStorage(); + const { + canUpload, uploadDefault + } = storage; + const [source, setSource] = useState('paste'); + const drag = useFileDrag(f => uploadFiles(f, 'drag')); + + function onPaste(event: ClipboardEvent) { + if (!event.clipboardData || !event.clipboardData.files.length) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + uploadFiles(event.clipboardData.files, 'paste'); + } + + function uploadFiles(files: FileList | File[], uploadSource: FileUploadSource) { + if (isFileUploadHandler(params)) { + return params.onFiles(files, storage, uploadSource); + } + + if (!canUpload) { + return; + } + + setSource(uploadSource); + + const { onSuccess, onError } = params as FileUploadEventHandlers; + const fileArray = Array.from(files); + const toUpload = multiple ? fileArray : _.take(fileArray); + toUpload.forEach((file) => { + uploadDefault(file) + .then(url => onSuccess(url, source)) + .catch((err: Error) => { + console.log(err); + onError && onError(err); + }); + }); + } + + return { + ...storage, + onPaste, + drag + }; +} diff --git a/pkg/interface/src/logic/lib/useLazyScroll.ts b/pkg/interface/src/logic/lib/useLazyScroll.ts index fe2d9ec10..a3068f38a 100644 --- a/pkg/interface/src/logic/lib/useLazyScroll.ts +++ b/pkg/interface/src/logic/lib/useLazyScroll.ts @@ -36,10 +36,10 @@ export function useLazyScroll( }; useEffect(() => { - if((oldCount > count) && ref.current) { + if((oldCount > count) && ref.current && !isLoading) { loadUntil(ref.current); } - }, [count]); + }, [count, isLoading]); useEffect(() => { if(!ready) { @@ -48,7 +48,7 @@ export function useLazyScroll( }, [ready]); useEffect(() => { - if (!ref.current || isDone || !ready) { + if (!ref.current || isDone || !ready || isLoading) { return; } const scroll = ref.current; @@ -64,7 +64,7 @@ export function useLazyScroll( return () => { ref.current?.removeEventListener('scroll', onScroll); }; - }, [ref?.current, ready, isDone]); + }, [ref?.current, ready, isDone, isLoading]); return { isDone, isLoading }; } diff --git a/pkg/interface/src/logic/lib/useLocalStorageState.ts b/pkg/interface/src/logic/lib/useLocalStorageState.ts index d64b9f6d0..396f010c3 100644 --- a/pkg/interface/src/logic/lib/useLocalStorageState.ts +++ b/pkg/interface/src/logic/lib/useLocalStorageState.ts @@ -1,6 +1,6 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useMemo, useEffect, useState } from 'react'; -function retrieve(key: string, initial: T): T { +export function retrieve(key: string, initial: T): T { const s = localStorage.getItem(key); if (s) { try { @@ -12,26 +12,16 @@ function retrieve(key: string, initial: T): T { return initial; } -interface SetStateFunc { - (t: T): T; -} -// See microsoft/typescript#37663 for filed bug -type SetState = T extends any ? SetStateFunc : never; export function useLocalStorageState(key: string, initial: T): any { - const [state, _setState] = useState(() => retrieve(key, initial)); + const [state, setState] = useState(() => retrieve(key, initial)); useEffect(() => { - _setState(retrieve(key, initial)); + setState(retrieve(key, initial)); }, [key]); - const setState = useCallback( - (s: SetState) => { - const updated = typeof s === 'function' ? s(state) : s; - _setState(updated); - localStorage.setItem(key, JSON.stringify(updated)); - }, - [_setState, key, state] - ); + useEffect(() => { + localStorage.setItem(key, JSON.stringify(state)); + }, [state]); - return [state, setState] as const; + return useMemo(() => [state, setState] as const, [state, setState]); } diff --git a/pkg/interface/src/logic/lib/useResize.ts b/pkg/interface/src/logic/lib/useResize.ts new file mode 100644 index 000000000..4daf40b1d --- /dev/null +++ b/pkg/interface/src/logic/lib/useResize.ts @@ -0,0 +1,30 @@ +import { useEffect, useMemo, useRef } from 'react'; +import _ from 'lodash'; + +export function useResize( + callback: (entry: ResizeObserverEntry, observer: ResizeObserver) => void +) { + const ref = useRef(); + + useEffect(() => { + function observer( + entries: ResizeObserverEntry[], + observer: ResizeObserver + ) { + for (const entry of _.flatten(entries)) { + callback(entry, observer); + } + } + let el = ref.current; + const resizeObs = new ResizeObserver(observer); + resizeObs.observe(el, { box: 'border-box' }); + + return () => { + resizeObs.unobserve(el); + }; + }, [callback]); + + const bind = useMemo(() => ({ ref }), [ref]); + + return bind; +} diff --git a/pkg/interface/src/logic/lib/useUrlField.tsx b/pkg/interface/src/logic/lib/useUrlField.tsx new file mode 100644 index 000000000..7672e1f19 --- /dev/null +++ b/pkg/interface/src/logic/lib/useUrlField.tsx @@ -0,0 +1,34 @@ +import { useField } from 'formik'; +import { MutableRefObject, useCallback, useMemo } from 'react'; +import useStorage from './useStorage'; + +export function useUrlField( + id: string, + ref: MutableRefObject +) { + const [field, meta, helpers] = useField(id); + const { setValue, setError } = helpers; + + const storage = useStorage(); + const { uploadDefault, canUpload } = storage; + + const onImageUpload = useCallback(async () => { + const file = ref.current?.files?.item(0); + + if (!file || !canUpload) { + return; + } + try { + const url = await uploadDefault(file); + setValue(url); + } catch (e) { + setError(e.message); + } + }, [ref.current, uploadDefault, canUpload, setValue]); + const extStorage = useMemo(() => ({ ...storage, onImageUpload }), [ + storage, + onImageUpload + ]); + + return [field, meta, helpers, extStorage] as const; +} diff --git a/pkg/interface/src/logic/lib/util.tsx b/pkg/interface/src/logic/lib/util.tsx index 38ec6c870..70dec9192 100644 --- a/pkg/interface/src/logic/lib/util.tsx +++ b/pkg/interface/src/logic/lib/util.tsx @@ -1,17 +1,14 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import _ from 'lodash'; import { patp2dec } from 'urbit-ob'; -import f, { compose, memoize } from 'lodash/fp'; +import f from 'lodash/fp'; import { Association, Contact, Patp } from '@urbit/api'; -import produce, { enableMapSet } from 'immer'; -import useSettingsState from '../state/settings'; +import { enableMapSet } from 'immer'; /* eslint-disable max-lines */ import anyAscii from 'any-ascii'; import { sigil as sigiljs, stringRenderer } from '@tlon/sigil-js'; import bigInt, { BigInteger } from 'big-integer'; -import { foregroundFromBackground } from '~/logic/lib/sigil'; import { IconRef, Workspace } from '~/types'; -import useContactState from '../state/contact'; enableMapSet(); @@ -50,14 +47,17 @@ export function parentPath(path: string) { return _.dropRight(path.split('/'), 1).join('/'); } -/** +/* * undefined -> initial * null -> disabled feed * string -> enabled feed */ export function getFeedPath(association: Association): string | null | undefined { - const { metadata } = association; - if(metadata.config && 'group' in metadata?.config && metadata.config?.group) { + const metadata = association?.metadata; + if(!metadata) { + return undefined; + } + if (metadata?.config && 'group' in metadata?.config && metadata.config?.group) { if ('resource' in metadata.config.group) { return metadata.config.group.resource; } @@ -67,23 +67,26 @@ export function getFeedPath(association: Association): string | null | undefined } export const getChord = (e: KeyboardEvent) => { - let chord = [e.key]; + const chord = [e.key]; if(e.metaKey) { chord.unshift('meta'); } if(e.ctrlKey) { chord.unshift('ctrl'); } + if(e.shiftKey) { + chord.unshift('shift'); + } return chord.join('+'); -} +}; export function getResourcePath(workspace: Workspace, path: string, joined: boolean, mod: string) { const base = workspace.type === 'group' ? `/~landscape${workspace.group}` : workspace.type === 'home' - ? `/~landscape/home` - : `/~landscape/messages`; - return `${base}/${joined ? 'resource' : 'join'}/${mod}${path}` + ? '/~landscape/home' + : '/~landscape/messages'; + return `${base}/${joined ? 'resource' : 'join'}/${mod}${path}`; } const DA_UNIX_EPOCH = bigInt('170141184475152167957503069145530368000'); // `@ud` ~1970.1.1 @@ -135,14 +138,14 @@ export function decToUd(str: string): string { ); } -/** +/* * Clamp a number between a min and max */ export function clamp(x: number, min: number, max: number) { return Math.max(min, Math.min(max, x)); } -/** +/* * Euclidean modulo */ export function modulo(x: number, mod: number) { @@ -238,11 +241,13 @@ export function uxToHex(ux: string) { export const hexToUx = (hex) => { const ux = f.flow( + f.reverse, f.chunk(4), // eslint-disable-next-line prefer-arrow-callback f.map(x => _.dropWhile(x, function(y: unknown) { - return y === 0; - }).join('')), + return y === '0'; + }).reverse().join('')), + f.reverse, f.join('.') )(hex.split('')); return `0x${ux}`; @@ -355,6 +360,7 @@ export function stringToTa(str: string) { add = '~~'; break; default: + // eslint-disable-next-line const charCode = str.charCodeAt(i); if ( (charCode >= 97 && charCode <= 122) || // a-z @@ -413,7 +419,7 @@ export function stringToSymbol(str: string) { } return result; } -/** +/* * Formats a numbers as a `@ud` inserting dot where needed */ export function numToUd(num: number) { @@ -428,7 +434,7 @@ export function numToUd(num: number) { } export function patpToUd(patp: Patp) { - return numToUd(patp2dec(patp)) + return numToUd(patp2dec(patp)); } export function usePreventWindowUnload(shouldPreventDefault: boolean, message = 'You have unsaved changes. Are you sure you want to exit?') { @@ -443,7 +449,7 @@ export function usePreventWindowUnload(shouldPreventDefault: boolean, message = window.onbeforeunload = handleBeforeUnload; return () => { window.removeEventListener('beforeunload', handleBeforeUnload); - // @ts-ignore + // @ts-ignore need better window typings window.onbeforeunload = undefined; }; }, [shouldPreventDefault]); @@ -453,13 +459,6 @@ export function pluralize(text: string, isPlural = false, vowel = false) { return isPlural ? `${text}s` : `${vowel ? 'an' : 'a'} ${text}`; } -// Hide is an optional second parameter for when this function is used in class components -export function useShowNickname(contact: Contact | null, hide?: boolean): boolean { - const hideState = useSettingsState(state => state.calm.hideNicknames); - const hideNicknames = typeof hide !== 'undefined' ? hide : hideState; - return Boolean(contact && contact.nickname && !hideNicknames); -} - interface useHoveringInterface { hovering: boolean; bind: { @@ -484,15 +483,15 @@ export function withHovering(Component: React.ComponentType) { return React.forwardRef((props, ref) => { const { hovering, bind } = useHovering(); // @ts-ignore needs type signature on return? - return - }) + return ; + }); } const DM_REGEX = /ship\/~([a-z]|-)*\/dm--/; export function getItemTitle(association: Association): string { if (DM_REGEX.test(association.resource)) { const [, , ship, name] = association.resource.split('/'); - if (ship.slice(1) === window.ship) { + if (deSig(ship) === window.ship) { return cite(`~${name.slice(4)}`); } return cite(ship); @@ -500,22 +499,58 @@ export function getItemTitle(association: Association): string { return association.metadata.title ?? association.resource ?? ''; } -export const svgDataURL = (svg) => 'data:image/svg+xml;base64,' + btoa(svg); +export const svgDataURL = svg => 'data:image/svg+xml;base64,' + btoa(svg); -export const svgBlobURL = (svg) => URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' })); +export const svgBlobURL = svg => URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' })); -export const favicon = () => { - let background = '#ffffff'; - const contacts = useContactState.getState().contacts; - if (contacts.hasOwnProperty(`~${window.ship}`)) { - background = `#${uxToHex(contacts[`~${window.ship}`].color)}`; + +export function binaryIndexOf(arr: BigInteger[], target: BigInteger): number | undefined { + let leftBound = 0; + let rightBound = arr.length - 1; + while(leftBound <= rightBound) { + const halfway = Math.floor((leftBound + rightBound) / 2); + if(arr[halfway].greater(target)) { + leftBound = halfway + 1; + } else if (arr[halfway].lesser(target)) { + rightBound = halfway - 1; + } else { + return halfway; + } } - const foreground = foregroundFromBackground(background); - const svg = sigiljs({ - patp: window.ship, - renderer: stringRenderer, - size: 16, - colors: [background, foreground] - }); - return svg; + return undefined; } + +export async function jsonFetch(info: RequestInfo, init?: RequestInit): Promise { + const res = await fetch(info, init); + if(!res.ok) { + throw new Error('Bad Fetch Response'); + } + const data = await res.json(); + return data as T; +} + +export function clone(a: T) { + return JSON.parse(JSON.stringify(a)) as T; +} + +export function toHarkPath(path: string, index = '') { + return `/graph/${path.slice(6)}${index}`; +} + +export function toHarkPlace(graph: string, index = '') { + return { + desk: (window as any).desk, + path: toHarkPath(graph, index) + }; +} + +export function createStorageKey(name: string): string { + return `~${window.ship}/${window.desk}/${name}`; +} + +// for purging storage with version updates +export function clearStorageMigration() { + return {} as T; +} + +export const storageVersion = parseInt(process.env.LANDSCAPE_STORAGE_VERSION, 10); diff --git a/pkg/interface/src/logic/reducers/connection.ts b/pkg/interface/src/logic/reducers/connection.ts deleted file mode 100644 index 529376c04..000000000 --- a/pkg/interface/src/logic/reducers/connection.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Cage } from '~/types/cage'; -import { StoreState } from '../store/type'; - -type LocalState = Pick; - -export default class ConnectionReducer { - reduce(json: Cage, state: S) { - if('connection' in json && json.connection) { - console.log(`Conn: ${json.connection}`); - state.connection = json.connection; - } - } -} diff --git a/pkg/interface/src/logic/reducers/contact-update.ts b/pkg/interface/src/logic/reducers/contact-update.ts index 6776dc08a..7f4f7ea3b 100644 --- a/pkg/interface/src/logic/reducers/contact-update.ts +++ b/pkg/interface/src/logic/reducers/contact-update.ts @@ -1,7 +1,9 @@ import { ContactUpdate, deSig } from '@urbit/api'; import _ from 'lodash'; -import { reduceState } from '../state/base'; -import useContactState, { ContactState } from '../state/contact'; +import { BaseState } from '../state/base'; +import { ContactState as State } from '../state/contact'; + +type ContactState = State & BaseState; const initial = (json: ContactUpdate, state: ContactState): ContactState => { const data = _.get(json, 'initial', false); @@ -71,23 +73,18 @@ const setPublic = (json: ContactUpdate, state: ContactState): ContactState => { return state; }; -export const ContactReducer = (json) => { - const data: ContactUpdate = _.get(json, 'contact-update', false); - if (data) { - reduceState(useContactState, data, [ - initial, - add, - remove, - edit, - setPublic - ]); - } - - // TODO: better isolation - const res = _.get(json, 'resource', false); - if (res) { - useContactState.setState({ - nackedContacts: useContactState.getState().nackedContacts.add(`~${res.ship}`) - }); +export const reduceNacks = (json, state: ContactState): ContactState => { + const data = json?.resource; + if(data) { + state.nackedContacts.add(`~${data.res}`); } + return state; }; + +export const reduce = [ + initial, + add, + remove, + edit, + setPublic +]; diff --git a/pkg/interface/src/logic/reducers/gcp-reducer.ts b/pkg/interface/src/logic/reducers/gcp-reducer.ts deleted file mode 100644 index f809c1a9f..000000000 --- a/pkg/interface/src/logic/reducers/gcp-reducer.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { Cage } from '~/types/cage'; -import type { GcpToken } from '../../types/gcp-state'; -import { reduceState } from '../state/base'; -import useStorageState, { StorageState } from '../state/storage'; - -export default class GcpReducer { - reduce(json: Cage) { - reduceState(useStorageState, json, [ - reduceToken - ]); - } -} - -const reduceToken = (json: Cage, state: StorageState): StorageState => { - const data = json['gcp-token']; - if (data) { - setToken(data, state); - } - return state; -}; - -const setToken = (data: any, state: StorageState): StorageState => { - if (isToken(data)) { - state.gcp.token = data; - } - return state; -}; - -const isToken = (token: any): token is GcpToken => { - return (typeof(token.accessKey) === 'string' && - typeof(token.expiresIn) === 'number'); -}; diff --git a/pkg/interface/src/logic/reducers/graph-update.ts b/pkg/interface/src/logic/reducers/graph-update.ts index da427a901..011853d55 100644 --- a/pkg/interface/src/logic/reducers/graph-update.ts +++ b/pkg/interface/src/logic/reducers/graph-update.ts @@ -7,8 +7,13 @@ import BigIntArrayOrderedMap, { import bigInt, { BigInteger } from 'big-integer'; import produce from 'immer'; import _ from 'lodash'; -import { reduceState } from '../state/base'; -import useGraphState, { GraphState } from '../state/graph'; +import { BaseState, reduceState } from '../state/base'; +import useGraphState, { GraphState as State } from '../state/graph'; +/* eslint-disable camelcase */ + +import { unstable_batchedUpdates } from 'react-dom'; + +type GraphState = State & BaseState; const mapifyChildren = (children) => { return new BigIntOrderedMap().gas( @@ -245,9 +250,6 @@ export const addNodes = (json, state) => { post, resource ) => { - if (!post.hash) { - return [graph, flatGraph, threadGraphs]; - } const timestamp = post['time-sent']; if (state.graphTimesentMap[resource][timestamp]) { @@ -403,26 +405,17 @@ export const addNodes = (json, state) => { const removePosts = (json, state: GraphState): GraphState => { const _remove = (graph, index) => { const child = graph.get(index[0]); + if(!child) { + return graph; + } if (index.length === 1) { - if (child) { - return graph.set(index[0], { - post: child.post.hash || '', - children: child.children - }); - } + return graph.set(index[0], { + post: child.post.hash || '', + children: child.children + }); } else { - if (child) { - _remove(child.children, index.slice(1)); - return graph.set(index[0], child); - } else { - const child = graph.get(index[0]); - if (child) { - return graph.set(index[0], produce((draft: any) => { - draft.children = _remove(draft.children, index.slice(1)); - })); - } - return graph; - } + const node = { ...child, children: _remove(child.children, index.slice(1)) }; + return graph.set(index[0], node); } }; @@ -445,39 +438,38 @@ const removePosts = (json, state: GraphState): GraphState => { return state; }; +export const reduceDm = [ + acceptOrRejectDm, + pendings, + setScreen +]; + export const GraphReducer = (json) => { const data = _.get(json, 'graph-update', false); - if (data) { - reduceState(useGraphState, data, [ - keys, - addGraph, - removeGraph, - addNodes, - removePosts - ]); - } - const loose = _.get(json, 'graph-update-loose', false); - if(loose) { - reduceState(useGraphState, loose, [addNodesLoose]); - } + unstable_batchedUpdates(() => { + if (data) { + reduceState(useGraphState, data, [ + keys, + addGraph, + removeGraph, + addNodes, + removePosts + ]); + } + const loose = _.get(json, 'graph-update-loose', false); + if(loose) { + reduceState(useGraphState, loose, [addNodesLoose]); + } - const flat = _.get(json, 'graph-update-flat', false); - if (flat) { - reduceState(useGraphState, flat, [addNodesFlat]); - } + const flat = _.get(json, 'graph-update-flat', false); + if (flat) { + reduceState(useGraphState, flat, [addNodesFlat]); + } - const thread = _.get(json, 'graph-update-thread', false); - if (thread) { - reduceState(useGraphState, thread, [addNodesThread]); - } - const dm = _.get(json, 'dm-hook-action', false); - if(dm) { - console.log(dm); - reduceState(useGraphState, dm, [ - acceptOrRejectDm, - pendings, - setScreen - ]); - } + const thread = _.get(json, 'graph-update-thread', false); + if (thread) { + reduceState(useGraphState, thread, [addNodesThread]); + } + }); }; diff --git a/pkg/interface/src/logic/reducers/group-update.ts b/pkg/interface/src/logic/reducers/group-update.ts index eb4d242ae..798ec3d2d 100644 --- a/pkg/interface/src/logic/reducers/group-update.ts +++ b/pkg/interface/src/logic/reducers/group-update.ts @@ -9,8 +9,10 @@ import { import _ from 'lodash'; import { Cage } from '~/types/cage'; import { resourceAsPath } from '../lib/util'; -import { reduceState } from '../state/base'; -import useGroupState, { GroupState } from '../state/group'; +import { BaseState } from '../state/base'; +import { GroupState as State } from '../state/group'; + +type GroupState = BaseState & State; function decodeGroup(group: Enc): Group { const members = new Set(group.members); @@ -54,21 +56,7 @@ function decodeTags(tags: Enc): Tags { export default class GroupReducer { reduce(json: Cage) { - const data = json.groupUpdate; - if (data) { - reduceState(useGroupState, data, [ - initial, - addMembers, - addTag, - removeMembers, - initialGroup, - removeTag, - addGroup, - removeGroup, - changePolicy, - expose - ]); - } + return; } } const initial = (json: GroupUpdate, state: GroupState): GroupState => { @@ -115,6 +103,9 @@ const addMembers = (json: GroupUpdate, state: GroupState): GroupState => { if ('addMembers' in json) { const { resource, ships } = json.addMembers; const resourcePath = resourceAsPath(resource); + if(!(resourcePath in state.groups)) { + return; + } for (const member of ships) { state.groups[resourcePath].members.add(member); if ( @@ -175,24 +166,6 @@ const removeTag = (json: GroupUpdate, state: GroupState): GroupState => { return state; }; -const changePolicy = (json: GroupUpdate, state: GroupState): GroupState => { - if ('changePolicy' in json && state) { - const { resource, diff } = json.changePolicy; - const resourcePath = resourceAsPath(resource); - const policy = state.groups[resourcePath].policy; - if ('open' in policy && 'open' in diff) { - openChangePolicy(diff.open, policy); - } else if ('invite' in policy && 'invite' in diff) { - inviteChangePolicy(diff.invite, policy); - } else if ('replace' in diff) { - state.groups[resourcePath].policy = diff.replace; - } else { - console.log('bad policy diff'); - } - } - return state; -}; - const expose = (json: GroupUpdate, state: GroupState): GroupState => { if( 'expose' in json && state) { const { resource } = json.expose; @@ -243,3 +216,33 @@ const openChangePolicy = (diff: OpenPolicyDiff, policy: OpenPolicy) => { console.log('bad policy change'); } }; + +const changePolicy = (json: GroupUpdate, state: GroupState): GroupState => { + if ('changePolicy' in json && state) { + const { resource, diff } = json.changePolicy; + const resourcePath = resourceAsPath(resource); + const policy = state.groups[resourcePath].policy; + if ('open' in policy && 'open' in diff) { + openChangePolicy(diff.open, policy); + } else if ('invite' in policy && 'invite' in diff) { + inviteChangePolicy(diff.invite, policy); + } else if ('replace' in diff) { + state.groups[resourcePath].policy = diff.replace; + } else { + console.log('bad policy diff'); + } + } + return state; +}; +export const reduce = [ + initial, + addMembers, + addTag, + removeMembers, + initialGroup, + removeTag, + addGroup, + removeGroup, + changePolicy, + expose +]; diff --git a/pkg/interface/src/logic/reducers/group-view.ts b/pkg/interface/src/logic/reducers/group-view.ts index fae75a0a6..d6f7137fb 100644 --- a/pkg/interface/src/logic/reducers/group-view.ts +++ b/pkg/interface/src/logic/reducers/group-view.ts @@ -1,6 +1,7 @@ -import { GroupUpdate } from '@urbit/api/groups'; -import { reduceState } from '../state/base'; -import useGroupState, { GroupState } from '../state/group'; +import { BaseState } from '../state/base'; +import useGroupState, { GroupState as State } from '../state/group'; + +type GroupState = State & BaseState; const initial = (json: any, state: GroupState): GroupState => { const data = json.initial; @@ -26,7 +27,9 @@ const progress = (json: any, state: GroupState): GroupState => { state.pendingJoin[resource].progress = progress; if(progress === 'done') { setTimeout(() => { - delete state.pendingJoin[resource]; + useGroupState.getState().set((state) => { + delete state.pendingJoin[resource]; + }); }, 10000); } } @@ -41,14 +44,9 @@ const hide = (json: any, state: GroupState) => { return state; }; -export const GroupViewReducer = (json: any) => { - const data = json['group-view-update']; - if (data) { - reduceState(useGroupState, data, [ - progress, - hide, - started, - initial - ]); - } -}; +export const reduce = [ + progress, + hide, + started, + initial +]; diff --git a/pkg/interface/src/logic/reducers/hark-update.ts b/pkg/interface/src/logic/reducers/hark-update.ts index beddf4aee..dccdd73fd 100644 --- a/pkg/interface/src/logic/reducers/hark-update.ts +++ b/pkg/interface/src/logic/reducers/hark-update.ts @@ -1,18 +1,20 @@ import { - NotificationContents, - NotifIndex, - Timebox + HarkPlace, + Timebox, + HarkStats, + harkBinToId, + makePatDa } from '@urbit/api'; import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; import _ from 'lodash'; import { compose } from 'lodash/fp'; -import { makePatDa } from '~/logic/lib/util'; -import { describeNotification, getReferent } from '../lib/hark'; -import { reduceState } from '../state/base'; -import useHarkState, { HarkState } from '../state/hark'; +import { BaseState } from '../state/base'; +import { HarkState as State } from '../state/hark'; + +type HarkState = State & BaseState; function calculateCount(json: any, state: HarkState) { - state.notificationsCount = Object.keys(state.unreadNotes).length; + state.notificationsCount = Object.keys(state.unseen).length; return state; } @@ -95,18 +97,25 @@ function readAll(json: any, state: HarkState): HarkState { return state; } -function removeGraph(json: any, state: HarkState): HarkState { - const data = _.get(json, 'remove-graph'); - if(data) { - delete state.unreads.graph[data]; +const emptyStats = () => ({ + each: [], + count: 0, + last: 0 +}); + +function updateNotificationStats(state: HarkState, place: HarkPlace, f: (s: HarkStats) => Partial) { + if(place.desk !== (window as any).desk) { + return; } - return state; + const old = state.unreads?.[place.path] || emptyStats(); + state.unreads[place.path] = { ...old, ...f(old) }; } function seenIndex(json: any, state: HarkState): HarkState { - const data = _.get(json, 'seen-index'); + const data = _.get(json, 'saw-place'); if(data) { - updateNotificationStats(state, data.index, 'last', () => data.time); + const last = data?.time || Date.now(); + updateNotificationStats(state, data.place, s => ({ last })); } return state; } @@ -114,7 +123,8 @@ function seenIndex(json: any, state: HarkState): HarkState { function readEach(json: any, state: HarkState): HarkState { const data = _.get(json, 'read-each'); if (data) { - updateUnreads(state, data.index, u => u.delete(data.target)); + const { place, path } = data; + updateNotificationStats(state, place, s => ({ each: s.each.filter(e => e !== path) })); } return state; } @@ -122,7 +132,8 @@ function readEach(json: any, state: HarkState): HarkState { function readSince(json: any, state: HarkState): HarkState { const data = _.get(json, 'read-count'); if(data) { - updateUnreadCount(state, data, () => 0); + console.log(data); + updateNotificationStats(state, data, s => ({ count: 0 })); } return state; } @@ -130,7 +141,8 @@ function readSince(json: any, state: HarkState): HarkState { function unreadSince(json: any, state: HarkState): HarkState { const data = _.get(json, 'unread-count'); if (data) { - updateUnreadCount(state, data.index, u => u + 1); + const { inc, count, place } = data; + updateNotificationStats(state, place, s => ({ count: inc ? s.count + count : s.count - count })); } return state; } @@ -138,31 +150,20 @@ function unreadSince(json: any, state: HarkState): HarkState { function unreadEach(json: any, state: HarkState): HarkState { const data = _.get(json, 'unread-each'); if(data) { - updateUnreads(state, data.index, us => us.add(data.target)); + const { place, path } = data; + updateNotificationStats(state, place, s => ({ each: [...s.each, path] })); } return state; } -function unreads(json: any, state: HarkState): HarkState { - const data = _.get(json, 'unreads'); - if(data) { - clearState(state); - data.forEach(({ index, stats }) => { - const { unreads, notifications, last } = stats; - updateNotificationStats(state, index, 'last', () => last); - _.each(notifications, ({ time, index }) => { - if(!time) { - addNotificationToUnread(state, index); - } - }); - if('count' in unreads) { - updateUnreadCount(state, index, (u = 0) => u + unreads.count); - } else { - updateUnreads(state, index, s => new Set()); - unreads.each.forEach((u: string) => { - updateUnreads(state, index, s => s.add(u)); - }); +function allStats(json: any, state: HarkState): HarkState { + if('all-stats' in json) { + const data = json['all-stats']; + data.forEach(({ place, stats }) => { + if(place.desk !== (window as any).desk) { + return; } + state.unreads[place.path] = stats; }); } return state; @@ -171,113 +172,23 @@ function unreads(json: any, state: HarkState): HarkState { function clearState(state: HarkState): HarkState { const initialState = { notifications: new BigIntOrderedMap(), - archivedNotifications: new BigIntOrderedMap(), + unseen: {}, + seen: {}, notificationsGroupConfig: [], notificationsGraphConfig: { watchOnSelf: false, mentions: false, watching: [] }, - unreads: { - graph: {}, - group: {} - }, - notificationsCount: 0 + unreads: {}, + notificationsCount: 0, + unreadNotes: {} }; Object.assign(state, initialState); return state; } -function updateUnreadCount(state: HarkState, index: NotifIndex, count: (c: number) => number): HarkState { - if(!('graph' in index)) { - return state; - } - const property = [index.graph.graph, index.graph.index, 'unreads']; - const curr = _.get(state.unreads.graph, property, 0); - const newCount = count(curr); - _.set(state.unreads.graph, property, newCount); - return state; -} - -function updateUnreads(state: HarkState, index: NotifIndex, f: (us: Set) => void): HarkState { - if(!('graph' in index)) { - return state; - } - const unreads: any = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, 'unreads'], new Set()); - f(unreads); - - _.set(state.unreads.graph, [index.graph.graph, index.graph.index, 'unreads'], unreads); - return state; -} - -function addNotificationToUnread(state: HarkState, index: NotifIndex) { - if('graph' in index) { - const path = [index.graph.graph, index.graph.index, 'notifications']; - const curr = _.get(state.unreads.graph, path, []); - _.set(state.unreads.graph, path, - [ - ...curr.filter((c) => { - return !(notifIdxEqual(c.index, index)); - }), - { index } - ] - ); - } else if ('group' in index) { - const path = [index.group.group, 'notifications']; - const curr = _.get(state.unreads.group, path, []); - _.set(state.unreads.group, path, - [ - ...curr.filter(c => !notifIdxEqual(c.index, index)), - { index } - ] - ); - } -} -function removeNotificationFromUnread(state: HarkState, index: NotifIndex) { - if('graph' in index) { - const path = [index.graph.graph, index.graph.index, 'notifications']; - const curr = _.get(state.unreads.graph, path, []); - _.set(state.unreads.graph, path, curr.filter(c => !notifIdxEqual(c.index, index))); - } else if ('group' in index) { - const path = [index.group.group, 'notifications']; - const curr = _.get(state.unreads.group, path, []); - _.set(state.unreads.group, path, curr.filter(c => !notifIdxEqual(c.index, index))); - } -} - -function updateNotificationStats(state: HarkState, index: NotifIndex, statField: 'unreads' | 'last', f: (x: number) => number, notify = false) { - if('graph' in index) { - const curr: any = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, statField], 0); - _.set(state.unreads.graph, [index.graph.graph, index.graph.index, statField], f(curr)); - } else if('group' in index) { - const curr: any = _.get(state.unreads.group, [index.group.group, statField], 0); - _.set(state.unreads.group, [index.group.group, statField], f(curr)); - } -} - -function added(json: any, state: HarkState): HarkState { - const data = _.get(json, 'added', false); - if (data) { - const { index, notification } = data; - const [fresh] = _.partition(state.unreadNotes, ({ index: idx }) => !notifIdxEqual(index, idx)); - state.unreadNotes = [...fresh, { index, notification }]; - - if ('Notification' in window && !useHarkState.getState().doNotDisturb) { - const description = describeNotification(data); - const referent = getReferent(data); - new Notification(`${description} ${referent}`, { - tag: 'landscape', - image: '/img/favicon.png', - icon: '/img/favicon.png', - badge: '/img/favicon.png', - renotify: true - }); - } - } - return state; -} - const dnd = (json: any, state: HarkState): HarkState => { const data = _.get(json, 'set-dnd', undefined); if (!_.isUndefined(data)) { @@ -286,22 +197,6 @@ const dnd = (json: any, state: HarkState): HarkState => { return state; }; -const timebox = (json: any, state: HarkState): HarkState => { - const data = _.get(json, 'timebox', false); - if (data) { - if (data.time) { - const time = makePatDa(data.time); - state.notifications = state.notifications.set(time, data.notifications); - } else { - state.unreadNotes = data.notifications; - _.each(data.notifications, ({ index }) => { - addNotificationToUnread(state, index); - }); - } - } - return state; -}; - function more(json: any, state: HarkState): HarkState { const data = _.get(json, 'more', false); if (data) { @@ -312,99 +207,104 @@ function more(json: any, state: HarkState): HarkState { return state; } -function notifIdxEqual(a: NotifIndex, b: NotifIndex) { - if ('graph' in a && 'graph' in b) { - return ( - a.graph.graph === b.graph.graph && - a.graph.group === b.graph.group && - a.graph.mark === b.graph.mark && - a.graph.description === b.graph.description - ); - } else if ('group' in a && 'group' in b) { - return ( - a.group.group === b.group.group && - a.group.description === b.group.description - ); +function added(json: any, state: HarkState): HarkState { + if('added' in json) { + const { bin } = json.added; + const binId = harkBinToId(bin); + state.unseen[binId] = json.added; } - return false; + + return state; } -function mergeNotifs(a: NotificationContents, b: NotificationContents) { - if ('graph' in a && 'graph' in b) { - return { - graph: [...a.graph, ...b.graph] - }; - } else if ('group' in a && 'group' in b) { - return { - group: [...a.group, ...b.group] - }; - } - return a; -} - -function read(json: any, state: HarkState): HarkState { - const data = _.get(json, 'note-read', false); - if (data) { - const { index } = data; - const time = makePatDa(data.time); - const [read, unread] = _.partition(state.unreadNotes,({ index: idx }) => notifIdxEqual(index, idx)); - state.unreadNotes = unread; - const oldTimebox = state.notifications.get(time) ?? []; - const [toMerge, rest] = _.partition(oldTimebox, i => notifIdxEqual(index, i.index)); - if(toMerge.length > 0 && read.length > 0) { - read[0].notification.contents = mergeNotifs(read[0].notification.contents, toMerge[0].notification.contents); - } - state.notifications = state.notifications.set(time, [...read, ...rest]); - removeNotificationFromUnread(state, index); +function archived(json: any, state: HarkState): HarkState { + if('archived' in json) { + const { lid, notification } = json.archived; + const seen = 'seen' in lid ? 'seen' : 'unseen'; + const binId = harkBinToId(notification.bin); + delete state[seen][binId]; + const time = makePatDa(json.archived.time); + const timebox = state.archive?.get(time) || {}; + timebox[binId] = notification; + state.archive = state.archive.set(time, timebox); } return state; } -function archive(json: any, state: HarkState): HarkState { - const data = _.get(json, 'archive', false); - if (data) { - const { index } = data; - if(data.time) { - const time = makePatDa(data.time); - const timebox = state.notifications.get(time); - if (!timebox) { - console.warn('Modifying nonexistent timebox'); - return state; - } - const unarchived = _.filter(timebox, idxNotif => - !notifIdxEqual(index, idxNotif.index) - ); - if(unarchived.length === 0) { - console.log('deleting entire timebox'); - state.notifications = state.notifications.delete(time); - } else { - state.notifications = state.notifications.set(time, unarchived); - } +function timebox(json: any, state: HarkState): HarkState { + if('timebox' in json) { + const { timebox } = json; + const { lid, notifications } = timebox; + if('archive' in lid) { + const time = makePatDa(lid.archive); + const old = state.archive.get(time) || {}; + notifications.forEach((note: any) => { + const binId = harkBinToId(note.bin); + old[binId] = note; + }); + state.archive = state.archive.set(time, old); } else { - state.unreadNotes = state.unreadNotes.filter(({ index: idx }) => !notifIdxEqual(idx, index)); - removeNotificationFromUnread(state, index); + const seen = 'seen' in lid ? 'seen' : 'unseen'; + notifications.forEach((note: any) => { + const binId = harkBinToId(note.bin); + state[seen][binId] = note; + }); } } return state; } +function opened(json: any, state: HarkState): HarkState { + if('opened' in json) { + const bins = Object.keys(state.unseen); + bins.forEach((bin) => { + const old = state.seen[bin]; + const curr = state.unseen[bin]; + curr.body = [...curr.body, ...(old?.body || [])]; + state.seen[bin] = curr; + delete state.unseen[bin]; + }); + } + return state; +} + +function delPlace(json: any, state: HarkState): HarkState { + if('del-place' in json) { + const { path, desk } = json['del-place']; + const pathId = `${desk}${path}`; + const wipeBox = (t: Timebox) => { + Object.keys(t).forEach((bin) => { + if (bin.startsWith(pathId)) { + delete t[bin]; + } + }); + }; + wipeBox(state.unseen); + wipeBox(state.seen); + state.archive.keys().forEach((key) => { + wipeBox(state.archive.get(key)!); + }); + } + return state; +} + export function reduce(data, state) { const reducers = [ calculateCount, - read, - archive, - timebox, + allStats, more, dnd, - added, - unreads, readEach, readSince, unreadSince, unreadEach, seenIndex, - removeGraph, - readAll + readAll, + added, + timebox, + archived, + opened, + delPlace ]; const reducer = compose(reducers.map(r => (s) => { return r(data, s); @@ -412,37 +312,17 @@ export function reduce(data, state) { return reducer(state); } -export const HarkReducer = (json: any) => { - const data = _.get(json, 'harkUpdate', false); - if (data) { - console.log(data); - reduceState(useHarkState, data, [reduce]); - } - const graphHookData = _.get(json, 'hark-graph-hook-update', false); - if (graphHookData) { - reduceState(useHarkState, graphHookData, [ - // @ts-ignore investigate zustand types - graphInitial, - // @ts-ignore investigate zustand types - graphIgnore, - // @ts-ignore investigate zustand types - graphListen, - // @ts-ignore investigate zustand types - graphWatchSelf, - // @ts-ignore investigate zustand types - graphMentions - ]); - } - const groupHookData = _.get(json, 'hark-group-hook-update', false); - if (groupHookData) { - reduceState(useHarkState, groupHookData, [ - // @ts-ignore investigate zustand types - groupInitial, - // @ts-ignore investigate zustand types - groupListen, - // @ts-ignore investigate zustand types - groupIgnore - ]); - } -}; +export const reduceGraph = [ + graphInitial, + graphIgnore, + graphListen, + graphWatchSelf, + graphMentions +]; + +export const reduceGroup = [ + groupInitial, + groupListen, + groupIgnore +]; diff --git a/pkg/interface/src/logic/reducers/invite-update.ts b/pkg/interface/src/logic/reducers/invite-update.ts index 8ab979b86..6f08ec77f 100644 --- a/pkg/interface/src/logic/reducers/invite-update.ts +++ b/pkg/interface/src/logic/reducers/invite-update.ts @@ -1,24 +1,9 @@ import { InviteUpdate } from '@urbit/api/invite'; import _ from 'lodash'; -import { Cage } from '~/types/cage'; -import { reduceState } from '../state/base'; -import useInviteState, { InviteState } from '../state/invite'; +import { BaseState } from '../state/base'; +import { InviteState as State } from '../state/invite'; -export default class InviteReducer { - reduce(json: Cage) { - const data = json['invite-update']; - if (data) { - reduceState(useInviteState, data, [ - initial, - create, - deleteInvite, - invite, - accepted, - decline - ]); - } - } -} +type InviteState = State & BaseState; const initial = (json: InviteUpdate, state: InviteState): InviteState => { const data = _.get(json, 'initial', false); @@ -67,3 +52,12 @@ const decline = (json: InviteUpdate, state: InviteState): InviteState => { } return state; }; + +export const reduce = [ + initial, + create, + deleteInvite, + invite, + accepted, + decline +]; diff --git a/pkg/interface/src/logic/reducers/launch-update.ts b/pkg/interface/src/logic/reducers/launch-update.ts index 204673343..59216c238 100644 --- a/pkg/interface/src/logic/reducers/launch-update.ts +++ b/pkg/interface/src/logic/reducers/launch-update.ts @@ -1,55 +1,9 @@ import _ from 'lodash'; -import { Cage } from '~/types/cage'; -import { LaunchUpdate, WeatherState } from '~/types/launch-update'; -import { reduceState } from '../state/base'; -import useLaunchState, { LaunchState } from '../state/launch'; +import { LaunchUpdate } from '~/types/launch-update'; +import { LaunchState as State } from '../state/launch'; +import { BaseState } from '../state/base'; -export default class LaunchReducer { - reduce(json: Cage) { - const data = _.get(json, 'launch-update', false); - if (data) { - reduceState(useLaunchState, data, [ - initial, - changeFirstTime, - changeOrder, - changeFirstTime, - changeIsShown - ]); - } - - const weatherData: WeatherState | boolean | Record = _.get(json, 'weather', false); - if (weatherData) { - useLaunchState.getState().set((state) => { - // @ts-ignore investigate zustand types - state.weather = weatherData; - }); - } - - const locationData = _.get(json, 'location', false); - if (locationData) { - useLaunchState.getState().set((state) => { - // @ts-ignore investigate zustand types - state.userLocation = locationData; - }); - } - - const baseHash = _.get(json, 'baseHash', false); - if (baseHash) { - useLaunchState.getState().set((state) => { - // @ts-ignore investigate zustand types - state.baseHash = baseHash; - }); - } - - const runtimeLag = _.get(json, 'runtimeLag', null); - if (runtimeLag !== null) { - useLaunchState.getState().set(state => { - // @ts-ignore investigate zustand types - state.runtimeLag = runtimeLag; - }); - } - } -} +type LaunchState = State & BaseState; export const initial = (json: LaunchUpdate, state: LaunchState): LaunchState => { const data = _.get(json, 'initial', false); @@ -87,3 +41,11 @@ export const changeIsShown = (json: LaunchUpdate, state: LaunchState): LaunchSta } return state; }; + +export const reduce = [ + initial, + changeFirstTime, + changeOrder, + changeFirstTime, + changeIsShown +]; diff --git a/pkg/interface/src/logic/reducers/metadata-update.ts b/pkg/interface/src/logic/reducers/metadata-update.ts index 9049a19f3..6fca3566e 100644 --- a/pkg/interface/src/logic/reducers/metadata-update.ts +++ b/pkg/interface/src/logic/reducers/metadata-update.ts @@ -1,50 +1,44 @@ -import { MetadataUpdate } from '@urbit/api/metadata'; +import { MetadataUpdate, Associations, ResourceAssociations } from '@urbit/api/metadata'; import _ from 'lodash'; import { Cage } from '~/types/cage'; -import { reduceState } from '../state/base'; -import useMetadataState, { MetadataState } from '../state/metadata'; +import { BaseState } from '../state/base'; +import { MetadataState as State } from '../state/metadata'; + +type MetadataState = State & BaseState; export default class MetadataReducer { reduce(json: Cage) { - const data = json['metadata-update']; - if (data) { - reduceState(useMetadataState, data, [ - associations, - add, - update, - remove, - groupInitial - ]); - } + return; } } -const groupInitial = (json: MetadataUpdate, state: MetadataState): MetadataState => { - const data = _.get(json, 'initial-group', false); - if(data) { - associations(data, state); - } - return state; -}; +function normalizeAssociations(assocs: ResourceAssociations): Associations { + return _.reduce(assocs, (acc, val) => { + const appName = val['app-name']; + const rid = val.resource; + const old = acc[appName]; + return { + ...acc, + [appName]: { + ...old, + [rid]: val + } + }; + }, { + groups: {}, + graph: {} + } as Associations); +} + +function removeGroup(group: string, assocs: Associations): Associations { + return _.mapValues(assocs, (val): any => _.omitBy(val, assoc => assoc.group === group)); +} const associations = (json: MetadataUpdate, state: MetadataState): MetadataState => { const data = _.get(json, 'associations', false); if (data) { - const metadata = state.associations; - Object.keys(data).forEach((key) => { - const val = data[key]; - const appName = val['app-name']; - const rid = val.resource; - if (!(appName in metadata)) { - metadata[appName] = {}; - } - if (!(rid in metadata[appName])) { - metadata[appName][rid] = {}; - } - metadata[appName][rid] = val; - }); - - state.associations = metadata; + state.associations = normalizeAssociations(data); + state.loaded = true; } return state; }; @@ -69,6 +63,17 @@ const add = (json: MetadataUpdate, state: MetadataState): MetadataState => { return state; }; +const groupInitial = (json: MetadataUpdate, state: MetadataState): MetadataState => { + const data = _.get(json, 'initial-group', false); + if(data) { + state.associations = removeGroup(data.group, state.associations); + const { groups, graph } = normalizeAssociations(data.associations); + state.associations.graph = { ...state.associations.graph, ...graph }; + state.associations.groups = { ...state.associations.groups, ...groups }; + } + return state; +}; + const update = (json: MetadataUpdate, state: MetadataState): MetadataState => { const data = _.get(json, 'update-metadata', false); if (data) { @@ -103,3 +108,12 @@ const remove = (json: MetadataUpdate, state: MetadataState): MetadataState => { } return state; }; + +export const reduce = [ + associations, + add, + update, + remove, + groupInitial +]; + diff --git a/pkg/interface/src/logic/reducers/s3-update.ts b/pkg/interface/src/logic/reducers/s3-update.ts index b67ff3d60..381bbe81c 100644 --- a/pkg/interface/src/logic/reducers/s3-update.ts +++ b/pkg/interface/src/logic/reducers/s3-update.ts @@ -1,26 +1,9 @@ import _ from 'lodash'; -import { Cage } from '~/types/cage'; import { S3Update } from '~/types/s3-update'; -import { reduceState } from '../state/base'; -import useStorageState, { StorageState } from '../state/storage'; +import { BaseState } from '../state/base'; +import { StorageState as State } from '../state/storage'; -export default class S3Reducer { - reduce(json: Cage) { - const data = _.get(json, 's3-update', false); - if (data) { - reduceState(useStorageState, data, [ - credentials, - configuration, - currentBucket, - addBucket, - removeBucket, - endpoint, - accessKeyId, - secretAccessKey - ]); - } - } -} +type StorageState = State & BaseState; const credentials = (json: S3Update, state: StorageState): StorageState => { const data = _.get(json, 'credentials', false); @@ -89,3 +72,14 @@ const secretAccessKey = (json: S3Update, state: StorageState): StorageState => { } return state; }; + +export const reduce = [ + credentials, + configuration, + currentBucket, + addBucket, + removeBucket, + endpoint, + accessKeyId, + secretAccessKey +]; diff --git a/pkg/interface/src/logic/reducers/settings-update.ts b/pkg/interface/src/logic/reducers/settings-update.ts index 1a5e165bb..56d1c286a 100644 --- a/pkg/interface/src/logic/reducers/settings-update.ts +++ b/pkg/interface/src/logic/reducers/settings-update.ts @@ -1,88 +1,81 @@ import { SettingsUpdate } from '@urbit/api/settings'; import _ from 'lodash'; -import useSettingsState, { SettingsState } from '~/logic/state/settings'; -import { reduceState } from '../state/base'; +import { SettingsState as State } from '~/logic/state/settings'; +import { BaseState } from '../state/base'; -export default class SettingsReducer { - reduce(json: any) { - let data = json['settings-event']; - if (data) { - reduceState(useSettingsState, data, [ - this.putBucket, - this.delBucket, - this.putEntry, - this.delEntry - ]); - } - data = json['settings-data']; - if (data) { - reduceState(useSettingsState, data, [ - this.getAll, - this.getBucket, - this.getEntry - ]); - } - } +type SettingsState = State & BaseState; - putBucket(json: SettingsUpdate, state: SettingsState): SettingsState { - const data = _.get(json, 'put-bucket', false); - if (data) { - state[data['bucket-key']] = data.bucket; - } - return state; - } - - delBucket(json: SettingsUpdate, state: SettingsState): SettingsState { - const data = _.get(json, 'del-bucket', false); - if (data) { - delete state[data['bucket-key']]; - } - return state; - } - - putEntry(json: SettingsUpdate, state: any): SettingsState { - const data: Record = _.get(json, 'put-entry', false); - if (data) { - if (!state[data['bucket-key']]) { - state[data['bucket-key']] = {}; - } - state[data['bucket-key']][data['entry-key']] = data.value; - } - return state; - } - - delEntry(json: SettingsUpdate, state: any): SettingsState { - const data = _.get(json, 'del-entry', false); - if (data) { - delete state[data['bucket-key']][data['entry-key']]; - } - return state; - } - - getAll(json: any, state: SettingsState): SettingsState { - const data = _.get(json, 'all'); - if(data) { - _.mergeWith(state, data, (obj, src) => _.isArray(src) ? src : undefined); - } - return state; - } - - getBucket(json: any, state: SettingsState): SettingsState { - const key = _.get(json, 'bucket-key', false); - const bucket = _.get(json, 'bucket', false); - if (key && bucket) { - state[key] = bucket; - } - return state; - } - - getEntry(json: any, state: any) { - const bucketKey = _.get(json, 'bucket-key', false); - const entryKey = _.get(json, 'entry-key', false); - const entry = _.get(json, 'entry', false); - if (bucketKey && entryKey && entry) { - state[bucketKey][entryKey] = entry; - } - return state; +function putBucket(json: SettingsUpdate, state: SettingsState): SettingsState { + const data = _.get(json, 'put-bucket', false); + if (data) { + state[data['bucket-key']] = data.bucket; } + return state; } + +function delBucket(json: SettingsUpdate, state: SettingsState): SettingsState { + const data = _.get(json, 'del-bucket', false); + if (data) { + delete state[data['bucket-key']]; + } + return state; +} + +function putEntry(json: SettingsUpdate, state: any): SettingsState { + const data: Record = _.get(json, 'put-entry', false); + if (data) { + if (!state[data['bucket-key']]) { + state[data['bucket-key']] = {}; + } + state[data['bucket-key']][data['entry-key']] = data.value; + } + return state; +} + +function delEntry(json: SettingsUpdate, state: any): SettingsState { + const data = _.get(json, 'del-entry', false); + if (data) { + delete state[data['bucket-key']][data['entry-key']]; + } + return state; +} + +function getDesk(json: any, state: SettingsState): SettingsState { + const data = _.get(json, 'desk'); + if(data) { + _.mergeWith(state, data, (obj, src) => _.isArray(src) ? src : undefined); + } + return state; +} + +function getBucket(json: any, state: SettingsState): SettingsState { + const key = _.get(json, 'bucket-key', false); + const bucket = _.get(json, 'bucket', false); + if (key && bucket) { + state[key] = bucket; + } + return state; +} + +function getEntry(json: any, state: any) { + const bucketKey = _.get(json, 'bucket-key', false); + const entryKey = _.get(json, 'entry-key', false); + const entry = _.get(json, 'entry', false); + if (bucketKey && entryKey && entry) { + state[bucketKey][entryKey] = entry; + } + return state; +} + +export const reduceUpdate = [ + putBucket, + delBucket, + putEntry, + delEntry +]; + +export const reduceScry = [ + getDesk, + getBucket, + getEntry +]; diff --git a/pkg/interface/src/logic/state/base.ts b/pkg/interface/src/logic/state/base.ts index 543cb7e40..3f03c7db7 100644 --- a/pkg/interface/src/logic/state/base.ts +++ b/pkg/interface/src/logic/state/base.ts @@ -1,8 +1,12 @@ import { applyPatches, Patch, produceWithPatches, setAutoFreeze, enablePatches } from 'immer'; import { compose } from 'lodash/fp'; import _ from 'lodash'; -import create, { UseStore } from 'zustand'; +import create, { GetState, SetState, UseStore } from 'zustand'; import { persist } from 'zustand/middleware'; +import Urbit, { SubscriptionRequestInterface, FatalError } from '@urbit/http-api'; +import { Poke } from '@urbit/api'; +import airlock from '~/logic/api'; +import { clearStorageMigration, createStorageKey, storageVersion } from '../lib/util'; setAutoFreeze(false); enablePatches(); @@ -44,6 +48,18 @@ export const reduceState = < }); }; +export const reduceStateN = < + S extends {}, + U +>( + state: S & BaseState, + data: U, + reducers: ((data: U, state: S & BaseState) => S & BaseState)[] +): void => { + const reducer = compose(reducers.map(r => sta => r(data, sta))); + state.set(reducer); +}; + export const optReduceState = ( state: UseStore>, data: U, @@ -58,9 +74,9 @@ export const optReduceState = ( export let stateStorageKeys: string[] = []; export const stateStorageKey = (stateName: string) => { - stateName = `Landscape${stateName}State`; - stateStorageKeys = [...new Set([...stateStorageKeys, stateName])]; - return stateName; + const key = createStorageKey(`${stateName}State`); + stateStorageKeys = [...new Set([...stateStorageKeys, key])]; + return key; }; (window as any).clearStates = () => { @@ -74,17 +90,41 @@ export interface BaseState { patches: { [id: string]: Patch[]; }; - set: (fn: (state: BaseState) => void) => void; + set: (fn: (state: StateType & BaseState) => void) => void; addPatch: (id: string, ...patch: Patch[]) => void; removePatch: (id: string) => void; - optSet: (fn: (state: BaseState) => void) => string; + optSet: (fn: (state: StateType & BaseState) => void) => string; + initialize: (api: Urbit) => Promise; + clear: () => void; +} + +export function createSubscription(app: string, path: string, e: (data: any) => void): SubscriptionRequestInterface { + const request = { + app, + path, + event: e, + err: () => {}, + quit: () => { + throw new FatalError('subscription clogged'); + } + }; + // TODO: err, quit handling (resubscribe?) + return request; } export const createState = ( name: string, - properties: T, - blacklist: (keyof BaseState | keyof T)[] = [] + properties: T | ((set: SetState>, get: GetState>) => T), + blacklist: (keyof BaseState | keyof T)[] = [], + subscriptions: ((set: SetState>, get: GetState>) => SubscriptionRequestInterface)[] = [], + clearedState?: Partial ): UseStore> => create>(persist>((set, get) => ({ + clear: () => { + set(clearedState as T & BaseState); + }, + initialize: async (api: Urbit) => { + await Promise.all(subscriptions.map(sub => api.subscribe(sub(set, get)))); + }, // @ts-ignore investigate zustand types set: fn => stateSetter(fn, set, get), optSet: (fn) => { @@ -105,11 +145,12 @@ export const createState = ( return { ...applyPatches(state, applying), patches: _.omit(state.patches, id) }; }); }, - ...properties + ...(typeof properties === 'function' ? (properties as any)(set, get) : properties) }), { blacklist, name: stateStorageKey(name), - version: process.env.LANDSCAPE_SHORTHASH as any + version: storageVersion, + migrate: clearStorageMigration })); export async function doOptimistically(state: UseStore>, action: A, call: (a: A) => Promise, reduce: ((a: A, fn: S & BaseState) => S & BaseState)[]) { @@ -125,3 +166,17 @@ export async function doOptimistically(state: UseStore(state: UseStore>, poke: Poke, reduce: ((a: A, fn: S & BaseState) => S & BaseState)[]) { + let num: string | undefined = undefined; + try { + num = optReduceState(state, poke.json, reduce); + await airlock.poke(poke); + state.getState().removePatch(num); + } catch (e) { + console.error(e); + if(num) { + state.getState().rollback(num); + } + } +} diff --git a/pkg/interface/src/logic/state/contact.ts b/pkg/interface/src/logic/state/contact.ts index 1f48833cf..bf234ef32 100644 --- a/pkg/interface/src/logic/state/contact.ts +++ b/pkg/interface/src/logic/state/contact.ts @@ -1,37 +1,51 @@ -import { Contact, Patp, Rolodex } from '@urbit/api'; +import { Contact, deSig, Patp, Rolodex, uxToHex } from '@urbit/api'; import { useCallback } from 'react'; -import { BaseState, createState } from './base'; +import _ from 'lodash'; +import { reduce, reduceNacks } from '../reducers/contact-update'; +import { + createState, + createSubscription, + reduceStateN +} from './base'; +import { sigil as sigiljs, stringRenderer } from '@tlon/sigil-js'; +import { foregroundFromBackground } from '~/logic/lib/sigil'; -export interface ContactState extends BaseState { +export interface ContactState { contacts: Rolodex; isContactPublic: boolean; nackedContacts: Set; - // fetchIsAllowed: (entity, name, ship, personal) => Promise; } // @ts-ignore investigate zustand types -const useContactState = createState('Contact', { - contacts: {}, - nackedContacts: new Set(), - isContactPublic: false - // fetchIsAllowed: async ( - // entity, - // name, - // ship, - // personal - // ): Promise => { - // const isPersonal = personal ? 'true' : 'false'; - // const api = useApi(); - // return api.scry({ - // app: 'contact-store', - // path: `/is-allowed/${entity}/${name}/${ship}/${isPersonal}` - // }); - // }, -}, ['nackedContacts']); +const useContactState = createState( + 'Contact', + { + contacts: {}, + nackedContacts: new Set(), + isContactPublic: false + }, + ['nackedContacts'], + [ + (set, get) => + createSubscription('contact-pull-hook', '/nacks', (e) => { + const data = e?.resource; + if (data) { + reduceStateN(get(), data, [reduceNacks]); + } + }), + (set, get) => + createSubscription('contact-store', '/all', (e) => { + const data = _.get(e, 'contact-update', false); + if (data) { + reduceStateN(get(), data, reduce); + } + }) + ] +); export function useContact(ship: string) { return useContactState( - useCallback(s => s.contacts[ship] as Contact | null, [ship]) + useCallback(s => s.contacts[`~${deSig(ship)}`] as Contact | null, [ship]) ); } @@ -39,4 +53,21 @@ export function useOurContact() { return useContact(`~${window.ship}`); } +export const favicon = () => { + let background = '#ffffff'; + const contacts = useContactState.getState().contacts; + if (Object.prototype.hasOwnProperty.call(contacts, `~${window.ship}`)) { + background = `#${uxToHex(contacts[`~${window.ship}`].color)}`; + } + const foreground = foregroundFromBackground(background); + const svg = sigiljs({ + patp: window.ship, + renderer: stringRenderer, + size: 16, + colors: [background, foreground] + }); + return svg; +}; + + export default useContactState; diff --git a/pkg/interface/src/logic/state/docket.ts b/pkg/interface/src/logic/state/docket.ts new file mode 100644 index 000000000..9344168c2 --- /dev/null +++ b/pkg/interface/src/logic/state/docket.ts @@ -0,0 +1,54 @@ +import { Docket, Treaties, Treaty } from '@urbit/api'; +import { useCallback } from 'react'; +import create from 'zustand'; +import airlock from '~/logic/api'; + +interface DocketState { + treaties: Treaties; + requestTreaty: (ship: string, desk: string) => Promise; +} + +const useDocketState = create((set, get) => ({ + requestTreaty: async (ship: string, desk: string) => { + const { treaties } = get(); + const key = `${ship}/${desk}`; + if (key in treaties) { + return treaties[key]; + } + + const result = await airlock.subscribeOnce('treaty', `/treaty/${key}`, 20000); + const treaty = { ...normalizeDocket(result, desk), ship }; + set(state => ({ + treaties: { ...state.treaties, [key]: treaty } + })); + return treaty; + }, + treaties: {}, + set +})); + +function normalizeDocket(docket: T, desk: string): T { + const color = docket?.color?.startsWith('#') + ? docket.color + : `#${docket.color.slice(2).replace('.', '')}`.toUpperCase(); + + return { + ...docket, + desk, + color + }; +} + +export function useTreaty(host: string, desk: string) { + return useDocketState( + useCallback( + (s) => { + const ref = `${host}/${desk}`; + return s.treaties[ref]; + }, + [host, desk] + ) + ); +} + +export default useDocketState; diff --git a/pkg/interface/src/logic/state/embed.tsx b/pkg/interface/src/logic/state/embed.tsx new file mode 100644 index 000000000..3edd9bbb6 --- /dev/null +++ b/pkg/interface/src/logic/state/embed.tsx @@ -0,0 +1,44 @@ +import { useCallback } from 'react'; +import create from 'zustand'; +import { suspend, Suspender , suspendWithResult } from '../lib/suspend'; +import { jsonFetch } from '~/logic/lib/util'; + +export interface EmbedState { + embeds: { + [url: string]: any; + }; + getEmbed: (url: string) => Suspender; + fetch: (url: string) => Promise; +} + +const OEMBED_PROVIDER = 'https://noembed.com/embed'; + +const useEmbedState = create((set, get) => ({ + embeds: {}, + fetch: async (url: string) => { + const { embeds } = get(); + if(url in embeds) { + return embeds[url]; + } + const search = new URLSearchParams({ + url + }); + const embed = await jsonFetch(`${OEMBED_PROVIDER}?${search.toString()}`); + const { embeds: es } = get(); + set({ embeds: { ...es, [url]: embed } }); + return embed; + }, + getEmbed: (url: string): Suspender => { + const { fetch, embeds } = get(); + if(url in embeds) { + return suspendWithResult(embeds[url]); + } + return suspend(fetch(url)); + } +})); + +export function useEmbed(url: string) { + return useEmbedState(useCallback(s => s.getEmbed(url), [url])); +} + +export default useEmbedState; diff --git a/pkg/interface/src/logic/state/graph.ts b/pkg/interface/src/logic/state/graph.ts index 7b59d006d..bbeb44e89 100644 --- a/pkg/interface/src/logic/state/graph.ts +++ b/pkg/interface/src/logic/state/graph.ts @@ -1,11 +1,17 @@ import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; import { patp2dec } from 'urbit-ob'; +import shallow from 'zustand/shallow'; -import { Association, deSig, GraphNode, Graphs, FlatGraphs, resourceFromPath, ThreadGraphs } from '@urbit/api'; +import { Association, deSig, GraphNode, Graphs, FlatGraphs, resourceFromPath, ThreadGraphs, getGraph, getShallowChildren, setScreen } from '@urbit/api'; import { useCallback } from 'react'; -import { BaseState, createState } from './base'; +import { createState, createSubscription, reduceStateN, pokeOptimisticallyN } from './base'; +import airlock from '~/logic/api'; +import { addDmMessage, addPost, Content, getDeepOlderThan, getFirstborn, getNewest, getNode, getOlderSiblings, getYoungerSiblings, markPending, Post, addNode, GraphNodePoke } from '@urbit/api/graph'; +import { GraphReducer, reduceDm } from '../reducers/graph-update'; +import _ from 'lodash'; +import { clone } from '../lib/util'; -export interface GraphState extends BaseState { +export interface GraphState { graphs: Graphs; graphKeys: Set; looseNodes: { @@ -19,18 +25,21 @@ export interface GraphState extends BaseState { pendingDms: Set; screening: boolean; graphTimesentMap: Record; - // getKeys: () => Promise; - // getTags: () => Promise; - // getTagQueries: () => Promise; - // getGraph: (ship: string, resource: string) => Promise; - // getNewest: (ship: string, resource: string, count: number, index?: string) => Promise; - // getOlderSiblings: (ship: string, resource: string, count: number, index?: string) => Promise; - // getYoungerSiblings: (ship: string, resource: string, count: number, index?: string) => Promise; - // getGraphSubset: (ship: string, resource: string, start: string, end: string) => Promise; - // getNode: (ship: string, resource: string, index: string) => Promise; + getShallowChildren: (ship: string, name: string, index?: string) => Promise; + getDeepOlderThan: (ship: string, name: string, count: number, start?: string) => Promise; + getNewest: (ship: string, resource: string, count: number, index?: string) => Promise; + getOlderSiblings: (ship: string, resource: string, count: number, index?: string) => Promise; + getYoungerSiblings: (ship: string, resource: string, count: number, index?: string) => Promise; + getNode: (ship: string, resource: string, index: string) => Promise; + getFirstborn: (ship: string, resource: string, index: string) => Promise; + getGraph: (ship: string, name: string) => Promise; + addDmMessage: (ship: string, contents: Content[]) => Promise; + addPost: (ship: string, name: string, post: Post) => Promise; + addNode: (ship: string, name: string, post: GraphNodePoke) => Promise; + setScreen: (screen: boolean) => void; } // @ts-ignore investigate zustand types -const useGraphState = createState('Graph', { +const useGraphState = createState('Graph', (set, get) => ({ graphs: {}, flatGraphs: {}, threadGraphs: {}, @@ -39,7 +48,108 @@ const useGraphState = createState('Graph', { pendingIndices: {}, graphTimesentMap: {}, pendingDms: new Set(), - screening: false + screening: false, + addDmMessage: async (ship: string, contents: Content[]) => { + const poke = addDmMessage(window.ship, ship, contents); + const promise = airlock.poke(poke); + const pending = clone(poke); + markPending(pending.json['add-nodes'].nodes); + pending.json['add-nodes'].resource.ship = deSig(pending.json['add-nodes'].resource.ship); + GraphReducer({ + 'graph-update': pending.json + }); + await promise; + }, + addPost: async (ship, name, post) => { + const thread = addPost(ship, name, post); + const promise = airlock.thread(thread); + const { body } = clone(thread); + markPending(body['add-nodes'].nodes); + body['add-nodes'].resource.ship = deSig(body['add-nodes'].resource.ship); + GraphReducer({ + 'graph-update': body, + 'graph-update-flat': body, + 'graph-update-thread': body + }); + await promise; + }, + addNode: async (ship, name, node) => { + const thread = addNode(ship, name, node); + const promise = airlock.thread(thread); + const { body } = clone(thread); + markPending(body['add-nodes'].nodes); + body['add-nodes'].resource.ship = deSig(body['add-nodes'].resource.ship); + GraphReducer({ + 'graph-update': body, + 'graph-update-flat': body, + 'graph-update-thread': body + }); + await promise; + }, + getDeepOlderThan: async (ship, name, count, start) => { + const data = await airlock.scry(getDeepOlderThan(ship, name, count, start)); + + data['graph-update'].fetch = true; + const node = data['graph-update']; + GraphReducer({ + 'graph-update': node, + 'graph-update-flat': node + }); + }, + + getFirstborn: async (ship, name,index) => { + const data = await airlock.scry(getFirstborn(ship, name, index)); + data['graph-update'].fetch = true; + const node = data['graph-update']; + GraphReducer({ + 'graph-update-thread': { + index, + ...node + }, + 'graph-update': node + }); + }, + getNode: async (ship: string, name: string, index: string) => { + const data = await airlock.scry(getNode(ship, name, index)); + data['graph-update'].fetch = true; + const node = data['graph-update']; + GraphReducer({ + 'graph-update-loose': node + }); + }, + getOlderSiblings: async (ship: string, name: string, count: number, index: string) => { + const data = await airlock.scry(getOlderSiblings(ship, name, count, index)); + data['graph-update'].fetch = true; + GraphReducer(data); + }, + getYoungerSiblings: async (ship: string, name: string, count: number, index: string) => { + const data = await airlock.scry(getYoungerSiblings(ship, name, count, index)); + data['graph-update'].fetch = true; + GraphReducer(data); + }, + getNewest: async ( + ship: string, + name: string, + count: number, + index = '' + ) => { + const data = await airlock.scry(getNewest(ship, name, count, index)); + data['graph-update'].fetch = true; + GraphReducer(data); + }, + getGraph: async (ship, name) => { + const data = await airlock.scry(getGraph(ship, name)); + GraphReducer(data); + }, + getShallowChildren: async (ship: string, name: string, index = '') => { + const data = await airlock.scry(getShallowChildren(ship, name, index)); + data['graph-update'].fetch = true; + GraphReducer(data); + }, + setScreen: (screen: boolean) => { + const poke = setScreen(screen); + pokeOptimisticallyN(useGraphState, poke, reduceDm); + } // getKeys: async () => { // const api = useApi(); // const keys = await api.scry({ @@ -72,19 +182,6 @@ const useGraphState = createState('Graph', { // }); // graphReducer(graph); // }, - // getNewest: async ( - // ship: string, - // resource: string, - // count: number, - // index: string = '' - // ) => { - // const api = useApi(); - // const data = await api.scry({ - // app: 'graph-store', - // path: `/newest/${ship}/${resource}/${count}${index}` - // }); - // graphReducer(data); - // }, // getOlderSiblings: async ( // ship: string, // resource: string, @@ -139,7 +236,7 @@ const useGraphState = createState('Graph', { // }); // graphReducer(node); // }, -}, [ +}), [ 'graphs', 'graphKeys', 'looseNodes', @@ -147,7 +244,30 @@ const useGraphState = createState('Graph', { 'flatGraphs', 'threadGraphs', 'pendingDms' -]); +], [ + (set, get) => createSubscription('graph-store', '/updates', (e) => { + GraphReducer(e); + }), + (set, get) => createSubscription('graph-store', '/keys', (e) => { + GraphReducer(e); + }), + + (set, get) => createSubscription('dm-hook', '/updates', (e) => { + const j = _.get(e, 'dm-hook-action', false); + if(j) { + reduceStateN(get(), j, reduceDm); + } + })], + { + graphs: {}, + looseNodes: {}, + graphTimesentMap: {}, + flatGraphs: {}, + threadGraphs: {}, + pendingDms: new Set() + } + +); export function useGraph(ship: string, name: string) { return useGraphState( @@ -176,7 +296,11 @@ export function useGraphTimesentMap(ship: string, name: string) { useCallback(s => s.graphTimesentMap[`${deSig(ship)}/${name}`], [ship, name]) ); } +const emptyObject = {}; +export function useGraphTimesent(key: string) { + return useGraphState(useCallback(s => s.graphTimesentMap[key] || emptyObject, [key]), shallow); +} export function useGraphForAssoc(association: Association) { const { resource } = association; const { ship, name } = resourceFromPath(resource); diff --git a/pkg/interface/src/logic/state/group.ts b/pkg/interface/src/logic/state/group.ts index 5f7324124..dcff40c75 100644 --- a/pkg/interface/src/logic/state/group.ts +++ b/pkg/interface/src/logic/state/group.ts @@ -1,27 +1,64 @@ -import { Association, Group, JoinRequests } from '@urbit/api'; +import { Association, Group, hideGroup, JoinRequests } from '@urbit/api'; import { useCallback } from 'react'; -import { BaseState, createState } from './base'; +import { reduce } from '../reducers/group-update'; +import _ from 'lodash'; +import { reduce as reduceView } from '../reducers/group-view'; +import { + createState, + createSubscription, + reduceStateN +} from './base'; +import api from '~/logic/api'; -export interface GroupState extends BaseState { +export interface GroupState { groups: { [group: string]: Group; - } + }; pendingJoin: JoinRequests; + hidePending: (group: string) => Promise; } // @ts-ignore investigate zustand types -const useGroupState = createState('Group', { - groups: {}, - pendingJoin: {} -}, ['groups']); +const useGroupState = createState( + 'Group', + (set, get) => ({ + groups: {}, + pendingJoin: {}, + hidePending: async (group) => { + get().set((draft) => { + delete draft.pendingJoin[group]; + }); + await api.poke(hideGroup(group)); + } + }), + ['groups'], + [ + (set, get) => + createSubscription('group-store', '/groups', (e) => { + if ('groupUpdate' in e) { + reduceStateN(get(), e.groupUpdate, reduce); + } + }), + (set, get) => createSubscription('group-view', '/all', (e) => { + const data = _.get(e, 'group-view-update', false); + if (data) { + reduceStateN(get(), data, reduceView); + } + }) + ] +); export function useGroup(group: string) { - return useGroupState(useCallback(s => s.groups[group] as Group | undefined, [group])); + return useGroupState( + useCallback(s => s.groups[group] as Group | undefined, [group]) + ); } export function useGroupForAssoc(association: Association) { return useGroupState( - useCallback(s => s.groups[association.group] as Group | undefined, [association]) + useCallback(s => s.groups[association.group] as Group | undefined, [ + association + ]) ); } diff --git a/pkg/interface/src/logic/state/hark.ts b/pkg/interface/src/logic/state/hark.ts index 864936161..ad0f99c67 100644 --- a/pkg/interface/src/logic/state/hark.ts +++ b/pkg/interface/src/logic/state/hark.ts @@ -1,78 +1,211 @@ -import { NotificationGraphConfig, Timebox, Unreads, dateToDa } from "@urbit/api"; +import { + archive, + HarkBin, + markCountAsRead, + NotificationGraphConfig, + Unreads, + Timebox, + HarkLid, + harkBinToId, + decToUd, + unixToDa, + opened, + markEachAsRead +} from '@urbit/api'; +import { Poke } from '@urbit/http-api'; import { patp2dec } from 'urbit-ob'; -import BigIntOrderedMap from "@urbit/api/lib/BigIntOrderedMap"; -import {useCallback} from "react"; +import _ from 'lodash'; +import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; +import api from '~/logic/api'; +import { useCallback, useMemo } from 'react'; -// import { harkGraphHookReducer, harkGroupHookReducer, harkReducer } from "~/logic/subscription/hark"; -import { createState } from './base'; +import { + createState, + createSubscription, + pokeOptimisticallyN, + reduceStateN +} from './base'; +import { reduce, reduceGraph, reduceGroup } from '../reducers/hark-update'; +import useMetadataState from './metadata'; export const HARK_FETCH_MORE_COUNT = 3; export interface HarkState { - archivedNotifications: BigIntOrderedMap; + archive: BigIntOrderedMap; doNotDisturb: boolean; - // getMore: () => Promise; - // getSubset: (offset: number, count: number, isArchive: boolean) => Promise; + poke: (poke: Poke) => Promise; + getMore: () => Promise; + opened: () => void; // getTimeSubset: (start?: Date, end?: Date) => Promise; - notifications: BigIntOrderedMap; - unreadNotes: Timebox; + unseen: Timebox; + seen: Timebox; notificationsCount: number; notificationsGraphConfig: NotificationGraphConfig; // TODO unthread this everywhere notificationsGroupConfig: string[]; unreads: Unreads; + archiveNote: (bin: HarkBin, lid: HarkLid) => Promise; + readCount: (path: string) => Promise; + readGraph: (graph: string) => Promise; + readGroup: (group: string) => Promise; } -const useHarkState = createState('Hark', { - archivedNotifications: new BigIntOrderedMap(), - doNotDisturb: false, - unreadNotes: [], - // getMore: async (): Promise => { - // const state = get(); - // const offset = state.notifications.size || 0; - // await state.getSubset(offset, HARK_FETCH_MORE_COUNT, false); - // // TODO make sure that state has mutated at this point. - // return offset === (state.notifications.size || 0); - // }, - // getSubset: async (offset, count, isArchive): Promise => { - // const api = useApi(); - // const where = isArchive ? 'archive' : 'inbox'; - // const result = await api.scry({ - // app: 'hark-store', - // path: `/recent/${where}/${offset}/${count}` - // }); - // harkReducer(result); - // return; - // }, - // getTimeSubset: async (start, end): Promise => { - // const api = useApi(); - // const s = start ? dateToDa(start) : '-'; - // const e = end ? dateToDa(end) : '-'; - // const result = await api.scry({ - // app: 'hark-hook', - // path: `/recent/${s}/${e}` - // }); - // harkGroupHookReducer(result); - // harkGraphHookReducer(result); - // return; - // }, - notifications: new BigIntOrderedMap(), - notificationsCount: 0, - notificationsGraphConfig: { - watchOnSelf: false, - mentions: false, - watching: [] - }, - notificationsGroupConfig: [], - unreads: { - graph: {}, - group: {} - } -}, ['unreadNotes', 'notifications', 'archivedNotifications', 'unreads', 'notificationsCount']); +const useHarkState = createState( + 'Hark', + (set, get) => ({ + archive: new BigIntOrderedMap(), + doNotDisturb: false, + unreadNotes: [], + poke: async (poke: Poke) => { + await pokeOptimisticallyN(useHarkState, poke, [reduce]); + }, + readGraph: async (graph: string) => { + const prefix = `/graph/${graph.slice(6)}`; + let counts = [] as string[]; + let eaches = [] as [string, string][]; + Object.entries(get().unreads).forEach(([path, unreads]) => { + if (path.startsWith(prefix)) { + if(unreads.count > 0) { + counts.push(path); + } + unreads.each.forEach(unread => { + eaches.push([path, unread]); + }); + } + }); + get().set(draft => { + counts.forEach(path => { + draft.unreads[path].count = 0; + }); + eaches.forEach(([path, each]) => { + draft.unreads[path].each = []; + }); + }); + await Promise.all([ + ...counts.map(path => markCountAsRead({ desk: window.desk, path })), + ...eaches.map(([path, each]) => markEachAsRead({ desk: window.desk, path }, each)) + ].map(pok => api.poke(pok))); + }, + readGroup: async (group: string) => { + const graphs = + _.pickBy(useMetadataState.getState().associations.graph, a => a.group === group); + await Promise.all(Object.keys(graphs).map(get().readGraph)); + }, + readCount: async (path) => { + const poke = markCountAsRead({ desk: (window as any).desk, path }); + await pokeOptimisticallyN(useHarkState, poke, [reduce]); + }, + opened: async () => { + reduceStateN(get(), { opened: null }, [reduce]); + + await api.poke(opened); + }, + archiveNote: async (bin: HarkBin, lid: HarkLid) => { + const poke = archive(bin, lid); + get().set((draft) => { + const key = 'seen' in lid ? 'seen' : 'unseen'; + const binId = harkBinToId(bin); + delete draft[key][binId]; + }); + await api.poke(poke); + }, + getMore: async (): Promise => { + const state = get(); + const oldSize = state.archive?.size || 0; + const offset = decToUd( + state.archive?.peekSmallest()?.[0].toString() + || unixToDa(Date.now() * 1000).toString() + ); + const update = await api.scry({ + app: 'hark-store', + path: `/recent/inbox/${offset}/5` + }); + reduceStateN(useHarkState.getState(), update, [reduce]); + return get().archive?.size === oldSize; + }, + unseen: {}, + seen: {}, + notificationsCount: 0, + notificationsGraphConfig: { + watchOnSelf: false, + mentions: false, + watching: [] + }, + notificationsGroupConfig: [], + unreads: {} + }), + [ + 'seen', + 'unseen', + 'archive', + 'unreads', + 'notificationsCount' + ], + [ + (set, get) => + createSubscription('hark-store', '/updates', (d) => { + reduceStateN(get(), d, [reduce]); + }), + (set, get) => + createSubscription('hark-graph-hook', '/updates', (j) => { + const graphHookData = _.get(j, 'hark-graph-hook-update', false); + if (graphHookData) { + reduceStateN(get(), graphHookData, reduceGraph); + } + }), + (set, get) => + createSubscription('hark-group-hook', '/updates', (j) => { + const data = _.get(j, 'hark-group-hook-update', false); + if (data) { + reduceStateN(get(), data, reduceGroup); + } + }) + ] +); + +export const emptyHarkStats = () => ({ + last: 0, + count: 0, + each: [] + }); export function useHarkDm(ship: string) { - return useHarkState(useCallback(s => { - return s.unreads.graph[`/ship/~${window.ship}/dm-inbox`]?.[`/${patp2dec(ship)}`]; - }, [ship])); + return useHarkState( + useCallback( + (s) => { + const key = `/graph/~${window.ship}/dm-inbox/${patp2dec(ship)}`; + return s.unreads[key] || emptyHarkStats(); + }, + [ship] + ) + ); +} + +export function useHarkStat(path: string) { + return useHarkState( + useCallback(s => s.unreads[path] || emptyHarkStats(), [path]) + ); +} + +export function selHarkGraph(graph: string) { + const [,, ship, name] = graph.split('/'); + const path = `/graph/${ship}/${name}`; + return (s: HarkState) => (s.unreads[path] || emptyHarkStats()); +} + +export function useHarkGraph(graph: string) { + const sel = useMemo(() => selHarkGraph(graph), [graph]); + return useHarkState(sel); +} + +export function useHarkGraphIndex(graph: string, index: string) { + const [, ship, name] = useMemo(() => graph.split('/'), [graph]); + return useHarkState( + useCallback(s => s.unreads[`/graph/${ship}/${name}/index`], [ + ship, + name, + index + ]) + ); } export default useHarkState; diff --git a/pkg/interface/src/logic/state/invite.ts b/pkg/interface/src/logic/state/invite.ts index 54bd3906b..d477236b1 100644 --- a/pkg/interface/src/logic/state/invite.ts +++ b/pkg/interface/src/logic/state/invite.ts @@ -1,13 +1,31 @@ import { Invites } from '@urbit/api'; -import { BaseState, createState } from './base'; +import { reduce } from '../reducers/invite-update'; +import _ from 'lodash'; +import { + createState, + createSubscription, + reduceStateN +} from './base'; -export interface InviteState extends BaseState { +export interface InviteState { invites: Invites; } -// @ts-ignore investigate zustand types -const useInviteState = createState('Invite', { - invites: {} -}); +const useInviteState = createState( + 'Invite', + { + invites: {} + }, + ['invites'], + [ + (set, get) => + createSubscription('invite-store', '/all', (e) => { + const d = _.get(e, 'invite-update', false); + if (d) { + reduceStateN(get(), d, reduce); + } + }) + ] +); export default useInviteState; diff --git a/pkg/interface/src/logic/state/join.ts b/pkg/interface/src/logic/state/join.ts new file mode 100644 index 000000000..0a66d89f2 --- /dev/null +++ b/pkg/interface/src/logic/state/join.ts @@ -0,0 +1,8 @@ +import { useOsDark } from './local'; +import { useTheme } from './settings'; + +export function useDark() { + const osDark = useOsDark(); + const theme = useTheme(); + return theme === 'dark' || (osDark && theme === 'auto'); +} diff --git a/pkg/interface/src/logic/state/launch.ts b/pkg/interface/src/logic/state/launch.ts index 4cefc57e2..85b9ffec7 100644 --- a/pkg/interface/src/logic/state/launch.ts +++ b/pkg/interface/src/logic/state/launch.ts @@ -1,27 +1,53 @@ import { Tile, WeatherState } from '~/types/launch-update'; -import { BaseState, createState } from './base'; +import { + createState, + createSubscription, + reduceStateN +} from './base'; +import { reduce } from '../reducers/launch-update'; +import _ from 'lodash'; -export interface LaunchState extends BaseState { +export interface LaunchState { firstTime: boolean; tileOrdering: string[]; tiles: { [app: string]: Tile; - }, - weather: WeatherState | null | Record | boolean, + }; + weather: WeatherState | null | Record | boolean; userLocation: string | null; - baseHash: string | null; - runtimeLag: boolean; -}; +} // @ts-ignore investigate zustand types -const useLaunchState = createState('Launch', { - firstTime: true, - tileOrdering: [], - tiles: {}, - weather: null, - userLocation: null, - baseHash: null, - runtimeLag: false, -}); +const useLaunchState = createState( + 'Launch', + (set, get) => ({ + firstTime: true, + tileOrdering: [], + tiles: {}, + weather: null, + userLocation: null + }), + ['weather'], + [ + (set, get) => + createSubscription('weather', '/all', (e) => { + const w = _.get(e, 'weather', false); + if (w) { + set({ weather: w }); + } + const l = _.get(e, 'location', false); + if (l) { + set({ userLocation: l }); + } + }), + (set, get) => + createSubscription('launch', '/all', (e) => { + const d = _.get(e, 'launch-update', false); + if (d) { + reduceStateN(get(), d, reduce); + } + }) + ] +); export default useLaunchState; diff --git a/pkg/interface/src/logic/state/local.tsx b/pkg/interface/src/logic/state/local.tsx index fe9becd8c..b1947bbb2 100644 --- a/pkg/interface/src/logic/state/local.tsx +++ b/pkg/interface/src/logic/state/local.tsx @@ -3,29 +3,37 @@ import f from 'lodash/fp'; import React from 'react'; import create, { State } from 'zustand'; import { persist } from 'zustand/middleware'; -import { BackgroundConfig, LeapCategories, RemoteContentPolicy, TutorialProgress, tutorialProgress } from '~/types/local-update'; +import { BackgroundConfig, LeapCategories, RemoteContentPolicy } from '~/types/local-update'; +import airlock from '~/logic/api'; +import { bootstrapApi } from '../api/bootstrap'; +import { clearStorageMigration, createStorageKey, storageVersion, wait } from '~/logic/lib/util'; + +export type SubscriptionStatus = 'connected' | 'disconnected' | 'reconnecting'; export interface LocalState { theme: 'light' | 'dark' | 'auto'; hideAvatars: boolean; hideNicknames: boolean; remoteContentPolicy: RemoteContentPolicy; - tutorialProgress: TutorialProgress; hideGroups: boolean; hideUtilities: boolean; - tutorialRef: HTMLElement | null, - hideTutorial: () => void; - nextTutStep: () => void; - prevTutStep: () => void; hideLeapCats: LeapCategories[]; - setTutorialRef: (el: HTMLElement | null) => void; dark: boolean; mobile: boolean; + breaks: { + sm: boolean; + md: boolean; + lg: boolean; + } background: BackgroundConfig; omniboxShown: boolean; suspendedFocus?: HTMLElement; toggleOmnibox: () => void; - set: (fn: (state: LocalState) => void) => void + set: (fn: (state: LocalState) => void) => void; + subscription: SubscriptionStatus; + reconnect: () => Promise; + bootstrap: () => Promise; + errorCount: number; } type LocalStateZus = LocalState & State; @@ -36,6 +44,11 @@ export const selectLocalState = const useLocalState = create(persist((set, get) => ({ dark: false, mobile: false, + breaks: { + sm: false, + md: false, + lg: false + }, background: undefined, theme: 'auto', hideAvatars: false, @@ -43,27 +56,6 @@ const useLocalState = create(persist((set, get) => ({ hideLeapCats: [], hideGroups: false, hideUtilities: false, - tutorialProgress: 'hidden', - tutorialRef: null, - setTutorialRef: (el: HTMLElement | null) => set(produce((state) => { - state.tutorialRef = el; - })), - hideTutorial: () => set(produce((state) => { - state.tutorialProgress = 'hidden'; - state.tutorialRef = null; - })), - nextTutStep: () => set(produce((state) => { - const currIdx = tutorialProgress.findIndex(p => p === state.tutorialProgress); - if(currIdx < tutorialProgress.length) { - state.tutorialProgress = tutorialProgress[currIdx + 1]; - } - })), - prevTutStep: () => set(produce((state) => { - const currIdx = tutorialProgress.findIndex(p => p === state.tutorialProgress); - if(currIdx > 0) { - state.tutorialProgress = tutorialProgress[currIdx - 1]; - } - })), remoteContentPolicy: { imageShown: true, audioShown: true, @@ -82,14 +74,44 @@ const useLocalState = create(persist((set, get) => ({ state.suspendedFocus.blur(); } })), + subscription: 'connected', + errorCount: 0, + // XX this logic should be handled by eventsource lib, but channel$a + // resume doesn't work properly + reconnect: async () => { + const { errorCount } = get(); + set(s => ({ errorCount: s.errorCount+1, subscription: 'reconnecting' })); + + if(errorCount > 5) { + set({ subscription: 'disconnected' }); + return; + } + await wait(Math.pow(2, errorCount) * 750); + + try { + airlock.reset(); + await bootstrapApi(); + } catch (e) { + console.error(`Retrying connection, attempt #${errorCount}`); + } + }, + bootstrap: async () => { + set({ subscription: 'reconnecting', errorCount: 0 }); + airlock.reset(); + await bootstrapApi(); + set({ subscription: 'connected' }); + }, // @ts-ignore investigate zustand types set: fn => set(produce(fn)) }), { blacklist: [ - 'suspendedFocus', 'toggleOmnibox', 'omniboxShown', 'tutorialProgress', - 'prevTutStep', 'nextTutStep', 'tutorialRef', 'setTutorialRef' + 'suspendedFocus', 'toggleOmnibox', 'omniboxShown', + 'subscription', + 'errorCount', 'breaks' ], - name: 'localReducer' + name: createStorageKey('local'), + version: storageVersion, + migrate: clearStorageMigration })); function withLocalState>(Component: C, stateMemberKeys?: S[]) { @@ -104,4 +126,9 @@ function withLocalState s.dark; +export function useOsDark() { + return useLocalState(selOsDark); +} + export { useLocalState as default, withLocalState }; diff --git a/pkg/interface/src/logic/state/metadata.ts b/pkg/interface/src/logic/state/metadata.ts index 4983d6d58..9beea5687 100644 --- a/pkg/interface/src/logic/state/metadata.ts +++ b/pkg/interface/src/logic/state/metadata.ts @@ -1,70 +1,119 @@ -import { Association, Associations } from '@urbit/api'; +import { Association, Associations, MetadataUpdatePreview } from '@urbit/api/metadata'; import _ from 'lodash'; -import { useCallback } from 'react'; -import { BaseState, createState } from './base'; +import { useCallback, useEffect, useState } from 'react'; +import { + createState, + createSubscription, + reduceStateN +} from './base'; +import airlock from '~/logic/api'; +import { reduce } from '../reducers/metadata-update'; export const METADATA_MAX_PREVIEW_WAIT = 150000; -export interface MetadataState extends BaseState { +export interface MetadataState { associations: Associations; - // preview: (group: string) => Promise; + loaded: boolean; + getPreview: (group: string) => Promise; + previews: { + [group: string]: MetadataUpdatePreview + } } +// @ts-ignore investigate zustand types +const useMetadataState = createState( + 'Metadata', + (set, get) => ({ + loaded: false, + associations: { + groups: {}, + graph: {} + }, + previews: {}, + getPreview: async (group: string): Promise => { + const state = get(); + if(group in state.previews) { + return state.previews[group]; + } + try { + const preview = await airlock.subscribeOnce('metadata-pull-hook', `/preview${group}`, 20 * 1000); + if('metadata-hook-update' in preview) { + const newState = get(); + newState.set((s) => { + s.previews[group] = preview['metadata-hook-update'].preview; + }); + return preview['metadata-hook-update'].preview; + } else { + throw 'no-permissions'; + } + } catch (e) { + if(e === 'timeout') { + throw 'offline'; + } + throw e; + } + } + }), + ['loaded'], + [ + (set, get) => + createSubscription('metadata-store', '/all', (j) => { + const d = _.get(j, 'metadata-update', false); + if (d) { + reduceStateN(get(), d, reduce); + } + }) + ] +); + export function useAssocForGraph(graph: string) { - return useMetadataState(useCallback(s => s.associations.graph[graph] as Association | undefined, [graph])); + return useMetadataState( + useCallback(s => s.associations.graph[graph] as Association | undefined, [ + graph + ]) + ); } export function useAssocForGroup(group: string) { - return useMetadataState(useCallback(s => s.associations.groups[group] as Association | undefined, [group])); + return useMetadataState( + useCallback( + s => s.associations.groups[group] as Association | undefined, + [group] + ) + ); +} + +const selPreview = (s: MetadataState) => [s.previews, s.getPreview] as const; + +export function usePreview(group: string) { + const [error, setError] = useState(null); + const [previews, getPreview] = useMetadataState(selPreview); + useEffect(() => { + let mounted = true; + (async () => { + try { + await getPreview(group); + } catch (e) { + if(mounted) { + setError(e); + } + } + })(); + + return () => { + mounted = false; + }; + }, [group]); + + const preview = previews[group]; + + return { error, preview }; } export function useGraphsForGroup(group: string) { const graphs = useMetadataState(s => s.associations.graph); return _.pickBy(graphs, (a: Association) => a.group === group); } -// @ts-ignore investigate zustand types -const useMetadataState = createState('Metadata', { - associations: { groups: {}, graph: {}, contacts: {}, chat: {}, link: {}, publish: {} } - // preview: async (group): Promise => { - // return new Promise((resolve, reject) => { - // const api = useApi(); - // let done = false; - - // setTimeout(() => { - // if (done) { - // return; - // } - // done = true; - // reject(new Error('offline')); - // }, METADATA_MAX_PREVIEW_WAIT); - - // api.subscribe({ - // app: 'metadata-pull-hook', - // path: `/preview${group}`, - // // TODO type this message? - // event: (message) => { - // if ('metadata-hook-update' in message) { - // done = true; - // const update = message['metadata-hook-update'].preview as MetadataUpdatePreview; - // resolve(update); - // } else { - // done = true; - // reject(new Error('no-permissions')); - // } - // // TODO how to delete this subscription? Perhaps return the susbcription ID as the second parameter of all the handlers - // }, - // err: (error) => { - // console.error(error); - // reject(error); - // }, - // quit: () => { - // if (!done) { - // reject(new Error('offline')); - // } - // } - // }); - // }); - // }, -}); export default useMetadataState; diff --git a/pkg/interface/src/logic/state/settings.ts b/pkg/interface/src/logic/state/settings.ts index 6951fe178..82f5710a2 100644 --- a/pkg/interface/src/logic/state/settings.ts +++ b/pkg/interface/src/logic/state/settings.ts @@ -1,8 +1,23 @@ import f from 'lodash/fp'; -import { RemoteContentPolicy, LeapCategories, leapCategories } from '~/types/local-update'; +import _ from 'lodash'; +import { + RemoteContentPolicy, + LeapCategories, + leapCategories +} from '~/types/local-update'; import { useShortcut as usePlainShortcut } from '~/logic/lib/shortcutContext'; -import { BaseState, createState } from '~/logic/state/base'; +import { + BaseState, + createState, + createSubscription, + reduceStateN, + pokeOptimisticallyN +} from '~/logic/state/base'; import { useCallback } from 'react'; +import { reduceUpdate } from '../reducers/settings-update'; +import airlock from '~/logic/api'; +import { Contact, getDeskSettings, Value } from '@urbit/api'; +import { putEntry } from '@urbit/api/settings'; export interface ShortcutMapping { cycleForward: string; @@ -10,9 +25,10 @@ export interface ShortcutMapping { navForward: string; navBack: string; hideSidebar: string; + readGroup: string; } -export interface SettingsState extends BaseState { +export interface SettingsState { display: { backgroundType: 'none' | 'url' | 'color'; background?: string; @@ -28,62 +44,98 @@ export interface SettingsState extends BaseState { }; keyboard: ShortcutMapping; remoteContentPolicy: RemoteContentPolicy; + getAll: () => Promise; + putEntry: (bucket: string, key: string, value: Value) => Promise; leap: { categories: LeapCategories[]; }; - tutorial: { - seen: boolean; - joined?: number; - }; } -export const selectSettingsState = -(keys: K[]) => f.pick(keys); +export const selectSettingsState = )>(keys: K[]) => + f.pick & SettingsState, K>(keys); export const selectCalmState = (s: SettingsState) => s.calm; export const selectDisplayState = (s: SettingsState) => s.display; // @ts-ignore investigate zustand types -const useSettingsState = createState('Settings', { - display: { - backgroundType: 'none', - background: undefined, - dark: false, - theme: 'auto' - }, - calm: { - hideNicknames: false, - hideAvatars: false, - hideUnreads: false, - hideGroups: false, - hideUtilities: false - }, - remoteContentPolicy: { - imageShown: true, - oembedShown: true, - audioShown: true, - videoShown: true - }, - leap: { - categories: leapCategories - }, - tutorial: { - seen: true, - joined: undefined - }, - keyboard: { - cycleForward: 'ctrl+\'', - cycleBack: 'ctrl+;', - navForward: 'ctrl+]', - navBack: 'ctrl+[', - hideSidebar: 'ctrl+\\' - } -}); +const useSettingsState = createState( + 'Settings', + (set, get) => ({ + display: { + backgroundType: 'none', + background: undefined, + dark: false, + theme: 'auto' + }, + calm: { + hideNicknames: false, + hideAvatars: false, + hideUnreads: false, + hideGroups: false, + hideUtilities: false + }, + remoteContentPolicy: { + imageShown: true, + oembedShown: true, + audioShown: true, + videoShown: true + }, + leap: { + categories: leapCategories + }, + keyboard: { + cycleForward: 'ctrl+\'', + cycleBack: 'ctrl+;', + navForward: 'ctrl+]', + navBack: 'ctrl+[', + hideSidebar: 'ctrl+\\', + readGroup: 'shift+Escape' + }, + getAll: async () => { + const { desk } = await airlock.scry(getDeskSettings((window as any).desk)); + get().set((s) => { + for(const bucket in desk) { + s[bucket] = { ...(s[bucket] || {}), ...desk[bucket] }; + } + }); + }, + putEntry: async (bucket: string, entry: string, value: Value) => { + const poke = putEntry((window as any).desk, bucket, entry, value); + pokeOptimisticallyN(useSettingsState, poke, reduceUpdate); + } + }), + [], + [ + (set, get) => + createSubscription('settings-store', `/desk/${(window as any).desk}`, (e) => { + const data = _.get(e, 'settings-event', false); + if (data) { + reduceStateN(get(), data, reduceUpdate); + } + }) + ] +); -export function useShortcut(name: T, cb: (e: KeyboardEvent) => void) { +export function useShortcut( + name: T, + cb: (e: KeyboardEvent) => void +) { const key = useSettingsState(useCallback(s => s.keyboard[name], [name])); return usePlainShortcut(key, cb); } +const selTheme = (s: SettingsState) => s.display.theme; + +export function useTheme() { + return useSettingsState(selTheme); +} + +// Hide is an optional second parameter for when this function is used in class components +export function useShowNickname(contact: Contact | null, hide?: boolean): boolean { + const hideState = useSettingsState(state => state.calm.hideNicknames); + const hideNicknames = typeof hide !== 'undefined' ? hide : hideState; + return Boolean(contact && contact.nickname && !hideNicknames); +} + export default useSettingsState; diff --git a/pkg/interface/src/logic/state/storage.ts b/pkg/interface/src/logic/state/storage.ts index 7ad79ceee..391738a5e 100644 --- a/pkg/interface/src/logic/state/storage.ts +++ b/pkg/interface/src/logic/state/storage.ts @@ -1,34 +1,72 @@ -import { BaseState, createState } from './base'; +import { reduce } from '../reducers/s3-update'; +import _ from 'lodash'; +import airlock from '~/logic/api'; +import { createState, createSubscription, reduceStateN } from './base'; export interface GcpToken { accessKey: string; expiresIn: number; } -export interface StorageState extends BaseState { +export interface StorageState { gcp: { configured?: boolean; token?: GcpToken; - }, + isConfigured: () => Promise; + getToken: () => Promise; + }; s3: { configuration: { buckets: Set; currentBucket: string; }; credentials: any | null; // TODO better type - } + }; } // @ts-ignore investigate zustand types -const useStorageState = createState('Storage', { - gcp: {}, - s3: { - configuration: { - buckets: new Set(), - currentBucket: '' +const useStorageState = createState( + 'Storage', + (set, get) => ({ + gcp: { + isConfigured: () => { + return airlock.thread({ + inputMark: 'noun', + outputMark: 'json', + threadName: 'gcp-is-configured', + body: {} + }); + }, + getToken: async () => { + const token = await airlock.thread({ + inputMark: 'noun', + outputMark: 'gcp-token', + threadName: 'gcp-get-token', + body: {} + }); + get().set((state) => { + state.gcp.token = token; + }); + } }, - credentials: null - } -}, ['s3']); + s3: { + configuration: { + buckets: new Set(), + currentBucket: '' + }, + credentials: null + } + }), + ['s3', 'gcp'], + [ + (set, get) => + createSubscription('s3-store', '/all', (e) => { + const d = _.get(e, 's3-update', false); + if (d) { + reduceStateN(get(), d, reduce); + } + }) + ] +); export default useStorageState; diff --git a/pkg/interface/src/logic/store/base.ts b/pkg/interface/src/logic/store/base.ts deleted file mode 100644 index f798f228f..000000000 --- a/pkg/interface/src/logic/store/base.ts +++ /dev/null @@ -1,43 +0,0 @@ -export default class BaseStore { - state: S; - setState: (s: Partial) => void = (s) => {}; - constructor() { - this.state = this.initialState(); - } - - initialState() { - return {} as S; - } - - setStateHandler(setState: (s: Partial) => void) { - this.setState = setState; - } - - clear() { - this.handleEvent({ - data: { clear: true } - }); - } - - handleEvent(data) { - const json = data.data; - - if (json === null) { - return; - } - - if ('clear' in json && json.clear) { - this.setState(this.initialState()); - return; - } - - this.reduce(json, this.state); - if('connection' in json) { - this.setState(this.state); - } - } - - reduce(data, state) { - // extend me! - } -} diff --git a/pkg/interface/src/logic/store/store.ts b/pkg/interface/src/logic/store/store.ts deleted file mode 100644 index cfc943d7f..000000000 --- a/pkg/interface/src/logic/store/store.ts +++ /dev/null @@ -1,67 +0,0 @@ -import _ from 'lodash'; -import { unstable_batchedUpdates } from 'react-dom'; -import { Cage } from '~/types/cage'; -import ConnectionReducer from '../reducers/connection'; -import { ContactReducer } from '../reducers/contact-update'; -import GcpReducer from '../reducers/gcp-reducer'; -import { GraphReducer } from '../reducers/graph-update'; -import GroupReducer from '../reducers/group-update'; -import { GroupViewReducer } from '../reducers/group-view'; -import { HarkReducer } from '../reducers/hark-update'; -import InviteReducer from '../reducers/invite-update'; -import LaunchReducer from '../reducers/launch-update'; -import MetadataReducer from '../reducers/metadata-update'; -import S3Reducer from '../reducers/s3-update'; -import SettingsReducer from '../reducers/settings-update'; -import BaseStore from './base'; -import { StoreState } from './type'; - -export default class GlobalStore extends BaseStore { - inviteReducer = new InviteReducer(); - metadataReducer = new MetadataReducer(); - s3Reducer = new S3Reducer(); - groupReducer = new GroupReducer(); - launchReducer = new LaunchReducer(); - connReducer = new ConnectionReducer(); - settingsReducer = new SettingsReducer(); - gcpReducer = new GcpReducer(); - - pastActions: Record = {} - - constructor() { - super(); - (window as any).debugStore = this.debugStore.bind(this); - } - - debugStore(tag: string, ...stateKeys: string[]) { - console.log(this.pastActions[tag]); - console.log(_.pick(this.state, stateKeys)); - } - - initialState(): StoreState { - return { - connection: 'connected' - }; - } - - reduce(data: Cage, state: StoreState) { - unstable_batchedUpdates(() => { - // debug shim - const tag = Object.keys(data)[0]; - const oldActions = this.pastActions[tag] || []; - this.pastActions[tag] = [data[tag], ...oldActions.slice(0, 14)]; - this.inviteReducer.reduce(data); - this.metadataReducer.reduce(data); - this.s3Reducer.reduce(data); - this.groupReducer.reduce(data); - GroupViewReducer(data); - this.launchReducer.reduce(data); - this.connReducer.reduce(data, this.state); - GraphReducer(data); - HarkReducer(data); - ContactReducer(data); - this.settingsReducer.reduce(data); - this.gcpReducer.reduce(data); - }); - } -} diff --git a/pkg/interface/src/logic/store/type.ts b/pkg/interface/src/logic/store/type.ts deleted file mode 100644 index 568cd2041..000000000 --- a/pkg/interface/src/logic/store/type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ConnectionStatus } from '~/types/connection'; - -export interface StoreState { - // local state - connection: ConnectionStatus; -} diff --git a/pkg/interface/src/logic/subscription/base.ts b/pkg/interface/src/logic/subscription/base.ts deleted file mode 100644 index 8100f0a61..000000000 --- a/pkg/interface/src/logic/subscription/base.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Path } from '@urbit/api'; -import BaseApi from '../api/base'; -import BaseStore from '../store/base'; - -export default class BaseSubscription { - private errorCount = 0; - constructor(public store: BaseStore, public api: BaseApi, public channel: any) { - this.channel.setOnChannelError(this.onChannelError.bind(this)); - this.channel.setOnChannelOpen(this.onChannelOpen.bind(this)); - } - - clearQueue() { - this.channel.clearQueue(); - } - - delete() { - this.channel.delete(); - } - - // Exists to allow subclasses to hook - restart() { - this.handleEvent({ data: { connection: 'reconnecting' } }); - this.start(); - } - - onChannelOpen(e: any) { - this.errorCount = 0; - this.handleEvent({ data: { connection: 'connected' } }); - } - - onChannelError(err) { - console.error('event source error: ', err); - this.errorCount++; - if(this.errorCount >= 5) { - console.error('bailing out, too many retries'); - this.handleEvent({ data: { connection: 'disconnected' } }); - return; - } - this.handleEvent({ data: { connection: 'reconnecting' } }); - setTimeout(() => { - this.restart(); - }, Math.pow(2,this.errorCount - 1) * 750); - } - - subscribe(path: Path, app: string) { - return this.api.subscribe(path, 'PUT', this.api.ship, app, - this.handleEvent.bind(this), - (err) => { - console.log(err); - this.subscribe(path, app); - }, - () => { - this.subscribe(path, app); - }); - } - - unsubscribe(id: number) { - this.api.unsubscribe(id); - } - - start() { - // extend - } - - handleEvent(diff) { - // extend - this.store.handleEvent(diff); - } -} - diff --git a/pkg/interface/src/logic/subscription/global.ts b/pkg/interface/src/logic/subscription/global.ts deleted file mode 100644 index 6e928b6f2..000000000 --- a/pkg/interface/src/logic/subscription/global.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Path } from '@urbit/api'; -import { StoreState } from '../store/type'; -import BaseSubscription from './base'; - -export default class GlobalSubscription extends BaseSubscription { - openSubscriptions: any = {}; - - start() { - this.subscribe('/all', 'metadata-store'); - this.subscribe('/all', 'invite-store'); - this.subscribe('/all', 'launch'); - this.subscribe('/all', 'weather'); - this.subscribe('/groups', 'group-store'); - this.clearQueue(); - - this.subscribe('/updates', 'dm-hook'); - this.subscribe('/all', 'contact-store'); - this.subscribe('/all', 's3-store'); - this.subscribe('/keys', 'graph-store'); - this.subscribe('/updates', 'hark-store'); - this.subscribe('/updates', 'hark-graph-hook'); - this.subscribe('/updates', 'hark-group-hook'); - this.subscribe('/all', 'settings-store'); - this.subscribe('/all', 'group-view'); - this.subscribe('/nacks', 'contact-pull-hook'); - this.clearQueue(); - - this.subscribe('/updates', 'graph-store'); - } - - subscribe(path: Path, app: string) { - if (`${app}${path}` in this.openSubscriptions) { - return; - } - - const id = super.subscribe(path, app); - this.openSubscriptions[`${app}${path}`] = { app, path, id }; - } - - unsubscribe(id) { - for (const key in Object.keys(this.openSubscriptions)) { - const val = this.openSubscriptions[key]; - if (id === val.id) { - delete this.openSubscriptions[`${val.app}${val.path}`]; - super.unsubscribe(id); - } - } - } - - restart() { - this.openSubscriptions = {}; - super.restart(); - } -} diff --git a/pkg/interface/src/register-sw.js b/pkg/interface/src/register-sw.js index 1d6bb0518..4cb527f25 100644 --- a/pkg/interface/src/register-sw.js +++ b/pkg/interface/src/register-sw.js @@ -1,7 +1,7 @@ if ('serviceWorker' in navigator && process.env.NODE_ENV !== 'development') { window.addEventListener('load', () => { - navigator.serviceWorker.register('/~landscape/js/bundle/serviceworker.js', { - scope: '/' + navigator.serviceWorker.register('/apps/landscape/serviceworker.js', { + scope: '/apps/landscape/' }).then((reg) => { }); }); diff --git a/pkg/interface/src/serviceworker.js b/pkg/interface/src/serviceworker.js index cd83dee19..14d52dfbf 100644 --- a/pkg/interface/src/serviceworker.js +++ b/pkg/interface/src/serviceworker.js @@ -13,10 +13,11 @@ const hash = process.env.LANDSCAPE_SHORTHASH; self.addEventListener('install', (ev) => { self.skipWaiting(); + console.log('registed sw', hash); }); self.addEventListener('activate', (ev) => { - ev.waitUntil(clients.claim()); + ev.waitUntil(self.clients.claim()); }); // Cache page navigations (html) with a Network First strategy @@ -56,6 +57,24 @@ registerRoute( }) ); +registerRoute( + ({ url }) => url.orign === 'https://noembed.com', + new CacheFirst({ + cacheName: 'embeds', + plugins: [ + // Ensure that only requests that result in a 200 status are cached + new CacheableResponsePlugin({ + statuses: [200] + }), + // Don't cache more than 150 items, and expire them after 30 days + new ExpirationPlugin({ + maxEntries: 150, + maxAgeSeconds: 60 * 60 * 24 * 30 // 30 Days + }) + ] + }) +); + // Cache images with a Cache First strategy registerRoute( // Check to see if the request's destination is style for an image diff --git a/pkg/interface/src/storage-wipe.ts b/pkg/interface/src/storage-wipe.ts new file mode 100644 index 000000000..169c4afc9 --- /dev/null +++ b/pkg/interface/src/storage-wipe.ts @@ -0,0 +1,12 @@ +import { createStorageKey } from './logic/lib/util'; + +const key = createStorageKey(`storage-wipe-${process.env.LANDSCAPE_LAST_WIPE}`); +const wiped = localStorage.getItem(key); + +// Loaded before everything, this clears local storage just once. +// Change VITE_LAST_WIPE in .env to date of wipe + +if (!wiped) { + localStorage.clear(); + localStorage.setItem(key, 'true'); +} diff --git a/pkg/interface/src/stories/ColorInput.stories.tsx b/pkg/interface/src/stories/ColorInput.stories.tsx index 65453ce56..101d74b8c 100644 --- a/pkg/interface/src/stories/ColorInput.stories.tsx +++ b/pkg/interface/src/stories/ColorInput.stories.tsx @@ -6,7 +6,7 @@ import { Formik } from 'formik'; import { ColorInput, ColorInputProps } from '~/views/components/ColorInput'; const initialValues = { - color: '#33FF22' + color: '33FF22' }; export default { diff --git a/pkg/interface/src/stories/GraphContentTall.stories.tsx b/pkg/interface/src/stories/GraphContentTall.stories.tsx index a5969e0d1..0255d53cc 100644 --- a/pkg/interface/src/stories/GraphContentTall.stories.tsx +++ b/pkg/interface/src/stories/GraphContentTall.stories.tsx @@ -12,8 +12,6 @@ export default { component: GraphContent } as Meta; -const fakeApi = {} as any; - const Template: Story = args => ( = args => ( m="3" maxWidth="100%" {...args} - api={fakeApi} showOurContact /> diff --git a/pkg/interface/src/stories/GraphContentWide.stories.tsx b/pkg/interface/src/stories/GraphContentWide.stories.tsx index 669be2256..6aae7a6d5 100644 --- a/pkg/interface/src/stories/GraphContentWide.stories.tsx +++ b/pkg/interface/src/stories/GraphContentWide.stories.tsx @@ -12,8 +12,6 @@ export default { component: GraphContent } as Meta; -const fakeApi = {} as any; - const Template: Story = (args) => { return ( = (args) => { width="100%" position="relative" > - + ); }; diff --git a/pkg/interface/src/stories/Invite.stories.tsx b/pkg/interface/src/stories/Invite.stories.tsx new file mode 100644 index 000000000..9c5f77b18 --- /dev/null +++ b/pkg/interface/src/stories/Invite.stories.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Meta, Story } from '@storybook/react'; + +import { Box } from '@tlon/indigo-react'; +import { InviteItem, InviteItemProps } from '~/views/components/Invite'; +import { JoinProgress } from '@urbit/api/groups'; + +export default { + title: 'Notifications/Invite', + component: InviteItem +} as Meta; + +const Template: Story = args => ( + + + +); + +const pendingJoin = (progress: JoinProgress) => ({ + hidden: false, + started: Date.now() - 3600, + ship: '~haddef-sigwen', + progress +}); + +export const Pending = Template.bind({}); +Pending.args = { + pendingJoin: pendingJoin('start'), + resource: '/ship/~bollug-worlus/urbit-index' +}; + +export const Errored = Template.bind({}); +Errored.args = { + pendingJoin: pendingJoin('no-perms'), + resource: '/ship/~bollug-worlus/urbit-index' +}; + +export const Done = Template.bind({}); +Done.args = { + pendingJoin: pendingJoin('done'), + resource: '/ship/~bollug-worlus/urbit-index' +}; diff --git a/pkg/interface/src/stories/LinkBlockItem.stories.tsx b/pkg/interface/src/stories/LinkBlockItem.stories.tsx new file mode 100644 index 000000000..927712e17 --- /dev/null +++ b/pkg/interface/src/stories/LinkBlockItem.stories.tsx @@ -0,0 +1,121 @@ +import React from 'react'; +import { Meta } from '@storybook/react'; +import { withDesign } from 'storybook-addon-designs'; + +import { Col, Row } from '@tlon/indigo-react'; +import { LinkBlockItem } from '~/views/apps/links/components/LinkBlockItem'; +import { createPost, GraphNode } from '@urbit/api'; +import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; + +export default { + title: 'Collections/BlockItem', + component: LinkBlockItem, + decorators: [withDesign] +} as Meta; + +const createLink = (text: string, url: string) => ({ + post: createPost('sampel-palnet', [{ text }, { url }]), + children: new BigIntOrderedMap() +}); + +export const Image = () => ( + + + + + +); + +Image.parameters = { + design: { + type: 'figma', + url: + 'https://www.figma.com/file/ovD1mlsYDa0agyYTdvCmGr/Landscape?node-id=8228%3A11' + } +}; + +export const Fallback = () => ( + + + + +); + +Fallback.parameters = { + design: { + type: 'figma', + url: + 'https://www.figma.com/file/ovD1mlsYDa0agyYTdvCmGr/Landscape?node-id=8228%3A57' + } +}; + +export const Audio = () => ( + + + +); + +Audio.parameters = { + design: { + type: 'figma', + url: + 'https://www.figma.com/file/ovD1mlsYDa0agyYTdvCmGr/Landscape?node-id=8229%3A0' + } +}; + +export const Youtube = () => ( + + + + +); + +Youtube.parameters = { + design: { + type: 'figma', + url: + 'https://www.figma.com/file/ovD1mlsYDa0agyYTdvCmGr/Landscape?node-id=8229%3A0' + } +}; diff --git a/pkg/interface/src/stories/LinkDetail.stories.tsx b/pkg/interface/src/stories/LinkDetail.stories.tsx new file mode 100644 index 000000000..c2a52fe3d --- /dev/null +++ b/pkg/interface/src/stories/LinkDetail.stories.tsx @@ -0,0 +1,131 @@ +import React from 'react'; +import { Meta } from '@storybook/react'; +import { withDesign } from 'storybook-addon-designs'; + +import { Box } from '@tlon/indigo-react'; +import { LinkDetail } from '~/views/apps/links/components/LinkDetail'; +import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; +import { GraphNode } from '@urbit/api'; +import useMetadataState from '~/logic/state/metadata'; +import { makeComment } from '~/logic/lib/fixtures'; + +const HOUR = 60*60 * 1000; + +export default { + title: 'Collections/LinkDetail', + component: LinkDetail, + decorators: [withDesign] +} as Meta; + +const nodeIndex = '/170141184504850861030994857749504231211'; +const node = { + post: { + index: '/170141184504850861030994857749504231211', + author: 'fabled-faster', + 'time-sent': 1609969377513, + signatures: [], + contents: [ + { text: 'IMG_20200827_150753' }, + { + url: + 'https://fabled-faster.nyc3.digitaloceanspaces.com/fabled-faster/2021.1.06..21.42.48-structure-0001.png' + } + ], + hash: null + }, + children: new BigIntOrderedMap().gas([ + makeComment( + 'ridlur-figbud', + Date.now() - 4*HOUR, + nodeIndex, + [{ text: 'Beautiful' }] + ), + makeComment( + 'roslet-tanner', + Date.now() - 3*HOUR, + nodeIndex, + [{ text: 'where did you find this?' }] + ), + + makeComment( + 'fabled-faster', + Date.now() - 2*HOUR, + nodeIndex, + [{ text: 'I dont\'t remember lol' }] + ) + ]) +}; + +const twitterNode = { + post: { + index: '/170141184504850861030994857749504231212', + author: 'fabled-faster', + 'time-sent': 1609969377513, + signatures: [], + contents: [ + { text: 'LindyMan' }, + { + url: 'https://twitter.com/PaulSkallas/status/1388896550198317056' + } + ], + hash: null + }, + children: new BigIntOrderedMap().gas([ + makeComment( + 'ridlur-figbud', + Date.now() - 4*HOUR, + nodeIndex, + [{ text: 'Beautiful' }] + ), + makeComment( + 'roslet-tanner', + Date.now() - 3*HOUR, + nodeIndex, + [{ text: 'where did you find this?' }] + ), + + makeComment( + 'fabled-faster', + Date.now() - 2*HOUR, + nodeIndex, + [{ text: 'I dont\'t remember lol' }] + ) + ]) +}; + +export const Image = () => { + const association = useMetadataState( + s => s.associations.graph['/ship/~bitbet-bolbel/links'] + ); + return ( + + + + ); +}; + +export const Twitter = () => { + const association = useMetadataState( + s => s.associations.graph['/ship/~bitbet-bolbel/links'] + ); + return ( + + + + ); +}; +Image.parameters = { + design: { + type: 'figma', + url: + 'https://www.figma.com/file/ovD1mlsYDa0agyYTdvCmGr/Landscape?node-id=8303%3A591' + } +}; diff --git a/pkg/interface/src/stories/LinkListItem.stories.tsx b/pkg/interface/src/stories/LinkListItem.stories.tsx new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/pkg/interface/src/stories/LinkListItem.stories.tsx @@ -0,0 +1 @@ + diff --git a/pkg/interface/src/stories/PendingDm.stories.tsx b/pkg/interface/src/stories/PendingDm.stories.tsx index 3579e2e95..13b98ebd7 100644 --- a/pkg/interface/src/stories/PendingDm.stories.tsx +++ b/pkg/interface/src/stories/PendingDm.stories.tsx @@ -8,10 +8,9 @@ export default { title: 'Notifications/PendingDm', component: PendingDm } as Meta; -const fakeApi = {} as any; export const Default = () => ( - + ); diff --git a/pkg/interface/src/stories/RemoteContent.stories.tsx b/pkg/interface/src/stories/RemoteContent.stories.tsx index 80fb8b3ff..469930953 100644 --- a/pkg/interface/src/stories/RemoteContent.stories.tsx +++ b/pkg/interface/src/stories/RemoteContent.stories.tsx @@ -12,7 +12,7 @@ export default { } as Meta; const Template: Story = args => ( - + ); @@ -38,3 +38,15 @@ Twitter.args = { // massive test flake unfold: false }; + +export const Image = Template.bind({}); + +Image.args = { + url: 'https://pbs.twimg.com/media/E343N9_UUAIm0Iw.jpg' +}; + +export const Fallback = Template.bind({}); + +Fallback.args = { + url: 'https://www.are.na/edouard-urcades/edouard' +}; diff --git a/pkg/interface/src/types/global.ts b/pkg/interface/src/types/global.ts index 4294f574f..4d29bdd31 100644 --- a/pkg/interface/src/types/global.ts +++ b/pkg/interface/src/types/global.ts @@ -3,5 +3,6 @@ import { PatpNoSig } from '@urbit/api'; declare global { interface Window { ship: PatpNoSig; + desk: string; } } diff --git a/pkg/interface/src/types/local-update.ts b/pkg/interface/src/types/local-update.ts index 31e99560d..9d9dd8220 100644 --- a/pkg/interface/src/types/local-update.ts +++ b/pkg/interface/src/types/local-update.ts @@ -1,10 +1,7 @@ -export const tutorialProgress = ['hidden', 'start', 'group-desc', 'channels', 'chat', 'link', 'publish', 'profile', 'leap', 'notifications', 'done', 'exit'] as const; - export const leapCategories = ['mychannel', 'messages', 'updates', 'profile', 'logout']; export type LeapCategories = typeof leapCategories[number]; -export type TutorialProgress = typeof tutorialProgress[number]; interface LocalUpdateSetDark { setDark: boolean; } diff --git a/pkg/interface/src/views/App.js b/pkg/interface/src/views/App.js index 7c0ab1cc8..41fc6c346 100644 --- a/pkg/interface/src/views/App.js +++ b/pkg/interface/src/views/App.js @@ -1,6 +1,7 @@ import dark from '@tlon/indigo-dark'; import light from '@tlon/indigo-light'; import Mousetrap from 'mousetrap'; +import shallow from 'zustand/shallow'; import 'mousetrap-global-bind'; import * as React from 'react'; import Helmet from 'react-helmet'; @@ -8,20 +9,16 @@ import 'react-hot-loader'; import { hot } from 'react-hot-loader/root'; import { BrowserRouter as Router, withRouter } from 'react-router-dom'; import styled, { ThemeProvider } from 'styled-components'; -import GlobalApi from '~/logic/api/global'; import gcpManager from '~/logic/lib/gcpManager'; -import { favicon, svgDataURL } from '~/logic/lib/util'; +import { svgDataURL } from '~/logic/lib/util'; import withState from '~/logic/lib/withState'; -import useContactState from '~/logic/state/contact'; -import useGroupState from '~/logic/state/group'; +import useContactState, { favicon } from '~/logic/state/contact'; import useLocalState from '~/logic/state/local'; import useSettingsState from '~/logic/state/settings'; +import useGraphState from '~/logic/state/graph'; import { ShortcutContextProvider } from '~/logic/lib/shortcutContext'; -import GlobalStore from '~/logic/store/store'; -import GlobalSubscription from '~/logic/subscription/global'; import ErrorBoundary from '~/views/components/ErrorBoundary'; -import { TutorialModal } from '~/views/landscape/components/TutorialModal'; import './apps/chat/css/custom.css'; import Omnibox from './components/leap/Omnibox'; import StatusBar from './components/StatusBar'; @@ -29,6 +26,7 @@ import './css/fonts.css'; import './css/indigo-static.css'; import { Content } from './landscape/components/Content'; import './landscape/css/custom.css'; +import { bootstrapApi } from '~/logic/api/bootstrap'; const Root = withState(styled.div` font-family: ${p => p.theme.fonts.sans}; @@ -74,37 +72,37 @@ class App extends React.Component { constructor(props) { super(props); this.ship = window.ship; - this.store = new GlobalStore(); - this.store.setStateHandler(this.setState.bind(this)); - this.state = this.store.state; - - this.appChannel = new window.channel(); - this.api = new GlobalApi(this.ship, this.appChannel, this.store); - gcpManager.configure(this.api); - this.subscription = - new GlobalSubscription(this.store, this.api, this.appChannel); this.updateTheme = this.updateTheme.bind(this); this.updateMobile = this.updateMobile.bind(this); } componentDidMount() { - this.subscription.start(); - this.api.graph.getShallowChildren(`~${window.ship}`, 'dm-inbox'); + bootstrapApi(); + this.props.getShallowChildren(`~${window.ship}`, 'dm-inbox'); const theme = this.getTheme(); - this.themeWatcher = window.matchMedia('(prefers-color-scheme: dark)'); - this.mobileWatcher = window.matchMedia(`(max-width: ${theme.breakpoints[0]})`); - this.themeWatcher.onchange = this.updateTheme; - this.mobileWatcher.onchange = this.updateMobile; setTimeout(() => { // Something about how the store works doesn't like changing it // before the app has actually rendered, hence the timeout. + this.themeWatcher = window.matchMedia('(prefers-color-scheme: dark)'); + this.mobileWatcher = window.matchMedia(`(max-width: ${theme.breakpoints[0]})`); + this.smallWatcher = window.matchMedia(`(min-width: ${theme.breakpoints[0]})`); + this.mediumWatcher = window.matchMedia(`(min-width: ${theme.breakpoints[1]})`); + this.largeWatcher = window.matchMedia(`(min-width: ${theme.breakpoints[2]})`); + // TODO: addListener is deprecated, but safari 13 requires it + this.themeWatcher.addListener(this.updateTheme); + this.mobileWatcher.addListener(this.updateMobile); + this.smallWatcher.addListener(this.updateSmall); + this.mediumWatcher.addListener(this.updateMedium); + this.largeWatcher.addListener(this.updateLarge); + this.updateMobile(this.mobileWatcher); + this.updateSmall(this.updateSmall); this.updateTheme(this.themeWatcher); + this.updateMedium(this.mediumWatcher); + this.updateLarge(this.largeWatcher); }, 500); - this.api.local.getBaseHash(); - this.api.local.getRuntimeLag(); //TODO consider polling periodically - this.api.settings.getAll(); + this.props.getAll(); gcpManager.start(); Mousetrap.bindGlobal(['command+/', 'ctrl+/'], (e) => { e.preventDefault(); @@ -114,8 +112,11 @@ class App extends React.Component { } componentWillUnmount() { - this.themeWatcher.onchange = undefined; - this.mobileWatcher.onchange = undefined; + this.themeWatcher.removeListener(this.updateTheme); + this.mobileWatcher.removeListener(this.updateMobile); + this.smallWatcher.removeListener(this.updateSmall); + this.mediumWatcher.removeListener(this.updateMedium); + this.largeWatcher.removeListener(this.updateLarge); } updateTheme(e) { @@ -130,6 +131,24 @@ class App extends React.Component { }); } + updateSmall = (e) => { + this.props.set((state) => { + state.breaks.sm = e.matches; + }); + } + + updateMedium = (e) => { + this.props.set((state) => { + state.breaks.md = e.matches; + }); + } + + updateLarge = (e) => { + this.props.set((state) => { + state.breaks.lg = e.matches; + }); + } + getTheme() { const { props } = this; return ((props.dark && props?.display?.theme == 'auto') || @@ -138,10 +157,9 @@ class App extends React.Component { } render() { - const { state } = this; const theme = this.getTheme(); - const ourContact = this.props.contacts[`~${this.ship}`] || null; + const { ourContact } = this.props; return ( @@ -151,22 +169,18 @@ class App extends React.Component { : null} - - + @@ -174,9 +188,8 @@ class App extends React.Component { @@ -187,10 +200,35 @@ class App extends React.Component { ); } } +const WarmApp = process.env.NODE_ENV === 'production' ? App : hot(App); + +const selContacts = s => s.contacts[`~${window.ship}`]; +const selLocal = s => [s.set, s.omniboxShown, s.toggleOmnibox, s.dark]; +const selSettings = s => [s.display, s.getAll]; +const selGraph = s => s.getShallowChildren; + +const WithApp = React.forwardRef((props, ref) => { + const ourContact = useContactState(selContacts); + const [display, getAll] = useSettingsState(selSettings, shallow); + const [setLocal, omniboxShown, toggleOmnibox, dark] = useLocalState(selLocal); + const getShallowChildren = useGraphState(selGraph); + + return ( + + ); +}); + +WarmApp.whyDidYouRender = true; + +export default WithApp; -export default withState(process.env.NODE_ENV === 'production' ? App : hot(App), [ - [useGroupState], - [useContactState], - [useSettingsState, ['display']], - [useLocalState] -]); diff --git a/pkg/interface/src/views/apps/chat/ChatResource.tsx b/pkg/interface/src/views/apps/chat/ChatResource.tsx index 03949d0da..b81bc9d53 100644 --- a/pkg/interface/src/views/apps/chat/ChatResource.tsx +++ b/pkg/interface/src/views/apps/chat/ChatResource.tsx @@ -1,4 +1,4 @@ -import { Content, createPost, Post } from '@urbit/api'; +import { Content, createPost, fetchIsAllowed, Post, removePosts, deSig } from '@urbit/api'; import { Association } from '@urbit/api/metadata'; import { BigInteger } from 'big-integer'; import React, { @@ -7,15 +7,17 @@ import React, { useMemo, useState } from 'react'; -import GlobalApi from '~/logic/api/global'; import { isWriter, resourceFromPath } from '~/logic/lib/group'; import { getPermalinkForGraph } from '~/logic/lib/permalinks'; import useGraphState, { useGraphForAssoc } from '~/logic/state/graph'; import { useGroupForAssoc } from '~/logic/state/group'; -import useHarkState from '~/logic/state/hark'; -import { StoreState } from '~/logic/store/type'; +import useHarkState, { useHarkStat } from '~/logic/state/hark'; import { Loading } from '~/views/components/Loading'; import { ChatPane } from './components/ChatPane'; +import airlock from '~/logic/api'; +import { disallowedShipsForOurContact } from '~/logic/lib/contact'; +import shallow from 'zustand/shallow'; +import { toHarkPath } from '~/logic/lib/util'; const getCurrGraphSize = (ship: string, name: string) => { const { graphs } = useGraphState.getState(); @@ -23,31 +25,38 @@ const getCurrGraphSize = (ship: string, name: string) => { return graph?.size ?? 0; }; -type ChatResourceProps = StoreState & { +type ChatResourceProps = { association: Association; - api: GlobalApi; baseUrl: string; }; const ChatResource = (props: ChatResourceProps): ReactElement => { - const { association, api } = props; + const { association } = props; const { resource } = association; const [toShare, setToShare] = useState(); const group = useGroupForAssoc(association)!; const graph = useGraphForAssoc(association); - const unreads = useHarkState(state => state.unreads); - const unreadCount = - (unreads.graph?.[resource]?.['/']?.unreads as number) || 0; + const stats = useHarkStat(toHarkPath(association.resource)); + const unreadCount = stats.count; const canWrite = group ? isWriter(group, resource) : false; + const [ + getNewest, + getOlderSiblings, + getYoungerSiblings, + addPost + ] = useGraphState( + s => [s.getNewest, s.getOlderSiblings, s.getYoungerSiblings, s.addPost], + shallow + ); useEffect(() => { const count = Math.min(400, 100 + unreadCount); const { ship, name } = resourceFromPath(resource); - props.api.graph.getNewest(ship, name, count); + getNewest(ship, name, count); setToShare(undefined); (async function () { if (group.hidden) { - const members = await props.api.contacts.disallowedShipsForOurContact( + const members = await disallowedShipsForOurContact( Array.from(group.members) ); if (members.length > 0) { @@ -55,12 +64,12 @@ const ChatResource = (props: ChatResourceProps): ReactElement => { } } else { const { ship: groupHost } = resourceFromPath(association.group); - const shared = await props.api.contacts.fetchIsAllowed( + const shared = await airlock.scry(fetchIsAllowed( `~${window.ship}`, 'personal', groupHost, true - ); + )); if (!shared) { setToShare(association.group); } @@ -77,7 +86,7 @@ const ChatResource = (props: ChatResourceProps): ReactElement => { ); return `${url}\n~${msg.author}: `; }, - [association] + [association.resource] ); const isAdmin = useMemo( @@ -85,54 +94,59 @@ const ChatResource = (props: ChatResourceProps): ReactElement => { [group] ); - const fetchMessages = useCallback(async (newer: boolean) => { - const { api } = props; - const pageSize = 100; +const fetchMessages = useCallback(async (newer: boolean) => { + const pageSize = 100; const [, , ship, name] = resource.split('/'); const graphSize = graph?.size ?? 0; const expectedSize = graphSize + pageSize; + if(graphSize === 0) { + // already loading the graph + return false; + } if (newer) { const index = graph.peekLargest()?.[0]; if (!index) { - return true; + return false; } - await api.graph.getYoungerSiblings( + await getYoungerSiblings( ship, name, pageSize, `/${index.toString()}` ); - return expectedSize !== getCurrGraphSize(ship.slice(1), name); + return expectedSize !== getCurrGraphSize(deSig(ship), name); } else { const index = graph.peekSmallest()?.[0]; if (!index) { - return true; + return false; } - await api.graph.getOlderSiblings(ship, name, pageSize, `/${index.toString()}`); - const done = expectedSize !== getCurrGraphSize(ship.slice(1), name); + await getOlderSiblings(ship, name, pageSize, `/${index.toString()}`); + const currSize = getCurrGraphSize(deSig(ship), name); + console.log(currSize); + const done = expectedSize !== currSize; return done; } }, [graph, resource]); const onSubmit = useCallback((contents: Content[]) => { const { ship, name } = resourceFromPath(resource); - api.graph.addPost(ship, name, createPost(window.ship, contents)); - }, [resource]); + addPost(ship, name, createPost(window.ship, contents)); + }, [resource, addPost]); const onDelete = useCallback((msg: Post) => { const { ship, name } = resourceFromPath(resource); - api.graph.removePosts(ship, name, [msg.index]); + airlock.poke(removePosts(ship, name, [msg.index])); }, [resource]); const dismissUnread = useCallback(() => { - api.hark.markCountAsRead(association, '/', 'message'); - }, [association]); + useHarkState.getState().readCount(toHarkPath(association.resource)); + }, [association.resource]); const getPermalink = useCallback( (index: BigInteger) => getPermalinkForGraph(association.group, resource, `/${index.toString()}`), - [association] + [association.resource] ); if (!graph) { @@ -144,7 +158,6 @@ const ChatResource = (props: ChatResourceProps): ReactElement => { id={resource.slice(7)} graph={graph} unreadCount={unreadCount} - api={api} canWrite={canWrite} onReply={onReply} onDelete={onDelete} diff --git a/pkg/interface/src/views/apps/chat/DmResource.tsx b/pkg/interface/src/views/apps/chat/DmResource.tsx index e3cbbe25c..d5b47b428 100644 --- a/pkg/interface/src/views/apps/chat/DmResource.tsx +++ b/pkg/interface/src/views/apps/chat/DmResource.tsx @@ -1,21 +1,21 @@ -import { cite, Content, Post } from '@urbit/api'; +import { acceptDm, cite, Content, declineDm, deSig, Post, removeDmMessage } from '@urbit/api'; import React, { useCallback, useEffect } from 'react'; import _ from 'lodash'; import bigInt from 'big-integer'; -import { Box, Row, Col, Text } from '@tlon/indigo-react'; -import { Link } from 'react-router-dom'; +import { Box, Row, Col, Text, Center } from '@tlon/indigo-react'; +import { Link, useHistory } from 'react-router-dom'; import { patp2dec } from 'urbit-ob'; -import GlobalApi from '~/logic/api/global'; import { useContact } from '~/logic/state/contact'; import useGraphState, { useDM } from '~/logic/state/graph'; -import { useHarkDm } from '~/logic/state/hark'; +import useHarkState, { useHarkDm } from '~/logic/state/hark'; import useSettingsState, { selectCalmState } from '~/logic/state/settings'; import { ChatPane } from './components/ChatPane'; -import { patpToUd } from '~/logic/lib/util'; +import shallow from 'zustand/shallow'; +import airlock from '~/logic/api'; +import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction'; interface DmResourceProps { ship: string; - api: GlobalApi; } const getCurrDmSize = (ship: string) => { @@ -50,22 +50,34 @@ function quoteReply(post: Post) { } export function DmResource(props: DmResourceProps) { - const { ship, api } = props; + const { ship } = props; const dm = useDM(ship); const hark = useHarkDm(ship); - const unreadCount = (hark?.unreads as number) ?? 0; + const history = useHistory(); + const unreadCount = hark.count; const contact = useContact(ship); const { hideNicknames } = useSettingsState(selectCalmState); const showNickname = !hideNicknames && Boolean(contact); const nickname = showNickname ? contact!.nickname : cite(ship) ?? ship; + const pending = useGraphState(s => s.pendingDms.has(deSig(ship))); + + const [ + getYoungerSiblings, + getOlderSiblings, + getNewest, + addDmMessage + ] = useGraphState( + s => [ + s.getYoungerSiblings, + s.getOlderSiblings, + s.getNewest, + s.addDmMessage + ], + shallow + ); useEffect(() => { - api.graph.getNewest( - `~${window.ship}`, - 'dm-inbox', - 100, - `/${patpToUd(ship)}` - ); + getNewest(`~${window.ship}`, 'dm-inbox', 100, `/${patp2dec(ship)}`); }, [ship]); const fetchMessages = useCallback( @@ -75,46 +87,55 @@ export function DmResource(props: DmResourceProps) { if (newer) { const index = dm.peekLargest()?.[0]; if (!index) { - return true; + return false; } - await api.graph.getYoungerSiblings( + await getYoungerSiblings( `~${window.ship}`, 'dm-inbox', pageSize, - `/${patpToUd(ship)}/${index.toString()}` + `/${patp2dec(ship)}/${index.toString()}` ); return expectedSize !== getCurrDmSize(ship); } else { const index = dm.peekSmallest()?.[0]; if (!index) { - return true; + return false; } - await api.graph.getOlderSiblings( + await getOlderSiblings( `~${window.ship}`, 'dm-inbox', pageSize, - `/${patpToUd(ship)}/${index.toString()}` + `/${patp2dec(ship)}/${index.toString()}` ); return expectedSize !== getCurrDmSize(ship); } }, - [ship, dm, api] + [ship, dm] ); const dismissUnread = useCallback(() => { - api.hark.dismissReadCount( - `/ship/~${window.ship}/dm-inbox`, - `/${patp2dec(ship)}` - ); + const harkPath = `/graph/~${window.ship}/dm-inbox/${patp2dec(ship)}`; + useHarkState.getState().readCount(harkPath); }, [ship]); const onSubmit = useCallback( (contents: Content[]) => { - api.graph.addDmMessage(ship, contents); + addDmMessage(ship, contents); }, - [ship] + [ship, addDmMessage] ); + const onDelete = useCallback((msg: Post) => { + airlock.poke(removeDmMessage(`~${window.ship}`, msg.index)); + }, []); + + const onAccept = async () => { + await airlock.poke(acceptDm(ship)); + }; + const onDecline = async () => { + history.push('/~landscape/messages'); + await airlock.poke(declineDm(ship)); + }; return ( - undefined} - isAdmin - onSubmit={onSubmit} - /> + {pending ? ( +
    + + + {ship} has invited you to a DM + + + + Accept + + + Decline + + + +
    + ) : ( + undefined} + isAdmin={false} + onSubmit={onSubmit} + /> + )} ); } diff --git a/pkg/interface/src/views/apps/chat/components/ChatAvatar.tsx b/pkg/interface/src/views/apps/chat/components/ChatAvatar.tsx new file mode 100644 index 000000000..1e6a3ec65 --- /dev/null +++ b/pkg/interface/src/views/apps/chat/components/ChatAvatar.tsx @@ -0,0 +1,50 @@ +import { BaseImage, Box } from '@tlon/indigo-react'; +import { Contact } from '@urbit/api'; +import React from 'react'; +import { Sigil } from '~/logic/lib/sigil'; +import { uxToHex } from '~/logic/lib/util'; + +interface ChatAvatar { + hideAvatars: boolean; + contact?: Contact; +} + +export function ChatAvatar({ contact, hideAvatars }) { + const color = contact ? uxToHex(contact.color) : '000000'; + const sigilClass = contact ? '' : 'mix-blend-diff'; + + if (contact && contact?.avatar && !hideAvatars) { + return ( + + ); + } + + return ( + + + + ); +} diff --git a/pkg/interface/src/views/apps/chat/components/ChatEditor.tsx b/pkg/interface/src/views/apps/chat/components/ChatEditor.tsx index cf9cf0340..3a5f29fb9 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatEditor.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatEditor.tsx @@ -4,11 +4,14 @@ import 'codemirror/addon/display/placeholder'; import 'codemirror/addon/hint/show-hint'; import 'codemirror/lib/codemirror.css'; import 'codemirror/mode/markdown/markdown'; -import React, { Component } from 'react'; -import { UnControlled as CodeEditor } from 'react-codemirror2'; +import React, { useRef, ClipboardEvent, useEffect, useImperativeHandle } from 'react'; +import { Controlled as CodeEditor } from 'react-codemirror2'; import styled from 'styled-components'; import { MOBILE_BROWSER_REGEX } from '~/logic/lib/util'; import '../css/custom.css'; +import { useChatStore } from './ChatPane'; + +const isMobile = Boolean(MOBILE_BROWSER_REGEX.test(navigator.userAgent)); const MARKDOWN_CONFIG = { name: 'markdown', @@ -30,6 +33,18 @@ const MARKDOWN_CONFIG = { } }; +const defaultOptions = { + mode: MARKDOWN_CONFIG, + lineNumbers: false, + lineWrapping: true, + scrollbarStyle: 'native', + cursorHeight: 0.85, + // The below will ony work once codemirror's bug is fixed + spellcheck: isMobile, + autocorrect: isMobile, + autocapitalize: isMobile +}; + // Until CodeMirror supports options.inputStyle = 'textarea' on mobile, // we need to hack this into a regular input that has some funny behaviors const inputProxy = input => new Proxy(input, { @@ -95,20 +110,13 @@ const MobileBox = styled(Box)` `; interface ChatEditorProps { - message: string; inCodeMode: boolean; - submit: (message: string) => void; - onUnmount: (message: string) => void; - onPaste: () => void; - changeEvent: (message: string) => void; placeholder: string; + submit: (message: string) => void; + onPaste: (codemirrorInstance, event: ClipboardEvent) => void; } -interface ChatEditorState { - message: string; -} - -interface CodeMirrorShim { +export interface CodeMirrorShim { setValue: (string) => void; setOption: (option: string, property: any) => void; focus: () => void; @@ -118,192 +126,146 @@ interface CodeMirrorShim { element: HTMLElement; } -export default class ChatEditor extends Component { - editor: CodeMirrorShim; - constructor(props: ChatEditorProps) { - super(props); +const ChatEditor = React.forwardRef(({ inCodeMode, placeholder, submit, onPaste }, ref) => { + const editorRef = useRef(null); + useImperativeHandle(ref, () => editorRef.current); + const editor = editorRef.current; - this.state = { - message: props.message - }; + const { + message, + setMessage + } = useChatStore(); - this.editor = null; - this.onKeyPress = this.onKeyPress.bind(this); - } + const onKeyPress = (e: KeyboardEvent, editor: CodeMirrorShim) => { + if (!editor) { + return; + } - componentDidMount() { - document.addEventListener('keydown', this.onKeyPress); - } - - componentWillUnmount(): void { - this.props.onUnmount(this.state.message); - document.removeEventListener('keydown', this.onKeyPress); - } - - onKeyPress(e) { const focusedTag = document.activeElement?.nodeName?.toLowerCase(); const shouldCapture = !(focusedTag === 'textarea' || focusedTag === 'input' || e.metaKey || e.ctrlKey); if(/^[a-z]|[A-Z]$/.test(e.key) && shouldCapture) { - this.editor.focus(); + editor.focus(); } if(e.key === 'Escape') { - this.editor.getInputField().blur(); + editor.getInputField().blur(); } - } + }; - componentDidUpdate(prevProps: ChatEditorProps): void { - const { props } = this; + useEffect(() => { + const focusListener = (e: KeyboardEvent) => onKeyPress(e, editorRef.current); + document.addEventListener('keydown', focusListener); - if (prevProps.message !== props.message && this.editor) { - this.editor.setValue(props.message); - this.editor.setOption('mode', MARKDOWN_CONFIG); - //this.editor?.focus(); - //this.editor.execCommand('goDocEnd'); - //this.editor?.focus(); + return () => { + document.removeEventListener('keydown', focusListener); + }; + }, []); + + useEffect(() => { + if (!editor) { return; } - if (!props.inCodeMode) { - this.editor.setOption('mode', MARKDOWN_CONFIG); - this.editor.setOption('placeholder', this.props.placeholder); + if (inCodeMode) { + editor.setOption('mode', null); + editor.setOption('placeholder', 'Code...'); } else { - this.editor.setOption('mode', null); - this.editor.setOption('placeholder', 'Code...'); + editor.setOption('mode', MARKDOWN_CONFIG); + editor.setOption('placeholder', placeholder); } - const value = this.editor.getValue(); // Force redraw of placeholder + const value = editor.getValue(); if(value.length === 0) { - this.editor.setValue(' '); - this.editor.setValue(''); + editor.setValue(' '); + editor.setValue(''); } - } + }, [inCodeMode, placeholder]); - submit() { - if(!this.editor) { + function messageChange(editor, data, value) { + if (message !== '' && value == '') { + setMessage(value); + } + if (value == message || value == '' || value == ' ') { return; } - const editorMessage = this.editor.getValue(); - if (editorMessage === '') { - return; - } - - this.setState({ message: '' }); - this.props.submit(editorMessage); - this.editor.setValue(''); + setMessage(value); } - messageChange(editor, data, value) { - if(value.endsWith('/')) { - editor.showHint(['test', 'foo']); + const codeTheme = inCodeMode ? ' code' : ''; + const options = { + ...defaultOptions, + theme: 'tlon' + codeTheme, + placeholder: inCodeMode ? 'Code...' : placeholder, + extraKeys: { + 'Enter': submit, + 'Esc': () => { + editor?.getInputField().blur(); + } } - if (this.state.message !== '' && value == '') { - this.props.changeEvent(value); - this.setState({ - message: value - }); - } - if (value == this.props.message || value == '' || value == ' ') { - return; - } - this.props.changeEvent(value); - this.setState({ - message: value - }); - } + }; - render() { - const { - inCodeMode, - placeholder, - message, - ...props - } = this.props; - - const codeTheme = inCodeMode ? ' code' : ''; - - const options = { - mode: MARKDOWN_CONFIG, - theme: 'tlon' + codeTheme, - lineNumbers: false, - lineWrapping: true, - scrollbarStyle: 'native', - cursorHeight: 0.85, - placeholder: inCodeMode ? 'Code...' : placeholder, - extraKeys: { - 'Enter': () => { - this.submit(); - }, - 'Esc': () => { - this.editor?.getInputField().blur(); - } - }, - // The below will ony work once codemirror's bug is fixed - spellcheck: Boolean(MOBILE_BROWSER_REGEX.test(navigator.userAgent)), - autocorrect: Boolean(MOBILE_BROWSER_REGEX.test(navigator.userAgent)), - autocapitalize: Boolean(MOBILE_BROWSER_REGEX.test(navigator.userAgent)) - }; - - return ( - - {MOBILE_BROWSER_REGEX.test(navigator.userAgent) - ? { - if (this.editor) { - this.editor.element.focus(); - } - }} - > + return ( + + {isMobile + ? { + if (editor) { + editor.element.focus(); + } + }} + > - this.messageChange(null, null, event.target.value) + messageChange(null, null, event.target.value) } onKeyDown={event => - this.messageChange(null, null, (event.target as any).value) + messageChange(null, null, (event.target as any).value) } + onPaste={e => onPaste(null, e)} ref={(input) => { if (!input) -return; - this.editor = inputProxy(input); + return; + editorRef.current = inputProxy(input); }} - {...props} /> - : this.messageChange(e, d, v)} - editorDidMount={(editor) => { - this.editor = editor; - }} - {...props} - /> - } + : messageChange(e, d, v)} + editorDidMount={(codeEditor) => { + editorRef.current = codeEditor; + }} + onPaste={onPaste as any} + /> + } - - ); - } -} + + ); +}); + +export default ChatEditor; diff --git a/pkg/interface/src/views/apps/chat/components/ChatInput.tsx b/pkg/interface/src/views/apps/chat/components/ChatInput.tsx index 330fe1bb6..bca329c04 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatInput.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatInput.tsx @@ -1,248 +1,166 @@ -import { BaseImage, Box, Icon, LoadingSpinner, Row } from '@tlon/indigo-react'; -import { Contact, Content } from '@urbit/api'; -import React, { Component, ReactNode } from 'react'; -import GlobalApi from '~/logic/api/global'; -import { Sigil } from '~/logic/lib/sigil'; +import { Box, Icon, LoadingSpinner, Row } from '@tlon/indigo-react'; +import { Contact, Content, evalCord } from '@urbit/api'; +import React, { FC, PropsWithChildren, useRef, useState } from 'react'; import tokenizeMessage from '~/logic/lib/tokenizeMessage'; import { IuseStorage } from '~/logic/lib/useStorage'; -import { MOBILE_BROWSER_REGEX, uxToHex } from '~/logic/lib/util'; +import { MOBILE_BROWSER_REGEX } from '~/logic/lib/util'; import { withLocalState } from '~/logic/state/local'; -import withStorage from '~/views/components/withStorage'; -import ChatEditor from './ChatEditor'; +import ChatEditor, { CodeMirrorShim } from './ChatEditor'; +import airlock from '~/logic/api'; +import { ChatAvatar } from './ChatAvatar'; +import { useChatStore } from './ChatPane'; +import { useImperativeHandle } from 'react'; +import { FileUploadSource, useFileUpload } from '~/logic/lib/useFileUpload'; -type ChatInputProps = IuseStorage & { - api: GlobalApi; - ourContact?: Contact; - onUnmount(msg: string): void; - placeholder: string; - message: string; - deleteMessage(): void; +type ChatInputProps = PropsWithChildren void; - children?: ReactNode; -}; +}>; -interface ChatInputState { - inCodeMode: boolean; - submitFocus: boolean; - uploadingPaste: boolean; - currentInput: string; -} +const InputBox: FC = ({ children }) => ( + + { children } + +); -export class ChatInput extends Component { - private chatEditor: React.RefObject; +const IconBox = ({ children, ...props }) => ( + + { children } + +); - constructor(props) { - super(props); +const MobileSubmitButton = ({ enabled, onSubmit }) => ( + onSubmit()} + > + + +); - this.state = { - inCodeMode: false, - submitFocus: false, - uploadingPaste: false, - currentInput: props.message - }; +export const ChatInput = React.forwardRef(({ ourContact, hideAvatars, placeholder, onSubmit }: ChatInputProps, ref) => { + const chatEditor = useRef(null); + useImperativeHandle(ref, () => chatEditor.current); + const [inCodeMode, setInCodeMode] = useState(false); - this.chatEditor = React.createRef(); + const { + message, + setMessage + } = useChatStore(); + const { canUpload, uploading, promptUpload, onPaste } = useFileUpload({ + onSuccess: uploadSuccess + }); - this.submit = this.submit.bind(this); - this.toggleCode = this.toggleCode.bind(this); - this.uploadSuccess = this.uploadSuccess.bind(this); - this.uploadError = this.uploadError.bind(this); - this.eventHandler = this.eventHandler.bind(this); + function uploadSuccess(url: string, source: FileUploadSource) { + if (source === 'paste') { + setMessage(url); + } else { + onSubmit([{ url }]); + } } - toggleCode() { - this.setState({ - inCodeMode: !this.state.inCodeMode - }); + function toggleCode() { + setInCodeMode(!inCodeMode); } - async submit(text) { - const { props, state } = this; - const { onSubmit, api } = this.props; - this.setState({ - inCodeMode: false - }); - props.deleteMessage(); - if(state.inCodeMode) { - const output = await api.graph.eval(text) as string[]; + async function submit() { + const text = chatEditor.current?.getValue() || ''; + + if (text === '') { + return; + } + + if (inCodeMode) { + const output = await airlock.thread(evalCord(text)); onSubmit([{ code: { output, expression: text } }]); } else { onSubmit(tokenizeMessage(text)); } - this.chatEditor.current.editor.focus(); - this.setState({ currentInput: '' }); + + setInCodeMode(false); + setMessage(''); + chatEditor.current.focus(); } - uploadSuccess(url: string) { - const { props } = this; - if (this.state.uploadingPaste) { - this.chatEditor.current.editor.setValue(url); - this.setState({ uploadingPaste: false }); - } else { - props.onSubmit([{ url }]); - } - } - - uploadError(error) { - // no-op for now - } - - onPaste(codemirrorInstance, event: ClipboardEvent) { - if (!event.clipboardData || !event.clipboardData.files.length) { - return; - } - this.setState({ uploadingPaste: true }); - event.preventDefault(); - event.stopPropagation(); - this.uploadFiles(event.clipboardData.files); - } - - uploadFiles(files: FileList | File[]) { - if (!this.props.canUpload) { - return; - } - Array.from(files).forEach((file) => { - this.props - .uploadDefault(file) - .then(this.uploadSuccess) - .catch(this.uploadError); - }); - } - - eventHandler(value) { - this.setState({ currentInput: value }); - } - - render() { - const { props, state } = this; - - const color = props.ourContact ? uxToHex(props.ourContact.color) : '000000'; - - const sigilClass = props.ourContact ? '' : 'mix-blend-diff'; - - const avatar = - props.ourContact && props.ourContact?.avatar && !props.hideAvatars ? ( - - ) : ( - - - - ); - - return ( - - - {avatar} - - - - - - {this.props.canUpload ? ( - - {this.props.uploading ? ( - - ) : ( - - this.props.promptUpload().then(this.uploadSuccess) - } - /> - )} - - ) : null} - {MOBILE_BROWSER_REGEX.test(navigator.userAgent) ? - this.chatEditor.current.submit()} - > - - - : null} + return ( + + + - ); - } -} + onPaste(e)} + placeholder={placeholder} + /> + + + + {canUpload && ( + + {uploading ? ( + + ) : ( + + promptUpload().then(url => uploadSuccess(url, 'direct')) + } + /> + )} + + )} + {MOBILE_BROWSER_REGEX.test(navigator.userAgent) && ( + + )} + + ); +}); // @ts-ignore withLocalState prop passing weirdness export default withLocalState, 'hideAvatars', ChatInput>( - // @ts-ignore withLocalState prop passing weirdness - withStorage(ChatInput, { accept: 'image/*' }), + ChatInput, ['hideAvatars'] ); diff --git a/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx b/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx index 0a0194108..5e59b19d2 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatMessage.tsx @@ -9,16 +9,15 @@ import React, { useMemo, useState } from 'react'; import VisibilitySensor from 'react-visibility-sensor'; -import GlobalApi from '~/logic/api/global'; import { useIdlingState } from '~/logic/lib/idling'; import { Sigil } from '~/logic/lib/sigil'; import { useCopy } from '~/logic/lib/useCopy'; import { - cite, daToUnix, useHovering, useShowNickname, uxToHex + cite, daToUnix, useHovering, uxToHex } from '~/logic/lib/util'; import { useContact } from '~/logic/state/contact'; -import useLocalState from '~/logic/state/local'; -import useSettingsState, { selectCalmState } from '~/logic/state/settings'; +import { useDark } from '~/logic/state/join'; +import useSettingsState, { selectCalmState, useShowNickname } from '~/logic/state/settings'; import { Dropdown } from '~/views/components/Dropdown'; import ProfileOverlay from '~/views/components/ProfileOverlay'; import { GraphContent } from '~/views/landscape/components/Graph/GraphContent'; @@ -54,17 +53,13 @@ export const DayBreak = ({ when, shimTop = false }: DayBreakProps) => ( ); -export const MessageAuthor = ({ +export const MessageAuthor = React.memo(({ timestamp, msg, - api, showOurContact, ...props }) => { - const osDark = useLocalState(state => state.dark); - - const theme = useSettingsState(s => s.display.theme); - const dark = theme === 'dark' || (theme === 'auto' && osDark); + const dark = useDark(); let contact: Contact | null = useContact(`~${msg.author}`); const date = daToUnix(bigInt(msg.index.split('/').reverse()[0])); @@ -138,7 +133,7 @@ export const MessageAuthor = ({ cursor='pointer' position='relative' > - + {img}
    @@ -159,16 +154,17 @@ export const MessageAuthor = ({ fontWeight={nameMono ? '400' : '500'} cursor='pointer' onClick={doCopy} - title={`~${msg.author}`} + title={showNickname ? `~${msg.author}` : contact?.nickname} > {copyDisplay} - + {timestamp} ); -}; +}); +MessageAuthor.displayName = 'MessageAuthor'; type MessageProps = { timestamp: string; timestampHover: boolean; } - & Pick + & Pick export const Message = React.memo(({ timestamp, msg, - api, timestampHover, transcluded, showOurContact @@ -205,6 +201,7 @@ export const Message = React.memo(({ top='2px' lineHeight="tall" fontSize={0} + whiteSpace='nowrap' gray > {timestamp} @@ -217,7 +214,6 @@ export const Message = React.memo(({ width="100%" contents={msg.contents} transcluded={transcluded} - api={api} showOurContact={showOurContact} /> @@ -388,7 +384,6 @@ interface ChatMessageProps { style?: unknown; isLastMessage?: boolean; dismissUnread?: () => void; - api: GlobalApi; highlighted?: boolean; renderSigil?: boolean; hideHover?: boolean; @@ -397,6 +392,7 @@ interface ChatMessageProps { showOurContact: boolean; onDelete?: () => void; } +const emptyCallback = () => {}; function ChatMessage(props: ChatMessageProps) { let { highlighted } = props; @@ -409,7 +405,6 @@ function ChatMessage(props: ChatMessageProps) { style, isLastMessage, isAdmin, - api, showOurContact, hideHover, dismissUnread = () => null, @@ -422,10 +417,10 @@ function ChatMessage(props: ChatMessageProps) { ); } - const onReply = props?.onReply ?? (() => {}); - const onDelete = props?.onDelete ?? (() => {}); - const transcluded = props?.transcluded ?? 0; - const renderSigil = props.renderSigil ?? (Boolean(nextMsg && msg.author !== nextMsg.author) || + const onReply = props?.onReply || emptyCallback; + const onDelete = props?.onDelete || emptyCallback; + const transcluded = props?.transcluded || 0; + const renderSigil = props.renderSigil || (Boolean(nextMsg && msg.author !== nextMsg.author) || !nextMsg ); @@ -468,7 +463,6 @@ function ChatMessage(props: ChatMessageProps) { timestamp, isPending, showOurContact, - api, highlighted, hideHover, transcluded, @@ -482,11 +476,10 @@ function ChatMessage(props: ChatMessageProps) { msg={msg} timestamp={timestamp} timestampHover={!renderSigil} - api={api} transcluded={transcluded} showOurContact={showOurContact} /> - ), [renderSigil, msg, timestamp, api, transcluded, showOurContact]); + ), [renderSigil, msg, timestamp, transcluded, showOurContact]); const unreadContainerStyle = { height: isLastRead ? '2rem' : '0' @@ -517,9 +510,9 @@ function ChatMessage(props: ChatMessageProps) { ); } -export default React.forwardRef((props: Omit, ref: any) => ( +export default React.memo(React.forwardRef((props: Omit, ref: any) => ( -)); +))); export const MessagePlaceholder = ({ height, diff --git a/pkg/interface/src/views/apps/chat/components/ChatPane.tsx b/pkg/interface/src/views/apps/chat/components/ChatPane.tsx index 056bc1c40..d9aa8373e 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatPane.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatPane.tsx @@ -1,19 +1,52 @@ import { Col } from '@tlon/indigo-react'; import { Content, Graph, Post } from '@urbit/api'; import bigInt, { BigInteger } from 'big-integer'; -import _ from 'lodash'; -import React, { ReactElement, useCallback, useEffect, useRef, useState } from 'react'; -import GlobalApi from '~/logic/api/global'; -import { useFileDrag } from '~/logic/lib/useDrag'; -import { useLocalStorageState } from '~/logic/lib/useLocalStorageState'; +import React, { ReactElement, useCallback, useEffect, useState } from 'react'; +import create from 'zustand'; +import { persist } from 'zustand/middleware'; +import { useFileUpload } from '~/logic/lib/useFileUpload'; +import { createStorageKey, storageVersion, clearStorageMigration } from '~/logic/lib/util'; import { useOurContact } from '~/logic/state/contact'; -import useGraphState from '~/logic/state/graph'; +import { useGraphTimesent } from '~/logic/state/graph'; import ShareProfile from '~/views/apps/chat/components/ShareProfile'; import { Loading } from '~/views/components/Loading'; import SubmitDragger from '~/views/components/SubmitDragger'; -import ChatInput, { ChatInput as NakedChatInput } from './ChatInput'; +import ChatInput from './ChatInput'; import ChatWindow from './ChatWindow'; +interface useChatStoreType { + id: string; + message: string; + messageStore: Record; + restore: (id: string) => void; + setMessage: (message: string) => void; +} + +export const useChatStore = create(persist((set, get) => ({ + id: '', + message: '', + messageStore: {}, + restore: (id: string) => { + const store = get().messageStore; + set({ + id, + messageStore: store, + message: store[id] || '' + }); + }, + setMessage: (message: string) => { + const store = get().messageStore; + store[get().id] = message; + + set({ message, messageStore: store }); + } +}), { + whitelist: ['messageStore'], + name: createStorageKey('chat-unsent'), + version: storageVersion, + migrate: clearStorageMigration +})); + interface ChatPaneProps { /** * A key to uniquely identify a ChatPane instance. Should be either the @@ -29,7 +62,6 @@ interface ChatPaneProps { * User able to write to chat */ canWrite: boolean; - api: GlobalApi; /** * Get contents of reply message */ @@ -67,7 +99,6 @@ interface ChatPaneProps { export function ChatPane(props: ChatPaneProps): ReactElement { const { - api, graph, unreadCount, canWrite, @@ -80,39 +111,15 @@ export function ChatPane(props: ChatPaneProps): ReactElement { promptShare = [], fetchMessages } = props; - const graphTimesentMap = useGraphState(state => state.graphTimesentMap); + const graphTimesentMap = useGraphTimesent(id); const ourContact = useOurContact(); - const chatInput = useRef(); + const { restore, setMessage } = useChatStore(s => ({ setMessage: s.setMessage, restore: s.restore })); + const { canUpload, drag } = useFileUpload({ + onSuccess: url => onSubmit([{ url }]) + }); - const onFileDrag = useCallback( - (files: FileList | File[]) => { - if (!chatInput.current) { - return; - } - (chatInput.current as NakedChatInput)?.uploadFiles(files); - }, - [chatInput.current] - ); - - const { bind, dragging } = useFileDrag(onFileDrag); - - const [unsent, setUnsent] = useLocalStorageState>( - 'chat-unsent', - {} - ); - - const appendUnsent = useCallback( - (u: string) => setUnsent(s => ({ ...s, [id]: u })), - [id] - ); - - const clearUnsent = useCallback(() => { - setUnsent((s) => { - if (id in s) { - return _.omit(s, id); - } - return s; - }); + useEffect(() => { + restore(id); }, [id]); const scrollTo = new URLSearchParams(location.search).get('msg'); @@ -126,7 +133,7 @@ export function ChatPane(props: ChatPaneProps): ReactElement { const onReply = useCallback( (msg: Post) => { const message = props.onReply(msg); - setUnsent(s => ({ ...s, [id]: message })); + setMessage(message); }, [id, props.onReply] ); @@ -136,43 +143,38 @@ export function ChatPane(props: ChatPaneProps): ReactElement { } return ( - // @ts-ignore - + // @ts-ignore bind typings + setShowBanner(false)} /> - {dragging && } + {canUpload && drag.dragging && } {canWrite && ( )} ); } + +ChatPane.whyDidYouRender = true; diff --git a/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx b/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx index 9913c7419..5b10257ef 100644 --- a/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx +++ b/pkg/interface/src/views/apps/chat/components/ChatWindow.tsx @@ -5,9 +5,9 @@ import { } from '@urbit/api'; import bigInt, { BigInteger } from 'big-integer'; import React, { Component } from 'react'; -import GlobalApi from '~/logic/api/global'; +import { GraphScroller } from '~/views/components/GraphScroller'; import VirtualScroller from '~/views/components/VirtualScroller'; -import ChatMessage, { MessagePlaceholder } from './ChatMessage'; +import ChatMessage from './ChatMessage'; import UnreadNotice from './UnreadNotice'; const IDLE_THRESHOLD = 64; @@ -18,7 +18,6 @@ type ChatWindowProps = { graphSize: number; station?: unknown; fetchMessages: (newer: boolean) => Promise; - api: GlobalApi; scrollTo?: BigInteger; onReply: (msg: Post) => void; onDelete: (msg: Post) => void; @@ -47,7 +46,7 @@ class ChatWindow extends Component< ChatWindowProps, ChatWindowState > { - private virtualList: VirtualScroller | null; + private virtualList: VirtualScroller | null; private prevSize = 0; private unreadSet = false; @@ -59,7 +58,7 @@ class ChatWindow extends Component< this.state = { fetchPending: false, idle: true, - initialized: false, + initialized: true, unreadIndex: bigInt.zero }; @@ -74,14 +73,10 @@ class ChatWindow extends Component< componentDidMount() { this.calculateUnreadIndex(); - setTimeout(() => { - this.setState({ initialized: true }, () => { - if(this.props.scrollTo) { - this.virtualList!.scrollLocked = false; - this.virtualList!.scrollToIndex(this.props.scrollTo); - } - }); - }, this.INITIALIZATION_MAX_TIME); + if(this.props.scrollTo) { + this.virtualList!.scrollLocked = false; + this.virtualList!.scrollToIndex(this.props.scrollTo); + } } calculateUnreadIndex() { @@ -90,7 +85,7 @@ class ChatWindow extends Component< if(state.unreadIndex.neq(bigInt.zero)) { return; } - const unreadIndex = graph.keys()[unreadCount]; + let unreadIndex = graph.keys()[unreadCount]; if (!unreadIndex || unreadCount === 0) { if(state.unreadIndex.neq(bigInt.zero)) { this.setState({ @@ -99,6 +94,13 @@ class ChatWindow extends Component< } return; } + /* Loop until we can find a index with an actual post */ + let attemptedCount = unreadCount; + while(attemptedCount > 0 && typeof graph.get(unreadIndex)?.post === 'string') { + attemptedCount--; + unreadIndex = graph.keys()[attemptedCount]; + } + this.setState({ unreadIndex }); @@ -136,7 +138,8 @@ class ChatWindow extends Component< } if(this.unreadSet && this.dismissedInitialUnread() && - this.virtualList!.startOffset() < 5) { + this.virtualList!.startOffset() < 5 && + document.hasFocus()) { this.props.dismissUnread(); } } @@ -181,7 +184,6 @@ class ChatWindow extends Component< renderer = React.forwardRef(({ index, scrollWindow }: RendererProps, ref) => { const { - api, showOurContact, graph, onReply, @@ -193,7 +195,6 @@ class ChatWindow extends Component< const permalink = getPermalink(index); const messageProps = { showOurContact, - api, onReply, onDelete, permalink, @@ -209,15 +210,6 @@ class ChatWindow extends Component< ); } - if (!this.state.initialized) { - return ( - - ); - } const isPending: boolean = 'pending' in msg && Boolean(msg.pending); const isLastMessage = index.eq( graph.peekLargest()?.[0] ?? bigInt.zero @@ -274,7 +266,7 @@ class ChatWindow extends Component< dismissUnread={this.props.dismissUnread} onClick={this.scrollToUnread} />)} - + { this.virtualList = list; }} diff --git a/pkg/interface/src/views/apps/chat/components/ShareProfile.tsx b/pkg/interface/src/views/apps/chat/components/ShareProfile.tsx index b24cb50b3..f819850f3 100644 --- a/pkg/interface/src/views/apps/chat/components/ShareProfile.tsx +++ b/pkg/interface/src/views/apps/chat/components/ShareProfile.tsx @@ -1,22 +1,18 @@ -import { BaseImage, Box, Row, Text } from '@tlon/indigo-react'; -import { Contact } from '@urbit/api'; +import { BaseImage, Row, Text, Button } from '@tlon/indigo-react'; +import { allowGroup, allowShips, Contact, share } from '@urbit/api'; import React, { ReactElement } from 'react'; -import GlobalApi from '~/logic/api/global'; import { Sigil } from '~/logic/lib/sigil'; import { uxToHex } from '~/logic/lib/util'; +import airlock from '~/logic/api'; interface ShareProfileProps { our?: Contact; - api: GlobalApi; recipients: string | string[]; onShare: () => void; } const ShareProfile = (props: ShareProfileProps): ReactElement | null => { - const { - api, - recipients - } = props; + const { recipients } = props; const image = (props?.our?.avatar) ? ( @@ -46,13 +42,13 @@ const ShareProfile = (props: ShareProfileProps): ReactElement | null => { const onClick = async () => { if(typeof recipients === 'string') { const [,,ship,name] = recipients.split('/'); - await api.contacts.allowGroup(ship,name); + await airlock.poke(allowGroup(ship, name)); if(ship !== `~${window.ship}`) { - await api.contacts.share(ship); + await airlock.poke(share(ship)); } } else if(recipients.length > 0) { - await api.contacts.allowShips(recipients); - await Promise.all(recipients.map(r => api.contacts.share(r))); + await airlock.poke(allowShips(recipients)); + await Promise.all(recipients.map(r => airlock.poke(share(r)))); } props.onShare(); }; @@ -65,14 +61,15 @@ const ShareProfile = (props: ShareProfileProps): ReactElement | null => { borderBottom={1} borderColor="lightGray" flexShrink={0} + px="3" > - + {image} Share private profile? - - Share - + ) : null; }; diff --git a/pkg/interface/src/views/apps/graph/App.tsx b/pkg/interface/src/views/apps/graph/App.tsx index 9cb22a715..c84654708 100644 --- a/pkg/interface/src/views/apps/graph/App.tsx +++ b/pkg/interface/src/views/apps/graph/App.tsx @@ -1,23 +1,17 @@ import { Center, Text } from '@tlon/indigo-react'; -import { GraphConfig } from '@urbit/api'; +import { GraphConfig, joinGraph } from '@urbit/api'; import React, { ReactElement } from 'react'; import { Route, Switch, useHistory } from 'react-router-dom'; -import GlobalApi from '~/logic/api/global'; import { deSig } from '~/logic/lib/util'; import useGraphState from '~/logic/state/graph'; import useMetadataState from '~/logic/state/metadata'; +import airlock from '~/logic/api'; -interface GraphAppProps { - api: GlobalApi; -} - -const GraphApp = (props: GraphAppProps): ReactElement => { +const GraphApp = (): ReactElement => { const associations= useMetadataState(state => state.associations); const graphKeys = useGraphState(state => state.graphKeys); const history = useHistory(); - const { api } = props; - return ( { const autoJoin = () => { try { - api.graph.joinGraph( + airlock.thread(joinGraph( `~${deSig(props.match.params.ship)}`, props.match.params.name - ); + )); } catch(err) { setTimeout(autoJoin, 2000); } diff --git a/pkg/interface/src/views/apps/launch/App.tsx b/pkg/interface/src/views/apps/launch/App.tsx index f84d4592d..0ab28cf2b 100644 --- a/pkg/interface/src/views/apps/launch/App.tsx +++ b/pkg/interface/src/views/apps/launch/App.tsx @@ -1,36 +1,18 @@ /* eslint-disable max-lines-per-function */ -import { Box, Button, Col, Icon, Row, Text } from '@tlon/indigo-react'; -import f from 'lodash/fp'; -import React, { ReactElement, useEffect, useMemo, useState } from 'react'; +import { Box, Icon, Row, Text } from '@tlon/indigo-react'; +import React, { ReactElement } from 'react'; import { Helmet } from 'react-helmet'; +import { Route } from 'react-router-dom'; import styled from 'styled-components'; -import GlobalApi from '~/logic/api/global'; -import { - hasTutorialGroup, - - TUTORIAL_BOOK, - TUTORIAL_CHAT, TUTORIAL_GROUP, - TUTORIAL_HOST, - - TUTORIAL_LINKS -} from '~/logic/lib/tutorialModal'; -import { useModal } from '~/logic/lib/useModal'; -import { useQuery } from '~/logic/lib/useQuery'; -import { useWaitForProps } from '~/logic/lib/useWaitForProps'; -import { writeText } from '~/logic/lib/util'; import useHarkState from '~/logic/state/hark'; -import useLaunchState from '~/logic/state/launch'; -import useLocalState from '~/logic/state/local'; -import useMetadataState from '~/logic/state/metadata'; import useSettingsState, { selectCalmState } from '~/logic/state/settings'; -import { StarIcon } from '~/views/components/StarIcon'; -import { StatelessAsyncButton } from '~/views/components/StatelessAsyncButton'; import { JoinGroup } from '~/views/landscape/components/JoinGroup'; import { NewGroup } from '~/views/landscape/components/NewGroup'; import Groups from './components/Groups'; import ModalButton from './components/ModalButton'; import Tiles from './components/tiles'; import Tile from './components/tiles/tile'; +import { Invite } from './components/Invite'; import './css/custom.css'; const ScrollbarLessBox = styled(Box)` @@ -41,148 +23,24 @@ const ScrollbarLessBox = styled(Box)` } `; -const tutSelector = f.pick(['tutorialProgress', 'nextTutStep', 'hideGroups']); - interface LaunchAppProps { connection: string; - api: GlobalApi; } export const LaunchApp = (props: LaunchAppProps): ReactElement | null => { - const { connection } = props; - const { baseHash, runtimeLag } = useLaunchState(state => state); - const [hashText, setHashText] = useState(baseHash); - const [exitingTut, setExitingTut] = useState(false); - const seen = useSettingsState(s => s?.tutorial?.seen) ?? true; - const associations = useMetadataState(s => s.associations); - const hasLoaded = useMemo(() => Boolean(connection === 'connected'), [connection]); const notificationsCount = useHarkState(state => state.notificationsCount); const calmState = useSettingsState(selectCalmState); - const { hideUtilities } = calmState; - const { tutorialProgress, nextTutStep } = useLocalState(tutSelector); - let { hideGroups } = useLocalState(tutSelector); - !hideGroups ? { hideGroups } = calmState : null; - - const waiter = useWaitForProps({ ...props, associations }); - const hashBox = ( - { - writeText(baseHash); - setHashText('copied'); - setTimeout(() => { - setHashText(baseHash); - }, 2000); - }} - > - - {hashText || baseHash} - - - ); - - const { query } = useQuery(); - - const { modal, showModal } = useModal({ - position: 'relative', - maxWidth: '350px', - modal: function modal(dismiss) { - const onDismiss = (e) => { - e.stopPropagation(); - props.api.settings.putEntry('tutorial', 'seen', true); - dismiss(); - }; - const onContinue = async (e) => { - e.stopPropagation(); - if (!hasTutorialGroup({ associations })) { - await props.api.groups.join(TUTORIAL_HOST, TUTORIAL_GROUP); - await props.api.settings.putEntry('tutorial', 'joined', Date.now()); - await waiter(hasTutorialGroup); - await Promise.all( - [TUTORIAL_BOOK, TUTORIAL_CHAT, TUTORIAL_LINKS].map(graph => props.api.graph.joinGraph(TUTORIAL_HOST, graph))); - - await waiter((p) => { - return `/ship/${TUTORIAL_HOST}/${TUTORIAL_CHAT}` in p.associations.graph && - `/ship/${TUTORIAL_HOST}/${TUTORIAL_BOOK}` in p.associations.graph && - `/ship/${TUTORIAL_HOST}/${TUTORIAL_LINKS}` in p.associations.graph; - }); - } - nextTutStep(); - dismiss(); - }; - return exitingTut ? ( - - - - You can always restart the tutorial by typing “tutorial” in Leap - - - - - - ) : ( - - - - - Welcome - - You have been invited to use Landscape, an interface to chat - and interact with communities -
    - Would you like a tour of Landscape? -
    - - - - Yes - - - - ); - } - }); - - useEffect(() => { - if(query.get('tutorial')) { - if (hasTutorialGroup({ associations })) { - if (nextTutStep) { - nextTutStep(); - } - } else { - showModal(); - } - } - }, [query, showModal]); - - useEffect(() => { - if(hasLoaded && !seen && tutorialProgress === 'hidden') { - showModal(); - } - }, [seen, hasLoaded]); + const { hideUtilities, hideGroups } = calmState; return ( <> - { notificationsCount ? `(${String(notificationsCount) }) `: '' }Landscape + { notificationsCount ? `(${String(notificationsCount) }) `: '' }Groups + + + - {modal} { - + { text="New Group" style={{ gridColumnStart: 1 }} > - + { color="black" text="Join Group" > - + {dismiss => } } {!hideGroups && () } - {hashBox} - {hashBox} ); }; diff --git a/pkg/interface/src/views/apps/launch/components/Groups.tsx b/pkg/interface/src/views/apps/launch/components/Groups.tsx index 209a540dc..81de08ec1 100644 --- a/pkg/interface/src/views/apps/launch/components/Groups.tsx +++ b/pkg/interface/src/views/apps/launch/components/Groups.tsx @@ -1,36 +1,40 @@ import { Box, Col, Text } from '@tlon/indigo-react'; import { Association, Associations, Unreads } from '@urbit/api'; import f from 'lodash/fp'; -import moment from 'moment'; -import React, { useRef } from 'react'; -import { getNotificationCount, getUnreadCount } from '~/logic/lib/hark'; -import { TUTORIAL_GROUP, TUTORIAL_GROUP_RESOURCE, TUTORIAL_HOST } from '~/logic/lib/tutorialModal'; +import React from 'react'; +import { getNotificationCount } from '~/logic/lib/hark'; import { alphabeticalOrder } from '~/logic/lib/util'; import useGroupState from '~/logic/state/group'; -import useHarkState from '~/logic/state/hark'; +import useHarkState, { selHarkGraph } from '~/logic/state/hark'; import useMetadataState from '~/logic/state/metadata'; -import useSettingsState, { selectCalmState, SettingsState } from '~/logic/state/settings'; -import { useTutorialModal } from '~/views/components/useTutorialModal'; +import useSettingsState, { + selectCalmState +} from '~/logic/state/settings'; import Tile from '../components/tiles/tile'; -interface GroupsProps {} - const sortGroupsAlph = (a: Association, b: Association) => - a.group === TUTORIAL_GROUP_RESOURCE - ? -1 - : b.group === TUTORIAL_GROUP_RESOURCE - ? 1 - : alphabeticalOrder(a.metadata.title, b.metadata.title); + alphabeticalOrder(a.metadata.title, b.metadata.title); -const getGraphUnreads = (associations: Associations, unreads: Unreads) => (path: string) => - f.flow( - f.pickBy((a: Association) => a.group === path), - f.map('resource'), - f.map(rid => getUnreadCount(unreads, rid, '/')), - f.reduce(f.add, 0) - )(associations.graph); +const getGraphUnreads = (associations: Associations) => { + const state = useHarkState.getState(); + const selUnread = (graph: string) => { + const { count, each } = selHarkGraph(graph)(state); + const result = count + each.length; + return result; + }; + return (path: string) => + f.flow( + f.pickBy((a: Association) => a.group === path), + f.map('resource'), + f.map(selUnread), + f.reduce(f.add, 0) + )(associations.graph); +}; -const getGraphNotifications = (associations: Associations, unreads: Unreads) => (path: string) => +const getGraphNotifications = ( + associations: Associations, + unreads: Unreads +) => (path: string) => f.flow( f.pickBy((a: Association) => a.group === path), f.map('resource'), @@ -38,8 +42,7 @@ const getGraphNotifications = (associations: Associations, unreads: Unreads) => f.reduce(f.add, 0) )(associations.graph); -export default function Groups(props: GroupsProps & Parameters[0]) { - const { inbox, ...boxProps } = props; +export default function Groups(props: Parameters[0]) { const unreads = useHarkState(state => state.unreads); const groupState = useGroupState(state => state.groups); const associations = useMetadataState(state => state.associations); @@ -47,8 +50,11 @@ export default function Groups(props: GroupsProps & Parameters[0]) { const groups = Object.values(associations?.groups || {}) .filter(e => e?.group in groupState) .sort(sortGroupsAlph); - const graphUnreads = getGraphUnreads(associations || {} as Associations, unreads); - const graphNotifications = getGraphNotifications(associations || {} as Associations, unreads); + const graphUnreads = getGraphUnreads(associations || ({} as Associations)); + const graphNotifications = getGraphNotifications( + associations || ({} as Associations), + unreads + ); return ( <> @@ -78,37 +84,26 @@ interface GroupProps { unreads: number; first: boolean; } -const selectJoined = (s: SettingsState) => s.tutorial.joined; function Group(props: GroupProps) { const { path, title, unreads, updates, first = false } = props; - const anchorRef = useRef(null); - const isTutorialGroup = path === `/ship/${TUTORIAL_HOST}/${TUTORIAL_GROUP}`; - useTutorialModal( - 'start', - isTutorialGroup, - anchorRef - ); const { hideUnreads } = useSettingsState(selectCalmState); - const joined = useSettingsState(selectJoined); - const days = Math.max(0, Math.floor(moment.duration(moment(joined) - .add(14, 'days') - .diff(moment())) - .as('days'))) || 0; return ( - + {title} - {!hideUnreads && ( - {isTutorialGroup && joined && - ({days} day{days !== 1 && 's'} remaining) - } - {updates > 0 && - ({updates} update{updates !== 1 && 's'} ) - } - {unreads > 0 && - ({unreads}) - } - + {!hideUnreads && ( + + {updates > 0 && ( + + {updates} update{updates !== 1 && 's'}{' '} + + )} + {unreads > 0 && {unreads}} + )} diff --git a/pkg/interface/src/views/apps/launch/components/Invite.tsx b/pkg/interface/src/views/apps/launch/components/Invite.tsx new file mode 100644 index 000000000..7cb4165fc --- /dev/null +++ b/pkg/interface/src/views/apps/launch/components/Invite.tsx @@ -0,0 +1,242 @@ +import React, { useState, useEffect, useCallback } from 'react'; +import { useHistory, useParams } from 'react-router-dom'; +import { + Box, + Col, + Row, + Text, + Action, + LoadingSpinner +} from '@tlon/indigo-react'; +import * as Dialog from '@radix-ui/react-dialog'; +import { PropFunc } from '~/types'; +import { useRunIO } from '~/logic/lib/useRunIO'; +import useMetadataState from '~/logic/state/metadata'; +import { GroupSummary } from '~/views/landscape/components/GroupSummary'; +import { + accept, + decline, + GraphConfig, + Invite as IInvite, + join, + Metadata, + MetadataUpdatePreview, + resourceFromPath +} from '@urbit/api'; +import useInviteState from '~/logic/state/invite'; +import useGroupState from '~/logic/state/group'; +import useGraphState from '~/logic/state/graph'; +import { useWaitForProps } from '~/logic/lib/useWaitForProps'; +import airlock from '~/logic/api'; + +function InviteDialog({ children, ...rest }: PropFunc) { + return ( + + + + + + + + {children} + + + + + ); +} + +function inviteUrl( + hidden: boolean, + resource: string, + metadata?: Metadata +) { + if (!hidden) { + return `/~landscape${resource}`; + } + + if (metadata.config?.graph === 'chat') { + return `/~landscape/messages/resource/${metadata.config.graph}${resource}`; + } else { + return `/~landscape/home/resource/${metadata.config?.graph}${resource}`; + } +} + +function useInviteAccept(resource: string, app?: string, uid?: string) { + const { ship, name } = resourceFromPath(resource); + const history = useHistory(); + const associations = useMetadataState(s => s.associations); + const groups = useGroupState(s => s.groups); + const graphKeys = useGraphState(s => s.graphKeys); + + const waiter = useWaitForProps({ associations, graphKeys, groups }); + return useRunIO( + async () => { + if (!(app && uid)) { + return false; + } + if (resource in groups) { + await airlock.poke(decline(app, uid)); + return false; + } + + await airlock.poke(join(ship, name)); + await waiter((p) => { + return ( + (resource in p.groups && + resource in (p.associations?.graph ?? {}) && + p.graphKeys.has(resource.slice(7))) || + resource in (p.associations?.groups ?? {}) + ); + }); + airlock.poke(accept(app, uid)); + return true; + }, + (success: boolean) => { + if (!success) { + history.push('/'); + return; + } + const redir = inviteUrl( + groups?.[resource]?.hidden, + resource, + associations?.graph?.[resource]?.metadata + ); + if (redir) { + // weird race condition + setTimeout(() => { + history.push(redir); + }, 200); + } + }, + resource + ); +} + +export function Invite() { + const { uid, app } = useParams<{ + app: string; + uid: string; + }>(); + + const invite = useInviteState(s => s.invites?.[app]?.[uid]); + + return ( + + {invite ? ( + <> + {renderInviteContent(app, uid, invite)} + + + ) : ( + + )} + + ); +} + +function InviteActions({ + app, + uid, + invite +}: { + app: string; + uid: string; + invite: IInvite; +}) { + const { push } = useHistory(); + const { ship, name } = invite.resource; + const resource = `/ship/~${ship}/${name}`; + + const inviteAccept = useInviteAccept(resource, app, uid); + const acceptInvite = () => inviteAccept(); + + const declineInvite = useCallback(async () => { + if (!(app && uid)) { + return; + } + await airlock.poke(decline(app, uid)); + push('/'); + }, [app, uid]); + + return ( + + + Accept + + + Decline + + + ); +} + +function GroupInvite({ uid, invite }: { uid: string; invite: IInvite }) { + const { + resource: { ship, name } + } = invite; + const { getPreview } = useMetadataState(); + const [preview, setPreview] = useState(null); + useEffect(() => { + (async () => { + setPreview(await getPreview(`/ship/~${ship}/${name}`)); + })(); + + return () => { + setPreview(null); + }; + }, [ship, name]); + + return preview ? ( + + ) : ( + + ); +} + +function GraphInvite({ uid, invite }: { uid: string; invite: IInvite }) { + return You have been invited to a group chat by {invite.ship}; +} + +function renderInviteContent(app: string, uid: string, invite: IInvite) { + switch (app) { + case 'groups': + return ; + case 'graph': + return ; + default: + return null; + } +} diff --git a/pkg/interface/src/views/apps/launch/components/tiles.tsx b/pkg/interface/src/views/apps/launch/components/tiles.tsx index fe3f27248..f7cf13433 100644 --- a/pkg/interface/src/views/apps/launch/components/tiles.tsx +++ b/pkg/interface/src/views/apps/launch/components/tiles.tsx @@ -1,59 +1,29 @@ import React, { ReactElement } from 'react'; -import GlobalApi from '~/logic/api/global'; import useLaunchState from '~/logic/state/launch'; import { WeatherState } from '~/types'; -import BasicTile from './tiles/basic'; import ClockTile from './tiles/clock'; -import CustomTile from './tiles/custom'; import WeatherTile from './tiles/weather'; -export interface TileProps { - api: GlobalApi; -} - -const Tiles = (props: TileProps): ReactElement => { +const Tiles = (): ReactElement => { const weather = useLaunchState(state => state.weather) as WeatherState; const tileOrdering = useLaunchState(state => state.tileOrdering); const tileState = useLaunchState(state => state.tiles); - console.log('tileOrdering', tileOrdering); - console.log('tileState', tileState); const tiles = tileOrdering.filter((key) => { const tile = tileState[key]; return tile.isShown; }).map((key) => { const tile = tileState[key]; - if ('basic' in tile.type) { - const basic = tile.type.basic; - return ( - - ); - } else if ('custom' in tile.type) { + if ('custom' in tile.type) { if (key === 'weather') { return ( - + ); } else if (key === 'clock') { const location = weather && 'nearest-area' in weather ? weather['nearest-area'][0] : ''; return ( ); - } else { - return ( - - ); } } return null; diff --git a/pkg/interface/src/views/apps/launch/components/tiles/weather.tsx b/pkg/interface/src/views/apps/launch/components/tiles/weather.tsx index ce049c150..7350b7e49 100644 --- a/pkg/interface/src/views/apps/launch/components/tiles/weather.tsx +++ b/pkg/interface/src/views/apps/launch/components/tiles/weather.tsx @@ -1,12 +1,11 @@ import { BaseInput, Box, Icon, Text } from '@tlon/indigo-react'; import moment from 'moment'; import React from 'react'; -import GlobalApi from '~/logic/api/global'; import withState from '~/logic/lib/withState'; import useLaunchState from '~/logic/state/launch'; import ErrorBoundary from '~/views/components/ErrorBoundary'; import Tile from './tile'; - +import airlock from '~/logic/api'; export const weatherStyleMap = { Clear: 'rgba(67, 169, 255, 0.4)', @@ -34,12 +33,11 @@ export const weatherStyleMap = { const imperialCountries = [ 'United States of America', 'Myanmar', - 'Liberia', + 'Liberia' ]; interface WeatherTileProps { weather: any; - api: GlobalApi; location: string; } @@ -49,6 +47,14 @@ interface WeatherTileState { error: boolean; } +function update(location: string) { + return { + mark: 'json', + json: location, + app: 'weather' + }; +} + class WeatherTile extends React.Component { constructor(props: WeatherTileProps) { super(props); @@ -64,7 +70,7 @@ class WeatherTile extends React.Component { navigator.geolocation.getCurrentPosition((res) => { const location = `${res.coords.latitude},${res.coords.longitude}`; this.setState({ location }); - this.props.api.launch.weather(location); + airlock.poke(update(location)); this.setState({ manualEntry: !this.state.manualEntry }); }); } @@ -73,13 +79,13 @@ class WeatherTile extends React.Component { event.preventDefault(); const location = (document.getElementById('location') as HTMLInputElement).value; this.setState({ location }); - this.props.api.launch.weather(location); + airlock.poke(update(location)); this.setState({ manualEntry: !this.state.manualEntry }); } // set appearance based on weather colorFromCondition(data) { - let weatherDesc = data['current-condition'][0].weatherDesc[0].value; + const weatherDesc = data['current-condition'][0].weatherDesc[0].value; return weatherStyleMap[weatherDesc] || weatherStyleMap.default; } @@ -196,19 +202,20 @@ class WeatherTile extends React.Component { const d = data['weather'][0]; const bg = this.colorFromCondition(data); - const sunset = moment(moment().format('YYYY-MM-DD') + ' ' + d.astronomy[0].sunset, 'YYYY-MM-DD hh:mm A'); - const sunsetDiff = sunset.diff(moment(), 'hours'); + const sunset = moment(moment().hours(1).format('YYYY-MM-DD') + ' ' + d.astronomy[0].sunset, 'YYYY-MM-DD hh:mm A'); + let sunsetDiff = sunset.diff(moment(), 'hours'); - const sunrise = moment(moment().format('YYYY-MM-DD') + ' ' + d.astronomy[0].sunrise, 'YYYY-MM-DD hh:mm A'); + const sunrise = moment(moment().hours(1).format('YYYY-MM-DD') + ' ' + d.astronomy[0].sunrise, 'YYYY-MM-DD hh:mm A'); let sunriseDiff = sunrise.diff(moment(), 'hours'); - if (sunriseDiff > 24) { - sunriseDiff = sunriseDiff - 24; - } else if (sunriseDiff < 0) { + if (sunsetDiff < 0) { + sunsetDiff = sunsetDiff + 24; + } + if (sunriseDiff < 0) { sunriseDiff = sunriseDiff + 24; } - const nextSolarEvent = sunsetDiff > 0 + const nextSolarEvent = sunsetDiff < sunriseDiff ? `Sun sets in ${sunsetDiff}h` : `Sun rises in ${sunriseDiff}h`; @@ -258,7 +265,7 @@ class WeatherTile extends React.Component { } if ('currently' in data) { // Old weather source - this.props.api.launch.weather(this.props.location); + airlock.poke(update(this.props.location)); } if ('current-condition' in data && 'weather' in data) { @@ -287,7 +294,7 @@ class WeatherTile extends React.Component { onClick={() => this.setState({ manualEntry: !this.state.manualEntry }) } - > + > {'->'}
    diff --git a/pkg/interface/src/views/apps/links/LinkResource.tsx b/pkg/interface/src/views/apps/links/LinkResource.tsx index eb69ca2e9..032a0bc70 100644 --- a/pkg/interface/src/views/apps/links/LinkResource.tsx +++ b/pkg/interface/src/views/apps/links/LinkResource.tsx @@ -1,31 +1,27 @@ import { Box, Center, Col, LoadingSpinner, Text } from '@tlon/indigo-react'; -import { Group } from '@urbit/api'; +import { deSig, Group } from '@urbit/api'; import { Association } from '@urbit/api/metadata'; import bigInt from 'big-integer'; import React, { useEffect } from 'react'; -import { Link, Route, Switch } from 'react-router-dom'; -import GlobalApi from '~/logic/api/global'; +import { Link, Route, Switch, useLocation } from 'react-router-dom'; +import { useQuery } from '~/logic/lib/useQuery'; +import { Titlebar } from '~/views/components/Titlebar'; import useGraphState from '~/logic/state/graph'; import useMetadataState from '~/logic/state/metadata'; -import { StoreState } from '~/logic/store/type'; -import { Comments } from '~/views/components/Comments'; import useGroupState from '../../../logic/state/group'; -import { LinkItem } from './components/LinkItem'; +import { LinkBlocks } from './components/LinkBlocks'; +import { LinkDetail } from './components/LinkDetail'; import './css/custom.css'; import LinkWindow from './LinkWindow'; -const emptyMeasure = () => {}; - -type LinkResourceProps = StoreState & { +interface LinkResourceProps { association: Association; - api: GlobalApi; baseUrl: string; -}; +} export function LinkResource(props: LinkResourceProps) { const { association, - api, baseUrl } = props; @@ -35,7 +31,7 @@ export function LinkResource(props: LinkResourceProps) { const associations = useMetadataState(state => state.associations); const [, , ship, name] = rid.split('/'); - const resourcePath = `${ship.slice(1)}/${name}`; + const resourcePath = `${deSig(ship)}/${name}`; const resource: any = associations.graph[rid] ? associations.graph[rid] : { metadata: {} }; @@ -45,98 +41,95 @@ export function LinkResource(props: LinkResourceProps) { const graphs = useGraphState(state => state.graphs); const graph = graphs[resourcePath] || null; const graphTimesentMap = useGraphState(state => state.graphTimesentMap); + const { query } = useQuery(); + const isList = query.has('list'); + const { pathname, search } = useLocation(); + const getGraph = useGraphState(s => s.getGraph); useEffect(() => { - api.graph.getGraph(ship, name); + getGraph(ship, name); }, [association]); const resourceUrl = `${baseUrl}/resource/link${rid}`; - if (!graph) { + if (!graph || !resource) { return
    ; } + const { title, description } = resource.metadata; + + const titlebar = (back?: string) => ( + + + + Switch to {!isList ? 'list' : 'grid' } + + + + ); return ( - - - { + + { + return ( + + {titlebar()} + { isList ? /* @ts-ignore withState typings */ ( + + ) : ( + + )} + + ); + }} + /> + { + const index = bigInt(props.match.params.index); + + if (!index) { + return
    Malformed URL
    ; + } + + const node = graph ? graph.get(index) : null; + + if (!node) { + return Not found; + } + + if (typeof node.post === 'string') { return ( - // @ts-ignore - - ); - }} - /> - { - const index = bigInt(props.match.params.index); - const editCommentId = props.match.params.commentId || null; - - if (!index) { - return
    Malformed URL
    ; - } - - const node = graph ? graph.get(index) : null; - - if (!node) { - return Not found; - } - - if (typeof node.post === 'string') { - return ( - - This link has been deleted. - - ); - } - return ( - - - {'<- Back'} - - + + This link has been deleted. - ); - }} - /> -
    - + } + return ( + + {titlebar(relativePath(''))} + + + ); + }} + /> +
    ); } diff --git a/pkg/interface/src/views/apps/links/LinkWindow.tsx b/pkg/interface/src/views/apps/links/LinkWindow.tsx index 7bd564462..5b1854798 100644 --- a/pkg/interface/src/views/apps/links/LinkWindow.tsx +++ b/pkg/interface/src/views/apps/links/LinkWindow.tsx @@ -1,12 +1,11 @@ import { Box, Col, Text } from '@tlon/indigo-react'; -import { Association, Graph, Group } from '@urbit/api'; -import bigInt from 'big-integer'; +import { Association, deSig, Graph, Group } from '@urbit/api'; +import bigInt, { BigInteger } from 'big-integer'; import React, { Component, ReactNode } from 'react'; -import GlobalApi from '~/logic/api/global'; import { isWriter } from '~/logic/lib/group'; -import VirtualScroller from '~/views/components/VirtualScroller'; +import { GraphScroller } from '~/views/components/GraphScroller'; import { LinkItem } from './components/LinkItem'; import LinkSubmit from './components/LinkSubmit'; @@ -19,7 +18,6 @@ interface LinkWindowProps { baseUrl: string; group: Group; path: string; - api: GlobalApi; pendingSize: number; mb?: number; } @@ -47,7 +45,7 @@ class LinkWindow extends Component { renderItem = React.forwardRef(({ index }: RendererProps, ref) => { const { props } = this; - const { association, graph, api } = props; + const { association, graph } = props; const [, , ship, name] = association.resource.split('/'); // @ts-ignore Uint8Array vs. BigInt mismatch? const node = graph.get(index); @@ -60,7 +58,6 @@ class LinkWindow extends Component { ...props, node }; - {/* @ts-ignore calling @liam-fitzgerald on Uint8Array props */} if (this.canWrite() && index.eq(first ?? bigInt.zero)) { return ( @@ -76,8 +73,7 @@ class LinkWindow extends Component { > { typeof post !== 'string' && } @@ -96,7 +92,7 @@ class LinkWindow extends Component { }); render() { - const { graph, api, association } = this.props; + const { graph, association } = this.props; const first = graph.peekLargest()?.[0]; const [, , ship, name] = association.resource.split('/'); if (!first) { @@ -113,8 +109,7 @@ class LinkWindow extends Component { {this.canWrite() ? ( ) : ( @@ -127,9 +122,9 @@ class LinkWindow extends Component { } return ( - + {/* @ts-ignore calling @liam-fitzgerald on virtualscroller */} - s.addPost; + +export function LinkBlockInput(props: LinkBlockInputProps) { + const { size, association } = props; + const [url, setUrl] = useState(props.url || ''); + const [valid, setValid] = useState(false); + const [focussed, setFocussed] = useState(false); + + const addPost = useGraphState(selGraph); + + const onFocus = useCallback(() => { + setFocussed(true); + }, []); + + const onBlur = useCallback(() => { + setFocussed(false); + }, []); + + const URLparser = new RegExp( + /((?:([\w\d\.-]+)\:\/\/?){1}(?:(www)\.?){0,1}(((?:[\w\d-]+\.)*)([\w\d-]+\.[\w\d]+))){1}(?:\:(\d+)){0,1}((\/(?:(?:[^\/\s\?]+\/)*))(?:([^\?\/\s#]+?(?:.[^\?\s]+){0,1}){0,1}(?:\?([^\s#]+)){0,1})){0,1}(?:#([^#\s]+)){0,1}/ + ); + + const handleChange = useCallback((val: string) => { + setUrl(val); + setValid(URLparser.test(val) || Boolean(parsePermalink(val))); + }, []); + + const { uploading, canUpload, promptUpload, drag } = useFileUpload({ + onSuccess: handleChange + }); + + const doPost = () => { + const text = ''; + const { ship, name } = resourceFromPath(association.resource); + if (!(valid || url)) { + return; + } + const contents = url.startsWith('web+urbitgraph:/') + ? [{ text }, permalinkToReference(parsePermalink(url)!)] + : [{ text }, { url }]; + + const post = createPost(window.ship, contents); + + addPost(ship, name, post).then(() => { + setUrl(''); + setValid(false); + }); + }; + + const onKeyPress = useCallback( + (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + doPost(); + } + }, + [doPost] + ); + + return ( + + {drag.dragging && } + {uploading ? ( + + + + ) : ( + + )} + + + Post + + + + ); +} diff --git a/pkg/interface/src/views/apps/links/components/LinkBlockItem.tsx b/pkg/interface/src/views/apps/links/components/LinkBlockItem.tsx new file mode 100644 index 000000000..b49080283 --- /dev/null +++ b/pkg/interface/src/views/apps/links/components/LinkBlockItem.tsx @@ -0,0 +1,128 @@ +import React from 'react'; +import { + Icon, + Center, + Row, + Text, + Col, + Box, + CenterProps +} from '@tlon/indigo-react'; +import { hasProvider } from 'oembed-parser'; +import { AUDIO_REGEX, IMAGE_REGEX } from '~/views/components/RemoteContent'; +import { AudioPlayer } from '~/views/components/AudioPlayer'; +import { useHistory } from 'react-router'; +import { useHovering } from '~/logic/lib/util'; +import Author from '~/views/components/Author'; +import { + GraphNode, + ReferenceContent, + TextContent, + UrlContent +} from '@urbit/api'; +import { + RemoteContentEmbedFallback, + RemoteContentImageEmbed, + RemoteContentOembed, + RemoteContentPermalinkEmbed +} from '~/views/components/RemoteContent/embed'; +import { PermalinkEmbed } from '../../permalinks/embed'; +import { referenceToPermalink } from '~/logic/lib/permalinks'; +import AsyncFallback from '~/views/components/AsyncFallback'; + +export interface LinkBlockItemProps { + node: GraphNode; + size?: CenterProps['height']; + border?: CenterProps['border']; + summary?: boolean; +} + +export function LinkBlockItem(props: LinkBlockItemProps & CenterProps) { + const { node, summary, size, m, border = 1, ...rest } = props; + const { post, children } = node; + const { contents, index, author } = post; + + const [{ text: title }, ...content] = contents as [ + TextContent, + UrlContent | ReferenceContent + ]; + let url = ''; + if ('url' in content?.[0]) { + url = content[0].url; + } + + const isReference = 'reference' in content[0]; + + const isImage = IMAGE_REGEX.test(url); + const isAudio = AUDIO_REGEX.test(url); + + const isOembed = hasProvider(url); + const history = useHistory(); + const { hovering, bind } = useHovering(); + const onClick = () => { + const { pathname, search } = history.location; + history.push(`${pathname}/index${index}${search}`); + }; + return ( +
    + }> + {isReference ? ( + summary ? ( + + ) : ( + + ) + ) : isImage ? ( + + ) : isAudio ? ( + + ) : isOembed ? ( + + ) : ( + + )} + + + + + + {title} + + + + {children.size} + + + + + + + +
    + ); +} diff --git a/pkg/interface/src/views/apps/links/components/LinkBlocks.tsx b/pkg/interface/src/views/apps/links/components/LinkBlocks.tsx new file mode 100644 index 000000000..0c24912e0 --- /dev/null +++ b/pkg/interface/src/views/apps/links/components/LinkBlocks.tsx @@ -0,0 +1,140 @@ +import { Col, Row, Text } from '@tlon/indigo-react'; +import { Association, Graph, GraphNode, markEachAsRead } from '@urbit/api'; +import React, { useCallback, useState, useMemo, useEffect } from 'react'; +import _ from 'lodash'; +import { useResize } from '~/logic/lib/useResize'; +import { LinkBlockItem } from './LinkBlockItem'; +import { LinkBlockInput } from './LinkBlockInput'; +import useLocalState from '~/logic/state/local'; +import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap'; +import bigInt from 'big-integer'; +import airlock from '~/logic/api'; +import useHarkState, { selHarkGraph } from '~/logic/state/hark'; +import { BlockScroller } from '~/views/components/BlockScroller'; + +export interface LinkBlocksProps { + graph: Graph; + association: Association; +} + +const style = { + height: '100%', + width: '100%', + display: 'flex', + flexDirection: 'column', + alignItems: 'center' +}; +const PADDING = 24; +const SMALL_PADDING = 16; + +export function LinkBlocks(props: LinkBlocksProps) { + const { association } = props; + const [linkSize, setLinkSize] = useState(250); + const linkSizePx = `${linkSize}px`; + + const isSmall = useLocalState(s => !s.breaks.lg); + const colCount = useMemo(() => (isSmall ? 2 : 4), [isSmall]); + const bind = useResize( + useCallback( + (entry) => { + const { width } = entry.target.getBoundingClientRect(); + const pad = isSmall ? SMALL_PADDING : PADDING; + setLinkSize((width - pad) / colCount - pad); + }, + [colCount, isSmall] + ) + ); + + useEffect(() => { + const unreads = selHarkGraph(association.resource)(useHarkState.getState()); + const [,,ship,name] = association.resource.split('/'); + unreads.each.forEach((u) => { + airlock.poke(markEachAsRead({ + desk: (window as any).desk, + path: `/graph/${ship}/${name}` + }, u)); + }); + }, [association.resource]); + + const orm = useMemo(() => { + const graph = Array.from(props.graph).filter( + ([idx, node]) => typeof node?.post !== 'string' + ); + const nodes = [null, ...graph]; + const chunks = _.chunk(nodes, colCount); + return new BigIntOrderedMap<[bigInt.BigInteger, GraphNode][]>().gas( + chunks.reverse().map((chunk, i) => { + return [bigInt(i), chunk]; + }) + ); + }, [props.graph, colCount]); + + const renderItem = useCallback( + React.forwardRef(({ index }, ref) => { + const chunk = orm.get(index) ?? []; + const space = [3, 3, 3, 4]; + + return ( + + {chunk.map((block) => { + if (!block) { + return ( + + ); + } + const [i, node] = block; + return typeof node.post === 'string' ? ( + + This link has been deleted + + ) : ( + + ); + })} + + ); + }), + [orm, linkSizePx] + ); + + return ( + + Promise.resolve(true)} + /> + + ); +} diff --git a/pkg/interface/src/views/apps/links/components/LinkDetail.tsx b/pkg/interface/src/views/apps/links/components/LinkDetail.tsx new file mode 100644 index 000000000..664af6caa --- /dev/null +++ b/pkg/interface/src/views/apps/links/components/LinkDetail.tsx @@ -0,0 +1,73 @@ +import { Col, Row, RowProps } from '@tlon/indigo-react'; +import { Association, GraphNode, markEachAsRead, TextContent, UrlContent } from '@urbit/api'; +import React, { useEffect } from 'react'; +import { useGroup } from '~/logic/state/group'; +import Author from '~/views/components/Author'; +import Comments from '~/views/components/Comments'; +import { TruncatedText } from '~/views/components/TruncatedText'; +import { LinkBlockItem } from './LinkBlockItem'; +import airlock from '~/logic/api'; +import { toHarkPlace } from '~/logic/lib/util'; + +export interface LinkDetailProps extends RowProps { + node: GraphNode; + association: Association; + baseUrl: string; +} + +export function LinkDetail(props: LinkDetailProps) { + const { node, association, baseUrl, ...rest } = props; + const group = useGroup(association.group); + const { post } = node; + + useEffect(() => { + airlock.poke(markEachAsRead(toHarkPlace(association.resource), node.post.index)); + }, [association, node]); + const [{ text: title }] = post.contents as [TextContent, UrlContent]; + return ( + /* @ts-ignore indio props?? */ + + + + + {title.length > 0 ? ( + + {title} + + ) : null} + + + + + + + + ); +} diff --git a/pkg/interface/src/views/apps/links/components/LinkItem.tsx b/pkg/interface/src/views/apps/links/components/LinkItem.tsx index fecd771e2..516ac9f24 100644 --- a/pkg/interface/src/views/apps/links/components/LinkItem.tsx +++ b/pkg/interface/src/views/apps/links/components/LinkItem.tsx @@ -1,24 +1,22 @@ import { Action, Anchor, Box, Col, Icon, Row, Rule, Text } from '@tlon/indigo-react'; -import { Association, GraphNode, Group, TextContent, UrlContent } from '@urbit/api'; +import { Association, GraphNode, Group, markEachAsRead, removePosts, TextContent, UrlContent, ReferenceContent } from '@urbit/api'; import React, { ReactElement, RefObject, useCallback, useEffect, useRef } from 'react'; import { Link, Redirect } from 'react-router-dom'; -import GlobalApi from '~/logic/api/global'; import { roleForShip } from '~/logic/lib/group'; import { getPermalinkForGraph, referenceToPermalink } from '~/logic/lib/permalinks'; import { useCopy } from '~/logic/lib/useCopy'; -import useHarkState from '~/logic/state/hark'; +import { useHarkStat } from '~/logic/state/hark'; import Author from '~/views/components/Author'; import { Dropdown } from '~/views/components/Dropdown'; import RemoteContent from '~/views/components/RemoteContent'; import { PermalinkEmbed } from '../../permalinks/embed'; +import airlock from '~/logic/api'; interface LinkItemProps { node: GraphNode; association: Association; resource: string; - api: GlobalApi; group: Group; - path: string; baseUrl: string; mt?: number; measure?: any; @@ -28,9 +26,7 @@ export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject; } - const remoteRef = useRef(null); + const remoteRef = useRef(null); + const setRef = useCallback((el: HTMLDivElement | null ) => { + remoteRef.current = el; + }, []); const index = node.post.index.split('/')[1]; + const [ship, name] = resource.split('/'); + const harkPath = `/graph/~${ship}/${name}`; const markRead = useCallback(() => { - api.hark.markEachAsRead(props.association, '/', `/${index}`, 'link', 'link'); - }, [association, index]); + airlock.poke( + markEachAsRead({ desk: (window as any).desk, path: harkPath }, `/${index}`) + ); + }, [resource, index]); useEffect(() => { function onBlur() { // FF will only update on next tick setTimeout(() => { - console.log(remoteRef.current); if(document.activeElement instanceof HTMLIFrameElement // @ts-ignore forwardref prop passing && remoteRef?.current?.containerRef?.contains(document.activeElement)) { @@ -76,7 +78,6 @@ export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject { if (confirm('Are you sure you want to delete this link?')) { - api.graph.removePosts(`~${ship}`, name, [node.post.index]); + airlock.poke(removePosts(`~${ship}`, name, [node.post.index])); } }; - const appPath = `/ship/~${resource}`; - const unreads = useHarkState(state => state.unreads); - const commColor = (unreads.graph?.[appPath]?.[`/${index}`]?.unreads ?? 0) > 0 ? 'blue' : 'gray'; - // @ts-ignore hark will have to choose between sets and numbers - const isUnread = unreads.graph?.[appPath]?.['/']?.unreads?.has(node.post.index); + const linkStats = useHarkStat(harkPath); + const commStats = useHarkStat(`${harkPath}/${index}`); + const commColor = commStats.count > 0 ? 'blue' : 'gray'; + const isUnread = linkStats.each.includes(`/${index}`); return ( - {contents[0].text} + {contents[0].text ? {contents[0].text} : null} { 'reference' in contents[1] ? ( <> - + ) : ( <> { - // @ts-ignore RemoteContent weirdness - remoteRef.current = r; - }} + embedRef={setRef} // @ts-ignore RemoteContent weirdness renderUrl={false} url={href} - text={contents[0].text} - unfold={true} - style={{ alignSelf: 'center' }} - oembedProps={{ - p: 2, - className: 'links embed-container', - onClick: markRead - }} - imageProps={{ - marginLeft: 'auto', - marginRight: 'auto', - display: 'block' - }} - textProps={{ - overflow: 'hidden', - color: 'black', - display: 'block', - alignSelf: 'center', - style: { textOverflow: 'ellipsis', whiteSpace: 'pre', width: '100%' }, - p: 2 - }} + tall /> diff --git a/pkg/interface/src/views/apps/links/components/LinkSubmit.tsx b/pkg/interface/src/views/apps/links/components/LinkSubmit.tsx index 43e684817..09851bd9f 100644 --- a/pkg/interface/src/views/apps/links/components/LinkSubmit.tsx +++ b/pkg/interface/src/views/apps/links/components/LinkSubmit.tsx @@ -1,31 +1,39 @@ -import { BaseInput, Box, Button, LoadingSpinner, Text } from '@tlon/indigo-react'; +import { BaseInput, Box, Button, LoadingSpinner } from '@tlon/indigo-react'; import { hasProvider } from 'oembed-parser'; -import React, { useCallback, useState } from 'react'; -import GlobalApi from '~/logic/api/global'; -import { createPost } from '~/logic/api/graph'; +import React, { useState, useEffect } from 'react'; import { parsePermalink, permalinkToReference } from '~/logic/lib/permalinks'; -import { useFileDrag } from '~/logic/lib/useDrag'; -import useStorage from '~/logic/lib/useStorage'; +import { StatelessUrlInput } from '~/views/components/StatelessUrlInput'; import SubmitDragger from '~/views/components/SubmitDragger'; +import useGraphState from '~/logic/state/graph'; +import { createPost } from '@urbit/api'; +import { useFileUpload } from '~/logic/lib/useFileUpload'; interface LinkSubmitProps { - api: GlobalApi; name: string; ship: string; parentIndex?: any; } const LinkSubmit = (props: LinkSubmitProps) => { - const { canUpload, uploadDefault, uploading, promptUpload } = - useStorage(); + const addPost = useGraphState(s => s.addPost); const [submitFocused, setSubmitFocused] = useState(false); - const [urlFocused, setUrlFocused] = useState(false); - const [linkValue, setLinkValueHook] = useState(''); + const [linkValue, setLinkValue] = useState(''); const [linkTitle, setLinkTitle] = useState(''); const [disabled, setDisabled] = useState(false); const [linkValid, setLinkValid] = useState(false); + const { + canUpload, + uploading, + promptUpload, + drag, + onPaste + } = useFileUpload({ + onSuccess: setLinkValue, + multiple: false + }); + const doPost = () => { const url = linkValue; const text = linkTitle ? linkTitle : linkValue; @@ -35,18 +43,17 @@ const LinkSubmit = (props: LinkSubmitProps) => { setDisabled(true); const parentIndex = props.parentIndex || ''; - const post = createPost(contents, parentIndex); + const post = createPost(window.ship, contents, parentIndex); - props.api.graph.addPost( + addPost( `~${props.ship}`, props.name, post - ).then(() => { - setDisabled(false); - setLinkValue(''); - setLinkTitle(''); - setLinkValid(false); - }); + ); + setDisabled(false); + setLinkValue(''); + setLinkTitle(''); + setLinkValid(false); }; const validateLink = (link) => { @@ -95,39 +102,16 @@ const LinkSubmit = (props: LinkSubmitProps) => { return link; }; - const onFileDrag = useCallback( - (files: FileList | File[], e: DragEvent): void => { - if (!canUpload) { - return; - } - uploadDefault(files[0]).then(setLinkValue); - }, - [uploadDefault, canUpload] - ); + useEffect(() => { + setLinkValid(validateLink(linkValue)); + }, [linkValue]); - const { bind, dragging } = useFileDrag(onFileDrag); - - const onLinkChange = (linkValue: string) => { - setLinkValueHook(linkValue); + const onLinkChange = () => { const link = validateLink(linkValue); setLinkValid(link); }; - const setLinkValue = (linkValue: string) => { - onLinkChange(linkValue); - setLinkValueHook(linkValue); - }; - - const onPaste = useCallback( - (event: ClipboardEvent) => { - if (!event.clipboardData || !event.clipboardData.files.length) { - return; - } - event.preventDefault(); - event.stopPropagation(); - uploadDefault(event.clipboardData.files[0]).then(setLinkValue); - }, [setLinkValue, uploadDefault] - ); + useEffect(onLinkChange, [linkValue]); const onKeyPress = (e) => { if (e.key === 'Enter') { @@ -136,26 +120,6 @@ const LinkSubmit = (props: LinkSubmitProps) => { } }; - const placeholder = {canUpload - ? <> - Drop or{' '} - promptUpload().then(setLinkValue)} - >upload - {' '}a file, or paste a link here - - : 'Paste a link here' - }; - return ( <> {/* @ts-ignore archaic event type mismatch */} @@ -166,7 +130,7 @@ const LinkSubmit = (props: LinkSubmitProps) => { borderColor={submitFocused ? 'black' : 'lightGray'} width='100%' borderRadius={2} - {...bind} + {...drag.bind} > {uploading && { > } - {dragging && } - - {!(linkValue || urlFocused || disabled) && placeholder} - onLinkChange(e.target.value)} - onBlur={() => [setUrlFocused(false), setSubmitFocused(false)]} - onFocus={() => [setUrlFocused(true), setSubmitFocused(true)]} - spellCheck="false" - // @ts-ignore archaic event type mismatch error - onPaste={onPaste} - onKeyPress={onKeyPress} - value={linkValue} - /> - + {drag.dragging && } + s.archive; + +export function Archive() { + const archive = useHarkState(selArchive); + const keys = archive.keys(); + + useEffect(() => { + useHarkState.getState().getMore(); + }, []); + + return ( + + {keys.map(key => + Object.entries(archive.get(key)!) + .sort(([, a], [, b]) => b.time - a.time) + .map(([binId, n]) => ( + + )) + )} + + ); +} diff --git a/pkg/interface/src/views/apps/notifications/NewBox.tsx b/pkg/interface/src/views/apps/notifications/NewBox.tsx new file mode 100644 index 000000000..56fb99ea4 --- /dev/null +++ b/pkg/interface/src/views/apps/notifications/NewBox.tsx @@ -0,0 +1,58 @@ +import { Box, Center, Col, Text } from '@tlon/indigo-react'; +import React from 'react'; +import useHarkState, { HarkState } from '~/logic/state/hark'; +import { harkBinToId, HarkLid, Timebox } from '../../../../../npm/api/dist'; +import { Notification } from './notification'; + +const unseenLid = { unseen: null }; +const seenLid = { seen: null }; +const selUnseen = (s: HarkState) => s.unseen; +const selSeen = (s: HarkState) => s.seen; +export function NewBox() { + const seen = useHarkState(selSeen); + const unseen = useHarkState(selUnseen); + const empty = Object.keys(seen).length + Object.keys(unseen).length === 0; + + return ( + + {empty ? ( +
    + All clear! +
    + ) : ( + <> + + + + )} +
    + ); +} + +function Lid({ + lid, + timebox, + title +}: { + lid: HarkLid; + timebox: Timebox; + title: string; +}) { + if(Object.keys(timebox).length === 0) { + return null; + } + return ( + <> + + {title} + + + {Object.entries(timebox) + .sort(([, a], [, b]) => b.time - a.time) + .map(([binId, n]) => ( + + ))} + + + ); +} diff --git a/pkg/interface/src/views/apps/notifications/PendingDm.tsx b/pkg/interface/src/views/apps/notifications/PendingDm.tsx index 2073bc127..286f57e92 100644 --- a/pkg/interface/src/views/apps/notifications/PendingDm.tsx +++ b/pkg/interface/src/views/apps/notifications/PendingDm.tsx @@ -2,20 +2,21 @@ import React, { useCallback } from 'react'; import { Box, Row, Text } from '@tlon/indigo-react'; import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction'; import Author from '~/views/components/Author'; -import GlobalApi from '~/logic/api/global'; import { useHistory } from 'react-router'; +import { acceptDm, declineDm } from '@urbit/api/graph'; +import airlock from '~/logic/api'; -export function PendingDm(props: { ship: string; api: GlobalApi }) { - const { ship, api } = props; +export function PendingDm(props: { ship: string; }) { + const { ship } = props; const { push } = useHistory(); const onAccept = useCallback(async () => { - await api.graph.acceptDm(ship); + await airlock.poke(acceptDm(ship)); push(`/~landscape/messages/dm/${ship}`); - }, [ship, push, api]); + }, [ship, push]); const onDecline = useCallback(async () => { - await api.graph.declineDm(ship); - }, [ship, api]); + await airlock.poke(declineDm(ship)); + }, [ship]); return ( ` - -webkit-line-clamp: ${p => p.truncate ?? 'unset'}; - display: -webkit-box; - overflow: hidden; - -webkit-box-orient: vertical; - color: ${p => p.theme.colors.black}; -`; - -function describeNotification( - description: string, - plural: boolean, - isDm: boolean, - singleAuthor: boolean -): string { - switch (description) { - case 'post': - return singleAuthor ? 'replied to you' : 'Your post received replies'; - case 'link': - return `New link${plural ? 's' : ''} in`; - case 'comment': - return `New comment${plural ? 's' : ''} on`; - case 'note': - return `New Note${plural ? 's' : ''} in`; - case 'edit-note': - return `updated ${pluralize('note', plural)} in`; - case 'mention': - return singleAuthor ? 'mentioned you in' : 'You were mentioned in'; - case 'message': - if (isDm) { - return 'messaged you'; - } - return `New message${plural ? 's' : ''} in`; - default: - return description; - } -} - -function ContentSummary({ icon, name, author, to }) { - return ( - - - - - - {name} - - - - - by - - - - - - ); -} - -export const GraphNodeContent = ({ post, mod, index, hidden, association }) => { - const { contents } = post; - const idx = index.slice(1).split('/'); - const url = getNodeUrl(mod, hidden, association?.group, association?.resource, index); - if (mod === 'graph-validator-link' && idx.length === 1) { - const [{ text: title }] = contents; - return ( - - ); - } - if (mod === 'graph-validator-publish' && idx[1] === '1') { - const [{ text: title }] = contents; - return ( - - ); - } - return ( - - - - ); -}; - -function getNodeUrl( - mod: string, - hidden: boolean, - groupPath: string, - graph: string, - index: string -) { - const graphValidator = 'graph-validator-'; - const rmValidator = mod.slice(graphValidator.length); - if (hidden && mod === 'graph-validator-chat') { - groupPath = '/messages'; - } else if (hidden) { - groupPath = '/home'; - } - const graphUrl = `/~landscape${groupPath}/resource/${rmValidator}${graph}`; - const idx = index.slice(1).split('/'); - if (mod === 'graph-validator-publish') { - const [noteId, kind, commId] = idx; - const selected = kind === '2' ? `?selected=${commId}` : ''; - return `${graphUrl}/note/${noteId}${selected}`; - } else if (mod === 'graph-validator-link') { - const [linkId, commId] = idx; - return `${graphUrl}/index/${linkId}${commId ? `?selected=${commId}` : ''}`; - } else if (mod === 'graph-validator-chat') { - if (idx.length > 0) { - return `${graphUrl}?msg=${idx[0]}`; - } - return graphUrl; - } else if (mod === 'graph-validator-post') { - return `/~landscape${groupPath}/feed/thread${index}`; - } else if (mod === 'graph-validator-dm') { - return `/~landscape${groupPath}/dm/${patp(idx[0])}`; - } - return ''; -} - -interface PostsByAuthor { - author: string; - posts: Post[]; -} -const GraphNodes = (props: { - posts: Post[]; - hideAuthors?: boolean; - index: string; - mod: string; - association: Association; - hidden: boolean; -}) => { - const { - posts, - mod, - hidden, - index, - hideAuthors = false, - association - } = props; - - const postsByConsecAuthor = _.reduce( - posts, - (acc: PostsByAuthor[], val: Post, key: number) => { - const lent = acc.length; - if (lent > 0 && acc?.[lent - 1]?.author === val.author) { - const last = acc[lent - 1]; - const rest = acc.slice(0, -1); - return [...rest, { ...last, posts: [...last.posts, val] }]; - } - return [...acc, { author: val.author, posts: [val] }]; - }, - [] - ); - - return ( - <> - {_.map(postsByConsecAuthor, ({ posts, author }, idx) => { - const time = posts[0]?.['time-sent']; - return ( - - {!hideAuthors && ( - - )} - - {_.map(posts, post => ( -