diff --git a/.circleci/main.yml b/.circleci/main.yml index 1fe38fc7a76..49591d50c30 100644 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -32,11 +32,12 @@ default_environment: &default_environment CIRCLE_TEST_REPORTS: /tmp/circleci-test-results CIRCLE_ARTIFACTS: /tmp/circleci-artifacts GIT_PAGER: cat + IPFS_CHECK_RCMGR_DEFAULTS: 1 executors: golang: docker: - - image: cimg/go:1.16.15 + - image: cimg/go:1.18.3 working_directory: ~/ipfs/go-ipfs environment: <<: *default_environment @@ -61,7 +62,7 @@ executors: E2E_IPFSD_TYPE: go dockerizer: docker: - - image: cimg/go:1.16.15 + - image: cimg/go:1.18.3 environment: IMAGE_NAME: ipfs/go-ipfs WIP_IMAGE_TAG: wip @@ -69,6 +70,7 @@ executors: jobs: gobuild: executor: golang + resource_class: 2xlarge+ steps: - checkout - *make_out_dirs @@ -106,7 +108,10 @@ jobs: command: bash <(curl -s https://codecov.io/bash) -cF unittests -X search -f coverage/unit_tests.coverprofile - run: command: | - # we want to test the examples against the current version of go-ipfs + # we want to first test with the go-ipfs in the go.mod file + go test -v ./... + + # we also want to test the examples against the current version of go-ipfs # however, that version might be in a fork so we need to replace the dependency # backup the go.mod and go.sum files to restore them after we run the tests @@ -116,11 +121,18 @@ jobs: # make sure the examples run against the current version of go-ipfs go mod edit -replace github.com/ipfs/go-ipfs=./../../.. go mod tidy + + # use the internal config package when we test the current version of go-ipfs + sed -i.bak 's;"github.com/ipfs/go-ipfs-config";"github.com/ipfs/go-ipfs/config";' ./main.go + go test -v ./... # restore the go.mod and go.sum files to their original state mv go.mod.bak go.mod mv go.sum.bak go.sum + + # restore the main.go to its original state + mv main.go.bak main.go working_directory: ~/ipfs/go-ipfs/docs/examples/go-ipfs-as-a-library - run: @@ -143,15 +155,15 @@ jobs: working_directory: ~/ipfs/go-ipfs environment: <<: *default_environment - TEST_NO_DOCKER: 1 + TEST_NO_DOCKER: 0 TEST_NO_FUSE: 1 TEST_VERBOSE: 1 steps: - run: sudo apt update - run: | mkdir ~/localgo && cd ~/localgo - wget https://golang.org/dl/go1.16.15.linux-amd64.tar.gz - tar xfz go1.16.15.linux-amd64.tar.gz + wget https://golang.org/dl/go1.18.3.linux-amd64.tar.gz + tar xfz go1.18.3.linux-amd64.tar.gz echo "export PATH=$(pwd)/go/bin:\$PATH" >> ~/.bashrc - run: go version - run: sudo apt install socat net-tools @@ -166,7 +178,7 @@ jobs: git checkout FETCH_HEAD - run: cd rb-pinning-service-api && - docker-compose pull && + (for i in {1..3}; do docker-compose pull && break || sleep 5; done) && docker-compose up -d - *make_out_dirs @@ -217,18 +229,24 @@ jobs: - *store_gomod interop: docker: - - image: cimg/go:1.16-node + - image: cimg/go:1.18.3-node parallelism: 4 + resource_class: large steps: - *make_out_dirs - attach_workspace: at: /tmp/circleci-workspace + - restore_cache: + keys: + - v1-interop-{{ .Branch }}-{{ .Revision }} + - v1-interop-{{ .Branch }}- + - v1-interop- - run: name: Installing dependencies command: | npm init -y npm install ipfs@^0.61.0 - npm install ipfs-interop@^8.0.0 + npm install ipfs-interop@^8.0.10 npm install mocha-circleci-reporter@0.0.3 working_directory: ~/ipfs/go-ipfs/interop - run: @@ -236,7 +254,7 @@ jobs: command: | mkdir -p /tmp/test-results/interop/ export MOCHA_FILE="$(mktemp /tmp/test-results/interop/unit.XXXXXX.xml)" - npx ipfs-interop -- -t node -f $(sed -n -e "s|^require('\(.*\)')$|test/\1|p" node_modules/ipfs-interop/test/node.js | circleci tests split) -- --reporter mocha-circleci-reporter + npx ipfs-interop -- -t node -f $(sed -n -e "s|^import '\(.*\)'$|test/\1|p" node_modules/ipfs-interop/test/node.js | circleci tests split --split-by=timings) -- --reporter mocha-circleci-reporter working_directory: ~/ipfs/go-ipfs/interop environment: LIBP2P_TCP_REUSEPORT: false @@ -244,6 +262,10 @@ jobs: IPFS_GO_EXEC: /tmp/circleci-workspace/bin/ipfs - store_test_results: path: /tmp/test-results + - save_cache: + key: v1-interop-{{ .Branch }}-{{ .Revision }} + paths: + - ~/ipfs/go-ipfs/interop/node_modules go-ipfs-api: executor: golang steps: @@ -271,7 +293,7 @@ jobs: - v1-go-api-{{ checksum "~/ipfs/go-ipfs/go-ipfs-api/go.sum" }} - v1-go-api- - run: - command: go test -v ./... + command: go test -count=1 -v ./... working_directory: ~/ipfs/go-ipfs/go-ipfs-api - save_cache: key: v1-go-api-{{ checksum "~/ipfs/go-ipfs/go-ipfs-api/go.sum" }} @@ -292,18 +314,15 @@ jobs: command: | git clone https://github.com/ipfs/go-ipfs-http-client.git git -C go-ipfs-http-client log -1 - cd go-ipfs-http-client - git checkout v0.2.0 - cd .. - restore_cache: keys: - v1-http-client-{{ checksum "~/ipfs/go-ipfs/go-ipfs-http-client/go.sum" }} - v1-http-client- - run: - name: go test -v ./... + name: go test -count=1 -v ./... command: | export PATH=/tmp/circleci-workspace/bin:$PATH - go test -v ./... + go test -count=1 -v ./... working_directory: ~/ipfs/go-ipfs/go-ipfs-http-client - save_cache: key: v1-http-client-{{ checksum "~/ipfs/go-ipfs/go-ipfs-http-client/go.sum" }} @@ -329,6 +348,7 @@ jobs: name: Installing dependencies command: | npm install + npx playwright install working_directory: ~/ipfs/go-ipfs/ipfs-webui - run: name: Running upstream tests (finish early if they fail) @@ -344,6 +364,7 @@ jobs: - save_cache: key: v1-ipfs-webui-{{ checksum "~/ipfs/go-ipfs/ipfs-webui/package-lock.json" }} paths: + - ~/.cache/ms-playwright - ~/ipfs/go-ipfs/ipfs-webui/node_modules # We only run build as a test here. DockerHub images are built and published # by Github Action now: https://github.com/ipfs/go-ipfs/pull/8467 diff --git a/.dockerignore b/.dockerignore index 10dd5fd886d..1e149a2bddb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,8 @@ Dockerfile.fast !.git/refs/ !.git/packed-refs test/sharness/lib/sharness/ +test/sharness/trash* +rb-pinning-service-api/ # The Docker client might not be running on Linux # so delete any compiled binaries diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..5151ad178ae --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,7 @@ +# Code owners are automatically requested for review when someone opens a pull +# request that modifies code that they own. Code owners are not automatically +# requested to review draft pull requests. + +# HTTP Gateway +core/corehttp/ @lidel +test/sharness/*gateway*.sh @lidel diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e5afd8ffa56..27fef31b01c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -4,14 +4,14 @@ contact_links: url: https://ipfs.io/help about: All information about how and where to get help on IPFS. - name: Go-ipfs configuration reference - url: https://github.com/ipfs/go-ipfs/blob/master/docs/config.md + url: https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#readme about: Documentation on the different configuration settings - name: Go-ipfs experimental features docs - url: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md + url: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#readme about: Documentation on Private Networks, Filestore and other experimental features. - - name: HTTP API Reference - url: https://docs.ipfs.io/reference/http/api/#api-v0-add - about: Documentation of all go-ipfs HTTP API endpoints. + - name: RPC API Reference + url: https://docs.ipfs.io/reference/http/api/ + about: Documentation of all go-ipfs RPC API endpoints. - name: IPFS Official Forum url: https://discuss.ipfs.io about: Please post general questions, support requests, and discussions here. diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 90bdd75b7bc..39f7073f5e6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,6 +2,7 @@ name: "CodeQL" on: + workflow_dispatch: push: branches: [ master ] pull_request: @@ -12,6 +13,7 @@ on: jobs: analyze: + if: github.repository == 'ipfs/go-ipfs' || github.event_name == 'workflow_dispatch' name: Analyze runs-on: ubuntu-latest diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 8d2a95a9a60..1fda1c8b3aa 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -11,17 +11,28 @@ on: jobs: push_to_registry: + if: github.repository == 'ipfs/go-ipfs' || github.event_name == 'workflow_dispatch' name: Push Docker image to Docker Hub runs-on: ubuntu-latest env: IMAGE_NAME: ipfs/go-ipfs - WIP_IMAGE_TAG: wip steps: - name: Check out the repo uses: actions/checkout@v2 - - name: Build wip Docker image - run: docker build -t $IMAGE_NAME:$WIP_IMAGE_TAG . + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Get tags + id: tags + run: | + TAGS="$(./bin/get-docker-tags.sh $(date -u +%F))" + TAGS="${TAGS//$'\n'/'%0A'}" + echo "::set-output name=value::$(echo $TAGS)" + shell: bash - name: Log in to Docker Hub uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 @@ -29,6 +40,11 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Publish Docker Image to Docker Hub - run: ./bin/push-docker-tags.sh $(date -u +%F) - + - name: Build Docker image and publish to Docker Hub + uses: docker/build-push-action@v2 + with: + platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 + context: . + push: true + file: ./Dockerfile + tags: "${{ steps.tags.outputs.value }}" diff --git a/.github/workflows/golang-analysis.yml b/.github/workflows/golang-analysis.yml new file mode 100644 index 00000000000..d9a57faa424 --- /dev/null +++ b/.github/workflows/golang-analysis.yml @@ -0,0 +1,37 @@ +on: [push, pull_request] +name: Go Checks + +jobs: + unit: + runs-on: ubuntu-latest + name: All + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - uses: actions/setup-go@v2 + with: + go-version: "1.18.x" + - name: Check that go.mod is tidy + uses: protocol/multiple-go-modules@v1.2 + with: + run: | + go mod tidy + if [[ -n $(git ls-files --other --exclude-standard --directory -- go.sum) ]]; then + echo "go.sum was added by go mod tidy" + exit 1 + fi + git diff --exit-code -- go.sum go.mod + - name: gofmt + if: always() # run this step even if the previous one failed + run: | + out=$(gofmt -s -l .) + if [[ -n "$out" ]]; then + echo $out | awk '{print "::error file=" $0 ",line=0,col=0::File is not gofmt-ed."}' + exit 1 + fi + - name: go vet + if: always() # run this step even if the previous one failed + uses: protocol/multiple-go-modules@v1.2 + with: + run: go vet ./... diff --git a/.github/workflows/sync-release-assets.yml b/.github/workflows/sync-release-assets.yml index d1e0826ace1..f6ca267199d 100644 --- a/.github/workflows/sync-release-assets.yml +++ b/.github/workflows/sync-release-assets.yml @@ -11,40 +11,13 @@ concurrency: jobs: sync-github-and-dist-ipfs-io: + if: github.repository == 'ipfs/go-ipfs' || github.event_name == 'workflow_dispatch' runs-on: "ubuntu-latest" steps: - - name: Setup go - uses: actions/setup-go@v2 + - uses: ipfs/download-ipfs-distribution-action@v1 + - uses: ipfs/start-ipfs-daemon-action@v1 with: - go-version: '1.16' - - uses: actions/cache@v2 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - name: Build go-ipfs binary - run: go install github.com/ipfs/go-ipfs/cmd/ipfs@latest - - name: Initialize go-ipfs and start daemon - run: | - sudo sysctl -w net.core.rmem_max=2500000 - ipfs init --profile flatfs,server - ipfs daemon --enable-gc=false & - while (! ipfs id --api "/ip4/127.0.0.1/tcp/5001"); do sleep 1; done - - name: Wait for go-ipfs to be ready - shell: pwsh - run: | - for ($i = 0; $i -lt 10; $i++) { - $addrs = ipfs id | jq .Addresses; - if ($addrs -eq "null") { - sleep 1 - } else { - echo "Successfully started the daemon" - exit 0 - } - } + args: --init --init-profile=flatfs,server --enable-gc=false - uses: actions/setup-node@v2 with: node-version: 14 diff --git a/.github/workflows/testground-on-push.yml b/.github/workflows/testground-on-push.yml index ee18c340b55..a73018ca7e9 100644 --- a/.github/workflows/testground-on-push.yml +++ b/.github/workflows/testground-on-push.yml @@ -1,10 +1,14 @@ --- name: Testground PR Checker -on: [push] +on: + workflow_dispatch: + push: + jobs: testground: + if: github.repository == 'ipfs/go-ipfs' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest name: ${{ matrix.composition_file }} strategy: @@ -25,7 +29,8 @@ jobs: steps: - uses: actions/checkout@v2 - name: testground run - uses: coryschwartz/testground-github-action@v1.1 + uses: testground/testground-github-action@v1 + timeout-minutes: 5 with: backend_addr: ${{ matrix.backend_addr }} backend_proto: ${{ matrix.backend_proto }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6836ba00a93..fd796ff66ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,1105 @@ # go-ipfs changelog +## v0.13.0 2022-05-04 + +We're happy to announce go-ipfs 0.13.0, packed full of changes and improvements! + +As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will _not_ be called out in the release notes. Please make sure to update ASAP. See our [release process](https://github.com/ipfs/go-ipfs/tree/master/docs/releases.md#security-fix-policy) for details. + +### Overview + +Below is an outline of all that is in this release, so you get a sense of all that's included. + +- [๐Ÿ›  BREAKING CHANGES](#---breaking-changes) + * [`ipfs block put` command](#-ipfs-block-put--command) + * [`ipfs cid codecs` command](#-ipfs-cid-codecs--command) + * [`Swarm` configuration](#-swarm--configuration) + * [Circuit Relay V1 is deprecated](#circuit-relay-v1-is-deprecated) + * [`ls` requests for `/multistream/1.0.0` are removed](#-ls--requests-for---multistream-100--are-removed) + * [Gateway Items](#gateway-items) +- [๐Ÿ”ฆ Highlights](#---highlights) + * [๐Ÿง‘โ€๐Ÿ’ผ libp2p Network Resource Manager (`Swarm.ResourceMgr`)](#------libp2p-network-resource-manager---swarmresourcemgr--) + * [๐Ÿ”ƒ Relay V2 client with auto discovery (`Swarm.RelayClient`)](#---relay-v2-client-with-auto-discovery---swarmrelayclient--) + * [๐ŸŒ‰ HTTP Gateway improvements](#---http-gateway-improvements) + + [๐Ÿฑ Support for Block and CAR response formats](#---support-for-block-and-car-response-formats) + + [๐ŸŽ Fast listing generation for huge directories](#---fast-listing-generation-for-huge--directories) + + [๐ŸŽซ Improved `Etag` and `If-None-Match` for bandwidth savings](#---improved--etag--and--if-none-match--for-bandwidth-savings) + + [โ›“๏ธ Added X-Ipfs-Roots for smarter HTTP caches](#---added-x-ipfs-roots-for-smarter-http-caches) + + [๐ŸŒก๏ธ Added metrics per response type](#----added-metrics-per-response-type) + * [๐Ÿ•ต๏ธ OpenTelemetry tracing](#----opentelemetry-tracing) + + [How to use Jaeger UI for visual tracing?](#how-to-use-jaeger-ui-for-visual-tracing-) + * [๐Ÿฉบ Built-in `ipfs diag profile` to ease debugging](#---built-in--ipfs-diag-profile--to-ease-debugging) + * [๐Ÿ”‘ Support for PEM/PKCS8 for key import/export](#---support-for-pem-pkcs8-for-key-import-export) + * [๐Ÿงน Using standard IPLD codec names across the CLI/HTTP API](#---using-standard-ipld-codec-names-across-the-cli-http-api) + * [๐Ÿณ Custom initialization for Docker](#---custom-initialization-for-docker) + * [RPC API docs for experimental and deprecated commands](#rpc-api-docs-for-experimental-and-deprecated-commands) + * [Yamux over Mplex](#yamux-over-mplex) + +### ๐Ÿ›  BREAKING CHANGES + +#### `ipfs block put` command + +`ipfs block put` command returns a CIDv1 with `raw` codec by default now. +- `ipfs block put --cid-codec` makes `block put` return CID with alternative codec + - This impacts only the returned CID; it does not trigger any validation or data transformation. + - Retrieving a block with a different codec or CID version than it was put with is valid. + - Codec names are validated against tables from [go-multicodec](https://github.com/multiformats/go-multicodec) library. +- `ipfs block put --format` is deprecated. It used incorrect codec names and should be avoided for new deployments. Use it only if you need the old, invalid behavior, namely: + - `ipfs block put --format=v0` will produce CIDv0 (implicit dag-pb) + - `ipfs block put --format=cbor` will produce CIDv1 with dag-cbor (!) + - `ipfs block put --format=protobuf` will produce CIDv1 with dag-pb (!) + +#### `ipfs cid codecs` command +- Now lists codecs from [go-multicodec](https://github.com/multiformats/go-multicodec) library. +- `ipfs cid codecs --supported` can be passed to only show codecs supported in various go-ipfs commands. + +#### `ipfs cid format` command +- `--codec` was removed and replaced with `--mc` to ensure existing users are aware of the following changes: + - `--mc protobuf` now correctly points to code `0x50` (was `0x70`, which is `dab-pg`) + - `--mc cbor` now correctly points to code `0x51` (was `0x71`, which is `dag-cbor`) + +#### `Swarm` configuration +- Daemon will refuse to start if long-deprecated RelayV1 config key `Swarm.EnableAutoRelay` or `Swarm.DisableRelay` is set to `true`. +- If `Swarm.Transports.Network.Relay` is disabled, then `Swarm.RelayService` and `Swarm.RelayClient` are also disabled (unless they have been explicitly enabled). + +#### Circuit Relay V1 is deprecated +- By default, `Swarm.RelayClient` does not use Circuit Relay V1. Circuit V1 support is only enabled when `Swarm.RelayClient.StaticRelays` are specified. + +#### `ls` requests for `/multistream/1.0.0` are removed +- go-libp2p 0.19 removed support for undocumented `ls` command ([PR](https://github.com/multiformats/go-multistream/pull/76)). If you are still using it for internal testing, it is time to refactor ([example](https://github.com/ipfs/go-ipfs/commit/39047bcf61163096d1c965283d671c7c487c9173)) + +#### Gateway Behavior +Directory listings returned by the HTTP Gateway won't have size column if the directory is bigger than [`Gateway.FastDirIndexThreshold`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#gatewayfastdirindexthreshold) config (default is 100). + +To understand the wider context why we made these changes, read *Highlights* below. + +### ๐Ÿ”ฆ Highlights + +#### ๐Ÿง‘โ€๐Ÿ’ผ libp2p Network Resource Manager (`Swarm.ResourceMgr`) + +*You can now easily bound how much resource usage libp2p consumes! This aids in protecting nodes from consuming more resources then are available to them.* + +The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) is disabled by default, but can be enabled via: + +`ipfs config --json Swarm.ResourceMgr.Enabled true` + +When enabled, it applies some safe defaults that can be inspected and adjusted with: + +- `ipfs swarm stats --help` +- `ipfs swarm limit --help` + +User changes persist to config at [`Swarm.ResourceMgr`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgr). + +The Resource Manager will be enabled by default in a future release. + +#### ๐Ÿ”ƒ Relay V2 client with auto discovery (`Swarm.RelayClient`) + +*All the pieces are enabled for [hole-punching](https://blog.ipfs.io/2022-01-20-libp2p-hole-punching/) by default, improving connecting with nodes behind NATs and Firewalls!* + +This release enables [`Swarm.RelayClient`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmrelayclient) by default, along with circuit v2 relay discovery provided by go-libp2p [v0.19.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.19.0). This means: +1. go-ipfs will coordinate with the counterparty using a [relayed connection](https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md), to [upgrade to a direct connection](https://github.com/libp2p/specs/blob/master/relay/DCUtR.md) through a NAT/firewall whenever possible. +2. go-ipfs daemon will automatically use [public relays](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmrelayservice) if it detects that it cannot be reached from the public internet (e.g., it's behind a firewall). This results in a `/p2p-circuit` address from a public relay. + +**Notes:** +- [`Swarm.RelayClient`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmrelayclient) does not use Circuit Relay V1 nodes any more. Circuit V1 support is only enabled when static relays are specified in [`Swarm.RelayClient.StaticRelays`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmrelayclientstaticrelays). +- One can opt-out via [`Swarm.EnableHolePunching`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmenableholepunching). + + +#### ๐ŸŒ‰ HTTP Gateway improvements + +HTTP Gateway enables seamless interop with the existing Web, clients, user agents, tools, frameworks and libraries. + +This release ships the first batch of improvements that enable creation of faster and smarter CDNs, and unblocks creation of light clients for Mobile and IoT. + +Details below. + +##### ๐Ÿฑ Support for Block and CAR response formats + +*Alternative response formats from Gateway can be requested to avoid needing to trust a gateway.* + +For now, `{format}` is limited to two options: +- `raw` โ€“ fetching single block +- `car` โ€“ fetching entire DAG behind a CID as a [CARv1 stream](https://ipld.io/specs/transport/car/carv1/) + +When not set, the default UnixFS response is returned. + +*Why these two formats?* Requesting Block or CAR for `/ipfs/{cid}` allows a client to **use gateways in a trustless fashion**. These types of gateway responses can be verified locally and rejected if digest inside of requested CID does not match received bytes. This enables creation of "light IPFS clients" which use HTTP Gateways as inexpensive transport for [content-addressed](https://docs.ipfs.io/concepts/content-addressing/) data, unlocking use in Mobile and IoT contexts. + + +Future releases will [add support for dag-json and dag-cbor responses](https://github.com/ipfs/go-ipfs/issues/8823). + +There are two ways for requesting CID specific response format: +1. HTTP header: `Accept: application/vnd.ipld.{format}` +- Examples: [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car), [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) +2. URL paramerer: `?format=` +- Useful for creating "Download CAR" links. + +*Usage examples:* + +1. Downloading a single raw Block and manually importing it to the local datastore: + +```console +$ curl -H 'Accept: application/vnd.ipld.raw' "http://127.0.0.1:8080/ipfs/QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN" --output block.bin +$ cat block.bin | ipfs block put +$ ipfs cat QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN +hello +``` + +2. Downloading entire DAG as a CAR file and importing it: + +```console +$ ipfs resolve -r /ipns/webui.ipfs.io +/ipfs/bafybeiednzu62vskme5wpoj4bjjikeg3xovfpp4t7vxk5ty2jxdi4mv4bu +$ curl -H 'Accept: application/vnd.ipld.car' "http://127.0.0.1:8080/ipfs/bafybeiednzu62vskme5wpoj4bjjikeg3xovfpp4t7vxk5ty2jxdi4mv4bu" --output webui.car +$ ipfs dag import webui.car +$ ipfs dag stat bafybeiednzu62vskme5wpoj4bjjikeg3xovfpp4t7vxk5ty2jxdi4mv4bu --offline +Size: 27684934, NumBlocks: 394 +``` + +See also: + +- [Content Addressable aRchives (CAR / .car) Specifications](https://ipld.io/specs/transport/car/) +- [IANA media type](https://www.iana.org/assignments/media-types/media-types.xhtml) definitions: [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car), [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) +- [ipfs-car](https://www.npmjs.com/package/ipfs-car) - CLI tool for verifying and unpacking CAR files +- [go-car](https://github.com/ipld/go-car), [js-car](https://github.com/ipld/js-car/) โ€“ CAR libraries for GO and JS + +##### ๐ŸŽ Fast listing generation for huge directories + +*Added [`Gateway.FastDirIndexThreshold`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#gatewayfastdirindexthreshold) configuration, which allows for fast listings of big directories, without the linear slowdown caused by reading size metadata from child nodes.* + +As an example, the CID `bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm` represents UnixFS directory with over 10k (10100) of files. + +Opening it with go-ipfs 0.12 would require fetching size information of each file, which would take a long long time, most likely causing timeout in the browser or CDN, and introducing unnecessary burden on the gateway node. + +go-ipfs 0.13 opens it instantly, because the number of items is bigger than the default [`Gateway.FastDirIndexThreshold`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#gatewayfastdirindexthreshold) and only the root UnixFS node needs to be resolved before the HTML Dir Index is returned to the user. + +Notes: +- The default threshold is 100 items. +- Setting to 0 will enable fast listings for all directories. +- CLI users will note that this is equivalent to running `ipfs ls -s --size=false --resolve-type=false /ipfs/bafybeiggvykl7skb2ndlmacg2k5modvudocffxjesexlod2pfvg5yhwrqm`. Now the same speed is available on the gateways. + +##### ๐ŸŽซ Improved `Etag` and `If-None-Match` for bandwidth savings + +*Every response type has an unique [`Etag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) which can be used by the client or CDN to save bandwidth, as a gateway does not need to resend a full response if the content was not changed.* + +Gateway evaluates Etags sent by a client in [`If-None-Match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) and returns status code 304 (Not Modified) on strong or weak match ([RFC 7232, 2.3](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3)). + +##### โ›“๏ธ Added X-Ipfs-Roots for smarter HTTP caches + +`X-Ipfs-Roots` is now returned with every Gateway response. It is a way to indicate all CIDs required for resolving path segments from `X-Ipfs-Path`. Together, these two headers are meant to improve interop with existing HTTP software (load-balancers, caches, CDNs). + +This additional information allows HTTP caches and CDNs to make better decisions around cache invalidation: not just invalidate everything under specific IPNS website when the root changes, but do more fine-grained cache invalidation by detecting when only a specific subdirectory (branch of a [DAG](https://docs.ipfs.io/concepts/glossary/#dag)) changes. + +##### ๐ŸŒก๏ธ Added metrics per response type + +New metrics can be found at `/debug/metrics/prometheus` on the RPC API port (`127.0.0.1:5001` is the default): + +- `gw_first_content_block_get_latency_seconds` โ€“ the time until the first content block is received on GET from the gateway (no matter the content or response types) +- `gw_unixfs_file_get_duration_seconds` โ€“ the time to serve an entire UnixFS file from the gateway +- `gw_unixfs_gen_dir_listing_get_duration_seconds` โ€“ the time to serve a generated UnixFS HTML directory listing from the gateway +- `gw_car_stream_get_duration_seconds` โ€“ the time to GET an entire CAR stream from the gateway +- `gw_raw_block_get_duration_seconds` โ€“ The time to GET an entire raw Block from the gateway + + +#### ๐Ÿ•ต๏ธ OpenTelemetry tracing + +*Opt-in tracing support with many spans for tracing the duration of specific tasks performed by go-ipfs.* + +See [Tracing](https://github.com/ipfs/go-ipfs/blob/master/docs/environment-variables.md#tracing) for details. + +We will continue to add tracing instrumentation throughout IPFS subcomponents over time. + +##### How to use Jaeger UI for visual tracing? + +One can use the `jaegertracing/all-in-one` Docker image to run a full Jaeger stack and configure go-ipfs to publish traces to it (here, in an ephemeral container): + +```console +$ docker run --rm -it --name jaeger \ + -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ + -p 5775:5775/udp \ + -p 6831:6831/udp \ + -p 6832:6832/udp \ + -p 5778:5778 \ + -p 16686:16686 \ + -p 14268:14268 \ + -p 14250:14250 \ + -p 9411:9411 \ + jaegertracing/all-in-one +``` + +Then, in other terminal, start go-ipfs with Jaeger tracing enabled: +``` +$ OTEL_TRACES_EXPORTER=jaeger ipfs daemon +``` + +Finally, the [Jaeger UI](https://github.com/jaegertracing/jaeger-ui#readme) is available at http://localhost:16686 + +Below are examples of visual tracing for Gateway requests. (Note: this a preview how useful this insight is. Details may look different now, as we are constantly improving tracing annotations across the go-ipfs codebase.) + +| CAR | Block | File | Directory | +| ---- | ---- | ---- | ---- | +| ![2022-04-01_01-46](https://user-images.githubusercontent.com/157609/161167986-951d5c8c-9a5e-464d-bc20-81eb5ccbdc22.png) | ![block_2022-04-01_01-47](https://user-images.githubusercontent.com/157609/161167983-e8cac0ce-0575-4271-8cb8-4d44a0d5d786.png) | ![2022-04-01_01-49](https://user-images.githubusercontent.com/157609/161167978-e19aa44c-f5a4-45f4-b7c7-14c313ab1dee.png) | ![dir_2022-04-01_01-48](https://user-images.githubusercontent.com/157609/161167981-456ca52b-3e87-4042-916b-8db149071228.png) | + +#### ๐Ÿฉบ Built-in `ipfs diag profile` to ease debugging +The `diag profile` command has been expanded to include all information that was previously included in the `collect-profiles.sh` script, and the script has been removed. Profiles are now collected in parallel, so that profile collection is much faster. Specific profiles can also be selected for targeted debugging. + +See `ipfs diag profile --help` for more details. + +For general debugging information, see [the debug guide](https://github.com/ipfs/go-ipfs/blob/master/docs/debug-guide.md). + +#### ๐Ÿ”‘ Support for PEM/PKCS8 for key import/export + +It is now possible to import or export private keys wrapped in interoperable [PEM PKCS8](https://en.wikipedia.org/wiki/PKCS_8) by passing `--format=pem-pkcs8-cleartext` to `ipfs key import` and `export` commands. + +This improved interop allows for key generation outside of the IPFS node: + +```console +$ openssl genpkey -algorithm ED25519 > ed25519.pem +$ ipfs key import test-openssl -f pem-pkcs8-cleartext ed25519.pem +``` + +Or using external tools like the standard `openssl` to get a PEM file with the public key: +```console + $ ipfs key export testkey --format=pem-pkcs8-cleartext -o privkey.pem + $ openssl pkey -in privkey.pem -pubout > pubkey.pem +``` + +#### ๐Ÿงน Using standard IPLD codec names across the CLI/HTTP API + +This release makes necessary (breaking) changes in effort to use canonical codec names from [multicodec/table.csv](https://github.com/multiformats/multicodec/blob/master/table.csv). We also switched to CIDv1 in `block put`. The breaking changes are discussed above. + + +#### ๐Ÿณ Custom initialization for Docker + +Docker images published at https://hub.docker.com/r/ipfs/go-ipfs/ now support custom initialization by mounting scripts in the `/container-init.d` directory in the container. Scripts can set custom configuration using `ipfs config`, or otherwise customize the container before the daemon is started. + +Scripts are executed sequentially and in lexicographic order, before the IPFS daemon is started and after `ipfs init` is run and the swarm keys are copied (if the IPFS repo needs initialization). + +For more information, see: +- Documentation: [ Run IPFS inside Docker](https://docs.ipfs.io/how-to/run-ipfs-inside-docker/) +- Examples in [ipfs-shipyard/go-ipfs-docker-examples](https://github.com/ipfs-shipyard/go-ipfs-docker-examples). + +#### RPC API docs for experimental and deprecated commands + +https://docs.ipfs.io/reference/http/api/ now includes separate sections for _experimental_ and _deprecated_ commands. + +We also display a warning in the command line: + +```console +$ ipfs name pubsub state --help +WARNING: EXPERIMENTAL, command may change in future releases +``` + +#### Yamux over Mplex + +The more fully featured yamux stream multiplexer is now prioritized over mplex for outgoing connections. + +### Changelog + +
+Full Changelog +- github.com/ipfs/go-ipfs: + - feat: upgrade to go-libp2p-kad-dht@v0.16.0 (#9005) ([ipfs/go-ipfs#9005](https://github.com/ipfs/go-ipfs/pull/9005)) + - docs: fix typo in the `swarm/peering` help text + - feat: disable resource manager by default (#9003) ([ipfs/go-ipfs#9003](https://github.com/ipfs/go-ipfs/pull/9003)) + - fix: adjust rcmgr limits for accelerated DHT client rt refresh (#8982) ([ipfs/go-ipfs#8982](https://github.com/ipfs/go-ipfs/pull/8982)) + - fix(ci): make go-ipfs-as-a-library work without external peers (#8978) ([ipfs/go-ipfs#8978](https://github.com/ipfs/go-ipfs/pull/8978)) + - feat: log when resource manager limits are exceeded (#8980) ([ipfs/go-ipfs#8980](https://github.com/ipfs/go-ipfs/pull/8980)) + - fix: JS caching via Access-Control-Expose-Headers (#8984) ([ipfs/go-ipfs#8984](https://github.com/ipfs/go-ipfs/pull/8984)) + - docs: fix abstractions typo + - fix: hanging goroutine in get fileArchive handler + - fix(node/libp2p): disable rcmgr checkImplicitDefaults ([ipfs/go-ipfs#8965](https://github.com/ipfs/go-ipfs/pull/8965)) + - pubsub multibase encoding (#8933) ([ipfs/go-ipfs#8933](https://github.com/ipfs/go-ipfs/pull/8933)) + - 'pin rm' helptext: rewrite description as object is not removed from local storage (immediately) ([ipfs/go-ipfs#8947](https://github.com/ipfs/go-ipfs/pull/8947)) + - ([ipfs/go-ipfs#8934](https://github.com/ipfs/go-ipfs/pull/8934)) + - Add instructions to resolve repo migration error (#8946) ([ipfs/go-ipfs#8946](https://github.com/ipfs/go-ipfs/pull/8946)) + - fix: use path instead of filepath for asset embeds to support Windows + - Release v0.13.0-rc1 + - docs: v0.13.0 changelog ([ipfs/go-ipfs#8941](https://github.com/ipfs/go-ipfs/pull/8941)) + - chore: build with go 1.18.1 ([ipfs/go-ipfs#8932](https://github.com/ipfs/go-ipfs/pull/8932)) + - docs(tracing): update env var docs for new tracing env vars + - feat: enable Resource Manager by default + - chore: Update test/dependencies to match go-ipfs dependencies. (#8928) ([ipfs/go-ipfs#8928](https://github.com/ipfs/go-ipfs/pull/8928)) + - chore: fix linting errors (#8930) ([ipfs/go-ipfs#8930](https://github.com/ipfs/go-ipfs/pull/8930)) + - docs: Swarm.ResourceMgr.Limits + - feat: EnableHolePunching by default ([ipfs/go-ipfs#8748](https://github.com/ipfs/go-ipfs/pull/8748)) + - ci: add more golang strictness checks ([ipfs/go-ipfs#8931](https://github.com/ipfs/go-ipfs/pull/8931)) + - feat(gateway): Gateway.FastDirIndexThreshold (#8853) ([ipfs/go-ipfs#8853](https://github.com/ipfs/go-ipfs/pull/8853)) + - docs: replace all git.io links with their actual URLs + - feat: relay v2 discovery (go-libp2p v0.19.0) (#8868) ([ipfs/go-ipfs#8868](https://github.com/ipfs/go-ipfs/pull/8868)) + - fix(cmds): add: reject files with different import dir + - chore: mark 'log tail' experimental (#8912) ([ipfs/go-ipfs#8912](https://github.com/ipfs/go-ipfs/pull/8912)) + - feat: persist limits to Swarm.ResourceMgr.Limits (#8901) ([ipfs/go-ipfs#8901](https://github.com/ipfs/go-ipfs/pull/8901)) + - fix: build after Go 1.17 and Prometheus upgrades (#8916) ([ipfs/go-ipfs#8916](https://github.com/ipfs/go-ipfs/pull/8916)) + - feat(tracing): use OpenTelemetry env vars where possible (#8875) ([ipfs/go-ipfs#8875](https://github.com/ipfs/go-ipfs/pull/8875)) + - feat(cmds): allow to set the configuration file path ([ipfs/go-ipfs#8634](https://github.com/ipfs/go-ipfs/pull/8634)) + - chore: deprecate /api/v0/dns (#8893) ([ipfs/go-ipfs#8893](https://github.com/ipfs/go-ipfs/pull/8893)) + - fix(cmds): CIDv1 and correct multicodecs in 'block put' and 'cid codecs' (#8568) ([ipfs/go-ipfs#8568](https://github.com/ipfs/go-ipfs/pull/8568)) + - feat(gw): improved If-None-Match support (#8891) ([ipfs/go-ipfs#8891](https://github.com/ipfs/go-ipfs/pull/8891)) + - Update Go version to 1.17 (#8815) ([ipfs/go-ipfs#8815](https://github.com/ipfs/go-ipfs/pull/8815)) + - chore(gw): extract logical functions to improve readability (#8885) ([ipfs/go-ipfs#8885](https://github.com/ipfs/go-ipfs/pull/8885)) + - feat(docker): /container-init.d for advanced initialization (#6577) ([ipfs/go-ipfs#6577](https://github.com/ipfs/go-ipfs/pull/6577)) + - feat: port collect-profiles.sh to 'ipfs diag profile' (#8786) ([ipfs/go-ipfs#8786](https://github.com/ipfs/go-ipfs/pull/8786)) + - fix: assets: correctly use the argument err in the WalkDirFunc Hashing Files + - Change `assets.Asset` from a `func` to the embed.FS + - Remove gobindata + - fix: fix context plumbing in gateway handlers (#8871) ([ipfs/go-ipfs#8871](https://github.com/ipfs/go-ipfs/pull/8871)) + - fix(gw): missing return if dir fails to finalize (#8806) ([ipfs/go-ipfs#8806](https://github.com/ipfs/go-ipfs/pull/8806)) + - fix(gw): update metrics only when payload data sent (#8827) ([ipfs/go-ipfs#8827](https://github.com/ipfs/go-ipfs/pull/8827)) + - Merge branch 'release' + - feat: detect changes in go-libp2p-resource-manager (#8857) ([ipfs/go-ipfs#8857](https://github.com/ipfs/go-ipfs/pull/8857)) + - feat: opt-in Swarm.ResourceMgr (go-libp2p v0.18) (#8680) ([ipfs/go-ipfs#8680](https://github.com/ipfs/go-ipfs/pull/8680)) + - feat(cmds): add support for CAR v2 imports (#8854) ([ipfs/go-ipfs#8854](https://github.com/ipfs/go-ipfs/pull/8854)) + - docs(logging): environment variables (#8833) ([ipfs/go-ipfs#8833](https://github.com/ipfs/go-ipfs/pull/8833)) + - fix: unknown fetcher type error (#8830) ([ipfs/go-ipfs#8830](https://github.com/ipfs/go-ipfs/pull/8830)) + - chore: deprecate tar commands (#8849) ([ipfs/go-ipfs#8849](https://github.com/ipfs/go-ipfs/pull/8849)) + - chore: bump go-ipld-format v0.4.0 and fix related sharness tests ([ipfs/go-ipfs#8838](https://github.com/ipfs/go-ipfs/pull/8838)) + - feat: add basic gateway tracing (#8595) ([ipfs/go-ipfs#8595](https://github.com/ipfs/go-ipfs/pull/8595)) + - fix(cli): ipfs add with multiple files of same name (#8493) ([ipfs/go-ipfs#8493](https://github.com/ipfs/go-ipfs/pull/8493)) + - fix(gw): validate requested CAR version (#8835) ([ipfs/go-ipfs#8835](https://github.com/ipfs/go-ipfs/pull/8835)) + - feat: re-enable docker sharness tests (#8808) ([ipfs/go-ipfs#8808](https://github.com/ipfs/go-ipfs/pull/8808)) + - docs: gateway.md (#8825) ([ipfs/go-ipfs#8825](https://github.com/ipfs/go-ipfs/pull/8825)) + - fix(core/commands): do not cache config (#8824) ([ipfs/go-ipfs#8824](https://github.com/ipfs/go-ipfs/pull/8824)) + - remove unused import (#8787) ([ipfs/go-ipfs#8787](https://github.com/ipfs/go-ipfs/pull/8787)) + - feat(cmds): document deprecated RPC API commands (#8802) ([ipfs/go-ipfs#8802](https://github.com/ipfs/go-ipfs/pull/8802)) + - fix(fsrepo): deep merge when setting config ([ipfs/go-ipfs#8793](https://github.com/ipfs/go-ipfs/pull/8793)) + - feat: add gateway histogram metrics (#8443) ([ipfs/go-ipfs#8443](https://github.com/ipfs/go-ipfs/pull/8443)) + - ErrNotFound changes: bubble tagged libraries. ([ipfs/go-ipfs#8803](https://github.com/ipfs/go-ipfs/pull/8803)) + - Fix typos + ([ipfs/go-ipfs#8757](https://github.com/ipfs/go-ipfs/pull/8757)) + - feat(gateway): Block and CAR response formats (#8758) ([ipfs/go-ipfs#8758](https://github.com/ipfs/go-ipfs/pull/8758)) + - fix: allow ipfs-companion browser extension to access RPC API (#8690) ([ipfs/go-ipfs#8690](https://github.com/ipfs/go-ipfs/pull/8690)) + - fix(core/node): unwrap fx error in node construction ([ipfs/go-ipfs#8638](https://github.com/ipfs/go-ipfs/pull/8638)) + - Update PATCH_RELEASE_TEMPLATE.md + - feat: add full goroutine stack dump (#8790) ([ipfs/go-ipfs#8790](https://github.com/ipfs/go-ipfs/pull/8790)) + - feat(cmds): extend block size check for dag|block put (#8751) ([ipfs/go-ipfs#8751](https://github.com/ipfs/go-ipfs/pull/8751)) + - feat: add endpoint for enabling block profiling (#8469) ([ipfs/go-ipfs#8469](https://github.com/ipfs/go-ipfs/pull/8469)) + - fix(cmds): option for progress bar in cat/get (#8686) ([ipfs/go-ipfs#8686](https://github.com/ipfs/go-ipfs/pull/8686)) + - docs: note the default reprovider strategy as all (#8603) ([ipfs/go-ipfs#8603](https://github.com/ipfs/go-ipfs/pull/8603)) + - fix: listen on loopback for API and gateway ports in docker-compose.yaml (#8773) ([ipfs/go-ipfs#8773](https://github.com/ipfs/go-ipfs/pull/8773)) + - fix(discovery): fix daemon not starting due to mdns startup failure (#8704) ([ipfs/go-ipfs#8704](https://github.com/ipfs/go-ipfs/pull/8704)) + ([ipfs/go-ipfs#8756](https://github.com/ipfs/go-ipfs/pull/8756)) + - feat: ipfs-webui v2.15 (#8712) ([ipfs/go-ipfs#8712](https://github.com/ipfs/go-ipfs/pull/8712)) + - feat: X-Ipfs-Roots for smarter HTTP caches (#8720) ([ipfs/go-ipfs#8720](https://github.com/ipfs/go-ipfs/pull/8720)) + - chore: add instructions for Chocolatey release + - fix prioritization of stream muxers ([ipfs/go-ipfs#8750](https://github.com/ipfs/go-ipfs/pull/8750)) + - fix(cmds/keystore): do not allow to import keys we don't generate (#8733) ([ipfs/go-ipfs#8733](https://github.com/ipfs/go-ipfs/pull/8733)) + - docs: add Internal.UnixFSShardingSizeThreshold (#8723) ([ipfs/go-ipfs#8723](https://github.com/ipfs/go-ipfs/pull/8723)) + - feat(cmd): add silent option for repo gc (#7147) ([ipfs/go-ipfs#7147](https://github.com/ipfs/go-ipfs/pull/7147)) + - docs(changelog): update v0.12.0 release notes + - Merge branch 'release' + - fix: installation without sudo (#8715) ([ipfs/go-ipfs#8715](https://github.com/ipfs/go-ipfs/pull/8715)) + - Fix typos (#8726) ([ipfs/go-ipfs#8726](https://github.com/ipfs/go-ipfs/pull/8726)) + - fix(build): Recognize Go Beta versions in makefile (#8677) ([ipfs/go-ipfs#8677](https://github.com/ipfs/go-ipfs/pull/8677)) + - chore(cmds): encapsulate ipfs rm logic in another function (#8574) ([ipfs/go-ipfs#8574](https://github.com/ipfs/go-ipfs/pull/8574)) + - feat: warn user when 'pin remote add' while offline (#8621) ([ipfs/go-ipfs#8621](https://github.com/ipfs/go-ipfs/pull/8621)) + - chore(gateway): debug logging for the http requests (#8518) ([ipfs/go-ipfs#8518](https://github.com/ipfs/go-ipfs/pull/8518)) + - docker: build for arm cpu (#8633) ([ipfs/go-ipfs#8633](https://github.com/ipfs/go-ipfs/pull/8633)) + - feat: refactor Fetcher interface used for downloading migrations (#8728) ([ipfs/go-ipfs#8728](https://github.com/ipfs/go-ipfs/pull/8728)) + - feat: log multifetcher errors + - docs: optionalInteger|String|Duration (#8729) ([ipfs/go-ipfs#8729](https://github.com/ipfs/go-ipfs/pull/8729)) + - feat: DNS.MaxCacheTTL for DNS-over-HTTPS resolvers (#8615) ([ipfs/go-ipfs#8615](https://github.com/ipfs/go-ipfs/pull/8615)) + - feat(cmds): ipfs id: support --offline option (#8626) ([ipfs/go-ipfs#8626](https://github.com/ipfs/go-ipfs/pull/8626)) + - feat(cmds): add cleartext PEM/PKCS8 for key import/export (#8616) ([ipfs/go-ipfs#8616](https://github.com/ipfs/go-ipfs/pull/8616)) + - docs: update badger section in config.md (#8662) ([ipfs/go-ipfs#8662](https://github.com/ipfs/go-ipfs/pull/8662)) + - docs: fix typo + - Adding PowerShell to Minimal Go Installation + - Fixed typos in docs/config.md + - docs: add Snap note about customizing IPFS_PATH (#8584) ([ipfs/go-ipfs#8584](https://github.com/ipfs/go-ipfs/pull/8584)) + - Fix typo ([ipfs/go-ipfs#8625](https://github.com/ipfs/go-ipfs/pull/8625)) + - chore: update version to v0.13.0-dev +- github.com/ipfs/go-bitswap (v0.5.1 -> v0.6.0): + - v0.6.0 + - Use ipld.ErrNotFound + - feat: add peer block filter option (#549) ([ipfs/go-bitswap#549](https://github.com/ipfs/go-bitswap/pull/549)) + - configurable target message size ([ipfs/go-bitswap#546](https://github.com/ipfs/go-bitswap/pull/546)) +- github.com/ipfs/go-blockservice (v0.2.1 -> v0.3.0): + - v0.3.0 + - s/log/logger + - Use ipld.ErrNotFound instead of ErrNotFound +- github.com/ipfs/go-cid (v0.1.0 -> v0.2.0): + - fix: remove invalid multicodec2string mappings (#137) ([ipfs/go-cid#137](https://github.com/ipfs/go-cid/pull/137)) + - sync: update CI config files (#136) ([ipfs/go-cid#136](https://github.com/ipfs/go-cid/pull/136)) + - Benchmark existing ways to check for `IDENTITY` CIDs + - avoid double alloc in NewCidV1 + - sync: update CI config files ([ipfs/go-cid#131](https://github.com/ipfs/go-cid/pull/131)) +- github.com/ipfs/go-cidutil (v0.0.2 -> v0.1.0): + ([ipfs/go-cidutil#36](https://github.com/ipfs/go-cidutil/pull/36)) + - sync: update CI config files ([ipfs/go-cidutil#35](https://github.com/ipfs/go-cidutil/pull/35)) + - sync: update CI config files (#34) ([ipfs/go-cidutil#34](https://github.com/ipfs/go-cidutil/pull/34)) + - fix staticcheck ([ipfs/go-cidutil#31](https://github.com/ipfs/go-cidutil/pull/31)) + - add license file so it can be found by go-licenses ([ipfs/go-cidutil#27](https://github.com/ipfs/go-cidutil/pull/27)) + - test: fix for base32 switch ([ipfs/go-cidutil#16](https://github.com/ipfs/go-cidutil/pull/16)) + - doc: add a lead maintainer +- github.com/ipfs/go-filestore (v1.1.0 -> v1.2.0): + - v1.2.0 + - refactor: follow the happy left practice in Filestore.DeleteBlock + - Use ipld.ErrNotFound +- github.com/ipfs/go-graphsync (v0.11.0 -> v0.13.1): + - docs(CHANGELOG): update for v0.13.1 + - feat(ipld): wrap bindnode with panic protection (#368) ([ipfs/go-graphsync#368](https://github.com/ipfs/go-graphsync/pull/368)) + - docs(CHANGELOG): update for v0.13.0 (#366) ([ipfs/go-graphsync#366](https://github.com/ipfs/go-graphsync/pull/366)) + - fix(impl): delete file + - Minimal alternate metadata type support (#365) ([ipfs/go-graphsync#365](https://github.com/ipfs/go-graphsync/pull/365)) + - Fix unixfs fetch (#364) ([ipfs/go-graphsync#364](https://github.com/ipfs/go-graphsync/pull/364)) + - [Feature] UUIDs, protocol versioning, v2 protocol w/ dag-cbor messaging (#332) ([ipfs/go-graphsync#332](https://github.com/ipfs/go-graphsync/pull/332)) + - feat(CHANGELOG): update for v0.12.0 + - Use do not send blocks for pause/resume & prevent processing of blocks on cancelled requests (#333) ([ipfs/go-graphsync#333](https://github.com/ipfs/go-graphsync/pull/333)) + - Support unixfs reification in default linksystem (#329) ([ipfs/go-graphsync#329](https://github.com/ipfs/go-graphsync/pull/329)) + - Don't run hooks on blocks we didn't have (#331) ([ipfs/go-graphsync#331](https://github.com/ipfs/go-graphsync/pull/331)) + - feat(responsemanager): trace full messages via links to responses (#325) ([ipfs/go-graphsync#325](https://github.com/ipfs/go-graphsync/pull/325)) + - chore(requestmanager): rename processResponses internals for consistency (#328) ([ipfs/go-graphsync#328](https://github.com/ipfs/go-graphsync/pull/328)) + - Response message tracing (#327) ([ipfs/go-graphsync#327](https://github.com/ipfs/go-graphsync/pull/327)) + - fix(testutil): fix tracing span collection (#324) ([ipfs/go-graphsync#324](https://github.com/ipfs/go-graphsync/pull/324)) + - docs(CHANGELOG): update for v0.11.5 release + - feat(requestmanager): add tracing for response messages & block processing (#322) ([ipfs/go-graphsync#322](https://github.com/ipfs/go-graphsync/pull/322)) + - ipldutil: simplify state synchronization, add docs (#300) ([ipfs/go-graphsync#300](https://github.com/ipfs/go-graphsync/pull/300)) + - docs(CHANGELOG): update for v0.11.4 release + - Scrub response errors (#320) ([ipfs/go-graphsync#320](https://github.com/ipfs/go-graphsync/pull/320)) + - fix(responsemanager): remove unused maxInProcessRequests parameter (#319) ([ipfs/go-graphsync#319](https://github.com/ipfs/go-graphsync/pull/319)) + - feat(responsemanager): allow ctx augmentation via queued request hook + - make go test with coverpkg=./... + - docs(CHANGELOG): update for v0.11.3 + - Merge tag 'v0.10.9' + - feat: add basic tracing for responses (#291) ([ipfs/go-graphsync#291](https://github.com/ipfs/go-graphsync/pull/291)) + - fix(impl): remove accidental legacy field (#310) ([ipfs/go-graphsync#310](https://github.com/ipfs/go-graphsync/pull/310)) + - docs(CHANGELOG): update for v0.11.2 + - Merge branch 'release/v0.10.8' + - feat(taskqueue): fix race on peer state gather (#303) ([ipfs/go-graphsync#303](https://github.com/ipfs/go-graphsync/pull/303)) + - feat(responsemanager): clarify response completion (#304) ([ipfs/go-graphsync#304](https://github.com/ipfs/go-graphsync/pull/304)) + - docs(CHANGELOG): update for v0.11.1 + - Merge branch 'release/v0.10.7' + - Expose task queue diagnostics (#302) ([ipfs/go-graphsync#302](https://github.com/ipfs/go-graphsync/pull/302)) + - chore: short-circuit unnecessary message processing + - Add a bit of logging (#301) ([ipfs/go-graphsync#301](https://github.com/ipfs/go-graphsync/pull/301)) + - Peer Stats function (#298) ([ipfs/go-graphsync#298](https://github.com/ipfs/go-graphsync/pull/298)) + - fix: use sync.Cond to handle no-task blocking wait (#299) ([ipfs/go-graphsync#299](https://github.com/ipfs/go-graphsync/pull/299)) + - ipldutil: use chooser APIs from dagpb and basicnode (#292) ([ipfs/go-graphsync#292](https://github.com/ipfs/go-graphsync/pull/292)) + - testutil/chaintypes: simplify maintenance of codegen (#294) ([ipfs/go-graphsync#294](https://github.com/ipfs/go-graphsync/pull/294)) + - fix(test): increase 1s timeouts to 2s for slow CI (#289) ([ipfs/go-graphsync#289](https://github.com/ipfs/go-graphsync/pull/289)) + - docs(tests): document tracing test helper utilities + - feat: add basic OT tracing for incoming requests + - fix(responsemanager): make fix more global + - fix(responsemanager): fix flaky tests + - feat: add WorkerTaskQueue#WaitForNoActiveTasks() for tests (#284) ([ipfs/go-graphsync#284](https://github.com/ipfs/go-graphsync/pull/284)) +- github.com/ipfs/go-ipfs-blockstore (v1.1.2 -> v1.2.0): + - v0.2.0 ([ipfs/go-ipfs-blockstore#98](https://github.com/ipfs/go-ipfs-blockstore/pull/98)) + - s/log/logger + - Use ipld.ErrNotFound for NotFound errors +- github.com/ipfs/go-ipfs-cmds (v0.6.0 -> v0.8.1): + - fix(cli/parse): extract dir before name ([ipfs/go-ipfs-cmds#230](https://github.com/ipfs/go-ipfs-cmds/pull/230)) + - Version 0.8.0 ([ipfs/go-ipfs-cmds#228](https://github.com/ipfs/go-ipfs-cmds/pull/228)) + - fix(cli): use NewSliceDirectory for duplicate file paths ([ipfs/go-ipfs-cmds#220](https://github.com/ipfs/go-ipfs-cmds/pull/220)) + - chore: release v0.7.0 ([ipfs/go-ipfs-cmds#227](https://github.com/ipfs/go-ipfs-cmds/pull/227)) + - feat(Command): add status for the helptext ([ipfs/go-ipfs-cmds#225](https://github.com/ipfs/go-ipfs-cmds/pull/225)) + - allow header and set header in client ([ipfs/go-ipfs-cmds#226](https://github.com/ipfs/go-ipfs-cmds/pull/226)) + - sync: update CI config files (#221) ([ipfs/go-ipfs-cmds#221](https://github.com/ipfs/go-ipfs-cmds/pull/221)) + - fix: chanResponseEmitter cancel being ineffective + - add: tests for postrun execution + - fix: postrun's run condition in Execute + - fix: exec deadlock when emitter is not Typer intf + - sync: update CI config files ([ipfs/go-ipfs-cmds#207](https://github.com/ipfs/go-ipfs-cmds/pull/207)) + - fix: preserve windows file paths ([ipfs/go-ipfs-cmds#214](https://github.com/ipfs/go-ipfs-cmds/pull/214)) + - Resolve `staticcheck` issue in prep for unified CI ([ipfs/go-ipfs-cmds#212](https://github.com/ipfs/go-ipfs-cmds/pull/212)) +- github.com/ipfs/go-ipfs-exchange-offline (v0.1.1 -> v0.2.0): + - v0.2.0 + - Improve NotFound error description +- github.com/ipfs/go-ipfs-files (v0.0.9 -> v0.1.1): + - Release v0.1.1 + - fix: add dragonfly build option for filewriter flags + - fix: add freebsd build option for filewriter flags + - Release v0.1.0 + - docs: fix community CONTRIBUTING.md link (#45) ([ipfs/go-ipfs-files#45](https://github.com/ipfs/go-ipfs-files/pull/45)) + - chore(filewriter): cleanup writes (#43) ([ipfs/go-ipfs-files#43](https://github.com/ipfs/go-ipfs-files/pull/43)) + - sync: update CI config files (#44) ([ipfs/go-ipfs-files#44](https://github.com/ipfs/go-ipfs-files/pull/44)) +- github.com/ipfs/go-ipld-format (v0.2.0 -> v0.4.0): + - chore: release version v0.4.0 + - feat: use new more clearer format in ErrNotFound + - chore: bump version to 0.3.1 + - fix: make Undef ErrNotFound string consistent with Def version + - Version 0.3.0 + - ErrNotFound: change error string ([ipfs/go-ipld-format#69](https://github.com/ipfs/go-ipld-format/pull/69)) + - Revert "Revert "Add IsErrNotFound() method"" ([ipfs/go-ipld-format#68](https://github.com/ipfs/go-ipld-format/pull/68)) + - sync: update CI config files (#67) ([ipfs/go-ipld-format#67](https://github.com/ipfs/go-ipld-format/pull/67)) + - ignore statticheck error for EndOfDag ([ipfs/go-ipld-format#62](https://github.com/ipfs/go-ipld-format/pull/62)) + - remove Makefile ([ipfs/go-ipld-format#59](https://github.com/ipfs/go-ipld-format/pull/59)) + - fix staticcheck ([ipfs/go-ipld-format#60](https://github.com/ipfs/go-ipld-format/pull/60)) + - Allowing custom NavigableNode implementations ([ipfs/go-ipld-format#58](https://github.com/ipfs/go-ipld-format/pull/58)) +- github.com/ipfs/go-ipld-legacy (v0.1.0 -> v0.1.1): + - feat(node): add json.Marshaller method ([ipfs/go-ipld-legacy#7](https://github.com/ipfs/go-ipld-legacy/pull/7)) +- github.com/ipfs/go-log/v2 (v2.3.0 -> v2.5.1): + - feat: add logger option to skip a number of stack frames ([ipfs/go-log#132](https://github.com/ipfs/go-log/pull/132)) + - release v2.5.0 (#131) ([ipfs/go-log#131](https://github.com/ipfs/go-log/pull/131)) + - config inspection (#129) ([ipfs/go-log#129](https://github.com/ipfs/go-log/pull/129)) + - release v2.4.0 (#127) ([ipfs/go-log#127](https://github.com/ipfs/go-log/pull/127)) + - sync: update CI config files (#125) ([ipfs/go-log#125](https://github.com/ipfs/go-log/pull/125)) + - fix: cannot call SetPrimaryCore after using a Tee logger ([ipfs/go-log#121](https://github.com/ipfs/go-log/pull/121)) + - Document environment variables ([ipfs/go-log#120](https://github.com/ipfs/go-log/pull/120)) + - sync: update CI config files (#119) ([ipfs/go-log#119](https://github.com/ipfs/go-log/pull/119)) + - Add WithStacktrace untility ([ipfs/go-log#118](https://github.com/ipfs/go-log/pull/118)) + - In addition to StdOut/Err check the outfile for TTYness ([ipfs/go-log#117](https://github.com/ipfs/go-log/pull/117)) +- github.com/ipfs/go-merkledag (v0.5.1 -> v0.6.0): + - v0.6.0 + - Improve ErrNotFound +- github.com/ipfs/go-namesys (v0.4.0 -> v0.5.0): + - Version 0.5.0 + - fix: CIDv1 error with go-libp2p 0.19 (#32) ([ipfs/go-namesys#32](https://github.com/ipfs/go-namesys/pull/32)) + - feat: add tracing (#30) ([ipfs/go-namesys#30](https://github.com/ipfs/go-namesys/pull/30)) + - fix(publisher): fix garbled code output (#28) ([ipfs/go-namesys#28](https://github.com/ipfs/go-namesys/pull/28)) +- github.com/ipfs/go-path (v0.2.1 -> v0.3.0): + - Release v0.3.0 ([ipfs/go-path#55](https://github.com/ipfs/go-path/pull/55)) + - Resolver: convert to interface. ([ipfs/go-path#53](https://github.com/ipfs/go-path/pull/53)) + - Release v0.2.2 (#52) ([ipfs/go-path#52](https://github.com/ipfs/go-path/pull/52)) + - chore: improve error message for invalid ipfs paths ([ipfs/go-path#51](https://github.com/ipfs/go-path/pull/51)) +- github.com/ipfs/go-peertaskqueue (v0.7.0 -> v0.7.1): + - Add topic inspector ([ipfs/go-peertaskqueue#20](https://github.com/ipfs/go-peertaskqueue/pull/20)) +- github.com/ipfs/go-pinning-service-http-client (v0.1.0 -> v0.1.1): + - chore: release v0.1.1 + - fix: error handling while enumerating pins + - sync: update CI config files (#15) ([ipfs/go-pinning-service-http-client#15](https://github.com/ipfs/go-pinning-service-http-client/pull/15)) + - Resolve lint issues prior to CI integration +- github.com/ipfs/go-unixfsnode (v1.1.3 -> v1.4.0): + - 1.4.0 release ([ipfs/go-unixfsnode#29](https://github.com/ipfs/go-unixfsnode/pull/29)) + - Partial file test ([ipfs/go-unixfsnode#26](https://github.com/ipfs/go-unixfsnode/pull/26)) + - Add unixfs to UnixFS path selector tail ([ipfs/go-unixfsnode#28](https://github.com/ipfs/go-unixfsnode/pull/28)) + - release v1.3.0 ([ipfs/go-unixfsnode#25](https://github.com/ipfs/go-unixfsnode/pull/25)) + - add AsLargeBytes support to unixfs files (#24) ([ipfs/go-unixfsnode#24](https://github.com/ipfs/go-unixfsnode/pull/24)) + - fix: add extra test to span the shard/no-shard boundary + - fix: more Tsize fixes, fix HAMT and make it match go-unixfs output + - fix: encode Tsize correctly everywhere (using wraped LinkSystem) + - docs(version): tag 1.2.0 + - Update deps for ADL selectors ([ipfs/go-unixfsnode#20](https://github.com/ipfs/go-unixfsnode/pull/20)) + - add license (#17) ([ipfs/go-unixfsnode#17](https://github.com/ipfs/go-unixfsnode/pull/17)) + - handle empty files (#15) ([ipfs/go-unixfsnode#15](https://github.com/ipfs/go-unixfsnode/pull/15)) + - Add ADL/single-node-view of a full unixFS file. (#14) ([ipfs/go-unixfsnode#14](https://github.com/ipfs/go-unixfsnode/pull/14)) + - sync: update CI config files (#13) ([ipfs/go-unixfsnode#13](https://github.com/ipfs/go-unixfsnode/pull/13)) + - Add builder for unixfs dags (#12) ([ipfs/go-unixfsnode#12](https://github.com/ipfs/go-unixfsnode/pull/12)) +- github.com/ipfs/interface-go-ipfs-core (v0.5.2 -> v0.7.0): + - refactor(block): CIDv1 and BlockPutSettings CidPrefix (#80) ([ipfs/interface-go-ipfs-core#80](https://github.com/ipfs/interface-go-ipfs-core/pull/80)) + - chore: release v0.6.2 + - fix: use IPLD.ErrNotFound instead of string comparison in tests + - fix: document error (#74) ([ipfs/interface-go-ipfs-core#74](https://github.com/ipfs/interface-go-ipfs-core/pull/74)) + - version: release 0.6.1 + - v0.6.0 + - Update tests to use ipld.IsNotFound to check for notfound errors + - sync: update CI config files (#79) ([ipfs/interface-go-ipfs-core#79](https://github.com/ipfs/interface-go-ipfs-core/pull/79)) +- github.com/ipld/go-codec-dagpb (v1.3.2 -> v1.4.0): + - bump to v1.4.0 given that we updated ipld-prime + - add a decode-then-encode roundtrip fuzzer + - 1.3.1 + - fix: use protowire for Links bytes decoding + - delete useless code + - sync: update CI config files (#33) ([ipld/go-codec-dagpb#33](https://github.com/ipld/go-codec-dagpb/pull/33)) +- github.com/ipld/go-ipld-prime (v0.14.2 -> v0.16.0): + - mark v0.16.0 + - node/bindnode: enforce pointer requirement for nullable maps + - Implement WalkTransforming traversal (#376) ([ipld/go-ipld-prime#376](https://github.com/ipld/go-ipld-prime/pull/376)) + - docs(datamodel): add comment to LargeBytesNode + - Add partial-match traversal of large bytes (#375) ([ipld/go-ipld-prime#375](https://github.com/ipld/go-ipld-prime/pull/375)) + - Implement option to start traversals at a path ([ipld/go-ipld-prime#358](https://github.com/ipld/go-ipld-prime/pull/358)) + - add top-level "go value with schema" example + - Support optional `LargeBytesNode` interface (#372) ([ipld/go-ipld-prime#372](https://github.com/ipld/go-ipld-prime/pull/372)) + - node/bindnode: support pointers to datamodel.Node to bind with Any + - fix(bindnode): tuple struct iterator should handle absent fields properly + - node/bindnode: make AssignNode work at the repr level + - node/bindnode: add support for unsigned integers + - node/bindnode: cover even more edge case panics + - node/bindnode: polish some more AsT panics + - schema/dmt: stop using a fake test to generate code ([ipld/go-ipld-prime#356](https://github.com/ipld/go-ipld-prime/pull/356)) + - schema: remove one review note; add another. + - fix: minor EncodedLength fixes, add tests to fully exercise + - feat: add dagcbor.EncodedLength(Node) to calculate length without encoding + - chore: rename Garbage() to Generate() + - fix: minor garbage nits + - fix: Garbage() takes rand parameter, tweak algorithms, improve docs + - feat: add Garbage() Node generator + - node/bindnode: introduce an assembler that always errors + - node/bindnode: polish panics on invalid AssignT calls + - datamodel: don't panic when stringifying an empty KindSet + - node/bindnode: start using ipld.LoadSchema APIs + - selectors: fix for edge case around recursion clauses with an immediate edge. ([ipld/go-ipld-prime#334](https://github.com/ipld/go-ipld-prime/pull/334)) + - node/bindnode: improve support for pointer types + - node/bindnode: subtract all absents in Length at the repr level + - fix(codecs): error when encoding maps whose lengths don't match entry count + - schema: avoid alloc and copy in Struct and Enum methods + - node/bindnode: allow mapping int-repr enums with Go integers + - schema,node/bindnode: add support for Any + - signaling ADLs in selectors (#301) ([ipld/go-ipld-prime#301](https://github.com/ipld/go-ipld-prime/pull/301)) + - node/bindnode: add support for enums + - schema/...: add support for enum int representations + - node/bindnode: allow binding cidlink.Link to links + - Update to context datastores (#312) ([ipld/go-ipld-prime#312](https://github.com/ipld/go-ipld-prime/pull/312)) + - schema: add support for struct tuple reprs + - Allow parsing padding in dag-json bytes fields (#309) ([ipld/go-ipld-prime#309](https://github.com/ipld/go-ipld-prime/pull/309)) +- github.com/libp2p/go-doh-resolver (v0.3.1 -> v0.4.0): + - Release v0.4.0 (#16) ([libp2p/go-doh-resolver#16](https://github.com/libp2p/go-doh-resolver/pull/16)) + - sync: update CI config files (#14) ([libp2p/go-doh-resolver#14](https://github.com/libp2p/go-doh-resolver/pull/14)) + - Add a max TTL for cached entries ([libp2p/go-doh-resolver#12](https://github.com/libp2p/go-doh-resolver/pull/12)) + - Perform test locally instead of using a live dns resolution ([libp2p/go-doh-resolver#13](https://github.com/libp2p/go-doh-resolver/pull/13)) + - sync: update CI config files (#7) ([libp2p/go-doh-resolver#7](https://github.com/libp2p/go-doh-resolver/pull/7)) + - fix staticcheck ([libp2p/go-doh-resolver#6](https://github.com/libp2p/go-doh-resolver/pull/6)) +- github.com/libp2p/go-libp2p (v0.16.0 -> v0.19.4): + - update go-yamux to v3.1.2, release v0.19.4 (#1590) ([libp2p/go-libp2p#1590](https://github.com/libp2p/go-libp2p/pull/1590)) + - update quic-go to v0.27.1, release v0.19.3 (#1518) ([libp2p/go-libp2p#1518](https://github.com/libp2p/go-libp2p/pull/1518)) + - release v0.19.2 + - holepunch: fix incorrect message type for the SYNC message (#1478) ([libp2p/go-libp2p#1478](https://github.com/libp2p/go-libp2p/pull/1478)) + - fix race condition in holepunch service, release v0.19.1 ([libp2p/go-libp2p#1474](https://github.com/libp2p/go-libp2p/pull/1474)) + - release v0.19.0 (#1408) ([libp2p/go-libp2p#1408](https://github.com/libp2p/go-libp2p/pull/1408)) + - Close resource manager when host closes (#1343) ([libp2p/go-libp2p#1343](https://github.com/libp2p/go-libp2p/pull/1343)) + - fix flaky reconnect test (#1406) ([libp2p/go-libp2p#1406](https://github.com/libp2p/go-libp2p/pull/1406)) + - make sure to not oversubscribe to relays (#1404) ([libp2p/go-libp2p#1404](https://github.com/libp2p/go-libp2p/pull/1404)) + - rewrite the reconnect test (#1399) ([libp2p/go-libp2p#1399](https://github.com/libp2p/go-libp2p/pull/1399)) + - don't try to reconnect to already connected relays (#1401) ([libp2p/go-libp2p#1401](https://github.com/libp2p/go-libp2p/pull/1401)) + - reduce flakiness of AutoRelay TestBackoff test (#1400) ([libp2p/go-libp2p#1400](https://github.com/libp2p/go-libp2p/pull/1400)) + - improve AutoRelay v1 handling ([libp2p/go-libp2p#1396](https://github.com/libp2p/go-libp2p/pull/1396)) + - remove note about gx from README (#1385) ([libp2p/go-libp2p#1385](https://github.com/libp2p/go-libp2p/pull/1385)) + - use the vcs information from ReadBuildInfo in Go 1.18 ([libp2p/go-libp2p#1381](https://github.com/libp2p/go-libp2p/pull/1381)) + - fix race condition in AutoRelay candidate handling (#1383) ([libp2p/go-libp2p#1383](https://github.com/libp2p/go-libp2p/pull/1383)) + - implement relay v2 discovery ([libp2p/go-libp2p#1368](https://github.com/libp2p/go-libp2p/pull/1368)) + - fix go vet error in proxy example (#1377) ([libp2p/go-libp2p#1377](https://github.com/libp2p/go-libp2p/pull/1377)) + - Resolve addresses when creating a new stream (#1342) ([libp2p/go-libp2p#1342](https://github.com/libp2p/go-libp2p/pull/1342)) + - remove mplex from the list of default muxers (#1344) ([libp2p/go-libp2p#1344](https://github.com/libp2p/go-libp2p/pull/1344)) + - refactor the holepunching code ([libp2p/go-libp2p#1355](https://github.com/libp2p/go-libp2p/pull/1355)) + - speed up the connmgr tests (#1354) ([libp2p/go-libp2p#1354](https://github.com/libp2p/go-libp2p/pull/1354)) + - update go-libp2p-resource manager, release v0.18.0 (#1361) ([libp2p/go-libp2p#1361](https://github.com/libp2p/go-libp2p/pull/1361)) + - fix flaky BackoffConnector test (#1353) ([libp2p/go-libp2p#1353](https://github.com/libp2p/go-libp2p/pull/1353)) + - release v0.18.0-rc6 (#1350) ([libp2p/go-libp2p#1350](https://github.com/libp2p/go-libp2p/pull/1350)) + - release v0.18.0-rc5 ([libp2p/go-libp2p#1341](https://github.com/libp2p/go-libp2p/pull/1341)) + - update README (#1330) ([libp2p/go-libp2p#1330](https://github.com/libp2p/go-libp2p/pull/1330)) + - fix parsing of IP addresses for zeroconf initialization (#1338) ([libp2p/go-libp2p#1338](https://github.com/libp2p/go-libp2p/pull/1338)) + - fix flaky TestBackoffConnector test (#1328) ([libp2p/go-libp2p#1328](https://github.com/libp2p/go-libp2p/pull/1328)) + - release v0.18.0-rc4 ([libp2p/go-libp2p#1327](https://github.com/libp2p/go-libp2p/pull/1327)) + - fix (and speed up) flaky TestBackoffConnector test (#1316) ([libp2p/go-libp2p#1316](https://github.com/libp2p/go-libp2p/pull/1316)) + - fix flaky TestAutoRelay test (#1322) ([libp2p/go-libp2p#1322](https://github.com/libp2p/go-libp2p/pull/1322)) + - deflake resource manager tests, take 2 ([libp2p/go-libp2p#1318](https://github.com/libp2p/go-libp2p/pull/1318)) + - fix race condition causing TestAutoNATServiceDialError test failure (#1312) ([libp2p/go-libp2p#1312](https://github.com/libp2p/go-libp2p/pull/1312)) + - disable flaky relay example test on CI (#1219) ([libp2p/go-libp2p#1219](https://github.com/libp2p/go-libp2p/pull/1219)) + - fix flaky resource manager tests ([libp2p/go-libp2p#1315](https://github.com/libp2p/go-libp2p/pull/1315)) + - update deps, fixing nil peer scope pointer issues in connection upgrading ([libp2p/go-libp2p#1309](https://github.com/libp2p/go-libp2p/pull/1309)) + - release v0.18.0-rc2 ([libp2p/go-libp2p#1306](https://github.com/libp2p/go-libp2p/pull/1306)) + - add semaphore to control push/delta concurrency ([libp2p/go-libp2p#1305](https://github.com/libp2p/go-libp2p/pull/1305)) + - release v0.18.0-rc1 ([libp2p/go-libp2p#1300](https://github.com/libp2p/go-libp2p/pull/1300)) + - default connection manager ([libp2p/go-libp2p#1299](https://github.com/libp2p/go-libp2p/pull/1299)) + - Basic resource manager integration tests ([libp2p/go-libp2p#1296](https://github.com/libp2p/go-libp2p/pull/1296)) + - use the resource manager ([libp2p/go-libp2p#1275](https://github.com/libp2p/go-libp2p/pull/1275)) + - move the go-libp2p-connmgr here ([libp2p/go-libp2p#1297](https://github.com/libp2p/go-libp2p/pull/1297)) + - move go-libp2p-discovery here ([libp2p/go-libp2p#1291](https://github.com/libp2p/go-libp2p/pull/1291)) + - speed up identify tests ([libp2p/go-libp2p#1294](https://github.com/libp2p/go-libp2p/pull/1294)) + - don't close the connection when opening the identify stream fails ([libp2p/go-libp2p#1293](https://github.com/libp2p/go-libp2p/pull/1293)) + - use the netutil package that was moved to go-libp2p-testing (#1263) ([libp2p/go-libp2p#1263](https://github.com/libp2p/go-libp2p/pull/1263)) + - speed up the autorelay test, fix flaky TestAutoRelay test ([libp2p/go-libp2p#1272](https://github.com/libp2p/go-libp2p/pull/1272)) + - fix flaky TestStreamsStress test (#1288) ([libp2p/go-libp2p#1288](https://github.com/libp2p/go-libp2p/pull/1288)) + - add an option for the swarm dial timeout ([libp2p/go-libp2p#1271](https://github.com/libp2p/go-libp2p/pull/1271)) + - use the transport.Upgrader interface ([libp2p/go-libp2p#1277](https://github.com/libp2p/go-libp2p/pull/1277)) + - fix typo in options.go (#1274) ([libp2p/go-libp2p#1274](https://github.com/libp2p/go-libp2p/pull/1274)) + - remove direct dependency on libp2p/go-addr-util ([libp2p/go-libp2p#1279](https://github.com/libp2p/go-libp2p/pull/1279)) + - fix flaky TestNotifications test ([libp2p/go-libp2p#1278](https://github.com/libp2p/go-libp2p/pull/1278)) + - move go-libp2p-autonat to p2p/host/autonat ([libp2p/go-libp2p#1273](https://github.com/libp2p/go-libp2p/pull/1273)) + - require the expiration field of the circuit v2 Reservation protobuf ([libp2p/go-libp2p#1269](https://github.com/libp2p/go-libp2p/pull/1269)) + - run reconnect test using QUIC ([libp2p/go-libp2p#1268](https://github.com/libp2p/go-libp2p/pull/1268)) + - remove goprocess from the mock package ([libp2p/go-libp2p#1266](https://github.com/libp2p/go-libp2p/pull/1266)) + - release v0.17.0 (#1265) ([libp2p/go-libp2p#1265](https://github.com/libp2p/go-libp2p/pull/1265)) + - use the new network.ConnStats ([libp2p/go-libp2p#1262](https://github.com/libp2p/go-libp2p/pull/1262)) + - move the peerstoremanager to the host ([libp2p/go-libp2p#1258](https://github.com/libp2p/go-libp2p/pull/1258)) + - reduce the default stream protocol negotiation timeout (#1254) ([libp2p/go-libp2p#1254](https://github.com/libp2p/go-libp2p/pull/1254)) + - Doc: QUIC is default when no transports set (#1250) ([libp2p/go-libp2p#1250](https://github.com/libp2p/go-libp2p/pull/1250)) + - exclude web3-bot from mkreleaselog ([libp2p/go-libp2p#1248](https://github.com/libp2p/go-libp2p/pull/1248)) + - identify: also match observed against listening addresses ([libp2p/go-libp2p#1255](https://github.com/libp2p/go-libp2p/pull/1255)) + - make it possible to run the auto relays tests multiple times ([libp2p/go-libp2p#1253](https://github.com/libp2p/go-libp2p/pull/1253)) +- github.com/libp2p/go-libp2p-asn-util (v0.1.0 -> v0.2.0): + - Release 0.2.0 (#21) ([libp2p/go-libp2p-asn-util#21](https://github.com/libp2p/go-libp2p-asn-util/pull/21)) + - perf: replace the ipv6 map by an array of struct (#20) ([libp2p/go-libp2p-asn-util#20](https://github.com/libp2p/go-libp2p-asn-util/pull/20)) + - sync: update CI config files (#18) ([libp2p/go-libp2p-asn-util#18](https://github.com/libp2p/go-libp2p-asn-util/pull/18)) +- github.com/libp2p/go-libp2p-blankhost (v0.2.0 -> v0.3.0): + - add a WithEventBus constructor option ([libp2p/go-libp2p-blankhost#61](https://github.com/libp2p/go-libp2p-blankhost/pull/61)) + - emit the EvtPeerConnectednessChanged event ([libp2p/go-libp2p-blankhost#58](https://github.com/libp2p/go-libp2p-blankhost/pull/58)) + - chore: update go-log to v2 ([libp2p/go-libp2p-blankhost#59](https://github.com/libp2p/go-libp2p-blankhost/pull/59)) + - Remove invalid links ([libp2p/go-libp2p-blankhost#57](https://github.com/libp2p/go-libp2p-blankhost/pull/57)) + - fix go vet ([libp2p/go-libp2p-blankhost#53](https://github.com/libp2p/go-libp2p-blankhost/pull/53)) +- github.com/libp2p/go-libp2p-circuit (v0.4.0 -> v0.6.0): + - release v0.6.0 (#151) ([libp2p/go-libp2p-circuit#151](https://github.com/libp2p/go-libp2p-circuit/pull/151)) + - chore: update go-log to v2 (#147) ([libp2p/go-libp2p-circuit#147](https://github.com/libp2p/go-libp2p-circuit/pull/147)) + - release v0.5.0 (#150) ([libp2p/go-libp2p-circuit#150](https://github.com/libp2p/go-libp2p-circuit/pull/150)) + - use the resource manager ([libp2p/go-libp2p-circuit#148](https://github.com/libp2p/go-libp2p-circuit/pull/148)) + - use the transport.Upgrader interface ([libp2p/go-libp2p-circuit#149](https://github.com/libp2p/go-libp2p-circuit/pull/149)) + - sync: update CI config files (#144) ([libp2p/go-libp2p-circuit#144](https://github.com/libp2p/go-libp2p-circuit/pull/144)) + - ([libp2p/go-libp2p-circuit#143](https://github.com/libp2p/go-libp2p-circuit/pull/143)) + - add a Close method, remove the context from the constructor ([libp2p/go-libp2p-circuit#141](https://github.com/libp2p/go-libp2p-circuit/pull/141)) + - chore: update go-libp2p-core, go-libp2p-swarm ([libp2p/go-libp2p-circuit#140](https://github.com/libp2p/go-libp2p-circuit/pull/140)) + - remove the circuit v2 code ([libp2p/go-libp2p-circuit#139](https://github.com/libp2p/go-libp2p-circuit/pull/139)) + - implement circuit v2 ([libp2p/go-libp2p-circuit#136](https://github.com/libp2p/go-libp2p-circuit/pull/136)) + - remove deprecated types ([libp2p/go-libp2p-circuit#135](https://github.com/libp2p/go-libp2p-circuit/pull/135)) + - fix race condition in TestActiveRelay ([libp2p/go-libp2p-circuit#133](https://github.com/libp2p/go-libp2p-circuit/pull/133)) + - minor staticcheck fixes ([libp2p/go-libp2p-circuit#126](https://github.com/libp2p/go-libp2p-circuit/pull/126)) + - Timeout Stream Read ([libp2p/go-libp2p-circuit#124](https://github.com/libp2p/go-libp2p-circuit/pull/124)) +- github.com/libp2p/go-libp2p-core (v0.11.0 -> v0.15.1): + - release v0.15.1 (#246) ([libp2p/go-libp2p-core#246](https://github.com/libp2p/go-libp2p-core/pull/246)) + - feat: harden encoding/decoding functions against panics (#243) ([libp2p/go-libp2p-core#243](https://github.com/libp2p/go-libp2p-core/pull/243)) + - release v0.15.0 (#242) ([libp2p/go-libp2p-core#242](https://github.com/libp2p/go-libp2p-core/pull/242)) + - sync: update CI config files (#241) ([libp2p/go-libp2p-core#241](https://github.com/libp2p/go-libp2p-core/pull/241)) + - fix: switch to go-multicodec mappings (#240) ([libp2p/go-libp2p-core#240](https://github.com/libp2p/go-libp2p-core/pull/240)) + - chore: add `String()` method to `IDSlice` type (#238) ([libp2p/go-libp2p-core#238](https://github.com/libp2p/go-libp2p-core/pull/238)) + - release v0.14.0 (#235) ([libp2p/go-libp2p-core#235](https://github.com/libp2p/go-libp2p-core/pull/235)) + - Network Resource Manager interface (#229) ([libp2p/go-libp2p-core#229](https://github.com/libp2p/go-libp2p-core/pull/229)) + - introduce a transport.Upgrader interface (#232) ([libp2p/go-libp2p-core#232](https://github.com/libp2p/go-libp2p-core/pull/232)) + - remove the transport.AcceptTimeout (#231) ([libp2p/go-libp2p-core#231](https://github.com/libp2p/go-libp2p-core/pull/231)) + - remove the DialTimeout (#230) ([libp2p/go-libp2p-core#230](https://github.com/libp2p/go-libp2p-core/pull/230)) + - remove duplicate io.Closer on Network interface (#228) ([libp2p/go-libp2p-core#228](https://github.com/libp2p/go-libp2p-core/pull/228)) + - release v0.13.0 (#227) ([libp2p/go-libp2p-core#227](https://github.com/libp2p/go-libp2p-core/pull/227)) + - rename network.Stat to Stats, introduce ConnStats (#226) ([libp2p/go-libp2p-core#226](https://github.com/libp2p/go-libp2p-core/pull/226)) + - release v0.12.0 (#223) ([libp2p/go-libp2p-core#223](https://github.com/libp2p/go-libp2p-core/pull/223)) + - generate ecdsa public key from an input public key (#219) ([libp2p/go-libp2p-core#219](https://github.com/libp2p/go-libp2p-core/pull/219)) + - add RemovePeer method to PeerMetadata, Metrics, ProtoBook and Keybook (#218) ([libp2p/go-libp2p-core#218](https://github.com/libp2p/go-libp2p-core/pull/218)) +- github.com/libp2p/go-libp2p-kad-dht (v0.15.0 -> v0.16.0): + - Version 0.16.0 (#774) ([libp2p/go-libp2p-kad-dht#774](https://github.com/libp2p/go-libp2p-kad-dht/pull/774)) + - feat: add error log when resource manager throttles crawler (#772) ([libp2p/go-libp2p-kad-dht#772](https://github.com/libp2p/go-libp2p-kad-dht/pull/772)) + - fix: incorrect format handling ([libp2p/go-libp2p-kad-dht#771](https://github.com/libp2p/go-libp2p-kad-dht/pull/771)) + - Upgrade to go-libp2p v0.16.0 (#756) ([libp2p/go-libp2p-kad-dht#756](https://github.com/libp2p/go-libp2p-kad-dht/pull/756)) + - sync: update CI config files ([libp2p/go-libp2p-kad-dht#758](https://github.com/libp2p/go-libp2p-kad-dht/pull/758)) +- github.com/libp2p/go-libp2p-mplex (v0.4.1 -> v0.7.0): + - release v0.7.0 (#36) ([libp2p/go-libp2p-mplex#36](https://github.com/libp2p/go-libp2p-mplex/pull/36)) + - release v0.6.0 (#32) ([libp2p/go-libp2p-mplex#32](https://github.com/libp2p/go-libp2p-mplex/pull/32)) + - update mplex (#31) ([libp2p/go-libp2p-mplex#31](https://github.com/libp2p/go-libp2p-mplex/pull/31)) + - release v0.5.0 (#30) ([libp2p/go-libp2p-mplex#30](https://github.com/libp2p/go-libp2p-mplex/pull/30)) + - implement the new network.MuxedConn interface (#29) ([libp2p/go-libp2p-mplex#29](https://github.com/libp2p/go-libp2p-mplex/pull/29)) + - sync: update CI config files (#28) ([libp2p/go-libp2p-mplex#28](https://github.com/libp2p/go-libp2p-mplex/pull/28)) + - remove Makefile ([libp2p/go-libp2p-mplex#25](https://github.com/libp2p/go-libp2p-mplex/pull/25)) +- github.com/libp2p/go-libp2p-noise (v0.3.0 -> v0.4.0): + - release v0.4.0 (#112) ([libp2p/go-libp2p-noise#112](https://github.com/libp2p/go-libp2p-noise/pull/112)) + - catch panics during the handshake (#111) ([libp2p/go-libp2p-noise#111](https://github.com/libp2p/go-libp2p-noise/pull/111)) + - sync: update CI config files (#106) ([libp2p/go-libp2p-noise#106](https://github.com/libp2p/go-libp2p-noise/pull/106)) + - update README to reflect that Noise is enabled by default ([libp2p/go-libp2p-noise#101](https://github.com/libp2p/go-libp2p-noise/pull/101)) +- github.com/libp2p/go-libp2p-peerstore (v0.4.0 -> v0.6.0): + - release v0.6.0 ([libp2p/go-libp2p-peerstore#189](https://github.com/libp2p/go-libp2p-peerstore/pull/189)) + - remove the pstoremanager (will be moved to the Host) ([libp2p/go-libp2p-peerstore#188](https://github.com/libp2p/go-libp2p-peerstore/pull/188)) + - release v0.5.0 (#187) ([libp2p/go-libp2p-peerstore#187](https://github.com/libp2p/go-libp2p-peerstore/pull/187)) + - remove metadata interning ([libp2p/go-libp2p-peerstore#185](https://github.com/libp2p/go-libp2p-peerstore/pull/185)) + - when passed an event bus, automatically clean up disconnected peers ([libp2p/go-libp2p-peerstore#184](https://github.com/libp2p/go-libp2p-peerstore/pull/184)) + - implement the RemovePeer method ([libp2p/go-libp2p-peerstore#174](https://github.com/libp2p/go-libp2p-peerstore/pull/174)) + - chore: update go-log to v2 (#179) ([libp2p/go-libp2p-peerstore#179](https://github.com/libp2p/go-libp2p-peerstore/pull/179)) +- github.com/libp2p/go-libp2p-pubsub (v0.6.0 -> v0.6.1): + - add tests for clearing the peerPromises map + - properly clear the peerPromises map + - more info + - add to MinTopicSize godoc re topic size +- github.com/libp2p/go-libp2p-quic-transport (v0.15.0 -> v0.17.0): + - release v0.17.0 (#269) ([libp2p/go-libp2p-quic-transport#269](https://github.com/libp2p/go-libp2p-quic-transport/pull/269)) + - update quic-go to v0.27.0 (#264) ([libp2p/go-libp2p-quic-transport#264](https://github.com/libp2p/go-libp2p-quic-transport/pull/264)) + - release v0.16.1 (#261) ([libp2p/go-libp2p-quic-transport#261](https://github.com/libp2p/go-libp2p-quic-transport/pull/261)) + - Prevent data race in allowWindowIncrease (#259) ([libp2p/go-libp2p-quic-transport#259](https://github.com/libp2p/go-libp2p-quic-transport/pull/259)) + - release v0.16.0 (#258) ([libp2p/go-libp2p-quic-transport#258](https://github.com/libp2p/go-libp2p-quic-transport/pull/258)) + - use the Resource Manager ([libp2p/go-libp2p-quic-transport#249](https://github.com/libp2p/go-libp2p-quic-transport/pull/249)) + - don't start a Go routine for every connection dialed ([libp2p/go-libp2p-quic-transport#252](https://github.com/libp2p/go-libp2p-quic-transport/pull/252)) + - migrate to standard Go tests, stop using Ginkgo ([libp2p/go-libp2p-quic-transport#250](https://github.com/libp2p/go-libp2p-quic-transport/pull/250)) + - chore: remove Codecov config (#251) ([libp2p/go-libp2p-quic-transport#251](https://github.com/libp2p/go-libp2p-quic-transport/pull/251)) + - reduce the maximum number of incoming streams to 256 (#243) ([libp2p/go-libp2p-quic-transport#243](https://github.com/libp2p/go-libp2p-quic-transport/pull/243)) + - chore: update go-log to v2 (#242) ([libp2p/go-libp2p-quic-transport#242](https://github.com/libp2p/go-libp2p-quic-transport/pull/242)) +- github.com/libp2p/go-libp2p-swarm (v0.8.0 -> v0.10.2): + - bump version to v0.10.2 ([libp2p/go-libp2p-swarm#316](https://github.com/libp2p/go-libp2p-swarm/pull/316)) + - Refactor dial worker loop into an object and fix bug ([libp2p/go-libp2p-swarm#315](https://github.com/libp2p/go-libp2p-swarm/pull/315)) + - release v0.10.1 ([libp2p/go-libp2p-swarm#313](https://github.com/libp2p/go-libp2p-swarm/pull/313)) + - release the stream scope if the conn fails to open a new stream ([libp2p/go-libp2p-swarm#312](https://github.com/libp2p/go-libp2p-swarm/pull/312)) + - release v0.10.0 (#311) ([libp2p/go-libp2p-swarm#311](https://github.com/libp2p/go-libp2p-swarm/pull/311)) + - add support for the resource manager ([libp2p/go-libp2p-swarm#308](https://github.com/libp2p/go-libp2p-swarm/pull/308)) + - use the transport.Upgrader interface ([libp2p/go-libp2p-swarm#309](https://github.com/libp2p/go-libp2p-swarm/pull/309)) + - remove dependency on go-addr-util ([libp2p/go-libp2p-swarm#300](https://github.com/libp2p/go-libp2p-swarm/pull/300)) + - stop using transport.DialTimeout in tests (#307) ([libp2p/go-libp2p-swarm#307](https://github.com/libp2p/go-libp2p-swarm/pull/307)) + - increment active dial counter in dial worker loop ([libp2p/go-libp2p-swarm#305](https://github.com/libp2p/go-libp2p-swarm/pull/305)) + - speed up the dial tests ([libp2p/go-libp2p-swarm#301](https://github.com/libp2p/go-libp2p-swarm/pull/301)) + - stop using the deprecated libp2p/go-maddr-filter ([libp2p/go-libp2p-swarm#303](https://github.com/libp2p/go-libp2p-swarm/pull/303)) + - add constructor options for timeout, stop using transport.DialTimeout ([libp2p/go-libp2p-swarm#302](https://github.com/libp2p/go-libp2p-swarm/pull/302)) + - release v0.9.0 (#299) ([libp2p/go-libp2p-swarm#299](https://github.com/libp2p/go-libp2p-swarm/pull/299)) + - count the number of streams on a connection for the stats ([libp2p/go-libp2p-swarm#298](https://github.com/libp2p/go-libp2p-swarm/pull/298)) + - chore: update go-log to v2 (#294) ([libp2p/go-libp2p-swarm#294](https://github.com/libp2p/go-libp2p-swarm/pull/294)) +- github.com/libp2p/go-libp2p-testing (v0.5.0 -> v0.9.2): + - release v0.9.2 (#56) ([libp2p/go-libp2p-testing#56](https://github.com/libp2p/go-libp2p-testing/pull/56)) + - fix memory allocation check in SubtestStreamReset (#55) ([libp2p/go-libp2p-testing#55](https://github.com/libp2p/go-libp2p-testing/pull/55)) + - release v0.9.1 (#54) ([libp2p/go-libp2p-testing#54](https://github.com/libp2p/go-libp2p-testing/pull/54)) + - remove stray debug statements for memory allocations + - release v0.9.0 (#53) ([libp2p/go-libp2p-testing#53](https://github.com/libp2p/go-libp2p-testing/pull/53)) + - add tests for memory management ([libp2p/go-libp2p-testing#52](https://github.com/libp2p/go-libp2p-testing/pull/52)) + - release v0.8.0 (#50) ([libp2p/go-libp2p-testing#50](https://github.com/libp2p/go-libp2p-testing/pull/50)) + - use io.ReadFull in muxer test, use require.Equal to compare buffers (#49) ([libp2p/go-libp2p-testing#49](https://github.com/libp2p/go-libp2p-testing/pull/49)) + - release v0.7.0 (#47) ([libp2p/go-libp2p-testing#47](https://github.com/libp2p/go-libp2p-testing/pull/47)) + - add mocks for the resource manager ([libp2p/go-libp2p-testing#46](https://github.com/libp2p/go-libp2p-testing/pull/46)) + - merge libp2p/go-libp2p-netutil into this repo ([libp2p/go-libp2p-testing#45](https://github.com/libp2p/go-libp2p-testing/pull/45)) + - reduce the number of connections in the stream muxer stress test (#44) ([libp2p/go-libp2p-testing#44](https://github.com/libp2p/go-libp2p-testing/pull/44)) + - release v0.6.0 (#42) ([libp2p/go-libp2p-testing#42](https://github.com/libp2p/go-libp2p-testing/pull/42)) + - expose a map, not a slice, of muxer tests (#41) ([libp2p/go-libp2p-testing#41](https://github.com/libp2p/go-libp2p-testing/pull/41)) + - sync: update CI config files (#40) ([libp2p/go-libp2p-testing#40](https://github.com/libp2p/go-libp2p-testing/pull/40)) +- github.com/libp2p/go-libp2p-tls (v0.3.1 -> v0.4.1): + - release v0.4.1 (#112) ([libp2p/go-libp2p-tls#112](https://github.com/libp2p/go-libp2p-tls/pull/112)) + - feat: catch panics in TLS negotiation ([libp2p/go-libp2p-tls#111](https://github.com/libp2p/go-libp2p-tls/pull/111)) + - release v0.4.0 (#110) ([libp2p/go-libp2p-tls#110](https://github.com/libp2p/go-libp2p-tls/pull/110)) + - use tls.Conn.HandshakeContext instead of tls.Conn.Handshake (#106) ([libp2p/go-libp2p-tls#106](https://github.com/libp2p/go-libp2p-tls/pull/106)) + - remove paragraph about Go modules from README (#104) ([libp2p/go-libp2p-tls#104](https://github.com/libp2p/go-libp2p-tls/pull/104)) + - migrate to standard Go tests, stop using Ginkgo ([libp2p/go-libp2p-tls#105](https://github.com/libp2p/go-libp2p-tls/pull/105)) + - chore: remove Codecov config (#103) ([libp2p/go-libp2p-tls#103](https://github.com/libp2p/go-libp2p-tls/pull/103)) +- github.com/libp2p/go-libp2p-transport-upgrader (v0.5.0 -> v0.7.1): + - release v0.7.1 ([libp2p/go-libp2p-transport-upgrader#105](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/105)) + - Fix nil peer scope issues ([libp2p/go-libp2p-transport-upgrader#104](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/104)) + - release v0.7.0 (#103) ([libp2p/go-libp2p-transport-upgrader#103](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/103)) + - use the Resource Manager ([libp2p/go-libp2p-transport-upgrader#99](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/99)) + - rename the package to upgrader ([libp2p/go-libp2p-transport-upgrader#101](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/101)) + - use the new transport.Upgrader interface ([libp2p/go-libp2p-transport-upgrader#100](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/100)) + - reset the temporary error catcher delay after successful accept ([libp2p/go-libp2p-transport-upgrader#97](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/97)) + - make the accept timeout configurable, stop using transport.AcceptTimeout ([libp2p/go-libp2p-transport-upgrader#98](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/98)) + - release v0.6.0 (#95) ([libp2p/go-libp2p-transport-upgrader#95](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/95)) + - remove note about go.mod and Go 1.11 in README (#94) ([libp2p/go-libp2p-transport-upgrader#94](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/94)) + - fix flaky TestAcceptQueueBacklogged test ([libp2p/go-libp2p-transport-upgrader#96](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/96)) + - chore: remove Codecov config (#93) ([libp2p/go-libp2p-transport-upgrader#93](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/93)) + - use the new network.ConnStats ([libp2p/go-libp2p-transport-upgrader#92](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/92)) + - sync: update CI config files (#89) ([libp2p/go-libp2p-transport-upgrader#89](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/89)) + - chore: update go-log ([libp2p/go-libp2p-transport-upgrader#88](https://github.com/libp2p/go-libp2p-transport-upgrader/pull/88)) +- github.com/libp2p/go-libp2p-yamux (v0.6.0 -> v0.9.1): + - release v0.9.1 (#55) ([libp2p/go-libp2p-yamux#55](https://github.com/libp2p/go-libp2p-yamux/pull/55)) + - release v0.9.0 (#53) ([libp2p/go-libp2p-yamux#53](https://github.com/libp2p/go-libp2p-yamux/pull/53)) + - release v0.8.2 (#50) ([libp2p/go-libp2p-yamux#50](https://github.com/libp2p/go-libp2p-yamux/pull/50)) + - disable the incoming streams limit (#49) ([libp2p/go-libp2p-yamux#49](https://github.com/libp2p/go-libp2p-yamux/pull/49)) + - Release v0.8.1 ([libp2p/go-libp2p-yamux#48](https://github.com/libp2p/go-libp2p-yamux/pull/48)) + - release v0.8.0 (#47) ([libp2p/go-libp2p-yamux#47](https://github.com/libp2p/go-libp2p-yamux/pull/47)) + - pass the PeerScope to yamux (satifiying its MemoryManger interface) (#46) ([libp2p/go-libp2p-yamux#46](https://github.com/libp2p/go-libp2p-yamux/pull/46)) + - release v0.7.0 (#43) ([libp2p/go-libp2p-yamux#43](https://github.com/libp2p/go-libp2p-yamux/pull/43)) + - sync: update CI config files (#42) ([libp2p/go-libp2p-yamux#42](https://github.com/libp2p/go-libp2p-yamux/pull/42)) + - reduce the number of max incoming stream to 256 ([libp2p/go-libp2p-yamux#41](https://github.com/libp2p/go-libp2p-yamux/pull/41)) +- github.com/libp2p/go-mplex (v0.3.0 -> v0.7.0): + - release v0.7.0 (#112) ([libp2p/go-mplex#112](https://github.com/libp2p/go-mplex/pull/112)) + - catch panics in handleIncoming and handleOutgoing (#109) ([libp2p/go-mplex#109](https://github.com/libp2p/go-mplex/pull/109)) + - remove benchmark tests (#111) ([libp2p/go-mplex#111](https://github.com/libp2p/go-mplex/pull/111)) + - release v0.6.0 (#105) ([libp2p/go-mplex#105](https://github.com/libp2p/go-mplex/pull/105)) + - fix incorrect reset of timer fired variable (#104) ([libp2p/go-mplex#104](https://github.com/libp2p/go-mplex/pull/104)) + - Mplex salvage operations, part II (#102) ([libp2p/go-mplex#102](https://github.com/libp2p/go-mplex/pull/102)) + - release v0.5.0 (#100) ([libp2p/go-mplex#100](https://github.com/libp2p/go-mplex/pull/100)) + - Salvage mplex in the age of resource management (#99) ([libp2p/go-mplex#99](https://github.com/libp2p/go-mplex/pull/99)) + - release v0.4.0 (#97) ([libp2p/go-mplex#97](https://github.com/libp2p/go-mplex/pull/97)) + - add a MemoryManager interface to control memory allocations ([libp2p/go-mplex#96](https://github.com/libp2p/go-mplex/pull/96)) + - sync: update CI config files (#93) ([libp2p/go-mplex#93](https://github.com/libp2p/go-mplex/pull/93)) + - chore: update go-log to v2 ([libp2p/go-mplex#92](https://github.com/libp2p/go-mplex/pull/92)) + - chore: remove Codecov config ([libp2p/go-mplex#91](https://github.com/libp2p/go-mplex/pull/91)) + - sync: update CI config files (#90) ([libp2p/go-mplex#90](https://github.com/libp2p/go-mplex/pull/90)) + - multiplex: add (*Multiplex).CloseChan ([libp2p/go-mplex#89](https://github.com/libp2p/go-mplex/pull/89)) + - add a Go Reference badge to the README ([libp2p/go-mplex#88](https://github.com/libp2p/go-mplex/pull/88)) + - sync: update CI config files ([libp2p/go-mplex#85](https://github.com/libp2p/go-mplex/pull/85)) + - Fixup tests & vet ([libp2p/go-mplex#84](https://github.com/libp2p/go-mplex/pull/84)) + - Bump lodash from 4.17.19 to 4.17.21 in /interop/js ([libp2p/go-mplex#83](https://github.com/libp2p/go-mplex/pull/83)) +- github.com/libp2p/go-msgio (v0.1.0 -> v0.2.0): + - release v0.2.0 (#34) ([libp2p/go-msgio#34](https://github.com/libp2p/go-msgio/pull/34)) + - print recovered panics to stderr (#33) ([libp2p/go-msgio#33](https://github.com/libp2p/go-msgio/pull/33)) + - catch panics when reading / writing protobuf messages (#31) ([libp2p/go-msgio#31](https://github.com/libp2p/go-msgio/pull/31)) + - remove outdated section about channels from README (#32) ([libp2p/go-msgio#32](https://github.com/libp2p/go-msgio/pull/32)) + - sync: update CI config files (#28) ([libp2p/go-msgio#28](https://github.com/libp2p/go-msgio/pull/28)) +- github.com/libp2p/go-netroute (v0.1.6 -> v0.2.0): + - release v0.2.0 (#21) ([libp2p/go-netroute#21](https://github.com/libp2p/go-netroute/pull/21)) + - move some functions from go-sockaddr here, remove go-sockaddr dependency ([libp2p/go-netroute#22](https://github.com/libp2p/go-netroute/pull/22)) + - ignore the error on the RouteMessage on Darwin ([libp2p/go-netroute#20](https://github.com/libp2p/go-netroute/pull/20)) + - sync: update CI config files (#19) ([libp2p/go-netroute#19](https://github.com/libp2p/go-netroute/pull/19)) + - sync: update CI config files (#18) ([libp2p/go-netroute#18](https://github.com/libp2p/go-netroute/pull/18)) + - skip loopback addr as indication of v6 routes ([libp2p/go-netroute#17](https://github.com/libp2p/go-netroute/pull/17)) + - fix staticcheck lint issues ([libp2p/go-netroute#15](https://github.com/libp2p/go-netroute/pull/15)) +- github.com/libp2p/go-stream-muxer-multistream (v0.3.0 -> v0.4.0): + - release v0.4.0 (#23) ([libp2p/go-stream-muxer-multistream#23](https://github.com/libp2p/go-stream-muxer-multistream/pull/23)) + - implement the new Multiplexer.NewConn interface ([libp2p/go-stream-muxer-multistream#22](https://github.com/libp2p/go-stream-muxer-multistream/pull/22)) + - sync: update CI config files (#19) ([libp2p/go-stream-muxer-multistream#19](https://github.com/libp2p/go-stream-muxer-multistream/pull/19)) +- github.com/libp2p/go-tcp-transport (v0.4.0 -> v0.5.1): + - release v0.5.1 (#116) ([libp2p/go-tcp-transport#116](https://github.com/libp2p/go-tcp-transport/pull/116)) + - fix: drop raw EINVAL (from keepalives) errors as well (#115) ([libp2p/go-tcp-transport#115](https://github.com/libp2p/go-tcp-transport/pull/115)) + - release v0.5.0 (#114) ([libp2p/go-tcp-transport#114](https://github.com/libp2p/go-tcp-transport/pull/114)) + - use the ResourceManager ([libp2p/go-tcp-transport#110](https://github.com/libp2p/go-tcp-transport/pull/110)) + - use the transport.Upgrader interface ([libp2p/go-tcp-transport#111](https://github.com/libp2p/go-tcp-transport/pull/111)) + - describe how to use options in README ([libp2p/go-tcp-transport#105](https://github.com/libp2p/go-tcp-transport/pull/105)) +- github.com/libp2p/go-ws-transport (v0.5.0 -> v0.6.0): + - release v0.6.0 (#113) ([libp2p/go-ws-transport#113](https://github.com/libp2p/go-ws-transport/pull/113)) + - use the resource manager ([libp2p/go-ws-transport#109](https://github.com/libp2p/go-ws-transport/pull/109)) + - chore: remove Codecov config (#112) ([libp2p/go-ws-transport#112](https://github.com/libp2p/go-ws-transport/pull/112)) + - remove contexts from libp2p constructors in README (#111) ([libp2p/go-ws-transport#111](https://github.com/libp2p/go-ws-transport/pull/111)) + - use the transport.Upgrader interface ([libp2p/go-ws-transport#110](https://github.com/libp2p/go-ws-transport/pull/110)) + - sync: update CI config files (#108) ([libp2p/go-ws-transport#108](https://github.com/libp2p/go-ws-transport/pull/108)) + - sync: update CI config files (#106) ([libp2p/go-ws-transport#106](https://github.com/libp2p/go-ws-transport/pull/106)) +- github.com/lucas-clemente/quic-go (v0.24.0 -> v0.27.1): + - don't send path MTU probe packets on a timer + - stop using the deprecated net.Error.Temporary, update golangci-lint to v1.45.2 ([lucas-clemente/quic-go#3367](https://github.com/lucas-clemente/quic-go/pull/3367)) + - add support for serializing Extended CONNECT requests (#3360) ([lucas-clemente/quic-go#3360](https://github.com/lucas-clemente/quic-go/pull/3360)) + - improve the error thrown when building with an unsupported Go version ([lucas-clemente/quic-go#3364](https://github.com/lucas-clemente/quic-go/pull/3364)) + - remove nextdns from list of projects using quic-go (#3363) ([lucas-clemente/quic-go#3363](https://github.com/lucas-clemente/quic-go/pull/3363)) + - rename the Session to Connection ([lucas-clemente/quic-go#3361](https://github.com/lucas-clemente/quic-go/pull/3361)) + - respect the request context when dialing ([lucas-clemente/quic-go#3359](https://github.com/lucas-clemente/quic-go/pull/3359)) + - update HTTP/3 Datagram to draft-ietf-masque-h3-datagram-07 (#3355) ([lucas-clemente/quic-go#3355](https://github.com/lucas-clemente/quic-go/pull/3355)) + - add support for the Extended CONNECT method (#3357) ([lucas-clemente/quic-go#3357](https://github.com/lucas-clemente/quic-go/pull/3357)) + - remove the SkipSchemeCheck RoundTripOpt (#3353) ([lucas-clemente/quic-go#3353](https://github.com/lucas-clemente/quic-go/pull/3353)) + - remove parser logic for HTTP/3 DUPLICATE_PUSH frame (#3356) ([lucas-clemente/quic-go#3356](https://github.com/lucas-clemente/quic-go/pull/3356)) + - improve code coverage of random number generator test (#3358) ([lucas-clemente/quic-go#3358](https://github.com/lucas-clemente/quic-go/pull/3358)) + - advertise multiple listeners via Alt-Svc and improve perf of SetQuicHeaders (#3352) ([lucas-clemente/quic-go#3352](https://github.com/lucas-clemente/quic-go/pull/3352)) + - avoid recursion when skipping unknown HTTP/3 frames (#3354) ([lucas-clemente/quic-go#3354](https://github.com/lucas-clemente/quic-go/pull/3354)) + - Implement http3.Server.ServeListener (#3349) ([lucas-clemente/quic-go#3349](https://github.com/lucas-clemente/quic-go/pull/3349)) + - update for Go 1.18 ([lucas-clemente/quic-go#3345](https://github.com/lucas-clemente/quic-go/pull/3345)) + - don't print a receive buffer warning for closed connections (#3346) ([lucas-clemente/quic-go#3346](https://github.com/lucas-clemente/quic-go/pull/3346)) + - move set DF implementation to separate files & avoid the need for OOBCapablePacketConn (#3334) ([lucas-clemente/quic-go#3334](https://github.com/lucas-clemente/quic-go/pull/3334)) + - add env to disable the receive buffer warning (#3339) ([lucas-clemente/quic-go#3339](https://github.com/lucas-clemente/quic-go/pull/3339)) + - fix typo (#3333) ([lucas-clemente/quic-go#3333](https://github.com/lucas-clemente/quic-go/pull/3333)) + - sendQueue: ignore "datagram too large" error (#3328) ([lucas-clemente/quic-go#3328](https://github.com/lucas-clemente/quic-go/pull/3328)) + - add OONI Probe to list of projects in README (#3324) ([lucas-clemente/quic-go#3324](https://github.com/lucas-clemente/quic-go/pull/3324)) + - remove build status badges from README (#3325) ([lucas-clemente/quic-go#3325](https://github.com/lucas-clemente/quic-go/pull/3325)) + - add a AllowConnectionWindowIncrease config option ([lucas-clemente/quic-go#3317](https://github.com/lucas-clemente/quic-go/pull/3317)) + - Update README.md (#3315) ([lucas-clemente/quic-go#3315](https://github.com/lucas-clemente/quic-go/pull/3315)) + - fix some typos in documentation and tests + - remove unneeded calls to goimports when generating mocks ([lucas-clemente/quic-go#3313](https://github.com/lucas-clemente/quic-go/pull/3313)) + - fix comment about congestionWindow value (#3310) ([lucas-clemente/quic-go#3310](https://github.com/lucas-clemente/quic-go/pull/3310)) + - fix typo *connections (#3309) ([lucas-clemente/quic-go#3309](https://github.com/lucas-clemente/quic-go/pull/3309)) + - add support for Go 1.18 ([lucas-clemente/quic-go#3298](https://github.com/lucas-clemente/quic-go/pull/3298)) +- github.com/multiformats/go-base32 (v0.0.3 -> v0.0.4): + - optimize encode ([multiformats/go-base32#1](https://github.com/multiformats/go-base32/pull/1)) + - Fix `staticcheck` issue +- github.com/multiformats/go-multiaddr (v0.4.1 -> v0.5.0): + - release v0.5.0 (#171) ([multiformats/go-multiaddr#171](https://github.com/multiformats/go-multiaddr/pull/171)) + - remove wrong (and redundant) IsIpv6LinkLocal ([multiformats/go-multiaddr#170](https://github.com/multiformats/go-multiaddr/pull/170)) + - move ResolveUnspecifiedAddress(es) and FilterAddrs here from libp2p/go-addr-util ([multiformats/go-multiaddr#168](https://github.com/multiformats/go-multiaddr/pull/168)) + - sync: update CI config files (#167) ([multiformats/go-multiaddr#167](https://github.com/multiformats/go-multiaddr/pull/167)) +- github.com/multiformats/go-multicodec (v0.3.0 -> v0.4.1): + - Version v0.4.1 ([multiformats/go-multicodec#64](https://github.com/multiformats/go-multicodec/pull/64)) + - update table with new codecs ([multiformats/go-multicodec#63](https://github.com/multiformats/go-multicodec/pull/63)) + - bump version to v0.4.0 + - sync: update CI config files (#60) ([multiformats/go-multicodec#60](https://github.com/multiformats/go-multicodec/pull/60)) + - add Code.Tag method + - add the KnownCodes API + - use "go run pkg@version" assuming Go 1.17 or later + - update submodule and re-generate + - update to newer multicodec table ([multiformats/go-multicodec#57](https://github.com/multiformats/go-multicodec/pull/57)) + - Update `multicodec` submodule to `1bcdc08` for CARv2 index codec +- github.com/multiformats/go-multistream (v0.2.2 -> v0.3.0): + - release v0.3.0 (#82) ([multiformats/go-multistream#82](https://github.com/multiformats/go-multistream/pull/82)) + - catch panics (#81) ([multiformats/go-multistream#81](https://github.com/multiformats/go-multistream/pull/81)) + - sync: update CI config files (#78) ([multiformats/go-multistream#78](https://github.com/multiformats/go-multistream/pull/78)) + - reduce the maximum read buffer size from 64 to 1 kB ([multiformats/go-multistream#77](https://github.com/multiformats/go-multistream/pull/77)) + - remove unused ls command ([multiformats/go-multistream#76](https://github.com/multiformats/go-multistream/pull/76)) + - chore: remove empty file cases.md ([multiformats/go-multistream#75](https://github.com/multiformats/go-multistream/pull/75)) + - chore: remove .gx ([multiformats/go-multistream#72](https://github.com/multiformats/go-multistream/pull/72)) + - don't commit the fuzzing binary ([multiformats/go-multistream#74](https://github.com/multiformats/go-multistream/pull/74)) + - sync: update CI config files (#71) ([multiformats/go-multistream#71](https://github.com/multiformats/go-multistream/pull/71)) + - remove Makefile ([multiformats/go-multistream#67](https://github.com/multiformats/go-multistream/pull/67)) +
+ +### โค Contributors +| Contributor | Commits | Lines ยฑ | Files Changed | +|-------------|---------|---------|---------------| +| Marten Seemann | 347 | +14453/-12552 | 842 | +| Rod Vagg | 28 | +8848/-4033 | 214 | +| vyzo | 133 | +7959/-1783 | 231 | +| hannahhoward | 40 | +3761/-1652 | 175 | +| Will Scott | 39 | +2885/-1784 | 93 | +| Daniel Martรญ | 32 | +3043/-969 | 103 | +| Adin Schmahmann | 48 | +3439/-536 | 121 | +| Gus Eggert | 29 | +2644/-788 | 123 | +| Steven Allen | 87 | +2417/-840 | 135 | +| Marcin Rataj | 29 | +2312/-942 | 75 | +| Will | 11 | +2520/-62 | 56 | +| Lucas Molas | 28 | +1602/-578 | 90 | +| Raรบl Kripalani | 18 | +1519/-271 | 38 | +| Brian Tiger Chow | 20 | +833/-379 | 40 | +| Masih H. Derkani | 5 | +514/-460 | 8 | +| Jeromy Johnson | 53 | +646/-302 | 83 | +| ลukasz Magiera | 26 | +592/-245 | 43 | +| Artem Mikheev | 2 | +616/-120 | 5 | +| Franky W | 2 | +49/-525 | 9 | +| Laurent Senta | 3 | +468/-82 | 52 | +| Hector Sanjuan | 32 | +253/-187 | 62 | +| Juan Batiz-Benet | 8 | +285/-80 | 18 | +| Justin Johnson | 2 | +181/-88 | 2 | +| Thibault Meunier | 5 | +216/-28 | 8 | +| James Wetter | 2 | +234/-1 | 2 | +| web3-bot | 36 | +158/-66 | 62 | +| gammazero | 7 | +140/-84 | 12 | +| Rachel Chen | 2 | +165/-57 | 17 | +| Jorropo | 18 | +108/-99 | 26 | +| Toby | 2 | +107/-86 | 11 | +| Antonio Navarro Perez | 4 | +82/-103 | 9 | +| Dominic Della Valle | 4 | +148/-33 | 6 | +| Ian Davis | 2 | +152/-28 | 6 | +| Kyle Huntsman | 2 | +172/-6 | 5 | +| huoju | 4 | +127/-41 | 6 | +| Jeromy | 19 | +71/-58 | 31 | +| Lars Gierth | 12 | +63/-54 | 20 | +| Eric Myhre | 3 | +95/-15 | 8 | +| Caian Benedicto | 1 | +69/-12 | 6 | +| Rauฬl Kripalani | 2 | +63/-13 | 2 | +| Anton Petrov | 1 | +73/-0 | 1 | +| hunjixin | 2 | +67/-2 | 5 | +| odanado | 1 | +61/-0 | 1 | +| Andrew Gillis | 2 | +61/-0 | 3 | +| Kevin Atkinson | 6 | +21/-34 | 7 | +| Richard Ramos | 1 | +51/-0 | 2 | +| Manuel Alonso | 1 | +42/-9 | 2 | +| Jakub Sztandera | 10 | +37/-13 | 13 | +| Aarsh Shah | 1 | +39/-5 | 2 | +| Dave Justice | 1 | +32/-4 | 2 | +| Tommi Virtanen | 3 | +23/-9 | 4 | +| tarekbadr | 1 | +30/-1 | 1 | +| whyrusleeping | 1 | +26/-4 | 3 | +| Petar Maymounkov | 2 | +30/-0 | 4 | +| rht | 3 | +17/-10 | 4 | +| Miguel Mota | 1 | +23/-0 | 1 | +| Manfred Touron | 1 | +21/-2 | 2 | +| watjurk | 1 | +17/-5 | 1 | +| SukkaW | 1 | +11/-11 | 5 | +| Nicholas Bollweg | 1 | +21/-0 | 1 | +| Ho-Sheng Hsiao | 2 | +11/-10 | 6 | +| chblodg | 1 | +18/-2 | 1 | +| Friedel Ziegelmayer | 2 | +18/-0 | 2 | +| Shu Shen | 2 | +15/-2 | 3 | +| Peter Rabbitson | 1 | +15/-2 | 1 | +| galargh | 2 | +15/-0 | 2 | +| แดแด€แด›แด› ส™แด‡สŸสŸ | 3 | +13/-1 | 4 | +| aarshkshah1992 | 3 | +12/-2 | 3 | +| RubenKelevra | 4 | +5/-8 | 5 | +| Feiran Yang | 1 | +11/-0 | 2 | +| zramsay | 2 | +0/-10 | 2 | +| Teran McKinney | 1 | +8/-2 | 1 | +| Richard Littauer | 2 | +5/-5 | 5 | +| Elijah | 1 | +10/-0 | 1 | +| Dimitris Apostolou | 2 | +5/-5 | 5 | +| Michael Avila | 3 | +8/-1 | 4 | +| siiky | 3 | +4/-4 | 3 | +| Somajit | 1 | +4/-4 | 1 | +| Sherod Taylor | 1 | +0/-8 | 2 | +| Eclรฉsio Junior | 1 | +8/-0 | 1 | +| godcong | 3 | +4/-3 | 3 | +| Piotr Galar | 3 | +3/-4 | 3 | +| jwh | 1 | +6/-0 | 2 | +| dependabot[bot] | 1 | +3/-3 | 1 | +| Volker Mische | 1 | +4/-2 | 1 | +| Aayush Rajasekaran | 1 | +3/-3 | 1 | +| rene | 2 | +3/-2 | 2 | +| keks | 1 | +5/-0 | 1 | +| Hlib | 1 | +4/-1 | 2 | +| Arash Payan | 1 | +5/-0 | 1 | +| Wayback Archiver | 1 | +2/-2 | 1 | +| T Mo | 1 | +2/-2 | 1 | +| Ju Huo | 1 | +2/-2 | 1 | +| Ivan | 2 | +2/-2 | 2 | +| Ettore Di Giacinto | 2 | +3/-1 | 2 | +| Christian Couder | 1 | +3/-1 | 1 | +| ningmingxiao | 1 | +0/-3 | 1 | +| ๅธ‚ๅทๆญไฝ‘ (ebi) | 1 | +1/-1 | 1 | +| star | 1 | +0/-2 | 1 | +| alliswell | 1 | +0/-2 | 1 | +| Preston Van Loon | 1 | +2/-0 | 1 | +| Nguyแป…n Gia Phong | 1 | +1/-1 | 1 | +| Nato Boram | 1 | +1/-1 | 1 | +| Mildred Ki'Lya | 1 | +2/-0 | 2 | +| Michael Burns | 1 | +1/-1 | 1 | +| Glenn | 1 | +1/-1 | 1 | +| George Antoniadis | 1 | +1/-1 | 1 | +| David Florness | 1 | +1/-1 | 1 | +| Daniel Norman | 1 | +1/-1 | 1 | +| Coenie Beyers | 1 | +1/-1 | 1 | +| Benedikt Spies | 1 | +1/-1 | 1 | +| Abdul Rauf | 1 | +1/-1 | 1 | +| makeworld | 1 | +1/-0 | 1 | +| ignoramous | 1 | +0/-1 | 1 | +| Omicron166 | 1 | +0/-1 | 1 | +| Jan Winkelmann | 1 | +1/-0 | 1 | +| Dr Ian Preston | 1 | +1/-0 | 1 | +| Baptiste Jonglez | 1 | +1/-0 | 1 | + ## v0.12.2 and v0.11.1 2022-04-08 This patch release fixes a security issue wherein traversing some malformed DAGs can cause the node to panic. @@ -56,6 +1156,8 @@ As usual, this release includes important fixes, some of which may be critical f - `ipfs refs local` will now list all blocks as if they were [raw]() CIDv1 instead of with whatever CID version and IPLD codecs they were stored with. All other functionality should remain the same. +Note: This change also effects [ipfs-update](https://github.com/ipfs/ipfs-update) so if you use that tool to mange your go-ipfs installation then grab ipfs-update v1.8.0 from [dist](https://dist.ipfs.io/#ipfs-update). + Keep reading to learn more details. #### ๐Ÿ”ฆ Highlights @@ -246,7 +1348,7 @@ Note: the limited Circuit Relay v2 provided with this release only allows low-ba Switching to v2 of the relay spec means removal or deprecation of configuration keys that were specific to v1. - Relay transport and client support circuit-relay v2: - - `Swarm.EnableAutoRelay` was replaced by `Swarm.RelayClient.Enable`. + - `Swarm.EnableAutoRelay` was replaced by `Swarm.RelayClient.Enabled`. - `Swarm.DisableRelay` is deprecated, relay transport can be now disabled globally (both client and service) by setting `Swarm.Transports.Network.Relay` to `false` - Relay v1 service provider was replaced by v2: - `Swarm.EnableRelayHop` no longer starts an unlimited v1 relay. If you have it set to `true` the node will refuse to start and display an error message. diff --git a/Dockerfile b/Dockerfile index 751ba6a9f23..913cde19b68 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Note: when updating the go minor version here, also update the go-channel in snap/snapcraft.yml -FROM golang:1.16.15-buster +FROM golang:1.18.3-buster LABEL maintainer="Steven Allen " # Install deps @@ -25,7 +25,7 @@ ARG IPFS_PLUGINS # Also: fix getting HEAD commit hash via git rev-parse. RUN cd $SRC_DIR \ && mkdir -p .git/objects \ - && make build GOTAGS=openssl IPFS_PLUGINS=$IPFS_PLUGINS + && GOFLAGS=-buildvcs=false make build GOTAGS=openssl IPFS_PLUGINS=$IPFS_PLUGINS # Get su-exec, a very minimal tool for dropping privileges, # and tini, a very minimal init daemon for containers @@ -54,6 +54,7 @@ LABEL maintainer="Steven Allen " ENV SRC_DIR /go-ipfs COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs +COPY --from=0 $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run COPY --from=0 /tmp/su-exec/su-exec-static /sbin/su-exec COPY --from=0 /tmp/tini /sbin/tini COPY --from=0 /bin/fusermount /usr/local/bin/fusermount @@ -93,6 +94,10 @@ RUN mkdir -p $IPFS_PATH \ RUN mkdir /ipfs /ipns \ && chown ipfs:users /ipfs /ipns +# Create the init scripts directory +RUN mkdir /container-init.d \ + && chown ipfs:users /container-init.d + # Expose the fs-repo as a volume. # start_ipfs initializes an fs-repo if none is mounted. # Important this happens after the USER directive so permissions are correct. diff --git a/README.md b/README.md index cc609152b22..f8d17ad20a3 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,12 @@ With snap, in any of the [supported Linux distributions](https://snapcraft.io/do $ sudo snap install ipfs ``` +The snap sets `IPFS_PATH` to `SNAP_USER_COMMON`, which is usually `~/snap/ipfs/common`. If you want to use `~/.ipfs` instead, you can bind-mount it to `~/snap/ipfs/common` like this: + +```sudo mount --bind ~/.ipfs ~/snap/ipfs/common``` + +If you want something more sophisticated to escape the snap confinement, we recommend using a different method to install `go-ipfs` so that it is not subject to snap confinement. + #### macOS package managers - [MacPorts](#macports) @@ -406,7 +412,6 @@ Listing of the main packages used in the IPFS ecosystem. There are also three sp | **Namesys** | | [`go-ipns`](//github.com/ipfs/go-ipns) | [![Travis CI](https://flat.badgen.net/travis/ipfs/go-ipns/master)](https://travis-ci.com/ipfs/go-ipns) | [![codecov](https://codecov.io/gh/ipfs/go-ipns/branch/master/graph/badge.svg?style=flat-square)](https://codecov.io/gh/ipfs/go-ipns) | IPNS datastructures and validation logic | | **Repo** | -| [`go-ipfs-config`](//github.com/ipfs/go-ipfs-config) | [![Travis CI](https://flat.badgen.net/travis/ipfs/go-ipfs-config/master)](https://travis-ci.com/ipfs/go-ipfs-config) | [![codecov](https://codecov.io/gh/ipfs/go-ipfs-config/branch/master/graph/badge.svg?style=flat-square)](https://codecov.io/gh/ipfs/go-ipfs-config) | go-ipfs config file definitions | | [`go-fs-lock`](//github.com/ipfs/go-fs-lock) | [![Travis CI](https://flat.badgen.net/travis/ipfs/go-fs-lock/master)](https://travis-ci.com/ipfs/go-fs-lock) | [![codecov](https://codecov.io/gh/ipfs/go-fs-lock/branch/master/graph/badge.svg?style=flat-square)](https://codecov.io/gh/ipfs/go-fs-lock) | lockfile management functions | | [`fs-repo-migrations`](//github.com/ipfs/fs-repo-migrations) | [![Travis CI](https://flat.badgen.net/travis/ipfs/fs-repo-migrations/master)](https://travis-ci.com/ipfs/fs-repo-migrations) | [![codecov](https://codecov.io/gh/ipfs/fs-repo-migrations/branch/master/graph/badge.svg?style=flat-square)](https://codecov.io/gh/ipfs/fs-repo-migrations) | repo migrations | | **IPLD** | diff --git a/assets/README.md b/assets/README.md index 3bfea9b8f64..02af2f19ca0 100644 --- a/assets/README.md +++ b/assets/README.md @@ -5,15 +5,11 @@ This directory contains the go-ipfs assets: * Getting started documentation (`init-doc`). * Directory listing HTML template (`dir-index-html`). -These assets are compiled into `bindata.go` with `go generate`. - ## Re-generating -Do not edit the .go files directly. - -Instead, edit the source files and use `go generate` from within the +Edit the source files and use `go generate` from within the assets directory: ``` go generate . -``` \ No newline at end of file +``` diff --git a/assets/assets.go b/assets/assets.go index d8bf49a00ea..ff87eec12ce 100644 --- a/assets/assets.go +++ b/assets/assets.go @@ -1,32 +1,65 @@ //go:generate npm run build --prefix ./dir-index-html/ -//go:generate go run github.com/go-bindata/go-bindata/v3/go-bindata -mode=0644 -modtime=1403768328 -pkg=assets init-doc dir-index-html/dir-index.html dir-index-html/knownIcons.txt -//go:generate gofmt -s -w bindata.go -//go:generate sh -c "sed -i \"s/.*BindataVersionHash.*/BindataVersionHash=\\\"$(git hash-object bindata.go)\\\"/\" bindata_version_hash.go" -//go:generate gofmt -s -w bindata_version_hash.go package assets import ( + "embed" "fmt" - "path/filepath" + "io" + "io/fs" + gopath "path" + "strconv" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" + "github.com/cespare/xxhash" cid "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" options "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" ) +//go:embed init-doc dir-index-html/dir-index.html dir-index-html/knownIcons.txt +var Asset embed.FS + +// AssetHash a non-cryptographic hash of all embedded assets +var AssetHash string + // initDocPaths lists the paths for the docs we want to seed during --init var initDocPaths = []string{ - filepath.Join("init-doc", "about"), - filepath.Join("init-doc", "readme"), - filepath.Join("init-doc", "help"), - filepath.Join("init-doc", "contact"), - filepath.Join("init-doc", "security-notes"), - filepath.Join("init-doc", "quick-start"), - filepath.Join("init-doc", "ping"), + gopath.Join("init-doc", "about"), + gopath.Join("init-doc", "readme"), + gopath.Join("init-doc", "help"), + gopath.Join("init-doc", "contact"), + gopath.Join("init-doc", "security-notes"), + gopath.Join("init-doc", "quick-start"), + gopath.Join("init-doc", "ping"), +} + +func init() { + sum := xxhash.New() + err := fs.WalkDir(Asset, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + file, err := Asset.Open(path) + if err != nil { + return err + } + defer file.Close() + _, err = io.Copy(sum, file) + return err + }) + if err != nil { + panic("error creating asset sum: " + err.Error()) + } + + AssetHash = strconv.FormatUint(sum.Sum64(), 32) } // SeedInitDocs adds the list of embedded init documentation to the passed node, pins it and returns the root key @@ -48,7 +81,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { basePath := path.IpfsPath(dirb.Cid()) for _, p := range l { - d, err := Asset(p) + d, err := Asset.ReadFile(p) if err != nil { return cid.Cid{}, fmt.Errorf("assets: could load Asset '%s': %s", p, err) } @@ -58,7 +91,7 @@ func addAssetList(nd *core.IpfsNode, l []string) (cid.Cid, error) { return cid.Cid{}, err } - fname := filepath.Base(p) + fname := gopath.Base(p) basePath, err = api.Object().AddLink(nd.Context(), basePath, fname, fp) if err != nil { diff --git a/assets/assets_test.go b/assets/assets_test.go deleted file mode 100644 index 8300af88489..00000000000 --- a/assets/assets_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package assets - -import ( - "bytes" - "io/ioutil" - "sync" - "testing" -) - -// TestEmbeddedDocs makes sure we don't forget to regenerate after documentation change -func TestEmbeddedDocs(t *testing.T) { - testNFiles(initDocPaths, 5, t, "documents") -} - -func testNFiles(fs []string, wantCnt int, t *testing.T, ftype string) { - if len(fs) < wantCnt { - t.Fatalf("expected %d %s. got %d", wantCnt, ftype, len(fs)) - } - - var wg sync.WaitGroup - for _, f := range fs { - wg.Add(1) - // compare asset - go func(f string) { - defer wg.Done() - testOneFile(f, t) - }(f) - } - wg.Wait() -} - -func testOneFile(f string, t *testing.T) { - // load data from filesystem (git) - vcsData, err := ioutil.ReadFile(f) - if err != nil { - t.Errorf("asset %s: could not read vcs file: %s", f, err) - return - } - - // load data from emdedded source - embdData, err := Asset(f) - if err != nil { - t.Errorf("asset %s: could not read vcs file: %s", f, err) - return - } - - if !bytes.Equal(vcsData, embdData) { - t.Errorf("asset %s: vcs and embedded data isn't equal", f) - return - } - - t.Logf("checked %s", f) -} diff --git a/assets/bindata.go b/assets/bindata.go deleted file mode 100644 index 512eb789cd9..00000000000 --- a/assets/bindata.go +++ /dev/null @@ -1,433 +0,0 @@ -// Code generated by go-bindata. (@generated) DO NOT EDIT. - -//Package assets generated by go-bindata.// sources: -// init-doc/about -// init-doc/contact -// init-doc/help -// init-doc/ping -// init-doc/quick-start -// init-doc/readme -// init-doc/security-notes -// dir-index-html/dir-index.html -// dir-index-html/knownIcons.txt -package assets - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -// Name return file name -func (fi bindataFileInfo) Name() string { - return fi.name -} - -// Size return file size -func (fi bindataFileInfo) Size() int64 { - return fi.size -} - -// Mode return file mode -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} - -// ModTime return file modify time -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} - -// IsDir return file whether a directory -func (fi bindataFileInfo) IsDir() bool { - return fi.mode&os.ModeDir != 0 -} - -// Sys return file is sys mode -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _initDocAbout = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x94\x41\x6f\xe4\xb6\x0f\xc5\xef\xfe\x14\xef\xf6\xdf\x4d\xc6\x33\xc0\xff\xb8\x28\x7a\x68\xd3\x74\x83\x05\x82\x00\x49\x51\xf4\x16\x5a\xe2\xd8\x6c\x64\xd1\x90\xe8\x99\x75\x3f\x7d\x21\x79\x9c\x4c\xb1\xb9\x24\x70\x48\x8a\xfc\x91\xef\x35\xf8\xe1\xe7\xe1\xe9\xfe\x19\x6d\x8b\x87\x68\x9c\xda\xa7\x40\x91\x8d\xd2\x82\x7b\x09\x8c\xbc\x64\xe3\xb1\x69\x6a\x90\x64\x10\xfa\xa0\x1d\x85\x1d\x4e\x9c\xb2\x68\x64\xbf\xc3\xc4\x9c\x5a\xd3\xb6\xfc\xc6\x51\x02\xaf\x59\x7b\x3c\x18\x9c\x8e\x9d\x44\xce\xe8\x55\x3d\xc4\x33\xe5\xe6\x98\x74\xc4\xef\x62\x3b\xfc\x22\xf6\xa2\x29\x71\xb4\x1d\xbe\x91\xe7\x31\x08\xed\xf0\x7c\xff\xbc\x03\x45\x0f\x1b\x18\x7f\x72\x57\x0b\x49\x46\x90\x37\x06\x21\x4b\xec\x03\xa3\x13\x6b\x1b\x5b\xb3\x91\xcf\x94\xc6\x1d\xf8\xbb\x1b\x28\xf6\x12\x7b\xf4\x62\xd0\xee\x6f\x76\x96\xf7\xeb\x8c\x53\xd2\x93\x78\xce\xa0\x08\x29\xc3\x1e\xc9\x31\x28\x23\xcb\x38\x05\x6e\x28\xd7\x07\xbf\xbe\xbc\x3c\xe1\xcc\xdd\x0e\xdd\x6c\x38\x8b\x0d\x98\x38\x8d\x14\x39\x3a\x46\x37\x4b\xb0\x56\xe2\x1e\x7f\xe9\x0c\x47\x11\x14\xb2\x62\xd4\x39\x5a\x4d\x3f\x6b\x0a\xbe\x21\xc3\x41\xa6\x63\xde\x5f\xa3\x9b\x92\x9a\x3a\x0d\x5f\x9a\x16\x9e\x8f\x15\x0b\xc1\x69\x34\x8e\xd6\x92\xf7\x89\x73\x66\x5f\x11\x6e\xe4\x5b\x38\xd5\xe4\x25\x92\x71\xde\x62\xe1\x39\xc8\x89\xd3\x52\xff\x7d\x01\xbc\xf1\xc3\xed\x15\x56\xdc\x16\xd0\xd7\x4d\x7c\xec\xa7\xb4\x31\x50\x86\x97\xc4\xce\x34\x49\x45\xb3\x3e\x9f\x9b\x76\x9d\x89\xba\xc0\x57\x39\xf8\x74\x12\xc2\xfd\x1f\xcf\xbf\x7d\xbe\x2e\x7a\xe6\xae\x54\x2b\x38\x3a\xc6\x5c\x86\x30\xc5\x49\xf8\x0c\xaf\x6e\x1e\x39\xda\x65\x7d\x15\x11\x77\x4d\xbb\x16\x05\x39\xc7\x39\x4b\x79\xa5\x54\xae\xf0\xc9\xf0\x3a\x98\x4d\x5f\x0e\x2b\x43\xd1\xc3\x4f\x13\xd9\xf0\xf3\x6b\xd3\xa2\x4b\x7a\xce\x9c\x32\x34\x81\xbf\x1b\xc7\x72\x85\xb9\x3e\x1d\x98\x52\x2c\x0f\xcf\x99\xf1\x5a\x52\xbf\x1c\x0e\xaf\x97\xf9\xc2\xb2\x8e\x3b\x5c\x81\xde\x70\xf6\x33\x25\x8a\xc6\xbc\x5e\x00\xcd\x36\x70\x34\x71\x62\xcb\xc7\x94\xa3\xfa\x39\x50\xaa\x73\x6a\x8c\xec\x4c\x34\x22\xd0\xc2\x09\x7a\xe2\x04\x8a\x0b\x22\xdb\x59\xd3\xdb\xfb\xaa\x9b\x16\x49\x67\x2b\x07\x59\x23\x9b\xb6\x34\x57\x90\xfd\xe7\x33\xee\xbe\xbe\xe0\xd3\xdb\x65\x83\x07\xa7\x89\xc2\xe7\x8f\xd8\x32\x7c\xdb\x51\x69\x39\xd2\x58\xb2\x32\xa7\x93\x38\xde\x42\x3e\x16\xde\x4a\xcc\x93\x24\xf6\xe8\x82\xba\xb7\x4d\x11\x7c\x99\xa3\x46\xbb\xb4\x4c\xa6\x75\x90\xfa\x57\x9f\x68\x1a\xc4\xb5\x85\xce\x3b\x93\x0b\x25\x89\x7d\x81\x5e\x6a\xb5\x81\x4f\x1c\xe0\xd9\xcf\x53\x10\x47\x65\xfe\xcb\x1e\xab\x9e\xfa\x24\xb6\xe0\x76\x73\x86\x35\xf3\xe3\x74\x2e\xe9\x1c\xeb\xa3\x85\xdd\x2d\xb2\xf4\xb1\x8e\x33\x4f\x93\xa6\xab\x3b\x9d\xfe\x3f\x95\xfe\xaa\x98\xce\xe2\xf9\x47\x8f\x81\x25\x8a\xf9\xc8\x29\xaf\x22\x98\x02\x1b\x87\x05\x9e\x1d\x47\x4b\x14\xe4\x1f\xf6\xa0\xe4\x06\x31\x76\x36\xa7\x02\xeb\xe6\x26\xea\xcd\x0d\x2e\x11\x98\x54\xa2\x41\x8f\x38\x92\x84\x12\x71\x75\xd2\xbf\xde\x3d\x96\x0e\xc8\xfb\x8b\x68\xca\x61\x95\xeb\xb8\x12\x43\x50\x47\x21\x2c\xab\x59\x89\xfd\x2f\x23\xea\x19\x74\x22\x09\x55\x37\x97\x8c\xd5\x12\x8a\x3c\xdc\x20\xb1\x6f\x8f\x49\x38\xfa\xb0\xe0\xd3\xa6\xfd\x4a\x7e\x5d\x6d\x59\xfb\xd5\x3a\xd7\xad\x77\x14\x0b\x06\x1b\xe0\x25\x5b\x92\x6e\xae\xf0\xd7\x76\x8b\x86\xa9\x64\xf3\x76\x16\xa5\xf1\x87\xa7\xc7\xea\xa2\xc5\x4d\xf1\x7e\x14\x6b\xd4\x66\x2d\xab\x97\xd7\x8f\x79\x2a\x66\xb8\xbe\xa6\x11\x4f\xdf\x1e\x9a\xb6\x96\x2b\x9a\xd0\x6a\x7b\x1e\x96\xe6\x6c\x70\x03\x49\xdc\xa8\x93\x55\xed\x56\x9b\x54\x1b\x38\xe1\xf1\xb9\xba\x47\x11\xe4\x48\x13\xee\x4a\x1b\x7b\x8d\xa2\x71\x87\x7d\x57\x5c\x9f\xcd\x95\x9a\xa5\xc3\xe6\xdf\x00\x00\x00\xff\xff\x6d\xaa\xeb\xd6\x91\x06\x00\x00") - -func initDocAboutBytes() ([]byte, error) { - return bindataRead( - _initDocAbout, - "init-doc/about", - ) -} - -func initDocAbout() (*asset, error) { - bytes, err := initDocAboutBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/about", size: 1681, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _initDocContact = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\xcd\xb1\x6a\x44\x21\x10\x85\xe1\xde\xa7\x38\x90\x5a\xed\xad\x42\x2e\x81\xa4\xcd\x1b\x18\x77\xae\x0e\xac\xce\x8d\x33\x2e\xec\xdb\x07\xb7\x3a\x70\xf8\xe0\x3f\xa4\x13\x5a\x1e\x15\xb2\x0c\x3c\x20\x6b\xe2\xfb\xe7\x40\x69\xd9\x30\x45\x3a\xf8\xc4\x53\x16\x5a\x7e\x10\xf2\x78\xe2\x6f\x91\x1a\xcb\xd0\xe0\xdc\x21\xc3\x72\x31\x58\x23\xf0\x75\x2a\x6e\xf4\x80\x51\xee\xc9\x79\x7c\xac\xaa\x09\xcd\xec\xd2\x14\x63\x65\x6b\xeb\x37\x14\xe9\x71\xcb\x58\xc5\xbf\x96\x55\x17\xa9\xf3\xf8\xa2\xfb\x95\xc0\xb3\x84\x73\x12\x0d\xb9\x51\x90\x59\xe3\xdb\x56\xce\xe3\xb3\x67\xbe\xa7\x1d\x78\xdf\x4f\x60\x71\xff\x01\x00\x00\xff\xff\x7d\x69\x95\xc6\xbd\x00\x00\x00") - -func initDocContactBytes() ([]byte, error) { - return bindataRead( - _initDocContact, - "init-doc/contact", - ) -} - -func initDocContact() (*asset, error) { - bytes, err := initDocContactBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/contact", size: 189, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _initDocHelp = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x3c\x8e\xb1\x72\x84\x30\x0c\x44\x7b\xbe\x62\x67\x52\x1b\x7a\xda\x54\x69\x93\x2f\xf0\x19\x19\x6b\x62\x2c\x22\xc9\x77\xc3\xdf\x67\xb8\x0b\x29\xb5\xbb\x6f\xb5\x5f\xb2\x11\x0a\xd5\x3d\xf7\x0a\x25\x93\xae\x89\x0c\x59\x14\x99\xdb\xc2\x6d\xc5\x21\x5d\xf1\x88\x07\xa2\x4a\x6f\x0b\x78\xcf\x36\x0f\x43\xc0\x4f\xe7\xf4\x1d\xcc\xa3\xfa\x8c\xf8\x3a\x61\x45\x1e\x90\x8c\x7b\x54\x96\x6e\xcf\x34\x32\x45\xef\x4a\x36\x0e\xe1\x25\x24\xd9\xb6\xd8\x16\x3b\xb9\xca\xe6\x27\x11\x6b\xfd\xd7\xaf\x5c\x08\xe7\xb6\x19\x74\x27\x3d\x2e\x17\x0b\x59\x52\xbe\x91\x81\xdd\xa8\xe6\x21\xa0\xb8\xef\x36\x4f\xd3\xca\x5e\xfa\x6d\x4c\xb2\x4d\x67\xc1\xb4\x4a\xf8\x2b\x82\x17\x82\x69\x82\xd2\x2e\xc6\x2e\x7a\x0c\x01\x6f\x4f\x57\x1a\x58\xd3\x98\x95\xa8\xc9\x42\xa3\xe8\x7a\x11\xe7\xcf\xde\xd8\x0f\x7c\x7c\xbe\x23\x95\xd8\x1a\xd5\xe1\x37\x00\x00\xff\xff\xd3\xb7\x7e\x3c\x37\x01\x00\x00") - -func initDocHelpBytes() ([]byte, error) { - return bindataRead( - _initDocHelp, - "init-doc/help", - ) -} - -func initDocHelp() (*asset, error) { - bytes, err := initDocHelpBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/help", size: 311, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _initDocPing = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xca\x2c\x48\x2b\x06\x04\x00\x00\xff\xff\x62\xe3\x30\xc9\x04\x00\x00\x00") - -func initDocPingBytes() ([]byte, error) { - return bindataRead( - _initDocPing, - "init-doc/ping", - ) -} - -func initDocPing() (*asset, error) { - bytes, err := initDocPingBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/ping", size: 4, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _initDocQuickStart = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x54\xdb\x72\xdb\x38\x0c\x7d\xc7\x57\x60\xdd\x97\xec\xec\x28\x72\xea\x3a\x75\x32\x3b\x99\x49\x9d\xc6\xae\x9b\x78\xe3\xe6\x9e\x37\x5a\x04\x25\xda\xe2\xa5\x24\x6d\x45\xfe\xfa\x1d\xc9\xd7\x99\xe6\xf6\x46\x00\x07\x38\xe7\x10\xa2\x3e\x61\x73\xff\x00\x23\x1c\xcd\x64\x32\xc5\xeb\xc0\x5c\x00\xb8\xc9\xa4\x47\xe9\x91\xa1\xa7\x80\x46\xa0\xcf\x8c\x0b\x48\xcf\x4c\xd9\x9c\x3c\x16\x32\x64\xa8\xa4\x96\x8a\xe5\x48\xcf\x36\x67\x9a\x05\x69\xf4\x3e\xfe\x08\x55\x9f\x22\xa6\x03\x32\x0f\x0c\x1b\xbf\xeb\xc1\xbe\x1a\xdc\xd8\x07\x80\x53\xce\x91\xa1\x90\x39\x61\x30\x28\xad\xf0\xc7\x00\x88\x94\x64\x06\x1b\x19\xe5\xb9\xc1\xc2\xb8\x9c\x37\xf0\xa4\x8e\x00\x6b\x10\x32\xce\x71\x99\x00\xb8\x93\x54\xa0\x0c\x75\x63\x5d\x4c\x58\xc0\x7f\x43\x46\x51\xc6\x7c\x16\x95\x66\x16\xa5\x26\x44\x19\x39\x3a\x01\x80\x1b\x57\x22\x43\x2e\x1d\x25\xc1\xb8\xb2\x6e\x53\x53\x2e\x1d\x0a\x63\x76\xcf\xf1\x98\xb9\x8d\x96\x31\x5b\x34\xf0\x64\x95\x5e\xbc\x9c\x76\xab\xd2\x46\x61\xb4\x9c\xb9\x92\x18\x32\xa9\x53\xbf\x95\x99\xfb\x1d\x95\x4b\x75\xaf\x56\x56\x5a\x5e\xb0\xb7\x2e\x2f\xde\x2e\xbb\x0f\x40\xde\xa4\x5f\x00\xc0\x2f\x12\xe4\x48\x27\xb4\xe3\xc2\x91\x78\xd5\x47\x5d\x8b\xdc\xdb\xe5\x28\xa3\xdc\x02\x40\x8f\x76\x56\x98\xd2\x1f\x0a\x31\x32\xd5\x6d\x7e\x06\x44\x2e\x85\xa8\xce\xcb\x18\xe0\xbf\xf1\x84\x92\xb0\x23\xca\xd4\x89\x97\xa6\xbc\x8f\x88\x57\x24\xbb\xb0\x8d\xc8\x2b\xa9\xf1\x1f\xec\x75\xb7\x54\x56\xea\x7a\xd7\xaf\x7a\xb4\x06\xd3\xe4\xfd\x9d\x57\x73\x9c\x7a\x6f\x0c\xc0\x19\x23\x65\xf4\x96\x9f\xd7\x31\xe2\x5e\xa5\x43\x9b\x90\x91\xc3\x40\x4e\x49\xcd\xf2\xbf\xd7\x20\xc9\x01\x60\x48\xa1\x30\x6e\x5a\xb7\xee\xa9\x99\x0f\x38\x26\x34\x3a\x97\x9a\x36\x40\x5f\x30\xa7\xd0\x12\x39\xbf\xd3\xbb\xfb\xd9\xd4\xda\x8c\x88\x1c\x29\x13\x28\x5a\x5e\x50\xf5\xae\x2e\xcd\x4c\x2f\x37\xb8\x57\x30\xa7\xa5\x4e\x8f\x51\xcc\x3c\x55\xbf\x00\x21\xb5\x4c\xa6\xe5\x5f\x1b\x1e\x55\x81\x01\x31\xe1\x18\x57\x89\xf8\x4f\xdf\xb9\xaf\x1e\xab\x31\xf9\xd6\xeb\x9c\x9c\x97\x46\xaf\xc3\x99\xe5\x2c\xd0\x46\x9d\x51\x8a\x69\xee\xb7\xb1\x16\x32\x5d\xaf\x0e\xd1\x58\xd2\x98\x85\x60\x8f\xe3\x38\x37\x09\xcb\x33\xe3\xc3\x71\xbb\xd9\x3c\x88\x0b\x1a\xcf\x24\x00\x7c\x73\xa6\xf0\x54\xf3\xdd\xd3\xf8\xf6\x47\x7d\xc2\xb7\x9b\x10\xe7\x92\x93\x79\x0d\xda\x69\x76\x9a\x4b\x87\x23\x75\x97\x1c\x2e\x66\xa7\x9a\x7e\x0e\x16\x32\xd1\x03\x2b\xdc\xef\x6e\xff\x28\xbd\x2e\x0f\xc7\x8b\xf6\x97\x41\x96\x94\x56\x0c\x1e\xb3\xde\xed\xf9\x68\x16\xdb\x9c\x95\x9f\xd6\x9d\x37\x3f\x9f\xd2\x5f\xc3\xe2\x6c\xf8\x54\xf4\xc3\xe0\x7a\xd2\xb5\x87\xae\x7d\xfe\x48\x62\x61\x6f\x2f\x44\xd9\xfa\x3a\x98\x5f\x86\xa3\xb3\x62\xfe\xe0\xa9\xbe\x2d\xc5\xd2\xd5\x23\x7d\x47\xd3\x93\x4d\x5a\xfd\xb9\x98\x7c\x7f\x98\x5f\xdc\xf7\x46\x57\xf7\xe3\xfe\xb4\x75\x3a\x39\x6b\x4f\x3a\xc3\xef\xc3\x2f\xa9\x3a\x1f\x76\x06\xca\xf1\x76\xda\x69\xc5\x89\xaf\x7f\x96\xcc\x4d\xb9\x29\x34\x3a\xd2\x9c\x1c\x39\x64\xd6\x7e\x84\xeb\xe1\xeb\xe5\x51\x57\x3e\x3e\x4c\xee\xe8\x5c\x4f\xc5\x5d\x4f\xb4\xca\xb6\x7c\xbe\x79\xfa\x7c\xda\xa5\xeb\x5e\x79\x71\x30\xff\x36\x78\x3c\xe8\xcf\x47\x57\x36\x56\x15\x05\xfc\x1f\x00\x00\xff\xff\x18\xa0\x78\x77\x91\x06\x00\x00") - -func initDocQuickStartBytes() ([]byte, error) { - return bindataRead( - _initDocQuickStart, - "init-doc/quick-start", - ) -} - -func initDocQuickStart() (*asset, error) { - bytes, err := initDocQuickStartBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/quick-start", size: 1681, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _initDocReadme = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x53\x4d\x6f\x13\x31\x10\xbd\xfb\x57\xbc\x9e\xb8\x90\x70\xaf\xb8\x21\x21\x7a\x00\x21\x28\xea\xd9\xf5\xce\xc6\x56\xbc\xf6\xe2\x19\x13\x56\xca\x0f\xe0\xd8\x48\x0d\x95\x90\xf2\xe7\xf2\x4b\x90\x4d\x36\x6d\xf3\x71\xa0\xd6\x1c\xc6\x4f\x33\xef\xcd\x3c\xef\x7e\x20\xef\x23\x74\x68\x70\x43\xde\xc4\x8e\x20\x11\x57\x9f\xdf\x7f\xbd\x50\x6a\xfb\xfb\x57\x89\xf5\xc3\x2e\x79\x1a\xeb\x07\x9c\x40\xcf\x55\x57\x7c\xcf\xb7\x1a\x93\xfb\xed\xfa\xae\xc4\x41\xe7\x1e\xdf\xc5\xe6\x1c\x7e\xc4\xf8\x4c\xf0\xfe\xb1\xf3\xe9\xd8\x67\xe7\x3e\x3f\x5f\x15\xc3\x11\xba\x01\xb6\xeb\x3f\xcf\x66\x1a\x19\x8e\xb9\x56\x28\xe7\xe4\xed\x70\x92\x95\x1a\x69\x37\xfb\xe4\x5f\xfd\xc9\xdb\xdd\xa1\x2b\xea\xaa\xc5\x10\xf3\xab\x44\x60\x22\x17\x66\x10\xeb\xf8\x75\xc1\x60\xf5\x0f\x02\x67\x63\x88\xb9\xcd\xde\x0f\x70\x81\x45\x7b\x4f\x8d\x2a\xcf\x5e\x3f\x05\x9d\x08\x21\x2e\xe0\x82\x50\x6a\xb5\x29\x14\x0b\x27\x16\x62\x09\xae\x6f\x19\x1d\xa5\xb9\xa7\x46\xcf\x2e\x94\xc2\xe4\x65\x47\x2d\x71\xa3\x53\x70\x61\x76\x89\xff\x3a\x4b\xb5\x04\x70\x6d\x1d\xc3\x31\xb4\xef\xad\x06\xc7\x56\x16\x3a\xd1\x14\xdf\x98\xa0\xa5\x2c\x9b\x10\x17\x01\x8d\x63\x93\x48\x5c\x0c\x17\xbb\xce\x8f\xd9\xd8\xd2\xd9\x39\xe6\xb2\x5a\x4c\xf0\xda\xcc\x4b\xda\x47\xef\xd8\x4e\x71\x6d\x29\x51\xf5\xe1\x36\xcf\x78\x3a\x6a\x7e\x8a\x82\x81\x04\x4c\x26\x17\xad\x2f\xa4\x9b\x6a\x4a\x05\x9c\x0c\x08\x51\x88\xd1\xc6\x84\x2e\x96\x8a\xd2\xf9\x62\x83\xd4\x3b\x4b\x66\x8e\x98\x05\x5c\x7e\xcd\xd8\x56\xb1\x28\x96\x12\x5a\xe7\x89\xe1\x42\x7d\x5c\x34\x2e\x91\x91\x98\x86\x4b\xa5\x80\xe9\x1b\x7d\x1b\xb3\xd4\xcc\x92\xef\x6b\xf2\x3d\x3b\x33\x9f\xb0\xe8\x24\xd5\xc6\xb7\x93\x09\x32\xeb\x19\x81\x7e\xea\xae\xf7\xc4\xb5\x2c\x91\x6e\x3a\x7a\x74\xbb\x94\x55\x89\x22\x58\x2b\xc6\x65\x27\x75\x59\xf5\x37\x00\x00\xff\xff\x16\x13\x92\x0d\x43\x04\x00\x00") - -func initDocReadmeBytes() ([]byte, error) { - return bindataRead( - _initDocReadme, - "init-doc/readme", - ) -} - -func initDocReadme() (*asset, error) { - bytes, err := initDocReadmeBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/readme", size: 1091, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _initDocSecurityNotes = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x53\xd1\x6e\xdb\x46\x10\x7c\xe7\x57\x4c\xf3\xd0\xbc\x28\xb4\x5d\xd7\x72\x6c\x20\x68\xe5\x44\x36\xfc\xe2\x18\xb1\xdb\xa2\x8f\xc7\xe3\x8a\x5c\xe8\x78\x4b\xdc\xed\x89\xe6\xdf\x17\x4b\x41\x46\x81\x56\x8f\xe2\xde\xcc\xec\xce\x0c\xfe\xe7\xf7\xf8\x7c\xff\x82\x4d\x18\x7b\x87\x17\xf2\x25\xb1\xce\x78\x12\xa5\x5c\x55\x7f\x11\x34\xcd\xe8\x5d\x6a\xa1\x02\x8a\xb9\x24\x82\x94\x84\x3c\x67\xa5\x01\x9c\x91\xdd\x8e\xe0\x62\x8b\x24\x4d\xc9\xba\x42\x53\x14\x2e\x04\x64\xd9\xe9\xe4\x12\x55\xbd\xcb\x68\x4a\x97\x57\xa0\x3c\x92\x67\x17\xc2\x8c\x48\xd3\xfb\x44\x8d\xd7\x9e\x33\x5a\xce\x9a\xb8\x29\xca\x12\x0d\x79\x20\x17\xd5\x78\x1b\x23\xa8\xdc\x22\x71\x4c\x74\x60\x9a\x56\x68\x25\x7e\x54\x94\x4c\x60\xc5\x4e\x12\x5c\x9c\xb5\xe7\xd8\x61\xe0\x9c\x0d\xc2\x27\x56\xf6\x2e\xd4\x55\xf5\x1c\xc8\x65\x42\x14\x25\x68\x4f\xd8\x49\x08\x32\x71\xec\x6e\xab\xea\xd3\x91\x9d\x33\x8e\x0c\x27\x55\xcb\x52\xa6\x3d\x8a\xa2\x21\x8a\x70\xa5\x65\xa5\xb6\xc6\xa3\xda\xb8\xdd\xa1\x13\x17\x2a\x98\x48\x2f\xb1\x2d\x5e\x61\x12\x65\xa4\x84\x7c\x3a\xe6\xf2\x0c\x12\x3d\x61\x22\xf8\x20\xa6\x39\x42\x22\x1c\x2e\xea\x73\x24\x5a\xd4\xd5\x26\x85\xc7\xdd\x51\x0a\x22\xe9\x24\x69\x4f\xad\xe1\x75\xc9\x0d\xab\x45\xd0\xe0\xcc\x8f\x03\x21\x53\x62\x29\x19\x25\xb6\x9c\xbd\x1c\x28\x51\x5b\x01\x87\x12\x22\x25\xd7\x70\x60\x65\xca\x27\xad\x53\x62\x55\x8a\xc6\xfb\x20\x47\xa4\x89\xd0\xca\xb2\x1c\xbd\x91\x2f\x6a\x0b\xcf\x15\xec\xa4\xc9\x38\x0f\xdc\x52\x8b\xd6\xa9\xab\x71\x57\x14\xe3\xf1\x86\xa3\x70\x54\x1b\xb5\x99\x26\xd0\x60\x87\x58\x6c\x2a\xd9\xe0\x5d\x05\x74\xac\x7d\x69\xc0\x39\x17\x5a\x41\x12\x68\x70\x1c\xde\x2f\xf2\xbb\x6d\x59\xb3\x60\x4c\x7c\x70\x4a\x61\x5e\x76\xff\xcf\xe7\x87\xe7\x07\xec\x69\xbe\xad\x80\x4f\xf8\xf5\xee\x66\xbd\xbe\xba\xbf\xc3\xcd\x2f\xeb\xcb\xf5\xb7\x8b\x6b\x5c\x7f\xbd\xde\x7c\x5e\x7f\xbb\xc4\xd5\xf9\x66\xb3\xfd\xbc\xb9\xc1\xd5\xcd\xdd\xc5\xe5\xe6\xfe\x72\x79\xd0\xab\x8e\xf9\xf6\xec\x6c\xec\xc6\x7a\x60\xad\xa9\x2d\x67\xe3\x3e\x9f\x05\x91\x7d\x19\x7f\x93\xf1\x4b\x47\xfa\x73\x26\x97\x7c\xff\xe5\xfc\xed\x04\xf2\x8e\x71\x72\xa3\x64\xca\xa0\xe8\xd3\x3c\x2e\xc9\x5c\xb2\x16\x02\xbc\x0c\x43\x89\xec\x9d\xfd\x7b\x8c\x3d\xeb\xc7\x8c\xa7\xef\xaf\x78\xfe\xf1\xfd\xcf\xed\x13\x5e\xb6\x5f\xff\xf8\xb1\xad\x80\xbf\xb7\xaf\x3f\xc1\xac\x30\xfb\x1a\x82\x8a\x2e\x2d\x68\x92\xec\x29\xd6\xb8\x97\x84\x28\xd3\x6a\x09\xa7\x97\x96\xcc\x33\x8e\x3e\x14\xf3\x40\x05\x83\xdb\x53\x05\x2c\xfd\x9b\x08\x0d\x45\xdf\x0f\x2e\xed\x97\x10\x5a\xdc\x16\x15\x19\x13\x6b\xff\x6f\xb1\x1c\x31\x70\xb4\xc8\xc6\x63\xf0\x8b\x96\x44\x2b\x8b\x6c\x4f\x86\xc5\x21\x1c\xfb\x85\x0f\x25\x5a\x97\x3f\x60\x30\x7e\xdb\xb2\xe7\xae\xc7\x48\x69\x27\x69\x70\x16\x5f\x8e\x9a\x5c\x24\x85\x1b\xc7\x5c\x57\xc0\xe3\x0e\x7a\x2a\x0f\x9a\x20\x7e\x6f\x05\xdc\x91\x33\x96\x05\x63\x96\xb2\x3a\x45\xc7\x4b\x54\xe7\xad\xb4\x75\xf5\x4f\x00\x00\x00\xff\xff\xa9\x8a\x29\x7c\x8a\x04\x00\x00") - -func initDocSecurityNotesBytes() ([]byte, error) { - return bindataRead( - _initDocSecurityNotes, - "init-doc/security-notes", - ) -} - -func initDocSecurityNotes() (*asset, error) { - bytes, err := initDocSecurityNotesBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "init-doc/security-notes", size: 1162, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dirIndexHtmlDirIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xfc\xd7\x12\xf4\xb8\x76\x26\x0a\xde\xeb\x29\xfe\xd9\x31\x17\x33\x87\x2d\x91\x49\x4f\x1d\xed\x8e\xa1\xf7\x49\x6f\x6f\x3a\xe8\xbd\xf7\x54\xe8\xdd\x27\xea\x2f\xa9\x77\xb5\xb4\xa5\xee\x3e\xaa\xe8\x28\x5e\x24\x88\x04\xf0\x01\x0b\x58\x58\x06\x0b\x99\xff\xf0\xff\xe2\x0c\xd6\x8d\x4c\xfe\x47\xbd\x0f\xfd\x7f\xfd\x9b\x7f\xfc\xc7\x1f\xff\xef\x75\x9a\xf6\x1f\x7f\xff\xe7\x1f\x7f\xf7\xe3\x9f\xfe\xe9\x6f\xfe\xe1\x97\xef\x7f\xf4\xc9\x58\xfd\xf9\x4f\xc5\xf8\xa7\xff\xfa\x37\xff\x50\x17\x49\xfe\x5f\xff\xe6\x1f\x86\x62\x4f\x7e\x64\x75\xb2\x6e\xc5\xfe\xe7\x3f\x1d\x7b\xf9\xb7\xe4\x9f\x7e\x80\xff\x52\x30\x26\x43\xf1\xe7\x3f\xe5\xc5\x96\xad\xcd\xbc\x37\xd3\xf8\xa7\x1f\xd9\x34\xee\xc5\xb8\xff\xf9\x4f\xf4\x8f\xbc\x59\x8b\x6c\x9f\xd6\xe7\xc7\x54\xfe\x28\x9b\xbe\xd8\x7e\xd4\xd3\xb6\x17\xf9\x8f\x69\xfc\xb1\xd7\xc5\x8f\xbc\xd9\xf6\xb5\x49\x8f\xbd\xc8\xff\xcb\x8f\xbc\xc8\x8a\x71\x5f\x93\xbe\x79\x8b\xfc\xc7\x55\xa4\x3f\x8e\xad\x19\xab\x1f\xb2\x29\x38\x7f\xfa\x97\x0e\xe7\x75\x9a\x8b\x75\x7f\xfe\xfc\xa7\xa9\xfa\xfb\xbd\xd9\xfb\xe2\x37\x3d\x0a\x3f\xbb\x98\xc6\xff\xa0\xc9\x5f\x1f\xea\x3f\xfe\xe3\x8f\xbf\x33\x93\xbd\xfe\xf1\x4f\xff\xf4\xef\xf4\xf4\xcc\xbf\xed\xe8\x2a\xd2\xad\xd9\x8b\xbf\x5e\xb7\x19\x92\xea\xb7\x95\xeb\x7d\x9f\xb7\xbf\x07\xc1\x2a\xd9\x8b\x2b\x79\xfe\xae\x99\xcb\xed\xef\x9a\x09\xfc\x25\x05\xad\xc1\xe1\x8a\x88\x2e\xa8\xa1\x4a\xf0\x6f\xee\x4e\x2f\x1d\x1f\x8f\xa8\x21\xd6\x27\x6c\x37\x6d\x3f\x43\x98\x0c\x85\x5b\x91\xc8\xc9\x6c\x97\x3f\xfd\x8f\xf3\xbe\x5f\xcd\xbe\x17\xeb\xbf\x99\x87\xbf\x46\xce\xff\xd8\xe2\xff\xe0\x8a\xfd\x8f\x1d\x67\xc9\x9a\xff\xa6\xc7\xed\x18\x86\x64\x7d\xfe\x5b\x9f\xac\x55\xf1\xdf\x7e\x9d\xb9\xbf\xde\xf0\xff\xfc\xac\x66\x6b\x91\xec\xd3\xfa\x9b\x3e\xff\x7f\xbf\x80\xff\x3b\xb5\x7f\xf2\xc3\x7f\x5c\xf5\xff\x1c\x09\x67\x53\x5c\xf3\xb4\xee\xbf\x65\xd9\x26\xdf\xeb\x3f\xe7\xc5\xd9\x64\xc5\xdf\xfe\xcc\xfc\x97\x1f\xcd\xd8\xec\x4d\xd2\xff\xed\x96\x25\x7d\xf1\xe7\xcf\xdf\x41\xbf\xc0\xf4\xcd\xd8\xfd\x58\x8b\xfe\xcf\x7f\xda\xea\x69\xdd\xb3\x63\xff\xd1\x64\xbf\xb0\x49\xbd\x16\xe5\x9f\xff\x94\x27\x7b\xf2\xeb\x62\x80\xf7\xdf\xfe\x52\xf0\x7f\xa7\xc9\x56\xe0\xe8\x7f\xa1\x69\x9a\xa1\x69\x9e\xe6\x19\x9a\xfe\x25\x95\x69\x66\xfa\xe5\x55\xa8\x68\x9a\x66\x7f\xf9\xa0\xad\x5f\x3e\x64\xfa\x5f\xca\xff\xe5\xb1\xe8\xff\xcc\xd3\x4f\x24\x05\x62\x78\x6c\x81\xe4\x7f\x0a\x87\xa6\x59\xaf\xe5\x8e\xcf\x4f\x3c\x7c\xa8\x5d\x13\x78\x57\xdf\x04\xc7\xb9\xe7\x40\x0c\x48\x6c\xf5\x7f\x03\x5f\xfa\x36\xb2\x83\x07\xed\x8b\x80\x47\x2a\x44\x20\x81\x7f\x02\x10\x38\xe7\x0f\x07\x1e\xab\x1d\x83\xe4\xc9\xc5\x25\x28\x9e\x83\xf4\x2b\xfe\x87\xf9\xca\xc3\x7f\x80\xaf\x24\xa6\x59\x02\xdd\xc8\xb7\xe0\xb9\xfa\xe9\x3f\xe3\x01\xbb\x7f\x82\x2b\x9e\x5b\x20\xb1\x40\x41\x09\x6a\x17\x1c\x82\x0f\xf9\xed\x7f\xc5\x07\xf6\xb9\x23\x7e\xc5\xbf\xfe\x2a\x1e\xbc\xfa\xe1\xbf\xc1\xfb\x99\xc7\x81\xd1\x33\x01\x7c\x17\xc6\xdf\xe0\xfd\x16\x5f\xc4\xc3\x13\x28\x06\xcf\x04\x7f\x33\x7f\x3f\xe9\xfd\xab\x78\x7f\x9d\xfe\x7f\x35\xde\x5f\xf3\xff\x7a\xbc\x3f\xd7\xe3\xaf\xe3\xfd\x4f\xe8\xff\x4d\xfe\x5f\xf3\xc7\xaf\xf4\xff\x55\xbc\x33\xb5\x13\x10\xfb\x59\xfe\x93\xbe\xbf\x4e\xff\xcf\xf9\xfd\x5f\xa7\x1f\x5b\x5c\xcb\x04\x9a\xb1\x4b\xc1\x69\xc6\x44\x10\x57\x73\xfb\xfc\x7f\x46\xff\xb6\xf4\xce\xaf\xf4\x80\xda\x1d\xa4\x20\xa4\xf7\x33\x48\x71\x4a\x52\x82\xea\x2f\xed\x27\x65\xe7\x41\x02\x40\x42\xf3\x7f\x4a\x3f\xb5\x0b\x2b\x38\x28\x3c\x00\x12\xe2\xe6\x9d\xa0\xfd\x0c\x2b\x08\x65\xf3\x02\x52\x92\x9a\xfc\x9b\x3c\x70\xaf\x82\xf6\xeb\xf8\xfe\x03\xfa\x7f\xd2\xf7\x57\xdb\xff\x4f\xf1\x7f\xce\xcf\x5f\xe5\x57\x55\x2d\xec\x13\x40\xb6\x3e\xfd\xdf\xc1\xfb\x6c\x42\xf8\xeb\x78\xfe\x35\xde\x6f\x9e\x5f\xca\xbd\x9f\xf8\xe0\xf7\x1e\xca\xbf\x8e\x47\x22\x62\x0c\xfe\x65\xfd\x9c\x7f\x1f\xee\xaf\xe2\x7f\xf0\x9f\xf8\x3f\xd7\xeb\x21\xfd\x01\xfc\x99\xff\x05\x2f\x31\xff\x37\xa0\xfe\x5d\xfc\x9f\x78\x7b\xf6\xbf\x54\x1f\x1c\x49\x9a\x36\xab\x92\xa6\xb9\x8b\xbb\x68\xfa\xa2\xf5\x5f\x84\x32\x43\xd3\xec\x4f\x51\x5c\xd1\xfc\x7f\x98\xff\x59\xdf\xa4\x4d\x9a\xe6\x50\xe9\xfa\x67\x3c\xfa\xcf\x7f\xfe\xd5\x2a\xfc\x69\x8a\xfc\xd7\xdf\x18\x20\xff\x00\xfe\xfa\xd5\xdf\xfc\xc3\xb6\x3f\xbf\xa4\xe0\xff\xf5\xc3\x99\x8e\x35\x2b\x7e\xfc\xed\x4f\x0b\xe3\x17\x1d\xb2\xfd\xdd\xb4\x56\x3f\xfe\x2f\xf0\xa7\x0a\xfc\xdb\xff\x96\xf6\xc9\xd8\xfd\xf8\xc7\x34\xc9\xba\x6a\x9d\x8e\x31\xff\xdb\x9f\x0a\xe7\xef\x8f\xb5\xff\xff\xfc\x46\xff\xcc\x63\xf5\x2f\xca\xa7\xf1\x19\xc3\xbe\x20\x55\xac\xa6\x5f\x68\xfc\x3a\x5e\xcd\x7b\xd5\xaf\x2a\xe9\x17\x0d\xc3\xd2\xd1\x2f\x69\x49\x82\x54\xfd\xcb\x8b\x18\xda\x42\x20\xd9\x6e\x0a\xc7\x50\x0e\x0b\x4f\x6c\x31\x4c\x2c\x52\x4d\xec\x30\x4a\x1a\x08\x63\xec\x2b\x7d\x14\xd8\x58\x96\xf5\xfd\xcf\x15\x0a\x18\xc5\xe6\x05\xaf\xf8\x2e\xbc\xd7\x7e\xb4\x9b\xa7\xad\x31\xff\xe8\x3e\x8d\xf6\x8f\xcc\x07\x37\xee\xc9\x2a\x2f\x7a\xfc\x2d\x6e\x29\x8b\xec\x5a\x79\x29\x60\xed\x82\x15\xe1\xf7\xec\x78\xa4\xcb\x1d\x32\x57\x05\x5a\x68\x6d\x99\xa0\x56\xab\x1a\x36\xc6\x07\xb3\x9d\x87\x58\x06\x98\x2e\x3e\xc7\xab\x13\xed\x9b\x9f\xfe\x61\x63\x5c\x15\x8d\x31\x50\x52\x54\xd2\x10\xfe\x8e\xed\x94\x4a\x1d\xe3\x81\x4a\xda\x55\xc8\xc8\x12\x44\xb7\x8c\x9b\xdc\xb4\xe5\x0f\x54\xd6\xd9\xb8\xdf\x06\x8a\xb2\x99\xc1\xbc\x26\x4d\x0c\x25\xff\x1c\xd2\x55\x12\xe3\x6e\x75\x68\x9b\x8d\xcf\x65\xdc\x72\x5f\xde\x06\xfb\x8d\x12\xcd\xaf\x52\x3c\x0b\xd3\xce\xcd\x6b\x25\x5c\x60\x47\xee\xbf\x3a\x0b\xdd\xf2\x52\x4b\xd9\xcb\xa5\x0d\x69\xf8\xef\xac\x39\x5e\x02\x05\x45\x6a\x97\x43\x53\x69\xd2\xd2\x7e\xf8\xcc\x8c\xc7\xab\x24\xaa\x94\x93\xd7\xc8\xb7\x1f\xbe\x19\x8f\xb5\xc5\x5b\x97\x91\x1e\x99\x98\x17\x7f\x15\xac\x85\x4f\x77\xdc\xe5\x87\x98\x3a\x3f\x5f\x9b\x56\xbe\xec\xe7\x76\xa3\x5b\xb6\x6a\x50\x1f\x6c\xaf\x1f\x04\x8b\x47\x96\xc0\x08\x3e\xe3\xc2\xc0\x6e\xd0\x7d\x40\x64\xaf\x14\x1f\xba\x12\xff\xec\x04\x99\x2f\xe2\x54\x5a\x50\xbe\x7f\xd4\x97\x1e\xf8\xd0\xb8\xf1\x6a\xe4\x7d\xe5\x08\x98\x77\xe8\x6c\x85\xb1\xcd\x48\x8c\x19\x6e\xf3\x13\xa3\x9f\x9d\xca\x57\x78\xf8\xf1\x13\xba\x00\xa1\xee\x06\x91\xe4\x65\x6c\x03\xf2\xb7\x54\x17\x62\x1e\x61\x39\x27\x56\xaf\x22\x2e\x23\xd9\xaf\x00\x2e\xc6\x4f\xa2\xa6\x44\xce\x37\xae\xd8\xbc\x40\x73\xba\xd5\x03\x2c\xe9\xea\xa2\xb5\x94\xa3\xc3\x92\xe0\x72\xab\xfb\xc9\x28\x8e\xe7\x1b\xb6\x8a\xb1\x91\x2c\xff\xf9\xff\xfb\x7f\xff\x86\x01\xd7\x62\x2e\x92\xfd\xef\xc7\xe9\x9f\xdf\x7e\x5b\xb6\x35\x6f\xf1\xf7\xbf\x18\x5a\x49\x33\xfe\xd3\x3f\xb3\xf0\x9c\x54\xc5\x1f\x8b\x83\x87\xfa\x9f\x39\x78\xde\xbc\x77\x3f\xa1\x0f\x1d\x99\x65\x5e\x1b\x0f\x18\xba\x31\x09\xf9\xfe\xc7\x9f\xd8\xa5\xa7\xe1\xd7\x5a\xbc\xea\xd2\x79\x7e\x0d\x18\x5a\x3b\x51\x51\xe1\x4a\x9e\x1b\x0c\x5e\xda\x04\x77\xf1\x59\x97\xbf\xe9\xa6\x71\x64\xd8\xe2\x55\x45\xe5\x1d\x5f\x10\x98\x60\x82\x50\x97\x77\xec\xb7\x7c\xe0\x8c\xd0\x22\xb0\xd3\xf6\x12\xce\x49\x00\xc3\xb0\xf7\xd4\xa9\x6f\x22\x7f\xa6\x35\xc1\xb6\x33\x7d\x28\x63\x4c\x3d\x9e\xb9\x2b\xae\x97\xd5\x26\x68\x43\xab\xd0\x9e\x0f\x05\x86\x1f\x62\xe3\xf7\xcc\x8c\xe0\x75\x97\x1c\x0a\x07\xa5\x03\xb2\xcf\x30\xd4\x5e\x20\xf3\x5e\x9d\x24\x5e\xa7\xde\x64\x98\xe2\x66\x89\x8d\x76\x94\xc7\x99\xe9\x46\xe5\xf8\x75\xc7\x94\xbb\x09\x9f\x40\xc5\xb6\x36\x9c\xf2\xaa\x78\x48\x82\x71\x84\x54\xa9\x1a\x22\x69\xa4\x91\x44\x3f\x6d\xdd\x8b\xa8\xf0\x68\xa0\x9f\x0b\x64\xaa\x22\x93\xbe\xa2\xa8\xb4\x67\x69\xd5\x72\x39\x94\xb2\xc0\xd1\xa1\x32\xb7\xc7\x51\x35\x44\xde\xca\x82\x2f\xa3\x26\x34\xf7\xd9\x5e\x29\x16\x74\x8f\x42\x81\x15\x86\x01\xc1\xc6\xc5\xcf\xb0\xdf\xd5\x0e\x3b\xb2\x64\x60\xb0\xf9\x52\x5d\xe3\x2b\xdc\x28\x28\x3f\xf3\x7c\xd9\xfe\x17\x08\xa3\x70\x2b\xb2\x25\xa6\x3f\x33\x83\x92\x45\x47\x8f\x17\x05\xa2\x62\x7c\x23\x1a\x84\x7e\x41\x71\x72\x2f\xbe\x0d\xd1\xec\x2b\x61\x67\x6f\x96\xed\x4e\xcb\xd1\x4c\x66\xc1\x6a\x1d\xfb\xbd\xb2\x98\x3e\xe5\x88\xbf\x85\xbe\xab\x0b\xce\xb2\x27\x3c\x50\xf5\x54\x5e\x27\xde\xcd\xc3\x7b\x18\x37\x02\x31\x46\x4d\x93\xec\x0a\x72\x62\x1b\x69\x83\x9f\xc7\x60\xbf\x9a\x71\x5c\x6d\xc7\x6b\x8d\x9b\x0e\x2c\x95\x2b\xd2\x2c\x27\x22\xed\x6c\x5c\x37\x09\x96\xa8\x58\x97\x14\xe8\x99\x14\x28\x91\x31\x78\xed\xc7\x68\x4f\x6b\xda\x8f\x67\xdf\xb1\x51\xd2\x35\x5e\xec\xd8\xe7\xc6\x2d\x0f\x21\xd1\xf6\xea\x3c\x3a\x87\xb7\x5b\x49\x1d\xd0\x72\xea\x78\xaf\x40\x72\x95\xde\xd7\x32\x5e\x27\x11\xea\xdb\x5a\x69\x3c\xaa\x2c\xdd\x92\xa6\x96\xf5\xfa\x6a\x64\x69\xfa\x54\x05\x66\x0a\xc3\x44\x2a\xe9\xd5\x61\x63\x8e\x87\xaa\x27\x50\x2a\x41\x56\x87\xd3\x13\x54\x03\xd5\xbd\xaf\xdc\xc1\x09\x0a\xd4\x06\xb7\x73\x9e\x7f\x28\xa0\x42\x20\x30\xad\x3a\x78\xbc\xcb\x43\xee\x3e\xb4\x65\x31\x48\x1a\x7f\xc9\x9e\xda\x09\x4c\x16\x6a\x48\xd1\xbd\xdc\x57\xb7\xa9\xde\x3c\x73\xb1\xab\xb1\x4b\xa0\x3d\xaa\xaa\x2a\x9a\x59\xa9\x53\x45\x77\x93\x64\xec\x6b\xe8\x53\xcb\xa0\x8d\x2b\xb3\x6c\x31\x9f\x21\x86\xd0\x32\x5f\x5a\x7b\xf2\x69\x3c\x76\x98\xdc\x86\x19\x72\x7e\x6d\x60\xbb\xca\x73\x55\xa8\x0f\x65\x5a\x52\x30\x29\xc1\xe7\x02\x73\xe4\x75\xbf\x3a\xee\x75\x89\x51\x36\x1b\x0e\x27\x5e\x95\xe7\x74\x3a\xbe\xc0\x1a\x1e\x66\x04\xf8\xe3\xdb\xee\x14\xc8\xbe\x34\x9d\x0e\x5a\xcb\xae\x25\xd3\xd8\xd5\xef\x2a\x21\x92\x24\xfb\x63\xc9\x87\xf1\xbf\xcb\x07\xc8\xeb\x3e\x26\x0f\xf1\x51\xb9\xaf\x87\xdf\x9f\xb4\xd7\xd5\x3e\x6f\x4e\x4c\xb6\xf1\x93\x66\x2b\x4c\x04\x7d\x74\x53\x6a\xd9\x0d\xc9\xce\xa9\xca\x5c\x10\x5d\x14\xe5\x8b\x7d\x4f\xa9\x9e\xa6\x3a\x33\x46\xf3\x42\x23\x5e\x94\x3b\xb6\x06\x26\x4d\x64\xd4\x01\x89\x89\x31\x46\xf2\xa1\x80\xcf\xd6\xa8\xdd\xac\x6d\x14\xe5\x8c\x5f\xf3\x34\x74\x12\x94\x44\x78\x41\x60\x8c\x5b\x91\x4e\x9b\x89\xe8\xd3\xa4\xb3\x7c\xb7\x1b\xaa\xd6\x16\x13\x97\xa7\x8f\x6f\x84\x8a\xf9\x29\x94\xb6\xc5\x54\x62\x71\x9f\x89\xcf\x66\x7e\x12\xec\x33\x34\xa5\xc1\x3d\xe9\xf9\xf2\xe4\xf0\xb2\xe9\x4a\x4f\x2e\x27\xbb\xb5\x3e\x89\x61\xdc\xc4\x68\xe4\x34\xc7\x5a\x02\xf1\x27\x2c\x0e\x76\x51\x08\xa3\x05\x36\x15\x69\xad\xec\x4b\x0f\x15\x79\x77\xa2\x45\x7c\x86\xa8\x68\x33\x9a\x41\xa9\x73\x1e\x8a\xe3\x55\xb2\xac\x87\x80\xdc\x6b\x71\x55\xa6\xcf\x52\x62\xcd\x0a\xf9\x02\x07\x7d\xa2\x67\x45\x31\xc6\x9d\xb1\x43\xc9\xbf\x87\x09\x56\xc5\x38\x0f\xc5\x52\xf3\x7a\x75\xe4\xc5\x07\x52\xae\x01\xe0\x0e\x4f\x7e\xbc\xdc\xed\x97\x03\x4e\x9f\x49\x2f\x43\x30\xb7\x8b\x75\x60\x0a\xfe\x96\x36\xb7\x09\xbe\x0d\x02\xf4\xfa\xfc\xda\x17\xd7\x35\xe4\x7b\xb3\x32\xed\x0e\x6f\x5a\x9c\xe5\xc0\xf6\x47\xd7\x98\xd8\x57\xa8\x95\xea\xea\xda\xc2\x76\x0b\xcd\xa9\x73\x63\xf2\x95\x65\xa4\xab\xab\xab\x58\x3a\xc6\x01\x2f\xd7\x58\x6a\xbf\x5a\x2b\x26\xe7\xfc\x6d\x26\xa1\x8b\x19\x29\x42\x16\x9c\x41\x7a\x34\x57\x78\x9e\x37\x0d\xb6\xe0\xd0\x2c\xf2\x25\x22\xdc\xca\x0f\x26\x00\x82\x3c\xb0\x04\x81\xc9\x5f\x5a\x61\x14\xa7\xf3\xa7\x60\x82\xac\x88\x8a\x96\xaa\xb1\xd1\x38\x7e\xed\x44\x64\xba\xfc\x52\x91\x54\xb8\x45\xcd\x8e\xbd\x92\x41\xec\x01\xbe\xd1\x9b\x62\xc5\x7d\xf3\x6e\x89\xb2\xa2\x4e\x95\x59\x4e\x38\xb4\x5b\xa5\xa7\x57\x8c\xaf\xdc\x5d\x18\x7b\x83\x85\x54\xeb\xc3\xb4\x31\x73\x9e\xd5\x59\x29\xc9\x5b\x90\x4e\xb8\x30\xfe\x0a\x4b\x91\xb3\xf2\x39\xda\x99\x83\x7a\xb3\x3d\x11\x40\xcd\x62\xaf\x37\x5c\xa4\x31\x17\xd4\xe5\x09\xcd\x78\xce\x43\x4c\x7c\xd5\x1d\xb6\xdd\x81\x41\x6b\x35\x9e\xf0\x91\x5c\x4c\xd4\x58\x3e\x12\xd3\xa9\xbd\x1f\xd1\x16\xb3\x7a\xfd\xdb\x30\x50\x68\x39\x4d\x89\x46\x83\x55\x77\x5b\xf5\x95\x95\x8e\x6a\x12\xad\x36\x13\x9f\x4a\x41\x6f\x00\x0e\xc5\x61\xf3\xf7\xe1\x52\x31\xb6\x6c\xa7\x3b\xdb\x09\x18\x51\xe5\x7b\x1f\xa9\xe8\x39\x1b\xdb\x02\x31\x3b\x1b\x5c\xd4\x76\xa2\x4e\x7f\x39\xb8\x23\x8a\xdb\xdb\xca\xba\x63\x73\x00\xa6\x9e\xea\x60\x48\x32\xe8\x09\x21\x00\x27\x7c\x77\x09\xb0\xca\xc2\x85\xae\xc4\x93\xa8\xeb\xfb\xa3\x05\x4c\xb3\x16\x92\x3f\x12\x54\x64\xe2\x6c\x6d\x21\x63\x9b\x82\x85\xd0\x97\xc1\x22\x2e\x2e\x22\x21\x71\x2f\xca\xb5\x28\xc3\x0d\xec\x19\xa0\x07\x5e\xdd\x45\xd3\xc3\x94\xf4\xd9\xdd\x7f\xe9\xcf\xcf\xdd\xc9\xf7\x82\xdb\x39\x87\x35\xb0\xec\x7f\x4a\x66\x34\x7f\x2c\x91\xd1\x61\x7f\x31\x29\xa0\xcf\xc9\xf7\xbc\x67\xba\xe6\x1b\x2f\x0c\x6d\x25\x8e\x60\x35\x4a\xe4\x0d\xbd\x1a\xd5\x93\x2b\xa0\x1f\x0d\x71\xd3\x03\xb4\x40\x80\x3e\xb7\x10\x61\x66\xb0\x32\xb7\x23\xd0\xd6\xe5\x59\x2c\xc2\xf5\x6e\x7d\xa7\x4f\xe1\xb3\x47\xe2\x14\x5e\xdf\x8b\xb8\x4e\xe2\xbd\xa2\x6a\x57\x43\x44\xbb\x10\x82\xc2\x08\x6c\xc6\x5e\x82\x30\xa0\xcf\x54\x07\x00\xc8\xf9\x35\xf9\xb6\x44\x12\xa9\x75\xd9\x8b\xb9\x48\xc5\x9b\x78\x69\xdf\x27\x2f\xcb\xca\x2f\xd7\x0f\x15\x49\xe7\xc6\x27\x40\x7c\x80\xe3\x3d\xe6\x53\x8a\x39\xbb\xa5\x02\xf9\xf3\x9e\xf1\xfb\x5c\x60\xa5\xf6\x83\xde\x12\xf2\x53\x09\x3a\x70\x9f\xdf\x2c\x19\x67\x14\xdc\xb1\x9c\x9e\x86\x50\x62\x1e\xd8\xf3\x18\xc3\x80\x75\xba\x07\x19\x0a\xcc\xcc\x14\x37\x3d\xed\x98\xa4\x1b\x0a\x74\xa8\x40\xc4\x73\xf6\x8c\x9b\x43\xae\x98\x56\x82\x63\x8f\x97\xc8\x8b\x86\x65\x76\x2a\xcc\xd0\x2b\x09\x89\x2c\x23\xd5\x30\x2a\x80\xc0\xa3\xef\xe7\xf5\xb1\x11\xa9\xa8\x3a\x95\x5f\x9a\x80\x71\x44\x1f\xb5\x91\xd3\x22\x36\xb9\x76\x32\x37\x16\xdc\x59\xba\x11\x1a\xfe\x60\x0c\xb6\xf5\x87\x1f\x81\x41\xa0\x57\x04\x40\xbb\x0c\xd8\x67\xda\xa6\xce\xee\x34\x4a\x2f\x07\x18\xba\xc0\x1f\xee\x4b\x36\x5d\xb7\x53\xea\xb5\x53\x91\x12\x33\x08\x99\xcd\x4c\x3e\x59\x74\xac\xe4\xda\xc9\x8a\xcc\x53\x4e\x26\x83\x87\x79\x47\x41\x73\xf4\xe0\x61\x85\x64\x20\x97\x04\x17\xbd\x56\x10\xc5\x25\x22\xd6\xb3\x9b\x27\x7c\xa1\x39\xeb\x62\x7a\x6a\x73\x96\x1c\xd0\xe4\x60\x96\x84\xd6\x0e\xa7\x2a\x5e\xc2\x67\x3e\xf6\xce\x39\x5e\x60\x58\xa7\x97\x30\x9a\xe0\xbd\x0a\xa3\x2b\x30\x77\x0d\x66\x95\x7f\x94\x6b\x80\x82\xc9\xa9\x94\xb2\xe5\xce\xd5\x55\xef\xfd\xa2\xe5\x87\xef\x68\xc3\xc2\x6a\x0f\x04\xe3\xbc\xc2\x8e\xe9\xe2\x7a\xef\xab\x8f\x57\xac\x05\xd0\xe6\x1c\xde\x41\xb3\x51\x7d\x59\xf6\x25\x9c\xca\x7d\xcc\x6c\xcb\x47\x9e\x97\x65\x46\x37\x25\xea\x90\x1b\x7d\x3c\x46\x1f\xb7\xab\xe8\x2c\xa4\xeb\xbb\x36\x2e\x6d\xe3\x36\x69\xfa\x22\x07\x6a\x60\x8a\xcb\x95\x3e\x2b\xe1\x32\x35\x96\xad\x9c\x23\x95\x5c\x39\x1e\xed\x0a\x4a\x07\xd6\x7e\x71\x8a\xbb\xa1\x5f\x0e\x14\x5e\x16\x42\xbf\x0c\x28\xac\xbd\x5a\x91\x16\x4c\xc8\x70\x9b\x9c\xfe\x14\xaf\x42\x75\x71\xe8\xe2\x37\x33\xcd\x3f\x7a\x3f\x26\x02\xbd\xbe\x49\x0b\x72\x10\xd7\xe8\x61\xaf\xd0\x82\xf5\xa8\xf0\x4a\x96\xa3\xae\xdb\xf1\x8c\xf6\xd6\x47\x4f\x1c\x0d\xdb\x3d\xf0\xd3\x2d\x74\xa7\xb3\x35\xbc\x47\x32\x40\x00\x5d\x4d\x40\x59\x6b\xa6\x2b\x9a\xf2\x31\xf6\x69\xe3\x95\x74\x95\x91\xa1\x4c\x25\x9c\x5f\xc4\x47\x69\x86\x36\x0d\xcb\x57\x46\xd8\xc2\x21\xf1\xf7\xdd\xfa\x65\xf9\xc7\xda\xfc\xd3\x7f\xb7\x17\x3a\x8f\xda\x17\xfe\xc3\x7b\x61\x3c\xc4\x33\x8f\x24\x2e\xa3\xa5\x8a\x60\xba\xbb\xe0\xd9\xbb\xc3\xee\xf5\x4a\x78\xec\xa3\xaa\x82\x02\x52\xf4\x88\x4c\x15\x4e\x57\xe0\x14\x96\x93\xd7\x12\x53\x45\x25\x1b\xcb\x44\xaa\x8b\x7b\xb2\x29\x25\xc1\x3e\x2f\xc4\xd7\x83\x93\x58\xc5\x5e\xec\x8a\xa9\xfb\xd6\x67\xfd\x8a\xb9\xa3\xb8\x5e\x6a\x5e\x57\x04\x8e\x1b\x03\x24\xd8\x6f\xc2\xdd\x88\xa1\xed\x78\x69\xb4\xcc\x22\x56\x60\xa2\xda\xac\x2c\x8f\x33\x09\xa8\x6f\xa9\x4a\x44\x79\xe4\xa3\x2f\x60\xe4\xc8\x7f\xf0\xa2\x07\xc0\xc7\x83\x07\x46\x70\x82\x58\x9d\x03\x45\xf5\x33\xc8\xa8\x3c\x66\x82\x60\x15\xfd\x72\x83\x87\x4f\x04\xa6\xdf\x40\x90\x1f\x94\xec\x85\x42\xd1\x18\x34\x38\x8f\x9f\x5b\x2a\xa2\xe4\xa8\x7c\x2e\x7f\xe7\x74\xa6\x3e\x8b\xd8\xd3\xaa\xe8\xde\x64\xce\x7e\x28\x30\x98\xef\xba\x1d\xb7\xbb\x05\x6d\xfb\xea\x48\xac\x16\x15\x96\xca\x3f\x06\x5e\x8e\x45\x40\x1f\xd3\xbb\x73\x91\xe3\x68\x05\x65\xb8\xb8\x73\x84\x0c\x9c\x65\x37\x81\xc4\xd4\x71\x74\x17\x77\x95\xfd\xf6\xa9\xa0\x3b\x96\x23\x90\xce\x41\x71\x7c\x76\x30\xf4\xcb\xf4\x89\x56\x87\xb3\x79\xd2\xe4\x6f\x89\xc1\x41\x92\xc1\xad\x23\xb9\xe5\xcb\x66\x04\x7d\x87\x1a\x99\x6e\xf4\x1b\xd0\xd8\x67\x23\xdb\x52\x54\x78\xaf\xe9\xe0\x60\x8e\x0d\x0e\x76\xac\x92\x9a\xb8\xdd\x5f\xac\x6b\x9a\x59\xba\x89\x70\x5c\x70\xc0\x69\x40\x52\x02\x63\x7d\x07\xd6\x7b\x8f\xa0\x15\x38\x68\x14\x86\x8d\xdb\x18\xce\x95\xc3\xee\x38\x25\x16\x2e\x81\xb6\x09\x8f\x65\xda\x04\x29\xbf\xe5\x1d\xc1\x11\x3f\xb1\xbb\xcd\xb6\x54\x31\x20\xee\x9c\x6f\xb8\x30\x2b\x5b\x21\xb2\xcc\xed\x40\x62\x15\x89\xcc\xbb\x5c\x38\x3c\x93\x68\x35\x46\x23\x2d\xc3\xac\x93\x3a\xa9\x59\xf3\xb3\x40\x27\x3c\xfc\x1a\x5c\xe2\xd1\x7d\x10\x5c\xdc\xe4\x60\x5c\x5d\x88\x4b\x1a\xcc\x3e\x0f\x42\xec\xb0\xb0\x11\xb5\x74\xfc\x23\x7f\x99\xac\x48\xe1\x83\xe6\xec\xaf\x45\xa6\x4e\x40\xfb\xfe\x2b\x0b\xea\x34\xb0\x56\x33\x00\x50\x7f\x38\xe8\xa3\x46\xfd\x26\xf5\xf6\x13\x4f\x04\xbf\x39\x3c\x0b\x23\x2a\x76\xd2\x5b\x58\x83\x12\x05\xbf\x71\x77\xd8\xe7\x5d\x30\x0e\x36\xf2\x37\xfc\xcc\xb0\xba\xd4\xb7\x39\xf9\x98\x1b\x39\x20\xc9\xee\x39\x3d\x3f\xbd\x4e\x6d\xb1\xa5\xaa\x8e\xf5\x3e\x85\xed\x6e\x85\xed\xc3\xd6\x44\xbf\x72\x14\x91\xed\x50\x60\xdc\x97\x2a\x65\x28\xb7\x26\x4f\x6e\xe9\xaf\xf8\xe4\x26\xe5\xeb\x84\x19\x5f\xd4\x0c\xd2\x0d\x33\x7f\xa3\x35\x4f\x2f\x70\x87\x1e\x57\x59\xec\x3d\xf7\x28\x6f\x2d\x15\xd6\xd3\x67\x47\x91\xab\x34\x78\xb7\xa8\xc0\x3e\x4c\xe6\x37\xd2\xab\x49\xc5\xc2\xda\x4b\x1d\x7f\xa2\xf0\xb3\x0b\xd7\xb7\x8c\x99\xdb\xa1\x0c\xe4\x1b\x74\x74\x26\x2d\x36\x0e\xe1\x1d\x38\x82\x48\x36\xa9\xf4\xe4\x83\x11\x71\x5a\xa0\x11\xb1\x71\x71\xf6\xeb\x70\x22\x19\x24\x6e\x42\x0d\xe1\x07\x02\x96\xa8\xaa\xd3\xcc\xe9\x04\x25\x27\x0d\xa9\x0a\xff\x74\x3d\x18\xc5\xf6\x30\x7e\xed\x94\xaa\xaa\xfe\xfc\x9f\xf3\x3d\xce\x3f\x98\x21\x31\x7c\xfe\x62\x48\x90\xfb\x01\x41\xb4\x67\x86\x71\xf6\x85\xc6\xd7\x9d\x17\x58\xb5\x90\x99\xbe\x3a\x99\x1e\x03\x69\x61\xa7\xa2\xb8\x99\x14\xa0\x2d\x80\x66\x62\x92\x86\x37\x80\x96\xbb\x7c\x80\x71\xdc\xf2\x14\x59\x08\x54\xa6\x93\xaa\x8f\x3a\xdb\x52\x83\x4d\x83\x22\x76\xa9\x82\xa4\xa2\xd4\x02\xa8\xfe\xe1\xad\xd5\x3d\x9d\x47\x34\xcd\xa3\x28\x8a\x0c\x00\x3e\x7c\x65\x31\xb7\x34\x03\x20\x35\xa4\xcf\xb1\x36\x76\x9c\xdf\xad\x92\x34\x2a\xc3\x21\x01\x70\x7c\x80\x99\x4a\x48\x0c\x1f\x92\x1b\xa8\x38\x83\x2c\x52\x17\x08\x5c\x18\xe2\xdf\x86\xfa\xc6\x0d\x98\xad\x4b\x92\x9f\x23\xac\x5b\x0c\x2d\x96\x33\x6b\xcc\xcb\x77\x3d\x60\x0a\x21\xce\xdb\x94\xe7\x08\x37\xc6\x36\xcb\x6e\xc4\xbd\xb2\x8e\xd2\x99\xc6\xf1\xa0\x31\x2b\xa5\x66\x0d\x85\x21\x0e\x11\x3d\xa7\xae\x85\xf5\xae\x86\xf7\xbf\xe0\x9b\x58\xa5\xb4\x43\x67\x99\x32\x05\x76\x58\xcf\x61\xfa\xd5\xdc\x63\xf1\xf8\xf9\x3c\xa9\x86\x82\x0d\xd8\x77\x32\x6b\x5c\xd8\xd8\x58\xb6\x68\x39\xf5\xd4\x2c\x32\xce\x4c\x28\x12\xc0\x47\x4a\x8e\x48\x6d\xef\x5a\xec\x12\x95\xfb\x8c\x1d\x5e\x75\x6c\x48\x55\xb4\x71\xcf\xf4\x78\xd7\x52\xcc\x5d\xec\x07\x4c\xe4\x0f\xef\x37\xca\xd4\x1f\xa0\x55\xab\xb6\x2e\xc5\x1f\x2f\x84\xc4\xf5\xe3\x39\x32\x3f\x62\x82\x19\x48\x0f\x00\x5e\xee\xd4\x75\xab\x65\x2c\xf0\xc9\x24\x52\xcc\x7c\xd1\x7a\x88\x28\xe5\x2a\x57\x94\x1e\xc1\xbd\x68\x78\x06\xc5\xe2\x98\xbb\xb8\x46\xaf\x27\xfe\x76\xa1\x2f\xb0\x45\x1c\x7b\x78\x5d\x37\xf7\x9a\xdc\x87\x26\x0a\x86\x7c\x98\x4f\x80\xed\xd5\x79\xcd\x38\x4e\xe9\x5d\xbb\xef\x7a\x22\xa9\xcb\x92\x4a\x59\xfe\x22\x13\x1c\x78\x44\xf8\xb9\xc2\xf3\x35\xb0\xe6\xda\xbd\x80\xdb\x51\xd5\x45\xdb\x81\x45\x05\xf7\x3c\xa7\x61\x5c\x7f\xc7\xf9\x02\x9e\x04\xa5\x31\x29\x6e\x70\x0d\xed\x65\x9b\x0c\x1e\x36\xd3\xf0\xcd\x8d\x1b\x3a\x68\x83\x8a\x1e\xe6\xbb\x1b\x31\xa0\x5b\xdc\x64\x50\xf1\xa0\x63\xaf\x81\xb7\x07\x8d\xd3\xce\x96\x81\x74\x8d\x6a\xba\x20\x34\x35\xe1\x98\xde\xc8\x48\x66\x44\x23\xa5\xe8\x8b\x73\x52\x9e\x3a\x60\x8e\xb1\x85\xeb\x33\x63\xce\xbc\x24\x21\xb0\x8c\x16\x75\x5f\xf7\x91\x5b\xc6\x2a\x86\x51\xe6\x37\x27\xc2\xfa\x68\x55\x3f\x80\x37\x05\x99\x3b\x69\x7a\xcb\x4b\xf4\x23\x5b\x30\xc3\x32\xce\x0d\x7e\xfd\x1a\x88\xbd\x7a\x5d\x06\x7e\x61\x8a\xd4\x41\x82\xa7\xce\xb5\x0a\x7a\x77\xf0\xa8\xe8\x44\xee\xfa\xcd\x11\x35\x89\xd5\x12\xfc\xe5\x74\xb1\x8e\x61\xa9\x7d\xc4\x6d\x9c\x05\x73\xf9\x4a\x63\x04\x97\x83\x74\x22\x36\xe6\xe8\xcf\x10\xa5\xb6\xb1\xbd\x8e\x05\xdb\x06\x1d\x51\x8b\xd4\x4c\xe5\xd9\xdf\x4e\x86\xdd\x9b\xaa\x2e\xcb\x18\x21\x79\x63\xf3\x54\x8d\x86\x58\x0e\xce\x6f\x45\xf4\xa3\x8e\x36\xe7\xb6\x5e\x34\x57\x50\x41\x05\xb2\x96\x52\x09\xf4\xef\x2b\x27\xd2\x61\xfe\x83\xc9\x89\xf8\x2f\x67\x14\xc0\x67\xf5\x7a\x3e\x02\x3f\xc8\x49\x45\x3e\x74\x2e\xf0\xb5\xef\x32\xc6\xe6\xb3\x46\x25\xbc\xc8\xc4\x1e\x77\x42\x79\x89\xe3\xa4\x8c\x8f\xc0\xb4\x42\x9e\x05\xda\xc7\xc1\x41\x7c\xe5\x73\x74\xbc\x6e\xaa\x80\xd2\xf6\x27\xc1\x59\x43\x0d\xb0\x25\x3c\xc3\x22\x83\x09\xf3\xf0\x8b\x3c\x41\xd2\x2a\x13\xf0\x82\x04\x9f\x02\x03\x73\x62\x6c\xf4\xb8\xae\xf8\x7b\x54\xa9\x32\x75\xd7\x01\x9b\x53\x46\xd4\x63\xae\xab\xd8\x67\x01\xfc\xa7\x76\xbd\xc4\xc5\xf9\x09\x8e\x25\xa5\x30\xcd\x20\x54\x42\xbb\x2e\x5e\x84\xf9\x3c\xf7\xa0\x83\x56\x9e\xed\xa1\xe7\xb0\xd5\xee\xa3\xe6\x83\xb2\x67\x84\x64\xdd\x83\x16\x9f\x1b\xe3\x7a\x8d\x4d\xc4\x34\x7d\xdb\x90\xcb\xa6\x63\x13\x31\xc3\x2a\x30\xc9\xb4\x1d\xd6\x32\x55\xd4\x9c\x37\x5e\x07\x43\x09\x0d\xce\xda\x41\xc7\xa9\x38\x10\xe5\x92\x44\xd1\x6e\x3c\xad\xde\xf4\x49\x8d\x1d\x54\x86\xc4\x9d\x97\x19\x6a\xa8\x3c\x4d\x11\x69\x08\xa0\x38\x93\x99\x19\x97\xd8\xca\xf2\x2c\x3f\x01\xa8\x55\xb8\x51\x29\x47\x79\x91\x2c\xc4\xda\x22\x1f\x06\xc9\xeb\x5d\x4d\xf3\x08\x56\x4b\x93\xe9\xd6\xfa\x6a\x9b\x28\xef\x74\xea\x1c\x68\x61\xd5\xfd\x28\xb5\x08\x67\xe7\x53\x84\x05\x9c\xd1\x07\xcd\x59\x5f\x91\x19\x98\x53\x4b\xc4\xc3\x15\xec\x84\x2b\x6b\xe4\xd3\x33\x6e\xd0\x50\xf3\x31\xb4\xa9\x0a\x31\xa8\x62\x1d\x3d\x72\x1a\xd6\xac\x93\x4a\xbe\x75\x86\xb6\xe6\xec\xc9\x65\x5c\x4b\x6f\xed\x5e\x61\xae\xdc\x4d\x8d\xaa\x25\x53\xa7\x7f\x6d\x38\x1b\xe3\x74\xf9\xd2\xfa\x93\x2d\x22\x11\xa6\x92\x6a\xc3\xa5\xfe\x5e\x06\x98\x6f\xb7\x73\x1d\x10\xd3\x30\xca\xf6\xdd\x4e\x58\xbb\x68\x85\x56\x58\x19\x3b\x6e\xb8\x0a\xa3\x74\xf9\x16\x7b\xf6\x62\xe6\x64\xd8\xf2\x27\xe3\x1c\x68\x24\xe9\x5b\x0c\x08\x1a\x78\x4f\x3e\x62\xd4\x18\x8e\xfb\x6c\xe3\x77\x45\x4b\x8b\x5c\x6f\x0b\x93\x49\x58\xd7\xd2\xab\xfa\x46\xb1\xa3\x7f\x82\xee\xbd\x75\xdf\xb3\x60\x5b\xb7\x6a\xad\x14\x8c\x0f\x1e\xd1\x0b\xbb\x36\xb7\x39\x0e\x78\xb3\xa8\xab\x9d\xc2\x01\x8c\xf0\xa5\x80\x66\xde\xd7\x59\xa5\x8a\x82\xb2\x95\xa8\xb9\x87\x41\x10\xdd\x1d\x9d\xc1\x53\x69\xcd\xdf\xd0\x43\xee\x6d\xa3\xbd\x2b\x80\xde\xcc\x5a\xf4\x7b\xa4\x3c\xe4\x1e\xde\x65\x83\x81\xa2\x84\xfa\x54\x9d\xd1\x50\xc3\x5d\xd3\x49\x0f\x15\xdd\xb4\x76\x9f\x26\x03\x3b\x51\x63\x0c\x5b\xbf\x1f\x58\xfd\x2c\x0e\xe5\x7f\x62\x2b\xfd\xba\xb5\xdc\xc2\xbc\x58\x03\xf0\xbe\x3d\xc6\xe8\x24\x0d\xb9\x7e\xbc\x5b\xff\xca\x0c\x03\x68\xb6\xeb\x7a\xda\x8a\x7a\xf9\x06\xa9\x9f\xdd\x03\x0f\x43\xbb\xe5\x75\x48\xbf\x2f\x19\x86\xce\x3a\xd2\x8e\x33\x1f\xa9\x48\x95\xa9\x6a\x3f\x7e\xfd\x19\xc1\xd7\xb9\x60\x6a\xa7\x26\xf6\x93\xa2\x84\x5e\x5e\x5e\x44\xd3\xde\xa6\x35\xc1\x8a\x5a\x9e\xf2\x7b\x3a\x24\x7f\xb0\xd3\xcb\xec\xfe\x4b\x7c\xae\xfb\xac\x3f\x4f\x2f\x87\x78\xec\xaa\x49\x61\x13\xf1\xcb\x16\xf5\xa1\xb8\x49\x5f\x2b\xb1\xe3\xc5\x0c\x8e\x27\x90\x74\x85\x9b\x09\x5a\x23\x20\xe8\x00\x05\xd4\xfb\x03\x69\xdf\x88\x5d\x61\x99\xf0\x7c\x4d\x0e\x20\x21\x83\xea\xd9\x9a\x1d\x87\x30\x08\x7d\x35\x28\x7d\x9b\x8f\xd3\xf7\xc9\x48\x1f\x3b\x70\x1c\xe1\x02\xbb\xa1\xc0\xb6\x05\xfd\x34\xc1\x0b\x0f\x9c\x17\x6b\xd3\x06\xa4\xbe\x77\x69\xe2\x14\x12\xcc\x08\xb7\x2a\xec\xa8\x07\x58\x0e\x93\x26\x91\x00\x32\xff\xc1\xfa\xa3\xb4\xc9\xe9\x13\xf3\xce\x7e\x99\x75\x17\x48\x5b\x90\xae\x31\x50\x7c\x79\xf3\xde\x8e\x23\xe5\x05\x7c\x80\x5c\xe6\x84\x2d\xb4\x6f\xcc\xa9\x0c\x8f\xf7\x2c\x8e\x7e\xdf\x9d\x25\x80\xbd\x4b\x02\xc4\x76\x61\xa1\x7a\x5a\x67\x47\x83\xc7\xd6\x23\x29\x40\x78\xf4\xab\xed\xdd\xfe\x36\x14\xdd\x4d\xa8\xd8\x92\x5e\xce\x92\xdb\xea\xca\xa7\x81\x7a\xb5\xb7\x0c\xcd\x8c\xc0\xba\x74\x34\xe8\xed\x62\x14\xb7\x67\xe1\x70\x5d\x2c\x5b\xd7\xee\xba\x41\x51\x98\xab\x18\xd4\x13\x98\xba\x32\xe7\x01\x61\xb0\xb9\x62\xa4\xaf\xe7\xdd\x96\x4a\x4b\x1b\x39\x4b\x25\xe2\xf2\x87\xa0\x17\xbb\x4e\xc9\xea\x0a\x36\xf0\x10\xe8\x17\x0b\x39\xe3\xe1\x08\xae\x08\x47\xea\x33\xcf\x97\x1a\xf9\xb9\x68\x10\xae\x50\xbf\xcc\x22\xca\xc5\xe8\x17\x1a\xeb\xed\xa5\x67\x57\xfc\x7a\x64\x37\xc6\xb3\xaa\xcd\xab\x8c\x87\xe6\x08\x43\x7c\x48\x53\x7a\xf1\x4c\x66\x45\x17\xfc\x58\x1b\xb9\xcc\xd6\x2e\x1a\xf9\x53\xef\x22\x4f\xdb\x01\x67\x09\x8b\xa5\x38\x05\xa7\x51\xe4\x81\xfa\xa9\x96\xa8\x17\x25\xdb\xb4\x62\x5e\xed\x3e\x29\x62\xef\xd3\x13\x67\x91\x10\x04\x94\xb6\xe0\xba\x51\x98\xb5\x7d\x16\x7e\xe1\x0a\x00\x36\x04\x9f\x31\xed\x7d\xfb\xb3\xf8\x34\xbc\x6d\x24\x24\x23\x4a\x1f\x3e\x5d\x1d\xba\x58\xd6\xf6\xe6\x97\x26\x93\xac\x9d\x04\x23\x87\x93\xf4\x39\xf9\x6e\xc4\xa5\xd0\x33\x75\x9e\x65\x0a\x93\x44\x93\xa7\x13\xed\x77\x36\x9d\x60\x25\x13\x85\x26\xb5\xde\x06\xaa\x57\x25\x74\x9f\xa6\x99\x4b\x15\xcd\xd3\xa4\x31\x89\x39\x0a\x35\x9f\x16\xfa\x5d\xa3\x01\xd9\xfc\x07\xd3\xb4\xa5\xf2\x97\xfd\xb4\x51\x26\x0f\xf1\x1e\x38\xc4\x70\x50\x2d\x73\x18\x02\x96\xcc\x09\x79\xd2\xfb\x5b\x5f\x93\xdf\x9e\x36\xac\xc4\x50\x05\xfa\x2a\x4f\xe9\xbc\x5c\x50\xd0\xc9\x02\xf4\x40\xdd\x18\x99\xe1\xca\x5a\x32\xe0\x20\x9a\xe5\xc5\xaa\x96\xbb\xd4\x83\xd2\x24\xe1\xf7\xba\x40\x0c\x57\x81\xe2\xc0\x87\xf1\x05\x21\x94\x78\xc7\xc9\xa2\x00\x53\x8a\x40\x90\x47\xa4\xaf\x4a\x4f\xb5\x0f\x0c\x96\x2f\x90\xbc\xe9\x48\x9b\x11\xfc\x5d\x77\x22\x2e\x97\x97\x52\xf4\x35\x8a\x01\x05\x05\x0b\x78\x36\x84\xb6\xc9\x1a\xfb\x0c\xfb\x6a\xc6\xc4\x57\x9a\xc6\xb0\x83\x27\xdc\x21\x7d\xbc\x03\xdd\x96\x59\x75\xf0\x16\x69\x54\xd7\x9e\xc2\x70\xcc\x98\x6c\xbb\x9b\xe0\x80\x63\x61\x3d\x84\x1e\x9e\xcf\x23\x47\xcd\xcb\x20\x38\xdd\xb3\x4e\x77\x95\x6d\xc0\xd9\xe8\x71\xa0\xd0\xa3\xf7\xe0\x06\x84\x57\x5b\x04\x6e\x6d\x59\x68\x8c\x5b\x5f\x67\x74\xba\xe8\xe9\x32\x2e\x4c\x36\x13\xed\x87\xf2\x34\x62\xd7\x11\xa8\x85\x74\x39\x86\x17\xcc\xf4\x8b\xa5\xc6\xc2\x56\x3d\xcb\xb2\xb7\x0a\xb9\xe7\x19\x3f\xb2\x8f\xb2\xf2\x9d\x56\x33\x0b\xa0\xd5\x00\x9a\xde\x20\xb0\x32\x4f\x36\x8a\xf9\xe8\x3c\x58\x90\xda\x34\x52\x2d\x2a\x9d\x8f\x14\x69\xad\xea\x5c\x36\xeb\xf0\x5e\x55\x52\xc0\x07\x1b\x84\xf4\x26\x2d\x07\x67\x63\x45\x7f\x15\xca\xe9\x19\xf6\x0a\x91\x52\xe1\x34\x11\x35\x43\xe2\xe9\xb2\xab\x1b\xac\x41\xd9\x67\xbe\x0e\x12\xa2\xfa\xe4\xe7\xb7\x77\xae\xf6\x2a\xfa\x22\x7d\x89\x9d\x0e\xb5\xa9\xaf\xa1\x19\x14\xee\x82\x2a\xf9\x55\x85\x03\x4e\x10\xf9\x4a\x6d\xef\xf2\xdb\x16\x55\x08\xf5\x9c\x9b\x81\x75\xf1\x3d\x04\x8a\x02\x25\x91\xdf\xfa\x4c\x0d\xaf\x67\x4a\xde\xe0\xcb\xe5\x3d\xbb\xe2\x00\x37\x29\xd5\xca\xbc\xb9\x0c\xb9\xd4\x1a\x19\xf8\x53\xc1\xef\xf6\xea\x7d\xa2\xea\x08\x77\x62\x06\xf3\xa6\xc7\x13\x1f\xef\xf0\x61\x3e\xb8\x87\x7e\xdf\x17\x2e\x91\x4c\x30\x6e\x48\x5c\x3e\xb0\x40\x65\xef\x3e\xf3\xf7\x98\x6d\x4b\x34\x25\xd2\xec\xc8\xea\x7e\x43\xaf\x92\xfb\xb2\x30\x4b\x16\x3e\x3f\x30\x35\x1c\xdf\xee\x73\xb8\x5f\x12\xa6\x26\x10\x77\x24\x7e\xac\x49\x48\x12\x12\x1e\xff\xb6\x83\x36\x06\xb7\xa7\x3c\x1f\xed\x71\xfb\x9d\x41\x3a\x92\x61\x2a\xa6\xe0\x0b\xcb\x6d\x02\x7b\xeb\x7e\x67\x6b\x37\xdb\xb6\x3f\xd6\x1e\xec\x7e\xe3\x15\x77\xfb\xe9\xf5\xbc\x05\x1e\x18\x37\xb1\x5a\x0f\xda\xb4\xaa\xaa\xde\x19\x0c\xf2\xdd\x46\xe3\x6e\xed\xd9\x81\x68\xe7\xcf\x4b\x27\xa1\xb6\x7f\xf0\x6c\x12\x58\xd8\xdc\xa6\x96\x4f\x74\x35\xde\xd9\x45\x48\xdc\x5c\x1c\xda\xd4\x81\x58\x11\x61\x1e\xe0\x2c\x1a\xc4\x30\x18\x47\x0c\x1d\x8f\x38\xde\xef\x13\x13\xe4\x8b\xbc\xb6\x80\x9f\x36\x1e\x9d\xe1\xfb\x9a\xab\xee\xb1\x4f\x89\x93\x29\x43\xbd\x06\xe0\x97\xb3\x6d\x8c\x58\xdd\x19\x79\x69\x9a\x21\x08\xf7\x12\xd8\x97\x8d\xd6\xe4\xef\x1e\x62\xc3\x17\x6e\x35\x51\x84\x56\x55\xe3\xbf\x32\x4f\xf6\x4d\x30\xe7\xef\x65\x12\xd2\xb9\x28\xcb\xd1\x0e\xe7\x91\x0b\x1e\x9a\x0a\x11\x19\x74\x1f\x21\xde\x0c\x66\x57\xe7\x39\x27\x23\x96\xfb\x1e\x04\xc1\xc6\xc5\x99\x23\x55\xd9\x97\xae\x27\x64\x5e\x6d\x42\x85\xa9\x35\x69\x23\xdb\xd4\xda\x3a\xcc\x5c\x5d\x74\x59\xa0\xb9\x9f\xf9\x78\x5e\xef\xc5\x8c\x9a\x12\x36\x6c\x4f\x2f\x46\xda\xfa\x16\x4f\xca\xaf\x99\x4b\x62\x42\xd4\x48\x20\xfb\x98\x74\x49\xa0\x95\x91\xb2\xf0\xa9\xd7\xef\xd6\xd8\xb5\x59\xcf\x2c\x5e\x58\x9e\x0e\xf0\xf4\x67\x56\x5e\x59\xe3\xc7\xd6\x76\x0e\x65\x6b\x0f\x42\x57\x96\xcd\x63\x1d\xbb\x68\x70\x6e\x46\x9e\x70\xc9\x72\xb1\x97\x62\x70\xd5\xcc\xe4\xb5\x02\x91\x1d\x49\x00\x8f\x02\x74\xa6\x3b\x3e\x80\x9c\xf6\xf5\xde\x64\x0c\x7a\x36\x01\xb5\x2a\xb3\xa1\xfe\x5b\x4e\xa7\xcb\x37\x78\x9f\xc9\xdd\x5b\x6c\xa3\x0e\xda\xa4\xdd\x7f\x21\xf9\x2b\xce\x48\x8d\x72\xd2\xc4\x6d\x3c\x16\xd9\xa7\xf5\x34\x6a\x63\x3b\xfa\xdb\x74\x36\x6d\x38\x70\x30\x2d\x53\x1c\x1c\xe8\x47\x25\xec\xeb\xed\x0d\x83\xf6\x39\x5d\xd7\xa5\x5a\x16\x4f\xa1\xb7\x6f\x45\x58\xd5\x28\x80\x8a\x19\x92\xa3\x8a\x45\x1c\xae\x46\xd3\x4f\xef\x2a\xed\xb7\xe4\xbf\xdb\x9a\xbc\x06\xad\xd3\x17\x4e\x42\x83\x79\x04\x00\xd9\x0b\xe3\xf4\x31\xd1\x90\x6b\x2a\xbb\x36\x9a\xcb\xa2\x1f\x45\x25\xdc\x74\xfb\x3a\xa0\x99\xd0\x44\xd5\xd0\x32\x5d\x47\x2f\xfc\xd8\x15\x23\x97\x9b\x4f\x93\x97\x5c\xec\xa6\x88\x0b\xf4\x52\xe7\xdf\x95\xc5\x0e\xa8\x04\x5c\xef\x91\xaa\x47\x77\x39\xce\x9d\xf8\x1d\x2c\x77\x6b\xe3\xcf\x00\xe5\x4d\x11\x33\xe2\x6c\x3d\x2f\x68\xe8\x9b\x21\x59\xdd\xb0\x33\xcb\x39\x34\xb3\x6f\x6f\x4d\xe2\xde\xd2\x6c\x35\xaf\x8f\x15\x6e\xe6\x77\x97\xc0\xf1\xb4\xc3\x85\x51\xe6\x49\x95\xf4\x57\xfc\x76\x5f\x06\x32\xf2\x7e\x23\xb4\xef\x43\x47\xea\xec\x2d\x9f\x7c\xff\x34\xc7\xc9\x10\xa5\xcd\xcd\x54\xb7\x52\xdc\xe7\x36\x84\xab\x9b\xa7\x6e\x0b\x8f\x6d\x08\x93\x38\x10\x46\x28\x9b\x7c\x92\x5a\xc1\x14\x07\xe9\xea\xa2\x3b\x8f\xff\x26\x56\x62\xdf\xdb\xf5\xbb\xea\xdf\x3c\xd9\xff\x58\x7b\xbf\xf4\xff\x45\xff\xea\x1e\xf4\x31\xf9\x0f\xef\x99\x05\xf8\x4d\xa0\x63\xde\x87\x9e\x76\x2a\x44\x9f\x9a\xb8\x62\x69\xa4\xb6\x48\x53\xa2\xdb\x74\xb9\x36\x87\x62\x11\x80\x35\xc9\xe0\x13\x80\x00\xe3\xd8\xc5\x13\x79\xe6\x25\xa3\x16\xed\x77\x74\xe5\xf1\x95\x9c\xfa\x72\xf5\x11\xe2\x14\x9e\x7b\x2c\x45\xde\x13\xce\x24\xa6\xdd\x12\xd7\x35\x12\xa0\xa0\x48\xca\x28\xcb\x4c\x2c\x54\x5c\xab\xdd\xe2\x14\x4e\xc0\x50\xa6\x58\x32\x25\xa3\x5c\x5f\x70\xeb\x49\x5c\x9d\x83\xb2\xbe\x47\xad\x20\xfa\x50\xfb\x80\xd3\x17\xd4\x9d\x78\x99\x46\x23\xf4\xc0\x0e\xa2\x69\xbc\x2f\xbf\x35\x2f\xc8\x6b\x4f\x6f\x26\x6c\xea\x8f\xb9\xaf\x1f\x7a\xcb\xb4\xf9\xa9\xb0\x39\xdd\x65\x89\x5f\xeb\xa5\x78\x51\x20\xb9\x86\x0c\xc5\x46\x99\x14\xf8\xf3\xfa\x26\x8d\x75\x30\xd2\xe2\x66\xce\xad\xb7\x4a\x3d\x84\x10\x68\x6c\xf3\xe7\x5e\x49\x82\x14\xee\x80\x7f\x2f\xbd\x19\x6f\xfa\xe5\x69\xf4\x16\xe4\x79\x34\xda\x22\x97\x5c\x75\x8e\xd2\x3b\x40\x3d\x98\x35\xd1\x96\x3c\x82\x7b\xf0\xd4\xad\xaa\x75\xb6\x12\x64\x78\x10\x0a\xca\xaa\xa4\xb8\x85\x98\x04\x7d\x6a\x41\x00\xd4\x53\x54\xdc\x49\xb6\xb5\xc3\x64\xc1\xa2\x1c\x5b\x0e\x07\x60\xfc\x62\x3e\xda\x02\xde\x55\xea\xb0\x4c\xa8\x16\x81\x22\x82\x86\x9b\x77\x0f\x99\x05\x6e\xee\x22\x2c\x65\x0f\x81\x23\x76\x70\xc8\x6a\x7d\x30\xa1\xb7\xfb\x4d\xcb\x2f\xb6\xd4\x84\x39\x87\x3a\x01\x8b\x6d\x5c\x48\x3b\x54\xcd\x0b\x65\xa5\x83\x84\x5e\xb5\x98\x02\xdf\xd9\x03\xd7\x82\xb3\x88\x3a\x0b\x7c\x3f\xbc\xcf\xd0\x90\xee\x97\xb5\xa6\xd9\xe2\xd5\x50\xe5\x53\x0d\x9f\x3e\xb1\x9c\x3d\x80\xc6\x62\x15\x0e\x73\x11\xfc\x6e\x52\xc1\x42\x25\x8d\xbe\x63\x2e\xaf\x92\xd1\x9e\x15\x1c\xa6\xb4\x65\x3b\xe5\x76\x3c\x54\x78\xb3\xf0\xf2\x36\xa0\x84\x31\x38\x88\x93\x01\x44\x6f\x62\x17\x40\xea\xa3\x98\x8c\x96\x72\x06\x54\x56\x88\x12\x82\xac\xa7\x93\x9f\x06\x4a\x39\x3c\x50\x0b\xbc\xa5\x16\xc3\x54\x10\x5e\xcf\x04\x68\x77\xbe\x9b\x40\xe3\x15\x9e\xf4\x4b\x00\xf8\x7b\xcc\x78\x1a\x41\xfa\x7b\x07\x18\xcb\x58\x10\x1e\xb5\x6e\xd8\x62\x58\x6c\xeb\xd4\x85\x22\x30\x85\x20\x0b\x46\xe9\x1f\xad\xe3\x45\x07\xb2\xca\x19\x7a\x2c\x77\x70\x12\x78\x46\xd3\x17\x7b\xa5\xa7\x9d\x22\x4e\x15\xdd\xd6\xef\xab\x83\xf3\xa1\xfa\x63\xed\xc3\x91\xfa\x6d\x88\x7b\xfd\x75\x1f\x52\x7d\xd7\xa1\xc4\x13\xb8\xce\xce\x0e\xfb\xb7\x16\x9c\xe0\x9e\x36\x98\x0f\xfd\xda\xd9\xec\x2c\xd9\x8e\x3b\xf2\x21\xcc\x27\xad\x12\xe5\x2a\x0e\xa4\x4f\x56\xc5\x78\xff\x33\x09\x32\xd1\x78\xcc\x32\xb0\xdf\x9c\x3b\xe7\x79\x81\x87\xc0\x71\x5e\xfe\x7d\x90\xd3\x34\x66\x41\x58\x80\x83\xfb\x96\x36\x88\x8c\xe3\x79\x14\x61\x11\x79\xd5\xca\x04\xd2\x07\xa4\xc0\x2f\x4f\x74\x18\xa3\xda\xe3\x61\x67\xa5\x00\x2f\xf9\x38\x28\x0b\xc5\x15\x02\xb5\x5b\x00\xdc\x6c\x87\xbe\xdd\xa1\x18\x48\x35\x98\x7c\x06\xde\xdf\x4c\xc5\x91\xb1\xd2\xf1\x10\xc3\xe4\x5b\x98\xfa\xc8\x72\xff\x45\x29\x3b\x7c\x21\x75\x79\x79\xab\x95\x8b\xd8\x01\x35\x2c\x02\x91\xcb\x14\x6b\xee\x96\x75\xb0\x01\x69\xa2\x8c\x83\xca\x17\xa1\x1d\xe3\x13\x11\x8a\xbd\x04\x52\x44\x9d\xac\x4e\x73\x8d\x07\x6d\xc7\x48\x2b\xba\x4e\xea\x33\x94\xf4\xc2\xca\x3c\xb4\xd1\x4b\x75\x0c\x8c\x20\xbb\xa2\xf5\xce\x5e\x54\x1f\x02\xa4\x96\x76\x42\x5c\x09\xf7\x84\x61\x38\xf5\xb3\xbf\x6e\x35\x08\xed\x95\xa3\x71\x2b\x26\x03\x97\x17\x4f\x1f\x4f\x62\x9d\x8e\x2e\x9b\xcc\x7c\x23\xbc\x3d\x04\x67\x48\x6d\x73\x65\xc1\xe4\x6d\x17\xa0\xec\x32\x03\x82\x2a\x7a\x99\x3c\x82\x81\x78\x57\xed\xca\x20\x3d\x58\xb7\x75\xa3\x62\xc1\x26\xde\xa1\x93\xa3\xb8\x33\xd7\xc9\x42\x20\xa6\xd9\x40\x18\xa0\xc8\x72\xb4\x58\xad\xa5\x7c\xc5\x09\x00\xbc\x02\xa8\x80\xf2\xaa\x8d\x26\x64\x63\xf9\x30\x7c\xd2\x68\x67\x38\xdf\x91\xb4\x19\x2e\x36\x44\x9e\x37\x59\x73\x60\x34\x43\xe1\xbe\x63\x2a\x9c\x7b\xed\xb6\xb2\x5f\x96\x8b\xc1\x7b\x85\xc4\xaf\xad\x5c\x57\xd4\x04\xd5\xbb\x03\x75\xa4\x27\x57\x5f\x1c\x90\x8f\x5c\x69\xe7\x02\x9d\xd7\xac\x46\x46\xc8\xa2\x42\xbf\x38\x69\x83\x56\xd2\x7d\x18\xba\xbf\x91\x7a\xa1\x1d\x53\x64\x14\x3b\x9c\x43\xe3\xc4\xc8\xbc\x7b\x91\x82\xae\xac\xc9\x18\xd0\xfa\x69\x31\xe2\x5b\xc5\x03\xa4\x4b\xe7\xcc\x0c\x2a\x6e\xe5\x5e\x5e\x81\x1c\x5d\x51\x99\xdd\xd5\x4d\xc6\x38\x5c\xa2\x2a\x79\x31\x7d\xd2\xfc\x1e\x6c\x98\xdb\x03\x8e\xf3\xee\x1e\xfb\x48\x31\x60\x49\xee\xb3\x71\x48\x98\x5b\x06\x85\x89\xe5\x09\xe1\x49\x21\x66\x74\xce\xac\x11\xc2\xd6\x0d\xd9\x5f\x06\x42\xe0\xa4\x15\x84\x84\x82\x2d\x9f\x30\x78\x7c\xe7\xae\x92\xb6\x31\x42\xed\x61\x44\xb8\x7e\x8f\xd5\x56\x7d\xaa\x1f\x76\x42\x76\xbe\x5d\xd7\x4e\xb8\x54\x7f\x9f\x76\x52\x01\xb8\x0a\xed\x4d\xe5\x31\x22\x96\x79\x78\xda\x3f\x50\xfc\x29\x5f\xc8\x2b\x50\x9a\xf1\x2f\xe4\xab\xb7\x63\xf0\x41\x57\x79\xac\xc9\xd6\x8d\x9e\x6b\x72\x2b\x84\x37\x84\xd9\xd0\xd1\x21\xfc\x96\x12\x65\x5a\x5e\x29\xf6\x2b\x7d\x31\xc6\x86\xc8\x64\xdf\xa6\xfb\xa1\x07\xb5\x1d\xbc\xb2\x6c\xae\xdd\x08\x88\x59\x94\x55\x72\xc0\x4f\x57\x1a\x03\xd0\xc2\x20\x08\x0a\xa2\xb2\x4e\x73\xbc\xd3\x2e\xe9\x28\xa5\x12\xf4\x3b\x47\xb6\xf2\xe9\x0f\x76\x2e\x35\xcf\x7f\x91\x1f\x04\x65\x0a\xfc\x4f\x3f\x1a\xa1\xce\xf8\x20\x88\x8a\xe0\xa6\x2e\x33\x21\x94\x61\x1c\x6f\x68\x78\x95\x75\xd8\x7b\x23\xf8\x06\x82\x14\x3a\x32\xe0\x6f\xef\xaa\x8f\xbe\x86\x00\xab\xd4\x89\x78\x4d\xb3\x63\x41\xb9\xbe\x0b\xfc\x96\x72\x36\x53\x35\x31\x6f\xc9\x02\x2a\x4b\x59\x05\xc0\x3b\x1c\x93\x45\x8c\x59\x5c\x3f\xea\x9f\x21\xa6\x00\x92\x22\x90\xb3\x2c\xc8\x2f\xef\x29\xf4\x5a\x3a\xdf\xfa\x35\x45\xc8\x97\xcb\x42\x6e\x38\xdb\xe1\xba\xeb\x93\x05\xfe\x8e\x7c\xc9\xb5\x16\x71\x27\x77\x0c\x58\x3c\x47\x32\x2f\x8f\xa3\x58\xe2\xeb\xf8\xc6\x4b\x87\x28\x77\x45\x34\xdf\x4c\x2e\x99\xb4\x0a\x39\x3c\x66\xc9\x03\x5b\xca\xf2\x0d\xc9\x62\x8a\x8a\x87\xbb\x59\x82\x38\x9e\x4a\xad\xb3\xe9\x98\xce\xca\xf7\xac\xf6\x23\xa1\x11\x03\x4f\xe7\xf7\xe0\x28\x60\x77\x5d\x0f\x7a\x75\x9f\x19\x44\x10\x60\x49\x5a\x8e\x6a\x52\x40\xf0\x0f\xa7\x81\x0f\x8f\x49\x23\xcd\xa9\x51\xef\xe7\x15\xae\x73\xf4\x10\x10\xd9\xf1\x62\x81\x78\x5c\x80\xb9\x05\x5c\x24\xd2\x67\xaa\x91\x3c\x2b\x78\x3b\xaa\x12\x20\x2d\xe5\xa0\x4c\x65\x04\xa3\x25\x77\x33\x72\xb0\x96\x63\xf1\x44\x54\x04\x69\x6b\x87\x5d\xf7\x8c\x03\x67\x73\x90\x8a\xa5\xb3\x97\x75\x79\xb1\xfc\xac\x42\xa3\xd7\xb2\x69\x70\x88\x9b\x96\x35\x8e\xc1\x6b\x66\xdd\x2d\x60\x54\xe5\x11\xd2\xe3\xd2\xa6\x95\x76\xa6\x45\x25\x30\x4b\xdf\x54\x82\x94\xa6\xe2\xcd\x4e\xa3\x1f\x7d\x6b\x78\x85\xf8\xae\x8b\xf5\xea\x9f\x86\xb8\x9e\x7a\xd2\xe3\xc5\xa8\x4f\x6b\xc3\x63\x68\x3a\xc3\x2a\xa7\x15\x9a\xb5\xa7\xa3\xe7\x2b\x4c\x32\xae\xd5\x58\x27\xb5\x83\x5e\x23\x82\x19\x6e\xf7\x67\x57\x80\x58\x0f\xef\xb4\xce\x52\xc2\x04\x60\xbe\xfc\x24\x42\xbd\xee\x6c\x0c\xa3\x5a\x61\xf0\xb5\xba\x7d\x98\xc4\x2c\x89\x0a\x27\xb1\x58\xd9\x0f\x8c\xd3\x8b\x2c\xba\x09\x62\xc1\xda\x3b\x6c\x70\xf4\xc9\x79\x79\x59\xdb\x99\xd5\x2d\xf9\xec\x6c\x58\x2c\xbd\xfc\xcb\x1a\xa6\x9a\xc2\x2f\x1a\x6a\x32\x2c\x67\x30\x62\xac\x8a\x29\x71\x65\x93\xcd\x53\x04\x7d\x39\xd9\x8d\xbe\x9a\x61\xc8\x85\xef\x6c\x01\x90\x5b\x2c\x40\x00\x5f\x27\xb8\xf1\x56\x41\xf7\x08\x5c\x83\xaf\x4f\x98\x65\x26\x9e\xd0\xce\x4c\xa6\xab\x13\x3a\x5a\xa8\x8a\x5f\xdd\xb0\xe0\xf2\xd4\x81\x5a\xa6\x83\xdf\x40\x27\xbd\xe5\x05\x0e\x06\xdd\x26\x6b\x00\xd7\x8a\x88\xd4\x0f\xf9\xca\x59\x71\x15\x47\x04\x98\xf6\x6e\xf3\x7a\xfe\xa6\xed\x9b\xe5\x58\xc0\x2c\x26\x83\xdf\x85\x2d\x7a\xba\x68\xbf\x52\x1b\x9c\xfa\x70\x5b\xc4\xde\x18\xc2\x47\x61\xbe\xb8\xd0\xb8\x39\xee\x3c\x94\x7d\x08\xa9\x34\x87\x84\xae\xeb\x8b\xc1\x41\x24\x29\x37\xc0\x34\x63\x86\x47\x1b\x44\xfb\x14\xb6\x58\x32\xd7\x2a\x90\x6c\x45\x0e\xe1\xc1\x69\xe8\x58\xe8\xe1\x5b\x09\x57\x7d\xc5\x2f\x50\x97\x44\x42\xe5\xd8\x73\x20\x31\xce\xb9\x66\xeb\x5b\x72\x44\x75\x44\xb1\x1a\x44\x84\x23\xda\x99\x91\xfc\xca\x17\xcf\x82\x2b\x89\x8e\x17\x65\x9b\x34\xe8\xf9\x8b\x8c\x61\x64\x88\xe3\xcd\xc5\x54\xbb\xe6\x77\x97\x31\xfb\xfd\xc7\x12\x32\x63\xfe\x6f\x8d\x14\xd7\x7c\x95\x0e\x7a\x80\xa0\xd6\x9d\x3d\x80\x97\xdc\x0f\x6e\xcf\xe7\x2d\x4f\x80\x64\x00\xe5\x35\xab\x61\x89\xfe\x45\xbf\xd4\x0b\xb9\x40\x2d\x52\xd7\x9a\xc7\xaa\x57\x69\xcb\xd1\xd7\x6b\xea\x24\xd5\x87\x55\x67\x17\xaa\x08\x7b\x8e\xda\x25\x1e\xca\xb2\x2f\xb0\x2f\xaf\xe6\xba\xd4\xbf\xe5\x79\x86\xa7\x69\x96\x65\x66\xa0\x89\xc7\x8f\x13\x55\x22\xfe\x8e\xe6\xee\x0c\x30\xa1\x51\x00\x25\x03\x1d\xe0\x37\xf5\xe7\x93\xa8\x49\xea\xeb\x7d\xda\x8f\xcb\xea\xa4\x44\x00\x77\x44\x5d\xca\x65\x4a\xb1\x9e\x1a\xad\x9d\xe4\x1a\x7d\xf2\x20\x5c\xb9\x93\xe2\x36\xae\x79\x93\x54\x07\x18\xbd\x9f\x83\x9a\x0b\x40\xae\x29\x9b\xb3\x01\x3a\xef\x63\x75\x28\x74\xb3\xfa\xcd\x38\x31\x15\x23\xec\x44\xdf\x18\x67\xb4\x85\xe4\x12\x4e\xca\x43\xa1\x33\xbf\x57\x42\x1a\x01\x43\xb5\xf2\x97\xd7\xa6\xde\xaa\x48\xda\x86\xf8\xca\x53\xc7\x8f\x29\xf7\x72\x30\x77\xde\x8e\x66\xe6\xf7\xee\x5c\xc3\xfb\xc0\xfb\xba\x91\x33\x85\xd9\x0d\x1d\xce\x4b\xf2\xee\xcb\x74\x90\x0b\xee\xa8\x96\xa2\x0c\xb1\xb3\x88\xd7\x36\xe5\xc2\x26\x2b\xdd\xa7\xcb\x1e\x2d\x3a\x09\xb9\x48\xca\x4c\xbb\x51\xc9\xfb\x76\x82\x80\xb6\x82\xcb\xdf\x7a\x0c\x31\x14\xb7\x96\x1c\x2a\x79\xfc\xb1\x45\x75\xb0\xa1\xa2\xc9\x2b\x15\x76\xf5\x0f\xb8\x33\x91\x2d\x1b\x05\x57\xcf\xfc\xd5\x3b\x08\x7a\x67\x4f\xd2\xe6\xd6\x8a\x78\x97\xe1\xc2\x7a\xaf\x18\x3c\x63\x1f\xe2\x57\x0a\x66\x8a\xb6\x6c\x3f\xe4\x4a\xab\x11\x7c\xd0\xc3\x44\xc6\x69\x2c\x6c\xc6\xc7\x8a\xe1\x13\xec\x45\xca\x46\xae\x59\xbc\xc2\x65\x9d\x63\x2e\x23\x9f\x24\xb3\x8b\x46\xc9\xf4\x9f\xfa\x0b\xed\x02\xc1\xa3\x96\x33\xaf\x14\xca\xf2\x86\xca\x6b\x65\xb9\x00\x0f\xc5\x2c\x00\xc7\x2a\xc4\x1a\x30\x93\x65\x31\x7e\x6a\xda\xb0\x81\x8b\xa8\xd1\x6f\x1a\xed\x28\xfa\xce\xc6\xa5\xb5\x0c\xd0\xd7\xc4\x64\x3f\x18\x93\x21\xa7\x3b\xef\x4e\x9f\x43\x8e\x76\x8e\xb8\x82\xa2\x4a\xa1\x88\x7e\x69\x5f\xef\x3a\x19\xff\x5e\xa6\x4e\xdd\xfc\x25\xf5\xd3\xc3\x89\xf4\xd0\x11\xb4\xea\x50\x2b\xed\x40\x82\x6a\xe4\x47\x95\x46\x05\x2d\x99\x07\x61\x98\xbc\x0e\xe8\x11\xb1\x20\xb5\xac\x2e\xae\x60\x49\x03\x8b\x84\x99\xf1\xcd\xc0\xf2\xce\x4b\x9d\x5b\x3b\xb0\xb8\xc0\x22\x7f\x9f\xfa\x3c\xdd\x81\xa1\xf3\x7c\xca\x7c\x7b\x91\x10\x61\x4d\xea\xe4\xc0\xf0\x65\x8e\xb9\x7a\x22\x00\x73\x74\xab\xb0\x2c\x1b\xb0\x4a\xa5\x68\xd0\xf8\xd3\x74\x64\x8b\x99\x31\xc5\xc3\xe1\x2d\x7a\x3f\x88\x88\x43\xd4\xab\x32\xe1\x39\x19\x7a\x1e\x8d\xf0\x5b\x0d\x44\x58\xc1\xba\xaf\x6b\x20\xca\x1f\xc8\x61\x56\x77\xdd\xc1\x55\x38\x7c\x7b\xf2\x04\x1b\x78\xce\x42\xd7\x24\x77\x35\x77\xf9\x2c\x0d\xb4\x78\xe1\xac\xf0\x3a\xc0\x1e\x9f\xcb\x2b\xe5\x47\x47\xdc\x5c\x4a\x08\x68\x1a\x1d\x72\xe9\x84\x41\x2a\x52\xd0\xdf\xf7\x80\xe1\xfa\x83\x39\x36\x93\xf0\x1b\x99\xb1\x9b\x3c\xcc\x7b\x66\x69\x54\x10\x84\xd7\x1c\xba\x5a\x35\x19\x54\x29\xeb\x5c\x9d\x5a\xa5\x02\x3c\x5d\x47\x9b\xb0\x8d\xb5\x85\xf7\x1c\x02\x1c\xae\x0f\xe9\x1e\xf2\x9b\xc4\x6a\x83\x4c\xa7\x3c\xfe\xd5\x26\x32\xea\x45\xf9\xb6\x79\x79\xab\xe5\xc5\xef\x81\xc1\xc2\x5b\x12\x7c\x05\x9f\x4d\x51\x6f\x3f\xe2\x23\x21\x28\x0c\x23\x88\xb5\x47\x04\x96\xe7\x31\xa6\x27\xa8\xd3\xcc\x31\x4d\x8a\x1a\xc3\x24\x32\xe9\x43\x7b\x41\x43\x62\xcf\x3e\x9c\x7d\xb2\x7d\x52\x85\xe2\xb1\xf5\x61\xc6\x5d\x42\x98\xf9\x30\xc1\x90\x6a\x88\xe9\xec\xfa\xe3\x68\x78\xf2\x4b\x39\x5c\x31\x27\xda\xcc\x66\x36\xcb\x2e\x09\xe8\x73\x6c\xa2\x1f\x72\xeb\x04\x26\x8c\x79\x73\x8f\x8f\x80\xc5\x4d\xec\x8b\x47\x35\xa1\xaa\x6f\x8d\x6c\x32\xac\x1d\x5e\x33\x98\xbb\x6d\x3f\xc9\x32\xe5\x2d\xa4\x73\xfd\x14\x35\xb2\xeb\xb8\x0d\x30\x48\x30\x15\x1c\x10\xed\x95\x14\xbb\xc5\xa6\x32\x05\x58\xf6\x2a\x3d\x4a\x6a\x03\x9b\x61\x9d\xac\x4e\x18\xdd\xe3\x04\x43\x55\x9e\x18\xdd\xeb\x31\x02\xd8\x77\xd4\x7b\x21\x06\x44\xb5\xb1\x68\xae\x85\x13\x82\x5e\x8e\xad\xd0\xe4\xb3\xd5\x4f\x4c\xd5\x13\x87\x39\xd0\x2d\xf0\x9b\x15\x40\x1a\xd2\x97\x7d\x35\x72\xd2\x07\xf2\xdc\x5c\xf0\xc8\x78\x3c\x48\x3a\x62\x24\xab\xf2\x0d\x85\xff\x62\x87\x11\x36\xa8\xb7\xe5\xc9\x75\x79\x90\xe0\x94\xb8\x9b\x38\xd3\x73\xe1\x9c\x7d\x1e\x9d\xd9\x55\x62\x30\x73\xea\x83\x0a\x64\x82\xb4\xf2\xc0\xae\x8b\xc0\x09\x23\xbe\xd6\xaa\x69\xa3\xbe\x38\xd6\xa7\xe1\xd2\x11\x12\x68\x59\xdb\x94\x99\x45\x6f\x8b\x5d\xd6\x5e\x06\x8a\xcb\x47\x57\xbf\x29\x53\x53\xa3\x4c\xeb\x5c\xcb\xcf\xf3\x94\xdd\x1b\x25\xb1\x7a\xb7\x97\xa2\xcb\x5e\x26\x38\x19\x4c\xe7\xa9\xdf\x0e\x5c\x04\x64\xe6\x22\x16\x57\xf7\x8e\xb4\xcb\xe0\x7d\x92\x64\x52\xd7\x25\xe7\x12\x86\xbb\x9e\x84\x0c\x3e\x03\x04\xb2\x26\x6b\x23\x9d\xf0\x10\x6c\x36\x0e\x81\x65\x7b\xca\x92\xd9\x8a\xe0\xa9\xbb\x3b\x9a\x6c\x61\x13\x1f\xed\x9a\x8a\x48\xa0\x60\x36\x7a\xfc\x91\x15\xe2\x99\x75\x57\x7b\x67\x4f\x6c\x9f\x60\x67\x27\x1d\x63\x55\xef\xc6\x5c\x78\x9e\x46\xcb\x2e\x72\x81\x41\x86\xd6\x7c\x2a\xbc\x46\xfa\x84\xb1\x7f\x58\xe6\xbc\xc9\xea\x72\xc1\xd6\x50\x36\xa5\xbb\x8d\x06\xcd\x34\xc1\xe3\xf4\x12\x75\x78\x90\x54\xc3\xfa\xd2\x6e\xb1\x8f\x69\xfb\x6c\x3a\x93\x58\x7c\xa9\x55\x1d\x6b\x26\x24\x8a\x7a\x32\x1c\x4d\x96\xcd\x72\x14\x8d\x6f\x28\xea\x7a\xf0\x25\x6e\xaf\xf4\xfb\x3c\xe2\xd2\x56\x47\x86\xb5\xc6\x24\x96\xab\x9c\x0f\xc1\xd5\x52\xc5\x59\x99\xec\x01\x61\xca\xdc\x23\xe7\x8e\x9f\xfb\xe3\x1d\x56\xa6\x50\xcd\x49\xf4\x98\x85\x15\x9f\x57\x13\xd7\x86\x82\x79\x4e\x11\xc6\x89\xae\xa4\x3d\x2b\x57\xfc\x4a\x53\x3f\xf4\x96\xe5\x43\x21\x00\xf4\x52\xc4\x88\x78\xca\xfe\x01\x72\xec\x33\x12\x89\x74\xf1\x22\x4d\x4b\xa1\x32\xd1\x47\xfc\xed\xdf\xdf\x33\xdc\x9e\xdf\x7f\xb4\xeb\xbf\xbf\xbd\xfb\xbf\xff\x62\x73\x44\x66\xf9\xd5\x87\x3d\x9f\x24\xb8\xe3\xbe\x83\x92\x26\xbe\x90\x25\x8c\x2f\xcc\xf4\x66\xf3\xd6\x2c\x5c\x11\x94\x1e\x88\xd4\x5a\xa3\xdb\x7e\x06\x3f\x07\xe8\x6f\x76\xb0\xc8\x62\x35\xf7\xb0\x3e\x38\x0f\x75\x81\xe0\xcb\x16\x90\xaa\x0f\xbc\xa7\x82\x32\x20\xc5\xf0\x84\xee\xd1\x8a\x59\x02\xa0\x5c\x77\x6d\x45\x5e\x6a\xe3\x88\x98\x46\x4e\x10\x87\x83\x13\xeb\xf5\x39\x59\x82\x2a\x3a\xa2\x8c\xf9\x77\x3e\x10\x3a\xf2\x16\x87\xda\x55\x4b\x8c\x4d\x6d\x4e\x10\x3f\x34\xa1\x43\x60\x07\x05\x24\x77\xca\xd0\x58\x64\x01\x0f\x25\xcd\x36\x2c\xed\xe4\x27\x3d\x73\x69\xd2\x37\x27\xd5\x54\xfe\x6b\x0f\xa7\x07\x07\xd9\x77\x74\x5b\x5b\xe0\x08\x5d\xfb\x04\xa2\x63\x2a\x92\x8c\x6f\x34\xaa\xda\x81\x4e\x07\x3e\x67\xde\x5a\x54\xdc\x48\xc3\x0e\xe5\x7c\xc8\xf5\xc7\xda\x04\xe7\xd1\x6f\xcb\x40\xc5\x33\x94\xa4\xcb\x50\xf0\x30\x70\x1e\x39\xeb\xc8\x13\x97\xac\x6d\x6c\xe9\x5b\xc8\x88\xd3\x6d\x61\xff\x62\x2a\x34\x11\x09\xd2\xcf\x19\xc9\x12\xd8\x0e\xc8\x53\x3f\xbb\xf5\xfc\x2a\x4e\xaa\x72\x1d\x9e\x45\x31\x6c\x93\x19\xe3\x80\x55\x6d\x9b\x14\xe1\x5d\x92\xcd\xa4\xce\x96\x2d\x38\xa6\x8f\x96\x77\x44\xfd\x30\xbc\x92\x55\x54\xe3\x2f\xc1\xae\x39\x66\x95\x1a\xe7\x82\x84\x3a\x33\x3a\x89\x66\x54\x29\x78\x42\x2b\xcc\xf0\x95\x77\xf8\x36\x94\xbd\xbd\xa9\xea\xa2\x27\x04\x5f\x95\x8a\x82\xd0\x19\x6c\xa8\x7d\xb3\xc3\x33\x3f\x30\xae\x55\x8e\x55\x3e\x8f\xc7\x3c\x79\x04\xe3\xed\xb6\xd8\x34\x6e\x41\x94\x61\x63\x2f\x83\x0a\xa8\x07\x37\xe2\xee\x7c\x46\x53\x35\x30\xb6\x92\xad\xc6\x25\x2b\x9a\x1c\xdc\x83\x0e\xe4\xc6\xf6\x68\xea\xfa\x58\x74\xa2\xcc\xad\xf2\x01\xe9\x7b\x15\x0d\xc4\x59\xf2\x78\x27\x3a\x35\x56\xd6\x57\x09\x98\x0a\x9b\x1b\x89\xff\x1e\x11\x79\xfa\x78\x01\x79\xc6\x53\x7c\xdc\xa7\xdc\x4f\x16\xeb\x81\x2a\x66\x48\x47\x52\xdc\x6b\x76\x6e\x74\x41\x95\xc2\xf5\xd4\xe4\xae\xc3\xc9\xc6\x88\x9a\xb0\x47\x00\x69\x84\xa9\x57\x90\xfb\x34\xeb\x24\xc5\xa5\x4a\x11\xc1\x59\x21\xda\xed\x6b\xa2\x9b\x17\x02\x6d\xdc\xb0\x15\xbf\x05\x39\xc8\xb5\x12\x26\xaf\x4e\x34\x33\x1e\xbd\x42\x8f\x34\xbf\xce\x14\xaa\x86\x09\x63\x09\x6e\x30\xf5\x98\xd7\xd0\x9b\x85\x9f\x45\x8e\x74\xd8\x96\xd3\x03\x6f\x20\xb5\x91\x38\x8c\x01\x45\x57\x97\x44\x08\xe9\x5c\x71\xe6\x35\x42\x22\xa1\x4b\x12\x8c\xe0\xaa\x17\x2e\x06\x9c\xb9\x63\x8c\x9d\xe5\x22\x85\xab\x63\x1e\xad\xec\x4c\xfd\xa6\xd1\x33\xd2\x4b\xca\xea\x69\x38\x5f\xb3\x6f\x0a\x29\x3f\x56\x50\xa2\x2a\x62\x1a\xbd\xea\x67\x46\x2f\xb9\xa8\xb4\x3e\xe3\xcd\x21\xdf\x01\xae\x0d\xd3\x37\xdb\x6e\xa1\x67\x9f\xd1\xbe\x2e\x9f\xbe\x02\xbc\x6e\x97\xa2\x82\xe2\x1d\x83\x3f\x4e\xc4\x06\xac\x72\xa6\x05\xe4\x8d\x30\xe5\x71\x37\x21\x55\xeb\x86\xc8\x7c\xb3\x4b\x61\x77\x21\xad\x71\xc2\x65\x4f\xc1\x1c\xc9\x30\x15\xad\x14\xcf\xc2\xd4\x14\xc4\x7f\x7f\xe7\xc3\xd6\x62\xfe\x83\x05\x3c\x87\xfe\x2f\xd7\xfb\xfe\xe5\xf7\x44\xa5\x2e\xb0\xbc\x4f\xaf\xf9\xe4\x2c\x3c\x0d\xa9\x3e\x8c\xe2\x9e\x92\x7b\x8a\x0e\x6b\x13\xac\xa8\x20\x25\xb4\xe1\x81\x1c\xbb\xb2\xb8\xdf\x17\xe5\xa8\x6b\x5a\xd7\xcd\xe2\xef\x54\x98\x69\xc1\x85\xdc\x68\x86\xd8\x98\x9c\x65\xba\x79\xf4\x52\x3f\x99\xf1\x1c\x60\x61\x4a\xa8\x23\x44\xb4\x8b\xc8\x28\x92\x22\xa8\x9b\x20\xea\xaf\x0e\x5d\x76\x49\x1c\xa5\xb9\x2d\x44\x0c\x3b\x56\x74\xc1\x96\x42\x77\xdc\x6d\x25\xbd\x17\x27\x48\x20\x93\xf5\x83\x54\x43\xbc\x7e\xb0\xf4\x00\x5e\xb2\x93\x35\xa6\x63\x0b\x9b\x55\x1a\x3c\x3d\x4a\x55\x6f\x1b\xe8\x5b\x5f\x0d\x6b\xd9\x78\xd3\xec\x79\xb2\xbb\xa7\x85\x69\x8f\xa1\x69\x7c\x13\x64\xd1\xd1\x0d\xc8\x80\xc6\xf5\x90\x2e\x1f\x26\xfc\x20\xc2\x33\xdd\x87\x44\xdc\x74\x9f\x9e\xf3\xa2\xda\xea\xa7\x74\x21\x33\x48\xed\x8b\x1f\x38\xfe\x69\x9e\x8f\xe5\x57\xa0\xff\x11\x0d\x08\xde\x8d\xcf\xae\x6a\x7c\x04\x9b\xf2\x83\xa8\x3c\xdd\x0f\x8a\xcd\x69\x61\x0a\xb9\x45\xac\x01\x23\x55\xa1\xba\xd4\x6b\x0a\x26\xc9\xcc\x11\x8d\xce\x1b\x2e\x00\xd7\x67\x9b\xa5\x75\x20\x47\x49\x53\xfd\x09\x56\xd9\x6b\x7b\x33\x9b\xb7\x48\xb4\x5e\x07\xd1\x82\x29\x61\xea\x53\x2d\xc2\x40\xb7\x58\x8e\xfe\x70\xd4\xbc\x93\x66\x12\xf2\xb6\xd7\x5e\x46\xcb\xc7\x96\x50\xc7\xd6\x4c\x69\xf0\xc3\xdb\xcd\x12\xd9\x6c\x67\xee\xe0\x8b\x91\x53\xe5\x8a\x8b\x64\x69\xfc\x87\xd1\x2a\x6f\x60\xf1\x50\xe4\x30\xba\x6f\x66\x46\x16\xd4\x2e\xad\x93\x51\x95\xc4\x48\x63\xb8\xc5\x42\x63\x9e\x83\x0c\x3a\x2d\xb5\x7e\x22\x0d\xf9\xbe\xc4\xb3\xf6\xab\xc7\x95\x7a\x1a\xb9\xbb\x69\x68\x25\xb0\x2a\x2a\xa6\xe2\x3c\x5b\x3f\xf1\x32\xe1\x52\x26\x9e\xbf\x00\xb8\x4b\x9d\x47\xcf\x5d\xee\xd2\xa0\x79\xc5\xb4\x79\x8f\xfb\x95\x7b\x4f\x1b\xd1\x20\x10\xeb\x8b\x22\xb5\x5a\xa5\x53\xcd\x09\xe2\xaf\xbd\xc3\x62\xa5\x27\x32\x0f\x7f\x12\x5f\x6e\x47\x67\x80\x38\xd1\x2c\x87\xfa\x7d\xf2\x02\xf2\x68\x1e\xe6\x5a\x60\x26\x8e\x55\x65\xcd\xb3\x8b\xbb\x83\x2a\x14\x59\x33\x1c\xdd\x1b\xbb\xd3\xaf\xe5\x89\x10\x23\x99\x41\x6e\x47\x8d\xf2\x7a\xa2\x3f\xc5\x1a\x8a\xbe\x1a\xce\xa7\x70\xc7\x57\xce\x4c\xe3\xc8\xe1\xa4\x69\x11\x11\x7f\xe9\xa8\x81\xde\x97\x6e\xde\x19\x69\x47\x3c\x49\x54\xa8\x20\x67\x2f\xd0\x9d\xe5\x30\xd2\x50\xf4\xca\x8a\xfc\x10\x04\x38\x40\x06\xbb\x6c\x6e\xd7\xb1\xee\xb3\xa9\x66\xab\x88\xc8\xd9\x68\x45\x83\x23\xe2\x80\x74\xac\x81\x7b\xc1\x92\xe9\x45\xdb\xde\x45\xa6\x9b\xc3\xbd\x4d\x82\xba\x47\xd3\x8c\x7b\xdf\x66\x8d\x34\x2a\xd8\x33\xcc\x90\x96\xf7\x1d\xe5\x50\x5a\x3e\x63\x42\x18\xa5\xae\xd8\x46\xa6\x92\x09\x6e\x10\x7a\x1b\x10\x63\xf9\xc6\xf9\x9a\x13\xed\xeb\xa2\x34\x43\xb3\x35\xf2\x15\xb7\x1a\x11\xb3\xfc\xf7\xb4\x39\x8a\xfb\x0f\xf6\x17\x06\xd3\x7f\xbf\x10\x01\x75\xe4\xfe\x33\x28\x7a\xaf\x40\xfc\x9e\xb6\x62\xe0\x70\xef\xd1\x56\xa2\xca\x16\x24\xf8\x8a\xd0\x32\x4c\x3e\xc9\xdd\xca\x71\xd2\x11\x2a\x0d\xfa\x1d\xa5\x3d\x04\x24\xb6\x0d\x50\x88\xb4\x40\x6b\x90\x5c\x3b\x61\x6d\x7b\xaa\x65\xa5\x29\xab\xa6\x61\x64\xd6\xb5\x0e\x98\x1a\xa4\x72\xcc\x08\x5d\xca\x00\xbd\xe7\x59\x35\xbf\xe3\x17\xa3\xb0\xb7\x04\x32\x02\x21\x46\x0e\x4f\x27\x23\x7a\x6f\x45\x63\xf1\x6f\x7d\x15\x2d\x51\x80\x30\x2a\x75\x06\x41\x50\x1b\x21\xe2\x83\xde\x66\xfc\x55\xaa\x31\xfc\x01\xc0\x1c\x28\x06\xc0\x4e\x93\x2a\x11\x8a\x13\x26\x17\x7e\x8e\xaf\x57\xad\x90\x38\xeb\x16\xd6\x94\x3e\x63\xe9\x90\xb5\x93\xc9\xf9\x53\x33\x05\xae\x2c\xae\x88\x98\xe5\xe3\xba\x85\xb6\x5e\x42\x7d\xa6\x6a\xfe\x50\xe0\xdd\x60\x56\xd5\x87\x1a\xf4\x88\xca\xa6\x72\x59\x16\x47\x84\xc6\xc9\xf4\x15\x48\xb3\x53\x16\x6b\xc0\xd4\x80\xfd\x25\xc7\x06\xf5\x9e\xde\xe7\x6d\x52\x8f\x70\x53\x6a\xa1\xc3\x99\x3d\x15\xaa\xef\xb7\x74\x87\x60\xf3\xf6\x71\xe2\x2f\x03\x59\x8b\x15\x47\x5b\xfe\xb9\x9b\x01\x07\xa5\x07\x27\xb8\x30\x91\xf8\xfb\x54\x42\xa4\xbd\x08\x36\x24\xc3\xb6\x34\x6c\x2f\xe7\x7a\x63\xaa\x6b\x0f\x2d\x69\xbf\x95\x35\xd6\x4c\x07\xca\xff\x3c\xf2\xa2\xc2\x42\x15\xed\x40\x3c\x6c\x71\x76\xa2\xbd\x44\x7e\x53\xec\x98\x43\x8e\x00\x6a\x5f\x6f\x65\xdb\x4a\xc8\xa5\xe0\x2a\xd2\x73\x23\xd3\xc3\x32\x37\xbb\x9d\x0e\x1d\x1d\x02\xa2\x42\x97\xc3\x90\xb8\x9e\x39\x40\x8e\x74\xda\x6c\x01\x97\x79\x29\xa4\x8c\x9b\x17\x9b\x24\x1f\xa5\xcd\x4f\x29\xe6\xfd\x23\xc5\x72\x27\xc7\xdd\x2a\x13\xe2\x53\x8f\x2a\xc5\xc6\xe1\x03\xd0\x4d\x85\xcf\x1f\x40\xb2\xe8\x08\x82\x10\x3a\x13\x48\xda\xdf\x45\xb1\xd4\x02\x91\x0a\x5d\x03\xd5\xb5\x18\xcb\x34\x28\xa0\x9b\x7b\x72\xd1\xd7\x1f\x4c\x89\xe6\x9c\x46\x9f\x90\xfa\x95\x68\xf0\xae\x0a\x2e\x10\xda\xf4\x5b\x91\x12\x42\x13\x9d\x3a\x86\x50\x37\xf1\x99\x99\xbb\x07\xf8\xf4\x95\x2d\xc6\x95\xd1\x7e\x4f\x84\x7c\x27\x27\x64\x49\x26\x56\x38\x5b\x35\xfa\x4b\xe4\x7d\xc8\x57\x7c\x51\x87\x1e\xb4\x9d\x68\xd3\xf8\x6c\x73\x98\xde\xf8\xf6\x95\x0a\xee\x73\xd8\x72\x24\x7a\xec\xed\x3b\x76\xcf\xed\x9f\x92\x25\xd7\xf2\xcc\xb8\x71\x1b\x14\x20\x37\x12\xad\x9a\xe8\x0d\xa7\x7d\x2d\x36\x15\x85\x08\xf2\x9a\xef\xbc\xc7\x25\x45\x65\x66\xca\xde\x61\x32\x5f\xe5\xdc\x73\xe6\x98\x0b\x16\x5f\x6b\xb1\xdc\x8f\x51\x25\xf1\xe2\x19\xf5\x2e\x58\x9e\xeb\xa9\xa3\xef\xfa\xc1\x77\xae\x1e\xec\x13\x69\xbe\x3a\xd7\xc4\xb6\xa8\x51\x47\xa3\xf4\xc7\xc9\xf8\xd2\xc5\xf1\x73\xc0\x3a\x16\x01\xa6\xb2\xc6\xc3\x17\xa3\x04\x0b\x4b\xe7\xee\xe4\x51\x2b\x40\x74\x8c\x9e\xa7\x67\x5a\xeb\x9e\xa2\x19\x59\x1d\x85\xea\x9b\xbb\x46\x0d\x7f\x3b\x45\xc4\x03\xa7\xa4\x0a\x9b\x51\xf6\x41\xb8\x34\x4e\x19\xd6\xc6\x7b\x8b\xc4\xe8\xa2\xf3\xcc\xc2\x5f\x7c\x18\xd9\xff\x4a\x78\xf6\x8b\x4e\xe8\x7e\x4f\x79\x52\xf6\xe7\x1f\x4b\x9e\x0c\xfb\x5f\x7c\x98\xfe\xe7\x5f\x1e\x78\x66\xba\x6d\x5a\xe4\xb1\x61\x3e\x27\x2c\x55\x05\x93\xe3\x56\xf4\x23\x34\x55\x63\x8b\x11\xa0\xb6\xe7\x71\xb8\x2b\x88\xd2\x28\xaa\x9b\x60\x75\x83\x95\x1e\x95\x97\xbc\x25\x23\x64\xb7\x72\x2b\x36\x8a\x1c\x57\x8e\x2c\x0a\xf2\x14\x3a\x1c\xb4\x23\x31\x92\x8f\x39\x01\xbd\xb3\xec\x26\xef\x11\x0f\xca\x6b\xfe\x0c\xee\x0e\x89\xce\x5b\x16\x7b\x23\xed\x8d\x53\x8e\x8f\x24\x88\x1a\xe8\x77\xb1\xcf\x4e\xa5\xde\x26\x32\xc0\x28\xcc\x4d\x28\xe2\x58\x0f\xdc\x81\x91\xfd\xe4\x67\xbe\xe1\xc4\x48\x26\x38\xd2\x01\x82\xed\x8c\x44\x0f\xa6\x79\x85\xed\xf9\x46\x1f\x3a\x52\x17\x20\x76\x15\x1c\x4b\x9e\x5a\xbe\x98\x5a\x25\xcb\x73\x9a\xc0\x63\x73\xdc\x18\x3c\x54\x20\xc8\x2d\xfd\x16\x39\x15\xd2\xbc\xbb\x41\x0c\xd9\xfb\x45\x38\x05\x01\x98\x87\xd5\x2a\x96\x91\xd0\xda\x10\x78\x81\xc8\xb8\xf9\x35\x59\xfb\x31\xe6\xa4\xd0\xc4\xd0\xc9\x60\x53\x43\xa4\x74\x0c\x90\x30\xb1\x2d\xd6\xe4\xab\x40\x86\xf5\xcd\xf6\x69\x7f\x59\xaf\x34\xa4\x52\xe9\x4e\x6b\x43\x9d\x1b\x05\x4c\xdf\x99\x33\x56\xb8\xc3\x49\x1f\x66\x76\xfb\xfb\xea\xfb\xc2\xf1\x8b\x59\xb4\x11\x88\xbe\x8e\xd8\xa6\x18\xca\xe8\xd0\x60\x91\x1d\x7a\x6f\xdc\x24\xeb\xc9\x11\xde\xe3\x12\x19\x1c\x61\x0e\x97\x93\x99\xc8\x27\x87\x1c\x07\x2c\xe8\xa3\xfe\xf4\xeb\xd4\x0b\xb3\xcc\x58\x5f\xeb\x82\xe7\x45\xc9\x97\x8d\xee\xe5\xac\x60\x3e\xb4\xc2\xca\x5d\xc7\x83\x42\xbc\x75\x21\x67\xf9\x76\x78\xe1\x72\x24\x35\x3c\x34\x32\x7c\x96\x98\xa1\xe3\x9c\xca\x28\x5e\x41\x67\x85\x34\x8f\x26\x19\x5d\xa7\xb7\xa9\x2b\xb3\x91\x4b\x57\x31\xe9\x75\x46\xa5\xb0\x40\xbe\x97\xda\xbc\x69\xde\x3f\xa6\xe6\x4b\x84\xa5\x55\x80\xa2\x32\xd1\x3b\x4d\xeb\xfd\xb6\x2f\x32\xd9\xaf\x37\xb9\x53\xc2\x5f\x94\xfa\x18\x64\x68\x05\x18\xcd\x63\xed\x2a\xb8\x38\x9d\xd2\x91\xef\x7f\x6f\x36\x86\xd4\x04\x71\x26\x80\x73\x5c\x7a\xe2\x9a\xa2\xc5\x9e\xcb\x7d\x9c\xb4\xdf\x3e\x06\xcf\x4d\x69\x2d\xf4\x7a\x16\xde\xab\x74\x01\x74\x2a\x7f\xf9\xf6\x1b\x56\x29\xf1\xe0\xcc\x98\x6b\x75\x47\x66\x76\x27\x49\x29\x47\x54\x68\xc5\xd7\x8d\x22\xdc\x5b\x5e\xaf\xdc\x92\x24\x03\x93\x70\xaa\x5a\xac\xa2\xe8\xa8\x97\x29\x53\x9d\x4d\xf1\x31\x9b\x7c\x69\xec\x48\x79\x82\xc6\x36\x52\x16\xea\x6d\xbd\xad\xae\x52\xea\x78\x4a\x40\x08\xbf\x59\xec\xb6\x5f\xf8\x04\x10\xc6\x68\x85\x3e\x5d\x32\xb1\x5f\x8e\x7b\x9b\xc6\xdc\xa5\xce\x08\x80\x67\x5a\xc9\x8b\xd8\xc6\x4b\x19\xc1\x30\xb6\xb2\xd8\x2f\x4c\xa3\xc6\xe7\x22\xaa\xce\x22\xb2\x5c\xf3\x0c\x5a\xcd\x6b\x1f\x3f\x04\xe7\x44\xba\x1c\x1c\xc9\xc1\xc5\xc9\x82\x25\x73\x35\xd0\xc6\x08\x15\xb6\xb2\x88\xad\x9a\x18\x7d\x7f\x87\x40\xda\x8a\xe8\xad\xc4\x2a\xc0\x39\x8b\xb9\xb0\x7e\xd7\x73\xd2\xaa\xf9\x83\x9d\x73\x0c\xfe\x6f\x7c\x92\x5f\x6d\x0e\x70\x5f\xe7\x9e\x5e\x7a\x0d\xea\x93\xe6\x42\xa1\x9b\x76\x98\x87\x57\xe4\x58\x10\xfd\xd1\x39\xdb\x4f\x0b\x54\xc1\xfd\x0d\x95\x85\xf0\xd7\x74\xbd\x04\xa2\xfe\x40\x99\xf3\xad\x75\x5b\x9a\x5a\xfe\xa0\x59\x9f\x51\x07\x09\x77\x14\xeb\x51\x8a\xd0\xbe\xdf\xf7\xa4\xf2\x27\x36\x1b\x76\xff\x62\xbd\x5e\x90\x24\x86\xbc\x63\x49\x61\xc8\x9d\x65\x68\xfd\xee\xdc\x1b\x7f\x00\x16\x2f\x2d\x5d\xa2\xcb\x1c\x05\x75\x46\x10\x81\x19\xaf\xc1\x11\x35\xe8\x82\x9e\xc4\xaf\x3b\x35\x60\x61\x0c\x00\x8d\x41\x9a\x6a\x27\x5a\x8d\x27\xc3\xb4\x3f\xf0\xe9\xcf\x71\x3e\xed\xdf\x30\xcb\x74\x5e\x45\xb4\x2b\xbe\x13\x38\xdd\x38\x27\x5f\xe9\xa5\x30\x4f\x70\xd0\x74\x6c\x77\x72\xfd\x8a\x98\xff\x3f\x7b\x6f\xde\xbb\x38\xb2\x2c\x88\x7e\x15\x34\xd2\x55\xbd\x11\x03\xde\xb7\xf7\xd4\x7f\x78\xc7\x78\xc1\x2b\xb6\xf9\xe7\xca\x1b\xb6\xf1\x06\x78\xf7\xa7\x7f\xb2\xf9\x55\x55\x9f\xd3\xdd\x73\xce\xd5\xed\x91\x7a\xa4\x2e\xf1\xcb\x32\x99\x91\x91\x91\xb1\x65\x44\x60\x8c\xff\x9a\x87\x91\x5a\xe2\xcc\xa9\x01\x05\xa3\x74\xf4\x22\x76\x22\xf9\x2a\x6f\x6c\x73\x82\x31\x14\xe0\x62\x36\x36\x18\x76\x7a\xdd\xfa\x7d\x9f\xbe\x6a\xb7\x71\xa9\x76\xd4\xb0\x24\x7b\xc2\x5a\xd3\xa5\x52\x83\x87\xa2\xe1\x8a\x5d\x60\x91\xfb\xc1\xc0\xae\x54\x00\xf6\x98\xb5\x87\xd2\x3b\xcd\xf0\x79\x49\xbf\x62\x27\xad\x28\xf2\xc4\x8d\x8e\x51\x70\x36\x79\xf6\x1a\x5d\x7f\xed\x99\x46\xc5\x0a\xd6\xaf\x04\x9b\x7a\xbc\xe7\x1a\xda\x67\x05\xdd\x11\x59\xc2\x4c\x64\x9c\x85\xd6\x48\xb3\x95\x4d\x3b\xa3\x9d\xc6\xe5\x0d\x60\xaf\xf2\x39\x50\x6a\x09\x12\x39\xd2\xce\x8b\x5b\xae\x5b\x26\x29\x4e\x79\x48\x46\xd9\x89\xc2\xaa\x9b\x3d\xa5\xa3\x7b\x1a\x4f\xc4\x3e\x15\xd4\x76\x7c\x45\x4d\x21\x99\xe1\x43\xbd\xc0\x27\x8e\xad\x6f\xd0\x75\xa0\xdf\xcf\x07\x5f\xd5\xf2\x2d\x22\xf7\xd1\xed\x7c\xf6\xc5\x56\x69\xd5\xfc\x46\xd2\xe9\xc8\xbf\x02\x1f\x57\x43\xdc\x34\x4c\x04\x39\x0b\x99\xc8\xb3\x0b\x6b\xce\x77\x5a\xf0\xb4\x9e\x1a\xf6\xe6\x55\x33\x6f\xae\xa4\xf6\xdc\x59\xeb\x7d\x95\x0e\xb8\x39\x72\x04\x31\x63\x2f\x69\xd7\xd3\x9d\x70\xe5\x68\x12\x11\x31\x9a\xb4\xdf\x02\x37\xee\x05\xcc\x50\xe9\x89\x96\xcf\xe7\x69\x81\xa7\xda\x45\x4c\xfd\x2c\x86\xd5\xfe\xcd\xce\x8f\xa6\xbb\x25\xdd\x09\xe5\xc4\x25\xb0\xac\x84\xa3\x91\x0c\xbd\x95\xa8\x09\x9e\x2f\xfc\xcd\xb5\x9f\xd2\x22\xa0\x35\x50\x51\x14\x16\x6a\xf1\xeb\x36\x32\x78\x05\xa6\xc2\xbd\x43\xe8\x02\x1f\x96\xbd\xec\xbb\xa3\xd0\x8a\xe5\x4b\x9a\x3c\xa9\xe3\x23\xae\x83\x68\x53\xe5\x3b\x39\xbe\xa6\xb7\x70\x7f\x1f\x69\x50\x84\x59\x38\xf3\x54\xf0\x66\xdf\x34\x33\xb2\xee\x60\x08\x3d\x2b\x2f\x27\x7a\xbf\x7e\x48\x7b\xe5\x1e\xd4\x15\x76\x37\x8d\x56\x26\x19\x69\x92\xa3\xb7\x4c\xe4\x40\x2f\xa5\xfa\xde\x1e\xf7\x42\x69\xf2\xaf\x93\x86\xdd\x27\x60\x98\x1d\xb4\x3f\x31\x3c\xee\x5c\xd0\x94\x73\x5f\x05\x70\x16\x02\xa5\x57\xa7\xc8\x4b\x84\x02\xb7\xfb\x33\x05\x5e\xc1\xd3\xa5\x80\xf2\x9a\x38\x93\x34\xfd\xa8\xd2\x42\xbf\x3f\x9c\x7d\xde\xfe\xa9\xbe\x21\xfb\x6b\x79\x86\xd0\xfc\x79\x8b\x66\x01\x29\x23\x48\x1b\xf5\x1d\x1c\x1b\x19\xec\xba\xeb\xeb\x09\x66\xe3\xeb\xca\x96\x7b\x87\xe1\x4d\x9b\x42\x05\x62\x22\x48\xf6\x8e\x3a\x0b\x44\x50\x9c\x0d\xa1\x02\xe9\x86\xfe\xa9\x33\x0b\xc6\x37\x15\xed\xc5\x75\x71\xa0\xdf\x94\x4b\xd8\x2b\x2d\xa4\x89\xa5\x17\xb9\xdc\xf9\x26\x86\xc9\xbc\x9f\x08\xc3\xe1\x8d\x54\x7a\xd9\x20\xa1\x2b\x98\x2b\x67\x27\x05\x3b\xa1\xf8\x79\x0f\xc3\x2f\x18\x1e\x5a\xf7\x19\xba\x63\x5c\x9b\x68\x73\x26\x41\x45\xcb\x17\x38\x5a\x44\xe7\xc1\x6b\xd9\xf0\x40\xa3\x4e\xe2\x51\xf7\xfd\x20\xbd\x4a\x77\x4a\x59\xa1\x6a\xd6\x8f\x2e\xc2\xc2\x53\x0f\xe8\x22\x5b\x36\x1b\x3f\xe2\x77\x97\x2b\xf1\x9b\x90\xb3\x6b\xba\xf0\xc3\xe8\xe2\xc5\x9b\xa5\x60\x1e\x2f\x50\x39\xa6\xc2\x73\x87\x11\xe7\x2b\x36\x08\x32\x2c\xdf\x4d\xc3\xbc\xee\x4d\x5a\x2d\x96\x29\x2d\x7d\x09\x32\x03\x6e\x86\x63\x17\x7a\x3f\x5d\xf3\x61\x34\xd8\x55\xcc\x23\x5f\x6a\xde\xee\xb5\x69\x84\xc1\xb8\xb2\x2c\xfd\x10\xc9\x4b\x35\x42\x6a\x2a\x92\xb4\x0a\xf6\x16\xe3\x70\x56\xcd\xde\x0b\x40\x12\xd9\xd3\x78\x47\x38\x96\x03\x08\x27\xbb\x28\xcc\x5b\x28\xb8\x3e\x79\x02\x19\xe7\x58\x16\x3b\x40\xb9\xdf\xa0\x6f\xe9\xfe\x12\xc7\xca\xb1\xb4\xf3\xe3\xee\x87\x4c\x64\xc8\xd9\x6d\x04\x03\x46\xa5\x51\x06\x25\x95\x91\xc9\x98\x0e\x88\x2e\x1a\x09\x9e\x2a\x95\xd2\x0c\xfc\xee\xa5\x80\x5b\x16\x3d\x6a\x8f\x95\xe6\x72\x4b\x60\xbc\x96\x93\xb8\x07\x75\x4b\x6e\x62\x2c\x3a\x61\xd7\x0c\x36\x73\x3a\xf3\xe5\x88\xe4\xca\x2b\xe4\xe8\xd6\xdc\x0b\xaa\x38\xa7\xd7\x52\x4d\x21\x40\xc7\x19\x16\xe7\x5e\x9e\x21\x93\x0f\xed\xc6\x79\xb4\x4f\x43\x77\x18\xba\x22\xe8\xa8\x7a\xbe\x10\xe4\xf3\x75\x04\xdf\xe7\x79\x51\xd2\x16\xb9\xaa\xc5\x74\x79\x88\x5d\x3e\x01\x57\xd0\x73\xd9\xec\x06\x46\x12\x9c\x03\xf1\x32\x78\xf1\xdd\x8e\x41\xe3\x4e\x41\x8c\xaa\xbf\xb3\x59\x5b\x52\xf9\x7e\xa9\xa6\xc0\x9d\x9f\xaf\x80\xf3\x4e\xdb\x23\x08\x3b\x56\x21\xbd\xcb\x5d\x40\x89\x3f\xf7\x01\x63\xd9\x5f\xed\x2b\x45\x49\xf6\xeb\xaf\xe8\x0d\x20\x48\x3b\x27\x19\xf0\xe4\x3b\x34\xdf\x62\xde\xba\x9a\x8c\xf7\x30\x2d\x53\x78\xa9\xc6\x95\xa1\x31\x29\xc2\x24\x84\xab\x47\x1e\x48\x9f\xb5\x52\xcf\x22\xa2\xa4\x5e\x5a\x4e\xa8\xc3\x71\xca\xcd\x02\x4d\xb7\xe0\x94\xdc\x9c\xac\xbe\x2d\xa8\x1e\x17\x3d\x2b\xa9\xc2\x4a\x49\xdd\x5b\xe8\x11\x7b\x38\xac\x6f\x25\x05\x57\x29\x98\x36\x0d\x12\x22\xf7\xfb\x05\xa8\xa3\x78\x98\xef\x8f\x53\x72\xc7\x5f\x30\x57\x0e\x2d\x69\xc0\x45\xb7\xbc\x21\x7c\x6f\x29\x38\xf8\xc8\xb2\x1b\x4e\x85\x17\xd2\x23\xd9\x52\x61\x89\x91\xf2\x62\xf9\x7c\x15\xc9\x7b\xaf\x82\x6f\xc8\x7d\x9f\x45\x34\xf5\x1e\xe9\xcb\x81\x38\x50\x15\x23\xb8\x60\xec\xb9\x2b\xf7\x44\x40\x79\x95\x1b\x95\x90\xc4\x00\xd9\x4d\xe6\xb3\x28\x7a\x61\xc1\xf9\x0c\x24\x48\x68\xf7\x84\x9b\x42\xec\xb5\x21\xde\x9a\x52\x9a\x99\x93\xa1\x8d\x5a\x7b\x0d\xd7\xcc\x59\x73\x12\x67\xb7\x72\x92\xbd\xe1\x84\xbc\x22\x05\x84\x4b\xb2\x0f\x5a\x28\xd5\x25\x5e\x92\xa8\x60\x47\x41\x03\x71\xda\xa6\x6b\xd2\xa8\x38\x55\x55\xc5\x52\xed\x47\xb7\x8f\x9e\x0d\x7b\xd2\x12\xf4\xc1\x14\xb4\x9a\xd4\x0f\x7f\x30\x75\x7b\xce\x31\xe4\x3c\xf4\xa3\x47\xd2\xcf\xb2\x4c\xe8\x84\x89\x4c\xe1\x7d\xc2\xdf\x9e\x34\x29\x79\x45\x49\xc0\x33\x47\x0c\x1a\x32\x33\x39\xf0\xa7\xf8\x51\x68\xa4\x34\x06\x25\xab\x4a\xa3\xdb\x52\xe5\x43\x2d\x32\x70\x5c\x8a\x3d\xa5\x12\x23\x44\x50\x2c\xa2\xdc\x34\x6f\x1a\x12\x38\xdb\x47\xc8\xa9\xa7\xa0\x53\x22\x57\x1c\x80\x2f\xa7\x8b\x52\x8f\x24\x92\x97\x0c\x04\x5c\x41\x36\x79\x39\x88\x41\x42\x0a\x0b\x5c\x50\x28\x84\x99\x6e\x82\x35\xf8\x7c\xd5\xe1\x77\x6e\x92\x89\xed\x4c\x55\x0e\xda\x0b\x33\xbe\xe5\x9b\xda\xbe\xd4\x66\x21\xd5\x96\xcb\x00\xce\xed\xdd\xcc\x61\x64\xc7\x54\xe4\xc9\x90\x92\x8b\xea\x36\xcf\xce\xd7\x6b\x0b\x8a\xf6\x92\x76\x63\x8a\x51\xb2\x9a\xea\x62\xb5\x15\x73\xb3\x08\x66\x8f\xb8\x97\xe5\x36\xbc\x65\x71\x29\x54\x3a\x17\x5f\xda\x4c\xa4\x7b\xa5\x32\x0b\xf3\x9e\x14\x4c\x4d\x6b\x33\x0c\xe1\x88\x7e\xf3\xde\x56\xf8\x36\xf0\x21\xca\x20\xca\x5b\xc8\xbb\xce\x9d\x66\x05\xa1\x8c\xa5\x38\x31\x72\x12\x7b\x8f\x7b\xbf\x9f\x11\x9a\x16\x1d\x84\x90\x34\xe6\xdc\x35\x7f\xea\x03\xba\xb6\x1f\x51\xf8\x4b\x19\x5d\xf5\xab\xe7\xd6\x16\x5f\xe1\x6b\xe5\xe3\x20\x16\xec\xb3\xec\x66\x33\x9a\x6c\x72\xf4\x53\x7b\xbb\x92\x49\xa3\x35\xcf\x38\xb7\xb8\x62\x53\x45\xcb\x51\x55\xc6\xee\x7b\x41\x8b\x7b\x24\x14\x06\xe8\x0c\xf1\xde\x85\x63\x4d\xe8\x7c\xb6\x54\x7b\x7c\xbe\x1c\x1d\xd7\x72\xf6\x99\x40\xe0\xed\xb1\x20\xd9\x03\x53\x2b\x24\xb7\xe6\xb0\x44\x88\x47\x7d\xdf\x47\x18\xf2\xa8\xb8\x50\x7b\xe6\x54\x12\xee\x71\xa1\x8b\xf2\x36\x09\x28\x90\x0a\x5d\x6d\xd1\x42\x3c\x1e\x17\xcb\x93\x8b\x4c\xea\x80\x37\x84\xee\x31\x08\x7b\x31\xaf\x8a\xa3\xc9\xd3\xf3\x25\x07\x69\x86\x21\x5e\xd0\x3c\xc3\xf2\x29\x85\xc9\xbe\xa8\xb9\xa7\x40\x67\x7a\x10\xc2\xdc\x08\xda\xf2\x60\xca\x44\x59\x69\x17\x6e\x49\x74\x26\xbd\x95\x32\xd5\x38\xae\xf5\xac\xae\x5a\xfc\x94\x1c\xd2\xde\x3f\x02\xb5\x9d\xd5\x80\x43\x55\x2e\xba\x5d\x83\xbd\x96\x9d\x55\x0d\x04\x47\xb0\xc6\xaf\x70\xad\x21\xb3\x91\xc6\x27\xf7\x16\xa4\x7b\x65\xf1\x75\xbb\xa9\x24\xba\xb3\x41\xfb\x74\xed\x74\x31\xa8\xab\x10\x60\xc2\xc7\xa8\x08\xc5\x50\xc3\x52\xd7\xf9\xa2\xff\x2c\xe5\x99\x5b\xda\x53\x46\xa4\x71\x35\xd3\xee\x3d\xc3\x96\xeb\x0b\x14\xfb\x2c\x45\x4d\xfa\x24\x38\x59\x75\x1f\x5e\xc8\x03\x42\xd0\xc0\x6b\xc8\x30\xde\x4b\x76\xad\x0a\x97\x4b\x33\x38\xd8\x23\x14\xcd\xe6\x36\x6a\x93\x50\x43\xd1\xd4\xd3\x52\xc4\xb9\x40\x7b\xe3\x1e\x34\x10\xa1\xfd\x9e\xd1\xa6\xcb\x79\x9e\x5e\x41\x52\x3f\x25\x64\x21\xc9\x54\xbd\xeb\x35\x75\x1a\x28\xf2\x64\xdc\x2c\xdc\x0c\x16\x17\x2f\x1e\xfc\x34\x08\x39\x69\x8b\x31\x67\xcd\x80\x0b\xf2\xd5\x1d\x55\x2c\xdc\x24\xdb\x01\x82\x98\xea\xbe\x58\x63\xa1\x47\x15\x81\x9e\x1b\x8a\xcf\x41\xf1\x96\x56\xc5\x48\x1a\xec\x25\x68\xc8\x8b\x17\x05\x0b\x80\x0d\xd6\xad\xd6\xe3\xfa\x89\xd0\xcf\x17\xc3\x28\x85\x7b\xe6\x41\x36\x27\x68\x6b\x09\xa5\x8c\x55\x14\x03\xe2\xc1\xfc\x52\x30\x5c\x46\x69\x4f\x27\xcd\x9d\xe4\xd1\x90\x8d\xd6\x9f\xc7\xb9\x06\x7d\x9d\x66\xba\x1a\x83\x1c\x5f\x10\xf2\x41\x44\x66\x46\x64\xb5\x5b\xd1\x73\x5d\x04\xa8\xee\xfe\x66\x48\xc8\xe5\xed\x3f\x99\x80\x36\x59\xb9\xbf\x17\x08\x83\x79\x52\xee\xce\x59\xae\x60\x17\xee\x49\xee\x85\xbb\x70\x3a\xed\xe5\x5c\xb6\x5e\xae\xec\x28\xe4\x9d\x05\xb4\xa5\x16\x4b\x9d\xa9\x96\x3d\x8c\xc6\xb7\x87\x5c\x73\x20\x7b\xe6\x22\xb5\x99\x5d\xd0\x7a\x79\xbd\xda\x9d\x18\x61\x24\xde\x99\x44\x73\x10\xff\xd6\x1c\x2d\xb8\x4f\x32\xa3\x25\x43\xf0\x1c\x7b\x1c\xd3\x9e\xbc\x81\x0a\x2f\x4f\xa2\xf7\xa6\x1a\xe3\xd7\x91\xd1\x91\x48\xb7\x78\x33\xc4\x53\x45\x12\xa4\x17\x0e\xed\x9d\x97\xe8\x06\x42\x1c\xbd\xaf\x1d\x50\x56\x74\xef\x3e\xe8\x1c\x0e\x72\x55\x18\xab\x8b\xdf\x4b\x67\x40\xc3\x55\x98\x1c\x46\x49\xa5\xd5\x46\xe3\xe6\x14\x7d\x47\x0e\xf5\x67\x3a\x85\x3c\xfa\x8b\x7d\xcc\x96\x99\xbf\xf2\x09\xc2\x8f\xef\xf6\xc6\xef\x80\x08\x15\xed\x99\xc3\xf4\x64\x08\x72\x50\x16\xe7\x77\x93\x49\x6c\xee\x17\x9e\x1e\xa4\xde\x7b\x22\x48\xee\x8e\xca\x28\x29\x72\xcc\x52\x19\x89\xae\xa8\x99\x73\xe1\xb4\xc9\xc0\xa2\x9c\x2f\xce\xd7\x17\xd7\x9d\xc5\x4a\x75\xdf\x2c\x6d\x9b\x61\x0c\x27\x51\x63\x61\x3d\x12\x34\x43\x95\x2c\xed\xd0\x53\xdb\x2d\xc9\x7a\x2e\x97\x99\x84\x7a\x0a\x11\xc1\x6f\xcc\x57\x48\x48\x91\x78\x85\x4f\x33\x85\x46\x7a\xa0\x8f\xa7\xea\x54\xeb\xd5\x5d\x74\x01\xb7\x1f\xf6\xca\x73\x1c\xe3\x3a\x31\x7d\x66\x22\xf4\xc4\x95\xc1\xf1\xe2\xfb\x59\xe4\x4d\x73\x54\x88\x57\xe8\x1e\x87\x75\xd8\xab\xad\x17\x15\xe5\x4b\x37\xcf\xc6\x24\xa8\xf2\x82\x9a\x13\xc7\x76\xd7\x0b\xda\x22\x53\x69\x3e\xdc\x86\x01\x05\xff\x51\x1a\x3a\xcf\x33\x79\xc2\x66\xa3\xcc\x9a\xa2\x3a\x61\xbd\xd2\x05\x72\x0b\xe9\x58\x92\x93\x92\x5c\x8a\x01\xe0\x17\x9e\xea\xf9\x5d\x69\xf3\x5c\xd9\xd6\x23\x50\xa9\x5e\xc6\x9c\xa3\xd7\x64\xc9\xf8\x50\x46\xcf\x00\xd5\xf9\x27\xdb\x34\xce\x2c\xbd\x5a\x4c\xc5\x33\x11\x6a\x60\xd6\x19\x5f\x34\x48\x41\x91\x10\xf9\xca\x1d\x68\x1f\x4b\xe4\x11\x18\x9f\x1b\x52\xf3\x90\x28\x82\xa0\x58\xdb\x37\xd1\xc7\x68\x33\xf7\xfd\x9b\x10\xe9\x31\x03\xe9\x89\xcd\x15\xfc\xac\xda\x00\x88\x0e\x06\x41\xf5\x64\x20\xc1\x17\x80\x38\x2f\x29\x4e\x35\xb8\xd8\x90\xc9\x38\x47\x4e\x90\x75\xcc\x93\xe6\xb2\x93\xac\xd4\x32\x90\x5c\xc3\x42\x8d\x3b\xf3\xe2\x4a\x03\x09\x6a\x06\xdc\xea\x59\x1d\xd1\xd4\xa9\x1b\xeb\x3d\x95\xdd\x44\xf0\xed\xe3\xdc\x22\x8c\xe7\x72\x4f\xc4\x59\x0b\xde\xda\xce\x99\xc9\x77\xdc\x8f\xba\x05\x8c\x31\x90\x64\x55\x8e\x14\xe3\x0b\x5d\xec\x53\xee\x3a\xa9\xf7\xdc\xf3\xbd\x42\x0a\x83\x36\x08\x25\x66\xd6\xe8\x44\x5b\x24\x9e\xcf\x12\x5c\xf8\x48\x0d\xaa\x03\x4a\x32\xf3\xfb\x62\x54\x41\x1d\xc5\x39\x29\x81\x72\xf4\x40\x1c\x2c\xef\x69\x98\x9a\xe8\xa4\x94\x59\xe7\xf4\xe6\xa5\x60\x5e\xca\x2e\x48\x45\x98\x47\xa5\xb1\x10\x02\x23\xb5\x58\xbc\xf4\x25\x90\xca\x35\x30\x26\xa5\x0e\xeb\xb5\x2b\x56\x8b\x58\x9b\x9e\x63\xd9\x67\x41\x91\x74\x1b\xfb\x72\x1b\x18\xc9\x12\x34\x9e\x99\xea\xb6\x5f\x38\x44\xf4\xd0\xe1\xce\xb5\xed\xb2\xbc\xe8\x1e\x7c\x14\x67\x83\x4b\x62\x56\x0c\x19\x9c\x76\x53\x0c\x7d\xfa\xa1\xde\xec\x35\xf1\xaa\xc7\x76\x4a\xf3\xf4\xcb\x78\x11\xa0\x3e\x77\x92\xf2\xe7\x7e\x17\x3f\x6f\x9b\xbf\x96\xbd\x3e\x7e\x7e\x2c\x5e\xb4\xdd\xdb\x01\x79\x67\x7a\x03\x05\xf6\x0a\xcf\x4b\xac\xfb\x4f\xb1\x78\xb6\xce\xb9\xa1\xe1\x17\xd4\x28\x0f\x3b\xce\xc5\x5c\x62\xb1\xa8\xf7\x4e\xe5\x34\x50\x0c\x7f\x79\x5b\x9d\x3d\x30\xb5\x31\x98\x6f\x8b\x96\xda\xe4\xc1\xbe\xcb\xd7\xb3\x75\xcc\x17\x9c\xb1\x67\xcd\xd8\xdb\x9a\x52\x61\x7d\x04\x4c\x88\x5a\x2d\xe7\x0c\x41\x2b\x4e\xab\x87\xa1\xd6\x96\x0b\x8f\x8a\xe2\x65\x9c\xc8\x7d\x47\x79\x46\x71\xaf\xc1\x2b\x0f\xfa\x18\x40\xdc\xf6\xc5\xa9\xda\xc7\xc3\x25\xeb\x62\x44\xa7\x22\x60\x1a\xb5\x5b\x46\xd4\x6e\xa0\xfa\x9d\xe6\x54\x1e\x20\x44\x1d\x30\x94\x1a\x01\x90\x67\x2c\x30\xcd\x74\x5e\x2a\x72\x5a\x9e\x26\xf7\x10\x79\x38\xb8\x9e\xd0\xab\xfd\x8a\xeb\xc6\xf1\x53\xc0\x2b\xf8\xac\x9a\xf7\xec\x84\x70\x19\x8d\x75\xea\x12\x0b\x4d\x39\xa4\x98\x3a\x21\xc2\x44\x59\xd5\x09\x3c\x4b\x29\x41\xdd\x1a\xe4\x81\x8a\x34\xa7\x4a\x4d\x71\xb6\xe5\xee\x11\xde\x69\xd9\x73\x50\x1f\x80\xb5\xc1\xba\xcf\x27\x02\xb3\x85\xcb\x14\x50\x6c\xf5\x06\xbd\xba\xd4\x57\xa5\x4e\x2e\x06\x3e\x6a\x2a\xd7\x36\x82\x87\xd3\x7c\xf9\x32\x4a\xed\x0a\xc9\xed\xa5\xd7\x46\x0b\xa0\x45\xe1\xc1\x3b\x12\x97\x55\x35\xb6\x07\x38\x55\x85\x70\x80\xca\x53\xa6\x19\xe9\x45\x90\xa5\x76\xd4\xcf\x6f\x5c\x7d\x94\x93\xa0\x23\xed\x15\x44\xd3\x40\x27\xcc\x45\xd5\x13\x7c\x1a\x5c\x15\x4a\x35\x87\x51\x61\x47\xf6\x4b\x26\xe8\x11\x23\xcd\xc4\x67\x96\xc2\xd4\x19\x49\xb9\x52\x51\xf2\xd2\xd5\x62\x0e\x49\x8b\x41\x92\x38\x33\xe3\xa8\x59\x4c\xe0\x8a\xbd\x82\x57\xf4\x24\x78\x3d\x3b\xd9\x18\x57\x0e\x24\xb7\x20\xad\x54\xd0\x2d\x88\x08\x41\xc9\x4d\x8c\x6a\x58\x1d\xc5\x98\x8c\x9a\x69\x75\xd4\x5f\x88\x78\x76\x60\x32\xa2\xba\xfa\x4e\xb2\x80\x01\xde\x3a\x13\x15\xa5\x2a\x31\xac\x07\x49\xeb\x8a\x79\x22\x08\x98\x71\xa3\x34\x17\x2e\xdc\xfd\xce\x0e\x40\x47\x9e\xa8\xee\x02\x0e\x88\xf9\xb8\x12\xd7\x57\x91\x24\x9e\x52\x2e\xdc\x7d\xf0\x1f\x0f\x92\xec\xbd\xac\x44\xcf\xa3\xd4\xbe\xfd\xa9\x52\x7c\x40\x85\x52\x3f\x2a\xa5\x41\xe4\xa9\xc7\xed\xae\xe9\x6f\x8b\xe5\x10\xc0\x48\x95\x39\x71\x6d\x9a\xbb\xe2\xa3\x4b\xd1\xef\x59\x8a\xd8\x82\x01\x7b\x88\x7e\x01\x0d\xab\xf7\x55\xd9\xdf\x1b\x81\x80\x07\x29\x4b\x02\x85\x7b\xa3\x23\xab\x48\x97\xd7\xdb\xaf\x1d\x85\x86\x50\xdd\x6a\x5e\x4f\xeb\xcc\xd3\x4e\x5e\xde\xde\x1c\x41\x58\x03\xa2\xc8\xfb\x48\x02\xf7\x4c\x42\x46\x74\x18\x56\xf4\xe5\xdd\x84\x60\x90\x76\x1c\x4a\x41\x8a\x7f\x2f\x9a\xd7\x50\xcf\x37\xa5\x75\xcd\x82\x06\xd2\x62\xa4\x19\x05\xb5\x10\x85\x20\x3d\x7f\xfe\x33\xcf\xe3\x47\x30\x04\x7f\x31\x03\xff\xfe\xf0\x9a\x27\xe9\x80\x9f\xcc\xb8\xd6\xf2\x0b\x3f\x27\x4f\x63\xce\x8c\x26\x34\x19\xab\xbc\x4a\x8d\xc9\x32\xbc\x6e\xd3\x0f\xa3\xb5\xf8\x3a\xe1\xf7\x74\x4d\x0a\xea\x6a\xe8\x8a\xd6\x18\x71\x2f\xd1\x3c\xf2\x6a\x9e\xb2\x76\xa6\x25\xe9\xf9\xa4\xe1\xc7\xfb\x62\x52\x48\x10\xe0\x80\x46\xce\xb7\xde\x99\xe6\xa9\x78\x7b\x6f\xe4\x7e\xaf\x96\x68\x09\x6d\xc3\x64\xd2\x13\x4b\x22\xf5\x03\x89\x02\x98\x8c\x39\x04\xaf\x27\xfc\x3e\xd4\xcb\x5b\xd3\xde\xf1\x13\x6d\xf2\x70\x76\xaa\x64\xa6\xee\x3a\x93\x2c\x7c\xea\x5e\x85\xde\x57\xe2\x79\x28\x75\x31\x50\x7d\xf4\x5e\x42\x81\x69\xed\xa9\xe7\x4b\xc7\xf8\x92\x2e\xaa\xa8\x2e\x6a\x73\xec\x2f\x7b\x6d\xee\xb0\x1e\xe0\x6d\xff\x3e\x3f\x28\xf7\xfd\xbc\xd5\xd5\x73\xaa\x61\xe0\x52\x40\xd6\x58\x03\xe2\xd0\xd5\x27\xac\x40\x6d\xa5\x4f\xd0\x42\xbb\x4f\x8d\xd0\x3c\xdf\xa6\x31\x40\xf6\x72\x09\xc9\x88\x96\x7a\x64\x7f\xe3\x88\x86\x03\x4e\x15\xe1\xf5\xd3\xf2\x32\x1d\x8d\xeb\xe2\xa2\x57\x72\xbb\x72\xb1\x4e\x98\xa2\x84\xf1\xca\xda\x4b\x0d\x9b\xbe\x98\x96\xda\xc1\x8d\x98\x2c\xce\xf9\x7c\x7e\xcb\x54\x2c\xb8\x31\x7f\x22\xa4\x02\x8d\x19\x98\x52\x72\xde\x4a\x1c\xfe\xec\xc5\x04\x10\xd3\x36\xa2\xec\xa1\x7c\x28\xd9\xd3\x9b\xd4\xf8\xa5\xef\x3c\x9b\x19\xc2\xb3\xae\x5b\xf1\x05\xa0\x4f\xd8\x38\xb7\x6c\x36\xaa\x00\x74\x5a\x58\xb1\xac\xe8\xe5\xf2\x96\xa7\x1e\x4e\xd8\x3e\xc6\x6f\xf0\xb9\x48\x60\x75\xb4\xb3\xa7\xe3\x29\xb8\x56\xc3\x37\xfa\x2a\xd8\xa5\x36\x12\x60\x28\x83\xb9\x59\x8b\xf4\x8b\x7a\x8d\xa7\xee\x52\xd9\xe6\xb3\x9d\x20\xad\x3d\xcd\xb2\x79\xad\x35\xbd\x6e\xd4\x46\xa6\x8a\x08\x66\x1e\x21\x87\x0e\x05\x76\x16\xaf\x98\x56\x30\x0d\xaf\xab\xa8\x20\xd4\x6c\x97\x9c\x05\xf7\x62\xa1\x75\x77\xe2\xef\xcf\xcc\x98\xe5\x40\xb0\x5d\x41\x19\x09\x10\xa5\xcf\x30\x7e\x13\x26\xe0\xc6\xf3\x39\xe2\xcf\x3e\x78\x81\xb8\xea\x8d\xf2\xb2\xed\x9c\x68\x32\x73\x6a\x0b\x6f\x73\x09\xe4\xf8\x93\xe2\x37\xe9\x3e\x84\x49\x93\x35\x7b\xcd\x33\x81\xdc\x70\x9e\xba\xc3\x1b\x7b\xed\x9a\x75\xb8\xd2\xc4\xf5\x63\xda\x8b\x9e\x9f\x72\x96\x60\xd6\x2f\x8a\xe0\x63\xf8\xe9\x59\xa5\x97\x39\x56\x22\x66\x93\x1f\x61\xad\x5c\x6a\x9e\x8a\x71\xa2\x62\xc2\xb6\x3a\xde\x6f\x57\x9d\x96\xf2\x7d\xd3\x89\x9a\x3b\x43\x77\xfe\xe6\xc8\x49\x83\xbe\x22\x74\x6e\xa5\xbd\x40\x5e\x8b\x56\x91\xce\x77\x3f\xe2\x28\xc3\x4f\x19\x80\xd3\x74\xf5\xd9\xb9\x4c\xd9\xd6\x8c\x64\x91\xf8\x54\x71\xaa\xcd\x34\x80\xee\xc6\xa0\xc2\xe0\xd7\xdb\x3d\xe6\xc3\xb3\xfd\x79\x5e\x2e\x8d\x9d\xa4\xa5\x1c\xa8\xb8\xfb\x53\xef\x5d\x79\x3c\x93\xf4\x7f\x7d\xbf\xfc\x8b\xdd\x7a\xff\xf3\x36\xb7\xd6\x21\xcb\x7e\x7b\x8a\x5d\x8b\xc6\x95\xfa\x2c\xdc\xc9\x6c\x9e\xe2\x59\xd3\xc2\x7c\xcc\x0a\xa8\x93\xba\x50\xec\xbc\xd3\x1b\xcc\xa2\xb1\x1a\xd2\x4b\xec\x96\x31\xce\xf4\x68\xd4\x78\x7d\xd5\x99\x3c\x8f\xdc\xe4\x9e\x14\xd2\x4b\xc9\x42\x85\xd4\x78\x1d\x8b\x3c\xf4\x7b\x1c\x01\xa4\xee\x48\xcf\xa5\x60\x54\x62\xbc\xef\xef\x40\xd6\x76\x2d\x8c\xfa\xd1\xd2\x27\x6f\xd1\x89\xc0\xaa\x61\x4a\xdf\xa6\x7d\x7a\x9f\x93\x6d\x18\x7b\x1d\xbd\x3c\x24\xdb\xec\x5e\x08\x55\xbc\x09\xa4\x05\xc4\x37\xc5\xd9\x8e\xaf\x5f\x92\xa0\x1a\x07\xbf\x3e\xc5\xef\xd8\x04\xad\x9a\x4b\xc2\x9e\x0d\xdb\xf1\x2c\xbe\x9e\xde\xde\xb9\x53\xf0\xe9\x55\x11\xd9\x22\xd0\x22\x80\xda\xa9\xf6\x86\x7a\x76\xe4\xcf\x60\xf7\x8e\x18\x96\x74\x40\x39\x84\x00\xdd\x28\x4e\x1d\x75\x9e\x2c\xa5\x56\x70\x9b\xd9\xfb\xf0\x42\x4b\xea\xe5\xcc\x88\x8a\x57\x75\x6d\xc8\xd3\x3e\xd3\x4e\xe4\xa9\x7e\xb1\xa2\x7c\xb5\x22\xda\x23\xfb\xd3\x1d\xe3\x9f\xaf\x4a\xf4\x06\x88\xbc\x5e\xf0\x2b\xc7\x27\xa0\xee\xb5\x32\xcd\x68\xe4\x9e\xa6\xd3\x3c\x08\x2b\x5f\xd0\xb4\xb3\xcd\x19\xb0\xe9\x08\x11\xb9\xbf\x51\x22\x78\xd1\x4d\x54\x97\xfd\x71\x90\x83\x77\x0e\xaa\x74\x9a\xfb\xc0\xc5\x10\x59\x3a\x78\x64\xaa\x66\xa2\x35\x77\x53\x03\xa9\x7e\xcb\x8c\x58\x12\xa0\xa5\xab\x56\x14\x15\x90\x66\x88\x88\x07\xb0\xb4\xab\xf0\x08\x10\xd3\xee\x15\xcb\x4c\xf3\x2a\x9d\xa7\x8b\xab\x15\xed\x5b\x87\xa8\x56\x48\xd5\xd7\x8b\x4e\x42\x47\xf4\x4f\xaa\x84\x77\xc9\x0b\xa4\xa9\xc6\xbe\xd2\xd9\xab\x87\xdb\x7b\xe8\xfb\x8f\x56\x21\x4a\xf6\x86\xe0\x24\x92\xd2\x04\x68\x23\xb6\x4c\x00\x0c\xca\x68\xcd\x05\x84\x41\x71\x64\x28\xfb\x39\xde\xe9\x85\x54\x52\xb5\x73\x6b\x40\x2b\xae\x24\x7f\x4a\x1b\x86\x84\x22\xa2\xf6\x47\x76\x66\x6e\x25\x7f\x2d\x4e\xd1\x4b\xb5\x65\xa1\x2e\xaa\x24\x3b\xdb\x17\x7d\xe0\xef\x6c\x2d\xe7\xe0\x9d\x9e\x69\xee\x2c\xdf\x3d\x16\xc8\x48\xc4\x0e\x6e\xf6\xf9\x11\x04\x58\x49\x6b\xca\xf3\x22\xbc\x68\xaf\x2b\x79\xba\x79\xd3\xe3\x85\xea\xb1\x76\xb6\x31\x67\x52\xee\x0e\x98\x20\x0d\x24\xa8\x3d\x34\xa1\x3d\x71\xe1\xfc\x17\x08\x33\x32\xad\xd2\x57\xeb\x6d\x69\xca\x5b\x86\xd4\x4c\xd1\x1f\x64\xa5\x09\xe0\x20\x54\x7b\x16\xba\x0d\xa3\xcc\x8c\x9e\xc7\xa3\xb4\x58\x43\x2e\x4d\x5b\xc1\xc2\x5b\xa3\xe3\x22\xcc\xe2\x58\x6a\x72\x86\x1b\x88\x7e\xa1\xad\xde\xbf\x07\xc3\xb7\x4c\x65\x2c\x33\xd3\xc4\x2b\x2b\xf0\xe7\x1c\x74\xcb\x27\x7d\x7e\x0b\xe6\x84\x34\x7d\x86\x01\xa5\xda\x61\xe5\x40\x32\xca\xe8\x3d\x41\x15\x2d\xad\xa7\xaf\x40\x44\x02\xf7\x32\x36\xea\x78\xf9\x00\x22\xf8\xa6\xd7\xb0\x29\xed\x7d\x9b\xbc\x73\xc3\xab\x99\x93\xf4\xaa\xcc\x77\x11\x2b\x18\x39\x30\x8c\xcb\x7d\x10\xe0\xa7\x12\xed\xf3\x3b\x4d\x33\xb9\x71\x42\x74\x3e\x82\x72\xe0\x4f\x75\x15\x7f\xb1\xf4\x7c\x3e\x3f\xaf\x42\x06\xba\x3c\xa4\x5e\x2a\x6d\x08\x2d\x2c\xfb\xc0\x63\x68\xe8\xd1\x9f\x7f\xdc\x08\x24\x27\x26\xf3\xe1\xae\x8c\x59\x26\xbf\xb9\xf1\x33\x7c\x80\x39\x41\xf4\x80\x94\x33\xcf\x1b\x07\xe6\xd7\xe5\xaa\xa9\x3c\x34\x1a\xf0\xb5\x09\x9c\x0c\x8f\xaa\xab\x9d\x14\x98\xe3\x23\xcf\xb7\xbf\x94\x85\xf4\x20\xf7\x12\x37\xa1\x97\x3a\xeb\x22\x11\x2a\x63\x91\x4f\x13\x11\x6a\xc3\x5a\xc5\x13\x0e\xcc\x7d\xd7\x1c\xfc\xca\xc1\xd7\xf7\xa1\x7b\x05\x7d\x8b\xcc\xa5\x53\x8a\x27\x22\x34\xc6\x62\x4b\x49\x85\x50\x84\xf0\xb9\x94\x84\x4c\x73\x58\x86\x0b\x91\x73\x29\x71\x4e\xaf\xce\xd0\x43\xe5\xf8\x49\xe2\x7c\x58\x79\xf0\xa0\x66\xfb\xb0\x6a\x8d\xa9\xfa\xa0\x27\x35\x27\xc7\xf5\x4f\xcb\xc1\x49\xe3\x1a\x48\x7b\x34\xb3\x36\xd3\xa9\xc4\x7e\xfd\x3d\xd0\x54\x3f\x9d\x8b\xdb\xe3\x69\x99\xbc\xff\x83\x9e\xa8\x32\x2b\xdd\x3a\x37\xf1\xc9\x1c\x2f\x39\x39\xc4\x48\x8c\x28\x75\xb4\x28\x15\x35\xdf\x66\x72\xba\xd8\x05\xa6\x2c\xf4\xac\x2c\xd2\xac\x78\xe7\xe2\x96\x43\x4b\xe2\x62\xa0\xef\xa5\x5d\x58\xab\x8f\x5f\xe1\xe5\x6f\x9e\xf6\x88\xaa\x72\x8c\xc5\x72\x08\x73\x66\xbe\x89\x3e\xee\xbb\xe7\x21\xf6\x0c\x4a\xca\xa5\x9f\x3c\x10\xa1\xf1\xd7\x6b\x86\xb5\xda\x7f\xf1\xa4\xf7\x61\xaa\x53\x90\x2c\x8b\x58\x72\x52\x1e\xf4\x20\xe5\x0c\x1a\xba\x53\x1f\x2d\x4f\x34\xf4\x18\xcd\xb6\xc1\x3c\x38\x99\x60\xc4\x35\x83\x02\x63\x8b\x52\x7d\x78\xa5\x6c\xf2\xa4\x50\xdf\xa3\x07\xd5\x42\x47\x05\x86\x3a\x65\xfe\xb9\x66\x84\x98\xd6\xcd\xf5\x29\xa9\xca\xc0\xf8\x44\xe3\xca\x4c\xf5\xd1\xfc\x43\xfe\x8f\x10\x06\x87\x44\x14\x46\x65\xe1\x7b\x95\xa5\x96\xeb\xa9\x1c\x6f\x16\x65\xdd\x3c\x6d\x88\xbd\xf3\x63\xd5\xa5\x5b\xae\xe6\xd2\x29\xeb\x22\xee\xc9\x45\xd5\x35\x8b\x45\x6a\xbe\x8a\xd4\x10\x72\x60\x6e\x7c\xe8\x4f\x1d\x31\x1b\x62\x91\x5a\x02\x91\x1a\x25\x5e\xb3\xb5\x9c\x6e\xae\x70\xd9\xdf\x44\x0a\x89\xe6\xe2\x33\x9f\x87\xb4\x4b\x51\xf6\x11\x62\x66\x61\xa5\x95\x96\x63\x50\xd2\xaa\x2b\x2c\xf6\x0c\x5c\x03\x37\x1d\x03\xbb\x70\x3e\x66\x80\x9a\xa8\xda\x3c\xaa\xda\x82\xa0\xda\x25\x67\x3e\x4a\x4e\x03\xaf\x8c\x61\xfb\x88\x61\x17\xa0\x6a\xf3\xbf\xc2\x67\x0e\x3e\x72\xed\x6e\x2e\x06\xfe\x0a\x5f\xf1\x8f\xf8\xcc\x7f\x89\x4f\xcf\x69\x72\x95\x8f\xed\x80\xb8\x29\x5e\xe7\xc0\xbb\x95\x37\xfe\x36\x87\x30\x98\x7e\xf1\x10\x0f\x5c\x6c\x89\x45\xa1\xf7\xe1\xeb\xd9\xe4\xc0\x7c\x85\x57\xaa\xf2\x79\xe3\x9e\x82\xc9\x15\xa8\xf6\x28\x39\xc3\xf1\x27\xd5\x4e\x27\xd5\x71\xa6\x8b\xa3\x89\x17\x47\x45\x4c\x47\x60\xb4\x47\xcc\x5c\x6c\x63\x52\x2d\xe9\x07\xbe\x9b\x48\x3d\x62\x17\x2a\xc3\xda\xfc\x15\x3e\xf3\x1f\xf1\x15\xff\x12\xdf\xb0\xd2\xae\x20\xbf\xa3\x8b\xab\x8e\xb2\xd4\xa6\x8f\x4e\x61\x8a\x1f\xb8\x8f\xbd\x6d\xf6\x67\xa3\xa9\xce\x51\x68\x24\x0a\x8f\x00\xbe\x82\x92\x78\xed\x57\x3b\x8f\x72\x09\xd0\x1b\x9b\x5c\x0c\x92\xa6\xe9\x73\x6c\x39\x26\x73\x3d\x3d\x82\x58\xd0\x42\x7b\xd2\x4c\x5e\xc7\xe0\x8e\xb0\xc0\xb0\xe8\x42\x59\xa0\x07\xdb\xb9\x06\x23\x0e\xfa\xaf\x82\x9f\x1c\x9b\xc3\x1b\x8e\x40\x5f\x2c\x30\x73\xc0\xf8\x04\xd2\x8c\x24\x31\x8f\xe7\x25\xd0\xa4\x67\xdf\x70\x72\xf5\x29\x31\xa2\x5a\xf8\x26\xde\xc0\x48\x10\xe6\x7b\x02\x49\xe0\x3e\x02\xd1\x01\x52\xcc\x8b\xda\xd5\x37\xdd\xd6\xef\xf7\x41\xd7\x4e\xaa\x38\x2b\x1c\x43\xb4\xe1\x19\x8e\x72\xc7\x2a\x73\xc4\x41\xb0\xb6\x2a\x64\xaa\x23\x26\x6a\x20\x6a\x38\xe6\x80\x94\x94\x9d\xc2\x19\xdd\x57\xa2\x23\x83\xbc\xc0\x88\x36\x9d\xc5\x25\x1d\x2f\x13\x68\xb2\x78\x65\xa5\x52\xb3\x77\xe5\x7e\xd0\x31\x5c\x4d\x9c\x65\x86\xeb\x33\x5f\x90\xba\xdb\x8a\xe7\xeb\xd5\xee\x33\x37\x7c\xa6\xd5\x69\x44\x09\x81\x21\x62\x8a\x74\x53\xb4\xba\xba\x32\x06\x37\x50\x3b\x5d\x52\xe4\x1a\x20\x7a\x25\x3c\xf7\x06\xac\xc7\xce\xab\x0f\x04\x47\xa5\x80\x61\xdc\x5f\xf0\x48\x47\xc2\x69\xac\x50\xdc\x1b\x33\x88\x56\x4c\x04\x18\x14\x28\xd9\x67\xe2\x23\x8a\xa8\xa2\xb1\x22\xa7\xb5\xad\x17\x12\x35\x57\xce\x68\xbd\x33\x32\x2e\x0d\x76\xe2\x5b\x24\x2a\xd3\x9b\xa6\xda\xd7\x78\x82\x6c\x90\x7f\x12\x51\x8d\x03\x80\x61\x1a\xa3\x9a\x2d\x34\xde\xdf\x4e\x0a\x87\x45\x92\xc0\x0b\x96\x2c\x39\x7b\x91\x54\xe4\x7d\x17\x82\x72\x2b\xde\xe4\xc8\x3e\x37\xfc\xac\x83\x24\x1d\x3e\x23\x65\xc6\xdb\x50\x97\x63\xe3\x9d\xa7\x31\x2d\x06\xdc\xe8\x4e\x2d\x77\x82\x7a\x31\x2c\x73\xd6\x97\xd2\x48\x25\x5d\x41\x4f\x49\xf5\x85\xe9\x8f\x25\x9e\x7b\xf4\xe1\x87\x2c\x8f\xa2\x7c\xf2\xf4\xd4\x53\x3f\x7a\xc9\x9e\x26\x27\x44\x96\xfd\xc9\x6f\x1f\x43\xe8\x2c\x55\xa9\x8b\x4f\xa6\xf2\xe3\x54\x82\x1a\xff\x61\xa9\xa1\x82\xd2\x0d\xe4\x7b\x6a\x11\xa9\x30\x17\xc3\x53\x1d\xd2\x41\xa5\x1b\xf4\x2b\x85\xc4\x8b\xa9\xdc\xe2\x39\xaa\x7c\x3b\x3e\xbf\x04\xb9\x80\x39\xdd\x44\xee\xd5\x28\xa1\x0b\xc3\xbd\x53\xca\xa4\xb9\xd7\xa4\xd3\xa1\xce\xe4\x77\xd8\xb5\x2d\x06\x23\x51\x00\x01\x6c\x31\x49\xf9\x4b\xde\xed\x39\x33\x1a\x0c\xf4\x72\x3b\xe7\x90\x92\x8e\x92\x21\x5f\xd9\x14\xce\xf1\x3a\x84\x24\xe2\x84\x30\x6f\xc4\x70\x5f\x36\xf5\x64\x68\x9d\xea\x39\x1f\x9b\x1e\xb1\xa5\x22\xe6\x6b\x4a\x1a\xa7\xb8\x5f\x6b\xfe\xe2\x92\x4e\xa1\xcc\x05\x6f\xda\x9a\xf7\x28\x54\x22\x43\xa4\x11\xd7\xb4\xe1\x34\xe2\xe7\x47\x9f\xd1\xd9\xf5\x1d\x06\xe0\xde\x48\x68\xa5\x59\x22\x89\xaa\x0d\x13\xbc\x0e\xda\x74\x8e\x80\x5b\x35\xb1\x9a\x38\x48\x8c\x11\x3d\x39\x11\xef\x63\x1a\x86\x8b\xd9\x85\xa9\x13\x4b\xc0\x63\x4f\xce\x22\x46\x50\xb7\x26\xb7\xfc\xde\x04\xca\x19\xde\xcf\x14\x4b\xa3\x5a\x94\xb8\x4a\xd5\x10\x10\x61\x43\x39\xe6\x28\xaf\xb3\xd6\x05\x4f\x85\x64\x39\x9a\x6d\x8b\x49\x17\x6e\xe6\xa4\x8c\x7f\xf2\xb7\x6a\x8a\x64\xfe\x6b\xc5\x13\xe5\xed\x67\xba\x01\x7d\xbf\xcb\x55\x25\x7a\x00\xa6\xbb\xb3\xe3\x3a\xf8\x2b\xcf\x2d\xdf\x6f\x30\xbe\xaa\x74\x8e\xe5\x28\xfa\x84\xe2\xed\x44\x46\x7c\xfd\x08\x80\x3d\xcb\x50\x24\xb5\xec\xfd\xbd\x2a\xeb\xa9\x9a\x73\xad\x6f\xd0\x6c\x14\x06\x2e\xc3\x34\xa9\xcf\x51\x70\x07\xdf\xfa\x98\xb8\x95\xc6\xad\x0d\x17\xf9\x86\x84\x25\xb2\x3c\x90\x1a\x91\xc6\x54\xea\x1e\x7e\xc2\x5d\x10\xb5\x74\xab\x04\x0c\x1f\x4e\x97\x91\x09\x09\xdc\x2f\x70\x77\x5a\x26\xc4\x7b\x39\x7c\x81\x81\xfd\xbd\xdb\x6b\x71\x9d\xc5\x55\x84\x58\xe5\x5d\xd3\x8b\xeb\xcd\x26\xd9\x19\x07\x41\xae\x91\x24\x6b\xb8\xde\x65\xbf\x2b\x87\xbb\x07\x3d\x71\xdc\xab\x1a\xc9\x6f\xd5\x5b\xfc\x38\x1b\xee\xc0\x0b\x61\xd8\xb2\x80\x85\xa5\xb0\x91\x59\x85\xec\xc8\xc4\x7b\xc2\x2f\xcb\xb0\xbc\x94\x67\xdb\x0c\x74\x16\xd0\x13\x8d\x70\x0e\x63\xd4\xb0\xed\x08\x6d\x49\xc8\xa3\x7d\xaf\xd0\x1b\xc5\x35\x17\x4c\x71\x89\x5e\xf7\x72\xca\x9d\x9e\xf7\x9a\xb8\xc9\x02\x48\x0d\xb3\x3e\x79\x70\xee\x46\x9a\x59\xc8\xe2\x6d\x01\x2b\xc3\x95\x1b\xad\x25\xe9\x2b\x83\x4f\xd0\x6c\xfa\xf0\xd3\xaf\x23\x58\x51\x9a\x7b\xef\xd9\x93\x9a\xd2\x65\x55\x7a\xd2\xbd\x4e\xd9\x49\x9b\xf8\x45\xdd\x73\xfa\x80\x6b\x46\x00\x33\x73\xaa\xa4\xb7\xd9\xc3\xcf\x36\x89\xd4\xe9\xc9\xd6\x30\x91\x56\x40\xd7\x6a\x1c\xa3\xb0\x8c\xda\x2b\x66\x26\x03\x0a\x50\x4c\x52\x9b\x0e\xca\x58\x85\xc1\xd6\x96\x87\xa4\xdb\xcf\x73\x26\xdd\xe8\x27\xcf\x06\x95\x02\x3e\x1c\x2b\x41\x1a\x81\xcd\x26\xc4\x6e\x9e\x2a\x6a\x27\xbc\xa1\xc3\x69\x84\x33\xa9\x28\x8d\x21\x2a\x8b\x9a\x67\x66\x6c\xa1\x8a\x53\x9a\xc2\xc5\x39\x99\x43\x33\xbf\xa9\x28\xc6\x91\x2e\x0e\xbd\x78\xba\xa8\xad\xea\x79\xb2\x3a\x26\x9b\xc7\x1e\xac\x85\x6b\xff\xb4\x58\x9b\x8e\x54\x94\x67\xc7\x57\xf0\x1c\xf6\x9a\x81\x2b\x16\x75\x16\x69\xa5\x51\x25\xa9\xd1\x7d\xee\x71\xcb\x79\x05\x9a\x4e\x5d\x38\x5f\x10\x8a\x36\x1c\x2e\xa0\x09\x13\xa2\x4f\x30\xc2\x59\x89\x45\xa3\xd9\x80\x99\x22\x70\xa5\xb3\xa9\xa9\x74\x5f\x27\xdb\x91\xa2\x51\x3b\x60\xa9\xfc\x54\x3c\x1c\xb7\x7a\x77\xe2\x10\xce\x2c\x44\x32\x4a\x82\x88\x3a\x58\x21\xae\x8b\x4a\x58\xc6\x33\x7c\xad\x4b\x56\xe7\x2d\x73\x2f\x48\x53\x88\xf2\x85\xca\x9f\x09\xca\x08\x80\xe9\x14\xca\x13\x1b\xab\xc4\x94\xb0\xe3\xe2\xdc\x2e\x8f\x94\x1f\xeb\x7e\xe9\x88\x97\xb2\xe0\x36\x12\xcd\x56\x65\xe8\x28\xd2\x2f\x8f\x44\xca\xed\xb3\x8a\xe7\x0d\xee\x42\x14\x03\x68\x0a\x2b\xab\x57\x91\x5d\x0a\xb6\x51\x4c\x00\x2c\xdf\xf7\x8b\x04\xdf\xb5\x19\xc8\x7a\x99\x85\x04\xbb\x95\x81\x77\x28\x6a\x89\x6a\xb2\x64\x7c\x7a\x9e\x98\xf9\xde\xef\x07\x9a\x56\x69\x05\x00\x1f\x03\x7d\xbd\x19\xe5\x9f\xfb\x31\x42\x99\xfc\xd5\x9e\x27\xfa\x77\x62\xf1\x77\x62\xf1\x7f\x43\x62\xf1\xb8\xf1\xeb\x9f\x66\x9f\x7f\x26\x02\x8e\x34\x5e\xf8\x2b\x6f\x3e\x0c\x4c\xb5\x6f\xbc\x5a\x5c\x19\x93\x77\xfe\xbd\xc4\xe2\x07\x3e\xed\x5f\xe2\xfb\x6f\x26\x16\xa2\x56\x98\xa2\x56\x18\x90\xca\xff\x4c\x04\x8c\x07\x8d\x9a\x8e\x29\x6a\x5c\x31\x69\x85\x31\x9b\x8e\xc0\x9b\xff\x5e\x62\xf1\x13\x9f\xf3\x2f\xf1\xfd\x9f\x49\x2c\x4a\x68\xa4\x08\x69\x4d\x2c\xb2\xef\x89\x45\x76\xd6\x94\x70\x3a\x9b\x82\x7a\x07\x46\x9d\x96\x54\x69\x52\x0b\x47\x22\x3a\x0b\xbc\xfa\xaf\x52\xe4\x14\x31\x7b\xc4\x72\xf1\x9a\x6f\x30\x1a\x9d\x05\x8d\x82\xb1\x38\xd9\x7b\xd1\x45\x3b\x05\x27\xf3\x81\x16\x84\xad\x71\xb8\x25\x36\xd0\xd5\x1d\xab\x27\x5c\x58\x4a\x56\xbe\x54\x2e\x34\x48\x22\x5d\x74\x3f\xf2\x89\x02\x15\xd3\xe6\x8c\x87\x55\x3c\x62\x14\xb9\x0c\xf5\xa0\x02\x14\xf6\x74\xae\xfe\xb5\x0a\xf6\xed\x10\x35\xc3\x44\xce\x6a\x2d\xdc\x4e\xb4\x7a\xd6\xcf\xcc\xf9\xce\x2d\x2f\x6c\x78\x7a\xf8\x1e\x18\x38\xec\xd5\x00\x0b\xc1\x5d\x54\x26\x6e\x80\x18\xc6\x3b\xfc\x21\xa8\x67\x24\xf7\x31\xe8\xc1\x2c\xa8\xba\x57\x74\x7c\x9c\xf8\x11\x05\xc5\x19\x46\x5e\xfe\xc2\x20\xa7\x0b\x71\x7f\x56\xcf\x1b\x7b\xa9\xee\xfc\x3d\x20\xbc\x10\xd5\xa6\xcb\x9b\x45\xcb\x21\xd4\xed\x26\x81\x67\x99\x47\x64\x48\x8f\xf5\x51\xbb\x74\xa7\x78\x22\x28\xde\xba\xbf\xd0\x97\x5c\xe4\x0f\x06\x03\xbc\x34\x19\xa4\xf9\x34\xf1\x2c\x8c\x3a\x56\x95\x8c\xdc\x8b\x83\x69\x66\xea\xc3\x40\x31\x8b\xbb\x8b\x2f\xea\xeb\xe1\x8a\x65\x46\x00\xcc\x3c\xd3\xdd\xe4\xd7\x17\xbd\x56\x40\x03\xde\xa7\xa2\x58\xc9\x66\x30\x92\x8b\xc3\x9c\x03\x3b\xb7\x30\xe3\x72\x81\x84\x73\xdd\x4b\xb4\x4a\x66\x51\x1e\x48\xee\x29\xcd\x49\x2d\xb2\xb4\x6e\x5f\x36\x57\xce\x27\xcf\x8c\x97\xc1\xcd\xe3\x4c\x9b\xd0\x29\xb4\x2d\x4d\x50\x9d\xe7\x95\xe4\xa6\xe8\x91\x82\xb5\xe5\x33\xef\x8e\x99\x62\x25\x7c\x49\x50\x9e\x25\xac\x93\x51\x9e\xa7\x89\xfd\x9b\x1e\xd9\x98\x2f\x42\xca\x98\x19\x4b\x08\x2a\xca\xe6\xee\x8d\x7e\x83\x14\x27\x85\x98\x13\x4c\x4a\xf9\xc8\xd3\xa6\x7d\xa5\x8d\xcb\x12\x09\xb2\x19\x9c\x6e\x4f\xa5\x09\xa8\x60\xf0\x71\x05\x12\xef\x2d\x18\x21\x70\x87\xea\x0e\xee\xc2\xa5\xdb\x5e\x49\x85\x6e\xde\x23\xc8\xb6\x50\xed\xdd\x3b\xdf\xe5\x91\xd7\x4d\x7c\x8d\xee\x69\xf1\x9f\xf0\xb2\x94\x69\xd2\xf5\x4d\x79\x15\x86\x2e\xe7\x94\xd0\x34\x65\xc1\xa6\x5d\x76\x9a\x60\x11\x90\x4b\xb5\xf3\x84\xcc\xd5\x5f\x97\xa5\x75\x4f\xe7\x91\x99\x88\xf7\x24\x0f\xb0\x49\x54\xa3\xb0\x20\xe5\x48\x01\x18\xa7\xb0\x80\x8a\x3a\x2d\x6c\x8e\x57\x30\x45\x1c\x8c\xf4\xce\xb5\x40\xc4\xc3\xbb\x65\x2e\x8d\x07\xd2\x61\x98\x3c\x00\x4e\x90\x4d\x55\x96\x10\xf0\x6e\x5f\x45\x16\x81\x5d\x1a\xae\xb0\x13\x15\x19\xc6\x90\xf9\x39\x38\xf0\x00\xe1\xc6\x69\xb4\xd4\x38\x6d\xd2\x94\xa1\x33\x6f\xa6\x5d\xa2\x27\xe0\x0d\xcf\xf9\x35\x25\xe1\x62\x80\x76\xd9\xbe\xf0\xb2\x9c\x94\x2c\xa1\x42\x0e\x8d\x04\xf5\x4d\x79\xf1\x43\x39\x3d\x95\x61\x6f\x29\x22\xe3\x9f\x68\x3f\xbf\xf6\x50\xa1\x5d\x9e\x74\x60\xda\x6e\xc8\x26\x8f\x34\x1f\xc1\x45\xcc\x04\xd1\x92\xa1\x60\xdc\x2f\x5e\x38\xdc\x65\x80\x61\x52\x5a\x1f\x69\x8e\x6e\x31\xf1\x29\xfe\xb9\xb7\xc0\x97\x4d\xfa\x47\x37\x27\xfc\x8f\x5f\x45\x15\xed\x90\xee\xa7\xaa\xfc\x5f\xff\x81\xb0\xed\x90\xee\xa6\xaa\xac\xdb\x5f\xbe\x65\x5d\xf7\xfc\x7f\x01\x60\x1c\xc7\xe3\x88\x1c\x9b\x77\x0a\xc0\x20\x08\xae\xc0\xdf\x76\x43\x9e\x8c\x4c\x33\xfd\xf2\x0d\xdc\x81\x3b\x0c\x43\x76\x30\x82\x1d\x91\x6f\xff\x81\xf0\xff\x81\xb0\x71\x72\x6f\x3f\x57\xc0\xcf\xcb\x67\xd0\x65\xbb\x7b\x5e\x96\xbf\x7c\xfb\x0f\x18\xb9\x6f\xff\xbe\xed\xe2\x5f\xbe\xa9\x30\x42\xed\x70\x24\x83\x88\x23\x39\x40\x20\x76\x82\x11\xea\x8a\x23\x4b\x85\x60\x47\x7c\x07\x66\x08\x7e\x44\x22\xe2\x48\xed\xc0\x1d\x84\x1e\xb1\x23\xb5\x83\xa8\x23\xbe\x83\x8f\x78\x4b\x1d\xe1\x1d\x7a\x84\x76\x10\x7c\x84\x76\xc4\x11\x0a\x60\xf4\x88\x62\xbb\x4f\xbb\x52\x06\xed\xf0\x23\xbc\x83\xc0\x15\x0e\x3c\x12\xd8\x57\xfb\x19\x82\x8e\xe4\x67\x26\x8a\x1d\x71\xea\xab\xdd\x86\x0e\x5f\x43\xd4\x0e\xc6\x8f\x18\xf9\xd5\x7e\x86\xbe\x10\x92\x3b\x04\x3c\x62\xd4\x57\xfb\x35\xeb\x43\x06\x12\x1d\xb0\xe3\x86\xfe\x00\x41\x47\x6c\x07\x1f\x89\x03\x44\x1d\x91\xf5\x22\x5b\xaf\xa0\x2b\x84\x93\xd9\x01\x22\x8e\xd8\x67\xa3\x2b\x4e\x0c\x0a\x10\xf2\x88\x10\xbb\x4f\x0b\x7e\x70\x42\xc7\x95\x18\x64\x07\xe1\xdf\x9b\xcf\x00\x7e\x24\x0f\xc8\x91\xd8\x41\xc8\x11\x41\xbf\xda\xcf\x08\x72\xc4\x0e\xd8\x91\xdc\xc1\xd4\xba\xd3\x4f\xfb\x85\xec\x40\xac\x7c\xc3\x8e\x38\xf9\xd5\x6e\xfd\x87\xb5\x9f\xd8\x41\xf0\xfa\xfa\xf4\x20\x47\xfc\x80\x1d\xb1\x1d\x44\x1c\xa1\xef\xed\x67\x04\x3f\x52\x07\xe4\x88\xee\x50\x68\xe5\xc8\xa7\xfd\xc2\x02\x1e\xa9\x03\x74\x84\xb3\x03\x44\x1e\xb1\x2b\x04\xa1\xd9\x7a\xb1\x54\x10\x44\x1d\xa9\x03\x06\x0d\x10\x76\x44\xb2\x03\x4a\x1d\xe1\x2b\x04\x92\x19\x8a\x1f\x91\xb5\x0f\xcd\x0e\xeb\xe5\x0f\x9e\x90\x57\x1c\xc9\x70\x62\xa9\xe0\x95\x2d\x04\x7c\xa4\xa2\x23\xb9\xc3\x8f\xd4\x0e\x59\x79\x00\x1d\xa9\x1d\x71\x44\x77\x10\xd6\x42\xe0\x4a\xc9\x4a\x3b\x79\xc4\xd7\x8b\x00\x81\x8f\x38\xb4\xfb\xb4\x5f\x9b\x06\xbf\x38\x08\x83\x47\x0c\xfe\x6a\xbf\xf3\x10\x3f\x20\xeb\x2e\x7f\xee\xfc\x8b\x7b\xf0\xaa\x62\x20\xf9\xd5\x82\x3f\x24\x8f\xae\x22\x80\xbe\xb7\x9f\x7d\x1f\x89\x03\xba\xea\x24\x7c\x24\x89\xaf\xf6\x33\x00\x1f\xf1\x03\xba\xa2\xc7\x57\x0d\xf9\xb4\x9f\x11\xec\x08\xad\x2c\xde\x21\xd8\xfa\xfa\xf4\x91\x47\xf8\x00\x1f\xd1\xf2\x00\x21\x47\xf4\x00\x1f\xb1\x80\xa4\x8e\x04\xbe\xfb\xb4\x5f\xfa\x85\x6e\x13\x89\x1d\x82\x1c\x31\xe8\xab\xfd\x1a\x02\x8f\xe8\x47\xec\xf0\x11\xfe\xde\x7e\x27\x1b\x39\x90\xab\xbe\xae\x96\xb2\x35\x9f\x7e\xf8\xb8\x69\x2c\xb1\x83\xf1\xf5\xf5\x65\x13\xd0\x11\x39\xc0\xf0\x11\xdd\xad\x66\x87\x7d\xb5\x5f\x63\xf0\xa6\x16\xf8\x0e\xc7\x8e\x24\xf5\xd5\x7e\x0d\x61\xab\xb2\x1f\xc9\x88\x38\xae\x9c\x5c\xf5\x71\xb5\x20\xf2\x08\xef\xd6\xad\x20\xe8\x11\xc5\x77\x9f\xf6\xc7\x3a\xd4\x0e\x5f\x8d\x83\x3c\xc2\xd0\x57\xfb\xdd\x62\xa9\xdd\x6a\x2d\xe8\x66\x9a\xf0\x77\x7a\x77\xc8\x2a\x16\xa8\x3c\x40\xf8\xba\xcd\x23\x1e\x1d\xa0\x6d\xcf\xab\x42\x12\x2b\x03\xe0\x03\xb1\x6e\x09\x39\x42\xed\x81\xdc\xc4\x82\xac\xc0\xd0\x7a\x11\xa0\xc8\x91\xda\x6d\xcd\x0f\x75\xc5\x76\xd0\x6a\xa6\xd4\x11\x25\xbe\xda\xef\x3a\x4e\xee\x90\xe3\x46\x23\x8e\x7c\xb5\xdf\xed\x82\xd8\xa1\x47\x7c\xf5\x43\xab\x76\xa0\x3f\xb4\xe3\xb0\x62\xc2\x8e\x68\x04\x7e\xc6\x8f\xf0\x6e\xc5\x41\xac\xea\x87\xb4\xeb\x8e\x36\x23\x85\x77\xd8\x11\x29\x57\x2f\xb6\x83\x8f\x64\xb4\x5a\xf7\x0e\xfe\xd0\xb0\x0e\xe1\x9b\xe7\x5a\xe7\x60\x2d\xf1\xdd\x39\xad\x17\x30\x74\x44\x03\x04\xda\xbc\x03\xf4\xdd\x3b\xac\x12\x44\x57\x18\x64\xb5\x66\x98\xf8\x6a\xbf\x5b\x3a\xba\xa3\xd6\x7d\x6c\x9e\x0b\xf9\x95\xff\x82\xd6\x59\xf8\x11\xdf\x61\xdb\xeb\xab\x93\xd8\xdc\x13\x1a\x6d\xea\xb7\x2a\xef\xaa\x83\xe4\x01\x81\x8e\xf8\x81\x3c\x62\xed\xea\xc9\xa8\x55\x01\xd1\xc3\xa6\x06\xab\x6d\x66\x10\xb9\x7c\x03\x7e\xcf\xbb\xa3\x38\x95\x04\xf0\xc7\xbb\x23\xe0\xe6\xb9\xd0\x92\x44\x77\x28\x79\xc4\x76\x24\x7a\x58\xff\xbf\xe2\x44\x79\xf8\xba\x3e\x7c\x8d\x0d\x14\xf1\x07\x18\xf1\x20\x0a\x62\xe8\x83\x11\x02\xb1\xd5\x06\xc0\x23\x54\x1e\x56\x6b\xc7\x8e\x70\x00\x91\x47\x88\xda\x7d\xda\x8f\xba\xac\xb6\x8c\x94\x38\xb8\xfa\x8d\x0d\x02\x3d\x62\xd8\xee\xd3\x7e\xe9\xe0\xba\x69\x70\x03\x39\xfc\x11\x92\x03\x72\x44\x14\x08\x46\xb6\xe5\x7e\x8b\xe3\xc3\x38\x70\xa9\x3e\x1b\x80\xbf\x13\x84\xaf\xa0\x04\xb2\xfb\xb4\x1f\xd0\xd5\x47\x41\x58\xb9\x8a\x14\x0c\x20\xec\x88\x11\xbb\x4f\xfb\x59\x0a\x5e\x05\x7e\xc4\x7f\x4d\xce\x3f\xa3\xd8\x91\x47\xfc\x00\x61\x57\x82\x3a\x52\x01\x0c\xee\x60\xf0\x87\x22\xac\xd6\x87\x2f\xd5\x01\xc2\xc0\x23\x79\x44\x7f\x8b\xff\xf0\x85\x7f\x20\xc0\x75\x18\x3d\x22\x9b\x02\x23\xe4\x4f\xd4\x2b\x75\xbf\xe2\xd7\xef\x51\xb8\xae\x32\x1c\x7e\x1f\xc5\xe1\x43\x9d\x82\x90\xab\x87\x26\x8f\x7f\x24\xca\x5f\x2b\x07\xb4\xce\xdf\xc1\x54\x49\xac\x27\x26\x8a\x1c\xd1\x81\xc4\x8f\x44\x79\xf8\xf1\x7e\xbb\x3a\xac\x57\x57\x02\x5e\x65\xf1\x35\xa3\xda\x4c\x18\x29\x7f\xa5\x3a\xff\xac\x61\xc3\x81\xfa\xa9\x62\xff\x26\x31\xd4\x0e\x42\xd6\x23\xec\x08\xd3\x10\x76\xc4\x57\x9e\xac\xed\x87\x01\x14\xb9\x83\xd6\x33\x78\x58\xc7\x83\xdf\x8e\x43\xd8\xea\x88\xb0\x23\x91\xfd\xf1\xf8\xd6\x0c\xbf\x3b\x7e\xf8\x31\xbe\x54\xe0\x0e\x47\x8f\x58\xf6\x63\x21\x6c\xf7\x69\xbf\xbc\xcd\xea\x5a\xc8\x72\x63\xc5\xea\x63\xd7\x8b\xf5\x04\xf9\x03\xd0\x03\xb9\x54\xe4\x7a\xb2\xad\x8c\xc8\x0e\xab\x76\xfe\xd3\xda\xe0\xe1\x37\xb4\x41\xc8\xee\xd3\x7e\x94\x0c\xde\x11\x47\xbc\xfc\x5a\x08\xb9\x42\x28\xb9\x6a\xdb\xf6\x96\x5a\xc1\xd7\x03\xf9\xf8\xfd\x4c\xdc\x80\x7f\x77\x93\xe0\x4f\x26\x64\x47\xfc\x8a\x13\x47\x58\x81\xc8\xf5\x50\xc2\xa8\xa5\x3a\xe0\xd4\x91\x3c\xa0\xe0\x2a\x67\x10\x5c\xc3\xae\x0d\x37\xb1\x91\x42\x7c\x27\xe5\xb3\xfb\x23\x94\xfd\x2e\x73\x76\x9f\x1d\x97\x87\xef\xb4\x2e\x2a\xba\xfa\x64\x8c\x3c\x52\x9f\xce\x1d\xb9\x06\x1e\xf8\x11\xc9\x7e\x8f\x13\x3f\xa5\xf8\x25\x66\x7c\x3b\x05\xf0\x9f\xa7\xc0\x7a\xce\x10\xcb\xea\xd8\xa8\x1d\x84\x92\x2b\x43\x57\x74\xf0\x77\x79\x20\xff\xcc\x8f\xdd\x3a\x03\x1f\x7e\x57\xab\xc0\xdd\x77\x3c\x7f\xa0\xa1\x20\x89\x84\x18\xfa\x6d\xeb\x38\x34\xcf\x20\xca\xbb\xf9\x97\x6f\xe0\x11\xc2\xfe\xc1\x84\xd6\xd3\x65\x55\xf8\xd5\x29\x7e\xd7\xff\xf5\xdd\x7f\x11\x2b\xf8\x1d\x2b\x45\x6e\xd1\x0e\x72\x24\xbf\x9b\xd1\xee\xb7\x38\xd7\x5c\x60\xbd\x02\xe9\xff\xf1\xdf\xc9\x52\xaa\x3c\xfe\x87\x24\xe5\xbf\x3a\xbd\xf8\xa3\xe7\x84\xfc\x4e\x8e\xf3\xff\x45\x59\xf0\x6e\x93\xee\x97\xbe\xbb\x93\xdf\x13\x9e\x3c\xfe\xe5\x9b\x12\xcc\xc9\xfb\x3f\xe1\x6f\xff\xe5\xec\x87\x58\xf3\x01\xf0\x2b\xf5\x69\xbb\xb9\x4c\xbe\xb8\x53\xe6\x75\x12\xbc\xc5\x77\x10\xe7\x49\xdd\x6d\x8b\x58\x57\x51\xe2\xfe\x13\xfa\xcf\x6f\xbb\xf4\xab\xdb\xa9\xf3\xae\xfd\xe5\x5b\xdf\x26\x6f\xeb\x19\x44\xc9\xa5\x76\xda\xe4\xdb\x6e\x82\x7e\xf9\xb6\xa6\x05\xdf\x76\x33\xf4\xcb\x37\x08\x84\xbe\xed\x26\xf8\x47\xd7\x7a\x75\x04\x57\x59\x7d\x47\x63\xbf\x83\xba\xbd\x37\xef\xea\x97\x6f\x55\xd0\xbd\xf3\xe9\xff\xf9\x84\x4d\x07\x68\x8b\x81\xe1\xff\xf9\x83\xbe\xe6\xb9\x6b\xee\xf7\x95\x03\xdf\xc0\x6f\xbb\xf5\xfd\x21\x6a\xca\xe6\xbd\xa9\x45\x02\x47\x71\x82\x7e\x17\xef\x3f\x00\x1f\x21\xe2\xb7\xe0\x60\x14\x24\xf0\xef\x83\x23\x10\xf2\x1b\xf8\x38\x8c\xc0\x38\xfe\x7d\x78\x14\xfd\x2d\xfe\x18\x0e\xa1\xf8\x0f\xc8\xc1\x08\xec\x37\xf0\x11\x41\xc5\x11\xf1\xfb\xf0\x38\x45\xfe\x06\x3e\x0c\x48\x34\xa4\x7e\x1f\x9e\x84\xa8\xdf\xc0\x07\x21\x4e\x06\x7f\x00\x4f\x21\xe8\x6f\xe0\xa9\x08\xc5\x28\xf2\x77\xe1\xa1\xdf\x02\x23\x70\x40\x26\x3f\x4c\xeb\x1f\xb5\xe7\x57\x36\xbc\x9a\x27\xba\xe5\x28\xe5\x1a\xf4\xe1\x47\xe2\x4a\x51\xa7\x35\xa9\xca\x50\x6c\xf9\xf6\x65\xe3\xab\xfa\xff\x07\x8c\x7c\x57\xb8\xff\xf9\x0f\x6e\xe0\xdf\x41\xf1\x2b\xaf\xb0\x92\xfa\x6e\x8a\x64\x23\x93\x24\x61\x84\x44\xbe\x77\x1d\xc6\x3c\xee\xb2\x5f\xbe\xc1\xbf\xc1\x4f\x1c\xb1\x1d\x05\x1d\xa1\x2b\xb1\x26\x85\xf8\x11\x2a\xd7\x94\x07\x5a\x13\xae\x35\xbd\x5c\x2f\xd6\xde\x2b\x05\x65\x07\xe4\x48\x5e\x09\x6c\xcd\x7e\x36\xb7\x89\xaf\x3d\x54\x79\x40\x57\x37\x8c\x5f\x29\xe8\x44\xac\x89\x24\xbc\xce\x05\x3f\xf8\xd0\x2b\x09\x96\x6b\xce\x44\x1e\xc9\x0c\x3b\xa2\x0a\xba\xc6\xd2\x04\x55\x7e\xa2\xe6\x6c\x4d\xe2\xca\x35\x87\x3d\x50\x47\x64\xcb\x58\x91\x23\x32\xe0\xd9\x01\x5d\xaa\x35\x4e\xde\x81\x0a\x4a\xed\x08\xe8\x88\x64\xe8\x11\x55\xb0\x2d\x6c\xc0\x4b\xf4\x13\xe4\x12\x19\xba\x86\x16\xc4\x27\x11\x24\xb3\x35\x83\xf8\xc1\xd9\x4f\xf5\xe2\xdb\xbf\x32\x72\xf8\xdf\x33\xf2\x35\x47\xfa\x18\x39\x06\x1e\x41\x18\xf9\xd8\xf9\x57\x2f\xfc\xb3\xf7\xbf\x65\xe8\x1f\x5f\xf1\xcf\xfa\x86\x23\x28\x05\xfd\x9b\xca\x49\x80\x10\x82\x87\xff\x5b\xe5\xfc\x43\x4e\x20\xff\x26\x27\xa0\x23\x06\x41\x5f\xbc\x80\x8e\x04\x84\x7f\x78\x81\x63\x47\x78\xeb\x87\x7f\xf6\xff\xf5\xb9\xf1\xc3\x0e\xf0\xf5\x78\xc6\xb0\x23\xb6\xe6\xab\xc4\xe1\x08\xaf\xda\x78\x38\x22\x5b\x15\xe0\x88\x1c\x88\x23\x72\xf8\xa4\xad\xc8\x1a\x9f\x1f\xa0\x2d\x57\x3f\x12\x16\x4c\xad\xa9\xf6\x6a\x34\xf0\x3a\x86\xa3\xd1\x3a\x73\xcb\x72\x91\xc3\x27\x2d\x5b\x33\xc0\xc3\x16\x95\x23\x87\xad\x20\x84\x1d\xa0\xc3\x1a\xbe\x6c\x89\x3a\x71\xd8\xf0\xad\xab\xae\x70\x6b\xaa\x72\x24\x0f\x47\x6a\x07\x7f\x95\x44\x56\x42\xa0\xe3\x56\x4c\x39\x42\x5b\xaa\x4e\x1c\xf1\xdd\x9a\xb9\x13\x47\xe8\x53\x5c\xc2\x0f\x47\x74\x07\xaf\xf9\x2d\xb6\xc3\xd7\x7c\xfa\x53\x6d\x5b\xb3\xc3\xcd\x36\xd6\x0b\x7c\x43\x74\x84\xd7\xcc\xfd\xf0\xa9\x8e\x21\x3b\xb0\x3a\x50\x6b\x5c\x83\x1d\x91\xe8\x88\x6d\xdd\xdb\x7e\x77\xd0\x06\xb4\xb1\x81\xf8\x6c\x7f\x45\x0b\x1d\xe1\x03\xbe\x75\xaf\x89\xe6\x6a\x85\xc4\x0e\x5e\xdf\xef\xd0\xdd\x11\x5d\x93\xe0\x75\x2a\xbc\x43\x37\x0a\x88\x6d\x4b\xd8\xa7\x22\x01\x1f\x89\x0a\xde\x6a\x6f\x19\x74\x84\xa2\x95\x94\x95\x4b\xd0\x07\xdb\x56\x94\xc2\x56\x86\x6c\x35\xbd\x4f\x31\xed\x48\x2d\x15\xb2\xd1\x91\x41\x47\xec\x8a\x90\x6b\xa0\x8d\x44\xe0\x6e\x65\x1d\xfa\xb5\x8b\x35\x0c\x47\x77\xe0\x46\xfd\x3a\x17\xfc\x70\x69\x13\xde\xaf\xf1\x6f\x73\x87\x0d\x7c\xab\xf7\xad\x71\x25\x15\xfd\x06\x6c\xab\x56\x6c\x0c\xdf\xea\x03\x1f\x4e\xae\x84\x1c\xd6\x1d\x46\x47\xe2\xb8\xe6\x57\x1b\x75\x2b\xbb\xd6\x68\x91\x88\x3e\xb4\x7f\xa4\x84\x6f\x42\xf8\x4c\xd9\x3c\xe8\x11\x5a\x29\xc6\x0f\x1b\x22\xf4\x43\xf2\x11\x3b\x7e\xa6\x7c\xd8\x0d\x6f\x2f\x7c\xd5\x94\x0f\x1a\x6a\xdd\xcb\xaa\x33\xeb\x28\x75\x44\x57\x5c\x2b\xcd\xe4\x46\x30\xb4\x6d\x71\xa5\x0f\xd9\x81\x87\xd5\xdb\xae\xaa\xb9\x92\xb5\xd1\x7b\x58\x89\x5c\x77\xfb\x5d\x11\x8e\xd0\x52\xc1\xe4\xaa\x7c\x68\xb4\x6e\x17\xf9\x88\x79\x63\x15\x75\x5c\xe5\x89\x7f\x76\xf4\x87\xa4\x20\x1f\x61\xad\x88\xb7\x6d\x7d\x0a\x23\x1f\x96\x7f\x89\xe1\x3b\x08\xb9\x4e\xdb\x3a\x57\x76\x64\x87\x23\xf5\x59\xf3\x43\x36\x72\xd8\x14\x18\xda\xca\x86\xd4\x56\x8b\xda\x2a\x5c\x5b\xc5\x6c\x1d\xdc\x0e\x83\x15\xcf\x7a\xfe\xac\x81\x39\xb1\x62\xc4\x76\xd0\x47\xf3\xd1\xad\x60\x80\x6f\x65\x1c\xf2\x88\xa8\xc8\x57\x95\x13\x8f\x8e\xd8\x71\xab\xd1\x6c\xda\xb8\xb1\xf8\x8b\x51\x1f\xf2\x56\x66\x6f\xd2\xa0\x56\xe2\xe0\x8f\xb0\x56\x26\xad\x92\x3d\x7e\xf2\x20\x2a\x3a\x52\x1b\x30\xfc\x99\xb3\x6d\xe2\x27\x3f\x37\xaf\xb0\x11\x8b\x7d\xf1\x17\xfa\xd8\xe5\x52\x1d\xb0\x23\xb2\xd2\xb0\x1d\x7d\xab\x7f\x58\xcd\x71\x35\xce\x55\x25\x3f\x62\xc6\x7e\x20\x3b\x6c\x72\x81\x7f\x60\xdb\xe4\x76\xa4\xb6\xde\x0f\x83\xd7\x43\x19\x3e\x41\x44\xb4\x0d\x7c\xe4\xf0\x13\x1e\xdd\xd6\x85\x3f\x68\x90\x55\x7a\x1b\xe6\xdd\x77\x1f\xb1\x59\x0d\xba\x83\xa2\x35\x37\x5f\x05\xb4\xd5\xe9\xa0\x23\xfa\x95\x92\xed\x56\xd8\x95\x78\xf8\xb8\x55\xd4\xe0\x03\xba\x52\x87\xad\xa7\xf9\x11\xda\x6a\x72\x2b\x6b\xe0\x8f\xad\x7f\xbc\xdd\xca\xda\xcd\x4e\x56\x6f\x81\x2c\xd5\x3a\x81\xfc\x61\xc8\xd8\x47\xda\xf0\x56\x4e\x85\x56\x4b\xc3\xa2\xcf\xee\x7f\xf2\x62\x63\xd2\xe6\x22\xa2\xad\xf8\xb8\x51\x8e\x7e\x8c\x6d\x5b\x71\xc3\xb2\x8a\xf6\xb0\x21\xfa\x68\x13\xba\xb2\x74\xb5\x83\x95\xf9\x9f\xff\xb0\x4d\x8d\xbe\xd4\xe1\x63\x79\xeb\x32\xd8\xb6\x0c\xba\x85\x10\xe4\x07\xdd\x4a\xc1\x2a\x63\x6a\xb7\xb9\xc9\xe3\x56\x45\xdd\xe6\xc3\x3b\xf4\xbb\xd2\x6e\x75\xe1\xcd\x6c\xc8\x4f\xe1\xe4\x93\x8b\xaf\x5e\x0d\x39\x6c\x6e\x1b\xfb\x18\x21\x75\x24\xb7\xcf\x33\xb0\xcd\xf1\xe3\x2b\x89\xbf\xa2\xf3\xf0\x63\xbf\xc4\x97\x8a\xaf\x7e\xf3\xb3\x27\xf4\x48\x55\x5b\x72\x8b\x6c\x9e\x0c\x8a\xd6\x75\x3f\x5e\x07\xfa\x6e\x26\x3f\x9d\xd3\xba\x27\x74\x58\x1d\xdd\xba\x9b\x0f\xba\xd5\xa5\x80\xc3\xc6\xd7\xc3\xb6\xf4\x87\xd9\xeb\xae\xe1\xa5\x22\x36\x5f\x80\x66\xd0\xa7\xe6\x81\x7d\xdc\xe4\x11\xfa\x28\xe3\xa6\x90\xd8\xe6\xf5\x0e\xd0\x8a\xf7\x57\x24\xa0\xdf\xd5\x7a\xfb\xef\x37\x2e\x67\x95\xdd\x8a\xe7\xcb\x3d\x7c\xd4\x8b\x58\x37\xfd\xb5\x33\xea\xbb\xc3\xc0\x36\x54\xe4\xe1\x3b\xc6\x8d\xb5\xf8\x47\xaf\x3f\x2e\x03\xdd\xad\x8b\x63\x1f\x0f\x8a\x7f\x6c\x02\xf9\xdf\x4e\x27\x3f\xd3\xd1\x45\x85\xb0\x1d\x46\x44\xbf\x16\x3e\xb1\x19\xc3\x2a\xbe\x8d\xe6\x4d\x49\x37\xb6\x23\x9b\x67\xd9\x0e\x90\xe8\x23\x13\xf4\x48\x7e\x38\xf8\xf9\x6c\x6a\x73\x6f\xbb\xcf\x07\x36\xc4\xe1\x4b\x7b\xc9\xcf\x8c\x0f\xa9\xeb\x01\x1b\x41\xdf\x61\xc9\x2f\x58\xea\x87\x2b\x43\x7f\xe5\xca\x7e\xfa\xf9\x4d\x66\x44\xf4\xdd\xd1\x23\x3f\xdc\x0e\xb9\x49\x6c\xb7\x91\x8d\x7f\x4e\x38\x64\x7d\xbf\xaa\xfd\x77\x5e\xab\x10\xbe\xc3\xc1\xd5\x19\x7e\x59\x03\x7c\xd8\x3c\xcc\xba\xee\xaa\xb6\x9f\x53\x7f\xf7\xe3\x54\x84\x3e\x21\x42\xb4\x49\xf8\x08\x7d\xb9\x2d\x64\xdd\xc7\x4f\xf7\xb5\xee\xee\xeb\x7c\xda\xbc\xf8\xba\xfe\x67\x2b\x47\xf2\xbb\xd7\x5b\x8f\x26\xf2\x1f\x9c\xc7\x76\xa2\x7c\xef\x5b\x6d\x71\xd3\x94\xaf\xa3\x65\xd3\x39\xea\x8b\x42\x68\xb7\x61\x5b\x55\x50\x85\xa8\x1d\x0e\x7f\xd4\x6f\x5d\x6e\x3b\x92\xf0\x8f\x38\x3f\x42\x86\xbe\x4e\x9c\x8f\x8f\xfe\xda\xc6\x6a\x4c\xab\x45\x20\xdf\x1d\x1d\x72\xf8\x3a\x84\xbe\x1f\xd8\x9b\x0c\xbf\x9c\xf2\x17\xbb\x7f\x37\x75\x42\x7e\xa6\x4e\x7f\x18\xe0\xa2\xff\x5e\x80\xbb\x66\x5c\x38\xf5\x09\x70\x09\xf4\x08\x83\x5f\x01\x2e\x46\x1e\x89\xad\x1f\xfe\xe5\x1b\x49\x1c\x09\xf0\xbf\x1b\xe0\xfe\x36\xaf\xbf\x53\xc9\xfd\x8e\xff\x41\xa2\x4e\xfc\x36\x31\xbe\x93\x49\x7c\xc7\xfe\x20\xf1\x86\x7e\x1b\x3d\xdf\x91\x04\xbf\xff\x7e\xf4\x7c\xc4\x21\xf8\xb7\x85\x83\x28\x0e\x93\xf0\x8f\x12\xf5\xdf\x82\x23\x51\xf4\x47\x75\x06\x02\xfb\x9d\xba\x01\x11\x92\xf1\x1f\xd4\x01\xc8\xdf\xa9\x63\x44\x41\x00\x45\x7f\x54\x07\x20\x7e\x1b\xff\x87\x11\x49\x86\x7f\x40\x3e\x05\xff\x16\x3e\x48\xf0\x28\xf8\x23\x78\xfc\x77\x92\x91\x3b\x1a\x53\xbf\x0f\xff\x67\xd6\x0d\xb2\x03\x4c\x5c\xa1\xdf\xd7\x7b\xf4\x5f\x96\x0c\xfe\x61\xf6\x7f\xb5\x5a\xf0\xbd\x63\xa5\xf6\xd1\xe4\xf5\x2f\xdf\xc2\x64\x48\xca\x7f\x2a\x2c\xfe\xf7\xaa\x8a\xcd\xdf\x65\xc1\xbf\xcb\x82\x7f\x97\x05\xff\x5a\x65\xc1\x35\xc3\xfa\xd3\xca\x82\xf8\x96\xef\xad\x51\x1f\x75\x24\x23\xf0\x00\xef\xb6\x62\x1f\x71\xa4\x0e\x9f\x3c\x18\xfa\x1e\x63\x6d\x49\xd7\x1a\xef\x90\x9f\xc0\x6b\x8d\xde\xd7\xb0\xfe\xab\x2c\xf0\xc9\x0b\xe1\x35\xfc\x20\x77\xe8\x16\x23\xee\xd6\x58\x6a\xcd\xbe\xa8\x1d\xb1\x7d\x4c\x4f\x7c\x6e\x18\xda\x6e\x3e\x20\x76\xe8\xe7\x7e\x9e\x1d\xb1\xc5\x60\xc8\x16\x66\xec\xb0\x2d\xbe\xc7\x77\x9f\x1c\x61\x03\x3e\xa0\x9f\xc9\x87\x2f\x24\xed\x9a\xac\xac\x21\x09\xf1\xc9\x93\xa2\x2d\x3c\x5d\xff\xe0\xaf\x5b\x16\x3e\xc0\xe8\x52\xa1\x5b\xc4\x12\x81\x5b\x21\x04\xdb\xad\x41\x14\xbe\xdb\xee\x2c\xda\x7d\xcf\x59\xd7\xa0\x79\x6b\xdb\x2d\x64\xc6\xb7\xfa\x08\x11\x6d\x69\xdc\x16\xba\xc2\xdb\xd6\xf1\xed\x9e\x16\xf0\x13\xd8\x62\x87\x4f\x72\xb3\x66\x1f\xd0\x16\x16\xc1\x9f\xc8\x77\xeb\x27\xda\x03\xb2\x3b\xe2\x87\x0d\x6b\xf4\x95\xe6\x6f\x61\xfc\x6e\x03\xda\x6d\x89\x01\xbc\x09\x0d\xdc\x4a\xa4\x87\xad\x44\xfa\x55\x45\x25\xfe\xae\xa2\xfe\x5d\x45\xfd\xbb\x8a\xfa\x77\x15\xf5\xef\x2a\xea\xdf\x55\xd4\xbf\xab\xa8\x7f\x57\x51\xff\xae\xa2\xfe\x5d\x45\xfd\xbb\x8a\xfa\x77\x15\xf5\xef\x2a\xea\xdf\x55\xd4\xbf\xab\xa8\xff\x17\x56\x51\x9f\xc8\x5f\xeb\x5b\xe9\xf5\xf4\xf3\x07\x96\x48\xea\xf3\x34\xea\x77\x40\x78\xee\xf4\xb4\x5a\xc1\x97\xc2\xab\x71\xa7\x4c\x5e\x60\x4e\x85\xcf\x98\x92\x7e\xce\xd0\xf1\xad\x21\x5c\x7b\x43\x55\x5d\xd4\xc9\x10\x18\x1d\x56\x3a\xf1\x23\xc6\xfb\xe0\x08\xa2\x0d\x25\x29\x91\xc9\x8b\xd5\x78\x4d\x03\x2f\x0c\xbd\xb8\x8e\xe1\xd0\xd3\x26\x3d\xc8\xc4\x39\x5a\x92\xb0\x5b\xde\x0b\x32\x24\x14\x45\xa0\xa0\x6b\x9a\xa7\xc2\xad\xb1\x28\x09\x7b\x34\x3a\xe1\x96\xea\x13\x09\xf8\x30\xe9\xd3\x9b\x8a\x10\x77\x6a\xaf\x43\x94\x54\x55\x38\xb7\xd4\x6c\xe3\xfb\xfe\x74\x26\x9b\x40\x4f\xee\xf3\x33\xd6\x39\x0e\xf3\xab\x0c\x1b\x61\x7c\x54\x0b\x3e\x6b\xc8\x73\xc7\x75\x3d\x7f\xb9\x09\xec\x7b\xd0\x00\xb4\x3f\xdf\x34\xf1\x04\xda\x18\xc5\x61\xa4\x07\xb0\x30\x11\x08\x1a\xad\x20\x5e\x97\x55\xed\x38\x62\x22\x3b\x6b\xe8\xbe\x5f\xfa\xfd\x45\xe9\x8c\xd6\xd1\x27\xdd\x98\xf0\x9b\x4a\x37\xc6\x83\xa1\x47\xe2\xb2\x0f\xf9\x2b\xab\xaa\x46\xfa\x9a\xd3\x76\xaf\x08\x2d\x94\xed\x63\x31\x26\xc3\x3a\x00\x8d\xca\xbb\x50\x17\x05\x3f\xfb\xe9\x48\x0f\x17\xe1\x26\xcb\xcd\x8c\x5c\x51\x94\x4d\xb5\xfb\x40\xf8\x13\xd9\x28\xa7\x7d\xe9\xf0\xe9\xb0\x08\xa4\x1f\x67\xcb\xbe\x46\xa1\xb6\xa6\x45\x53\xc4\x52\x87\x1f\xd9\x72\xc9\x4e\xf1\xd0\x75\xc2\x74\xd7\x66\x5f\x06\xf9\xfa\xdc\x2c\xb2\x8c\x25\x62\x74\x87\x5e\xa7\x06\x12\x2f\x53\xf7\x18\xa5\xfd\xf3\x3e\x54\x68\x0a\xb8\xd0\xab\x3b\xa7\xc9\xdb\xe7\x61\xcb\x3b\x5b\x92\x42\xed\x5d\xf0\x51\x80\x15\x6b\x65\xf4\xc4\x79\xa9\x21\xa7\xa1\xe6\x4d\xb7\x17\x82\x0d\x86\xcc\xe6\xb2\x51\x58\x8e\x17\x47\xd0\x3e\x8d\xa2\x0c\x12\x4e\xa2\x5e\xc9\xbd\x94\x32\x6c\x1c\xe1\xf8\xeb\x6c\x9c\x54\x91\xda\x43\x9a\xf4\x74\xe6\x72\x9a\x4e\x5d\xef\xe2\x29\x9f\xdb\x52\xbf\xd7\xd0\xf9\x11\xbb\x69\x37\x83\xb3\x5d\xc5\xda\x43\x58\xa2\x51\x7e\xf8\xa0\xea\x10\xaa\xd2\xed\xa5\x47\x63\x05\x31\x84\x0b\x8d\x34\x21\x21\x40\x83\xdc\x8d\x10\x7c\xaf\x6e\xe3\x27\xfd\x70\x54\xee\xf2\x90\xb0\x45\x4f\xef\x0d\xd3\x9a\x4d\x9c\x65\x62\x76\x3b\xdd\x19\xc6\x01\x6a\x91\x16\xcd\x6e\x72\xa5\x4b\x8a\x95\x36\xac\x75\x6f\x09\x8b\x15\xd0\x62\x30\xf9\xbc\x28\x4d\x5c\x36\x2f\x2f\xb8\xf0\x41\xa7\x8b\x4b\x27\xbf\xb0\x54\x44\x2c\x8c\xd3\x1e\x3d\x2d\x63\xda\x43\x3e\xdf\x75\x5f\x96\xc0\xa6\x60\x0a\x2b\x4e\x2a\x36\xb7\x52\x0b\x78\x17\x86\xa6\x58\x89\xde\x4d\xcc\x03\x55\x2c\x76\xbc\x0b\x1d\x0f\x16\xef\xd7\xcb\x23\x6e\x57\xb5\xee\x29\xaf\x54\xbd\x19\x2e\x09\x95\x07\xe3\x85\x46\x72\x5a\x33\x66\x1f\x1f\xdc\x89\xc5\x21\xc7\x47\xa1\xc5\x9e\xb5\xc8\xcf\x70\xc0\x60\x35\xcf\x18\x96\x1c\x8b\x4d\x84\xaa\x4f\xd7\x17\xc4\x38\x73\xaf\x8a\x34\x6d\xb6\x02\xde\x85\x61\x82\xe6\x32\x07\xbd\x89\x4b\x85\xe5\x02\x13\x57\x2e\x64\xb5\xdc\xbd\x54\xf2\x9e\xc1\x5b\x8f\x02\xf7\x34\x6d\x70\x27\xda\x25\x62\x17\xf4\xeb\x25\xfd\x73\x1f\x6d\x53\x3d\xd1\xbf\x98\xef\x60\x7e\x3c\xda\xa6\xa0\xa8\x37\x08\xd1\xce\x44\x50\xcf\xf6\x6d\xbf\xfb\xc7\xb5\x0b\xa3\x24\x08\xeb\x5b\x8b\x72\xbe\x79\xb2\x1a\x35\xc3\xb9\xf4\x45\x10\xef\x7a\x4f\xdf\x1b\x1a\xd8\x4b\x77\x94\x69\x8a\x3d\x0b\xb2\xf7\xe9\x6a\x72\x4c\xb6\x97\x60\xed\x75\x5b\xde\x4f\x0b\xe2\xae\x43\xd8\x39\x88\x75\xd6\xa3\x8a\xb4\xac\xb2\x3d\x97\x49\xd4\xd6\x54\x6c\x13\x48\x7d\x21\xb1\x2b\xc0\x50\x27\xf0\x44\x90\x17\x25\xee\x00\x85\x2b\x0d\xa8\x57\xfd\x39\x94\xe8\x54\xa2\x6a\x8a\xba\xb8\x53\x93\x90\x48\x5d\xe4\x0b\x95\x71\x5c\x90\x20\x08\x78\x1e\x26\x05\x25\x2f\x18\xe4\x4d\x15\x90\xd4\x5a\x27\xeb\xe1\x75\xa4\x33\x90\x8f\xf0\xc2\x7f\x7a\x41\x47\xe9\x75\x09\x8b\x0c\x0b\xc2\xa7\xf7\x43\xc5\x7c\x22\x43\x75\x72\x4f\x08\x9d\x24\x5c\xcf\x28\x75\x79\x4f\x4e\x5d\x12\x7d\x24\xc5\xf7\x6c\xd8\x33\x12\x37\xec\xef\x4c\xf4\x20\x9e\x40\xe7\xa9\xfa\xbb\x85\x4d\xef\x6a\x8f\xe8\xc5\x83\x9d\x5a\xb0\xdf\x1e\x1b\x86\x3e\xd1\x3d\xd5\x96\x86\x10\x81\xb3\x38\xfa\x62\xa0\xe9\x99\x17\x9d\xb3\xd2\x82\xba\x9e\x51\x6c\xc1\x5b\xad\xfe\xae\xa6\x89\x5f\xe0\xf2\x1d\x20\xef\xfa\x49\x77\x88\x88\x07\x71\x1a\x1b\x19\xf3\xac\x12\xa5\x10\x9a\x58\xab\xda\xc7\xf3\xa2\x37\x1e\xf3\x36\x6c\x2e\xaa\x04\x41\xb3\x88\x1c\x51\x4d\x6e\x59\x74\x76\x04\x86\x21\x20\xf3\xc2\xd9\xb3\x17\x63\xaa\x20\x94\x61\xb2\xe1\x1c\x9d\x14\xf1\x29\xea\xf6\x85\x3e\x4f\x53\xa2\x84\x6f\x33\xa5\x0b\xbf\x7f\x30\xf1\x09\x15\xb1\xc6\x3d\xbb\x9e\xe3\x42\x94\xaf\xa0\xde\xab\xaf\x69\x55\xc8\xea\x17\xc4\xbc\x5c\x3f\x0d\x7c\x48\xa5\x4f\xb4\x65\x5c\x72\x87\xc2\x17\x79\x29\x1c\x02\xaf\xc6\x24\x0b\x2e\xc3\x84\x67\x54\xaf\x0e\x84\x2c\x68\x88\xd9\x3c\x15\xb4\xb1\x69\x09\x3d\x99\x19\x3a\x5a\x25\x42\x51\x53\x19\xec\x41\xd0\x0f\x4d\x64\x7e\x4b\x8b\x4a\x59\x8b\xf5\x4a\xcf\xe7\xba\x91\xa3\xa2\x14\xdf\x27\x90\x64\xa3\xf3\xa3\x66\x3a\x45\x61\x5b\x8b\x17\xc5\xa7\xe5\x9e\x87\x53\xc7\xc9\x5a\x23\xe4\xcf\x67\x7b\x06\xfb\x52\x6a\x39\xce\x61\x59\xda\x56\x4b\xc6\x28\xb4\x3e\xc8\xf8\x39\xbf\xd9\x91\xd2\x56\x02\x23\x07\xc6\x14\x5c\x0a\x0c\xb1\xcb\x53\x22\x17\x2a\x01\xd2\x0f\xba\x69\xd8\x34\x63\x2e\x05\xd5\xca\x9d\x34\xbc\x3a\xfd\x65\xa1\x02\x13\x98\xf5\xd9\x32\x3d\xb2\x7b\xc0\xdc\x25\x43\x4a\x81\xc1\x8c\x11\xbe\x69\x82\x8c\x29\x66\x83\x8f\x68\x2b\x77\x70\x9a\xd2\xcb\x3c\xe6\x31\xad\x6a\x00\xd5\x4b\xba\x75\x4b\x4b\x46\xe1\x2e\x98\x20\x20\x95\xc9\x21\xe3\x89\xa7\x5e\x57\x73\x68\x4e\x6f\xe7\x79\xaf\xf7\x0e\x6f\xc8\x20\x40\x58\x59\x37\x86\xcd\xe9\x8c\x3f\xe2\x13\x69\xde\x26\x8b\xc5\x88\xcc\xba\xf2\x76\x48\x24\x18\x00\xf7\xa0\x30\xbd\xf4\xd3\xb9\x19\xf7\x64\x7e\x43\x4b\xdf\x87\x0d\xb1\x47\xf2\x38\x93\xa6\x0b\xe1\x13\x4f\x92\xa6\x47\x5a\x61\xc5\x9b\xcc\xeb\x8c\xc8\xfe\xe9\xbe\xe2\x2f\xf6\xd4\xdd\x9f\x71\x46\xfb\xe3\x87\x1c\xfb\xd0\x8c\xcb\x57\x55\x3b\x4c\xd8\x04\xa0\x93\x38\x06\x97\x3b\x22\xcb\x42\xfb\x73\xf5\xce\xa6\xc6\xeb\x80\x94\x19\xbc\x73\x4e\xa0\xd2\x1d\xa5\xaf\xa0\x8f\xb4\x9a\x2c\x80\xbe\x13\x48\xec\xab\x91\xee\x8f\xf4\x6a\x65\x7c\x2e\x0a\x68\xc7\x5d\xe2\x0b\x70\xbf\x24\x97\xc0\x92\xbb\x3c\xc1\xc4\x5b\x4f\x3c\x97\x05\x49\x80\x88\x58\x3a\x59\x94\x02\x09\x1d\x6a\xea\xb9\x07\x74\x24\x43\x13\x34\xc0\xf5\x01\xe7\x1b\x83\xe1\xf2\x99\xd0\xb1\x77\x04\xe9\x90\xd7\xe1\x9e\x4e\xaa\x58\xf2\xf0\x1a\xdc\x39\xef\x63\x37\xec\x93\x2a\xb1\xc5\xf8\x39\x68\x71\xae\x25\x94\x3f\x18\x4a\x82\x32\x39\xaa\x57\xf6\xd3\xac\xe6\x17\x59\x11\xd0\xfb\x49\xa0\xcc\x24\x0b\x70\x37\x4a\xa7\x81\x6e\xf6\x77\xa0\x84\x6c\xd8\x7f\x82\x4b\x94\x9c\xf2\xe5\x7e\xb9\x05\xc0\x64\xd6\x77\xc6\xcc\x44\x94\x35\x5e\xb4\x9f\x37\x8c\x9b\x78\xdc\x4c\x93\x5c\x8e\x27\x39\x14\x25\x1e\x0b\x79\xcc\xf8\xb6\xbd\x93\x7e\x82\x07\x17\x8f\x22\x86\x61\x54\x09\x67\x5a\xcb\xe1\x8d\x25\x28\x44\x05\x9f\x18\xb0\x1b\x1e\x33\x33\x99\xda\x14\xb3\x5d\x04\x7b\x77\xd2\xa4\xec\x39\x70\x6d\xee\x92\xc2\xf6\xe3\x7e\x8d\x47\x3c\x7b\x49\x0d\x4f\x31\xb0\x38\x15\x3c\xe7\x96\xca\x89\x68\xd1\xa4\xeb\x12\xb8\xb0\x9e\x60\xc3\x99\xc9\xf2\x36\x46\x56\x92\x68\xa4\x11\x4f\x6f\x10\xa8\x64\xb5\xe2\x31\xe4\xd5\xc0\x88\x8b\xee\x47\xcc\xda\x1b\x58\x93\x35\x21\xe5\x21\x5d\x7a\x4a\x2f\xa4\xa3\x18\x34\xcb\x12\xa9\x3a\x51\x95\x6c\xe8\x08\xc8\xbb\x78\xc5\x9f\x9e\x7e\x4e\x4e\xd1\x99\x8f\x17\xb5\x8f\x1e\xf7\x42\x8e\xde\xf6\xbd\x7a\x55\xb9\xe0\x33\x13\x2b\x00\x52\xbc\x4f\x83\x59\x3e\x8f\x8d\xf1\x38\xc5\x6f\x1a\x1b\xd0\x93\x4c\xb0\x2f\x14\x95\x1f\x37\xcd\x7d\x06\x69\xf0\x7a\x12\x06\xcd\x16\x2d\x78\xa2\x96\xda\x45\x70\x2c\x0f\x60\x94\x5b\x1a\x9e\x6b\x96\xcb\x39\x3c\x91\xc9\xb5\x13\xad\xcc\x3b\xd9\xa3\xf6\x0e\xa2\xba\x15\x89\x17\xae\x2c\x2d\xdf\x07\x74\xa9\xe9\x15\x95\x11\x9c\x65\x5d\x1f\xca\xcc\xaa\xc5\xf3\xc9\x49\x7b\xd1\x82\xad\xce\x70\x69\xc8\x2c\xe5\x06\xf4\x30\xbc\x86\xbd\x3d\x6e\x9c\x8a\xaa\xe0\x82\x62\x12\x28\x57\xbd\xbe\xdc\x59\xde\xb7\x00\xf3\xee\x32\xff\x3e\xb8\x0b\xe4\xa4\xfb\xc5\xe1\xa2\x87\xaa\xab\x15\x98\x21\xcf\x89\x7f\x08\x55\x80\xb0\xa1\xd4\xb3\x7d\x4c\x34\x6a\x04\x2a\x0a\x74\x4b\x2b\xbe\x7c\x8a\xe7\xce\x45\x98\x3d\x84\x9d\x24\x51\x93\xec\xb7\xea\x4b\xe5\xe5\x44\xe4\xa0\x83\x42\xda\x5b\xaa\x4d\x7e\x2e\xfd\xb0\x47\x4d\xec\x65\x84\x06\x13\xd0\x19\x85\xdd\xaf\xf2\x8d\xad\x9f\x06\x5b\x87\x14\xf7\x76\x6f\xf3\xdb\xe4\x4d\x0b\xd7\xb8\xc4\x19\xf7\xf3\x29\xf0\x32\xe2\xdd\xa1\x2c\xca\x90\xf3\x9e\x1a\x8a\xb1\x26\x8a\x51\xd6\xcc\x27\xd7\x04\x54\x90\x0b\x32\xe3\xd7\xc2\xde\x8c\x4c\xfe\x65\xc0\x09\x54\x21\x26\xc9\x30\x29\x3d\x53\xc5\x42\xcd\x2d\xcb\xe3\x7f\xf2\x23\xf4\x9a\xf8\x2f\xf6\x23\xb0\x39\xf6\x33\x47\x29\x3e\xbf\xc0\x01\x54\x61\x8f\x08\x77\x1e\x92\x4d\xd3\x79\xba\x7e\x96\xd0\x8a\xc6\x38\xa6\x73\x9d\x89\x68\xa6\x9c\xe2\x82\xcb\x2e\xb0\x57\xc2\x0e\x94\xf4\x56\xe8\x73\x34\x55\x98\xd0\x79\x09\x81\xd3\x7b\xbc\xed\xc8\xac\x1f\x80\x0f\x0b\x9b\x6f\xf0\xed\x82\x61\x44\x88\xa9\x95\xed\x3d\xd3\x8a\xd3\xeb\xfb\x25\x22\x1e\x4b\xad\x8a\x92\xe6\xeb\x39\x18\x27\x98\x33\x54\xcf\x8b\x39\x3d\x1f\x3c\x50\x84\xda\xcb\x05\x41\x8c\xbb\xf6\xa4\xed\x8e\xd0\x89\xc0\xc8\xdb\xbd\x10\x52\x2d\x3d\x57\xdd\x3c\x59\xba\xf9\x38\x4b\x0f\xd0\xb0\x5d\xc0\xe4\x72\x5f\xf4\xc4\x90\xe0\x4a\x04\x06\x12\xef\x7d\x6d\x63\x30\xb5\xd8\x89\xaa\xf2\x17\x0b\x36\x0d\x1b\x3f\x71\x2a\xc5\x0c\x20\xc3\x2f\x8a\x06\x76\x33\x36\xd7\x52\x31\x2e\xea\xe8\x8c\x19\x2c\x8c\x6a\x1c\x85\x5c\xce\xde\x0c\xaf\x2c\x5e\x02\xfb\xe4\x1b\xdd\x06\xc6\x3c\x83\xfc\x87\x22\xd5\xb4\x16\x71\x7b\xc0\x09\xa8\xb0\x47\xc6\x73\x29\x0e\x6f\xe6\xc6\x56\x49\x07\xef\x2d\x5c\xe5\xb1\x14\x6d\xc4\xf2\x46\xd1\x80\x44\x80\x1e\xcb\x65\x19\x97\x4c\xba\x66\x0b\x55\x3b\x9e\x99\x31\xaa\x7b\xaf\x10\x48\xfc\x6a\x69\xb7\xe9\xda\x83\x7d\xa1\x58\x62\xcd\x44\xaf\xb2\xd6\xd0\x53\xc3\x1a\x52\x20\xf5\xd2\x40\x28\x4e\xd3\xa8\x97\xd4\x20\x5e\x04\xa6\xd0\x74\x88\x51\x0c\x95\xb2\xcc\xc9\x92\xd3\x57\x52\x99\x6f\x0a\xad\x54\xb9\xe2\x60\x94\xbd\xab\x64\x1d\x12\xf6\xc9\x17\x0d\x4d\x79\xd2\x85\x53\x44\x21\x8e\x9f\x67\x91\x11\x04\xde\x35\xaf\x0a\x46\xa4\x02\x7f\xc2\x5e\x0f\x52\x99\xc6\x28\x80\x5f\x16\xc2\xdf\x82\x3e\xad\x16\x7a\x84\xd1\xd8\x04\x3c\x23\x1d\xbb\x96\xb5\x98\x87\x2e\xc5\x6e\xe8\x34\x3c\xec\x9c\x15\xa6\xbe\x92\x74\x04\x44\xb9\x7b\x6a\x65\x0a\x48\x4b\x57\xa9\x39\x5c\x86\x87\x54\x6f\x97\xf6\x12\x5f\x8c\xf8\x9e\x18\x50\x04\xd8\x99\xdc\xd8\x29\x57\x53\x34\x22\x3b\x3c\x07\x60\x70\x8c\x62\x53\x94\xdd\xda\xa1\x79\x73\x38\x73\x07\x6e\x38\xf8\xce\xaf\x88\x41\xdd\x00\x30\x0c\x45\x07\xea\x9b\xa7\x2f\x16\x77\xde\xb4\x0c\xe4\x1a\xb6\xea\x58\x82\xaf\xf2\xd5\x48\xb4\x59\x59\x8d\xee\x7b\xee\x0c\xc6\xcd\x9b\xa0\x94\x3b\xa3\xf2\x7c\x4c\x3e\xc4\x16\xe8\x0d\xc4\x2f\x09\xfd\x2c\x68\x42\xd8\xf3\x5e\x7e\x85\xdf\x39\x7b\x27\xc9\x7b\x33\x78\x19\x13\x36\xc0\xf0\xd2\x91\x0e\x84\x81\x9b\x5f\x9d\x85\x97\x5d\x2c\x3e\x84\x83\x62\x43\xf5\xbc\x1a\x0a\x32\x99\x99\x80\xf6\x8e\xbd\x4e\xe8\x9d\x6b\x55\x57\xb3\x75\x15\xd3\x0b\x3a\xa0\x8a\x4a\xd3\x0f\x33\xad\x2e\x7b\xeb\x7c\xce\xff\x74\x9b\xfe\x8b\x3d\x0d\x2f\xe9\x7e\xfe\x7c\xeb\x03\x92\x4e\x3c\xef\x00\x39\xd1\x13\x37\x18\x49\xc8\x4e\x4c\xeb\x44\x34\xf4\x11\xc9\x6e\x5c\x51\x64\x46\x6e\xf5\xa3\x6a\x98\x7c\x18\xa0\xbd\x93\x3e\xaf\x25\xfb\x1e\x78\x23\xeb\xdf\x05\xdb\xb8\xaf\xc8\x30\xc0\xc6\xa6\x03\x5f\xd6\x5e\xe7\x39\x15\xf9\x31\x3d\xb1\x16\x83\xcb\x75\x4d\x24\x5e\x14\x7b\x80\x58\xc5\xa7\xab\xee\xfa\x82\x8e\xa4\x23\x41\x42\x04\x02\x0c\xd5\xe0\x17\x86\xd1\xd2\xa3\x36\x44\xc5\x8b\xc2\x9d\x7a\x96\xf8\x8c\x00\x62\xb4\x23\x7a\x27\x06\xc8\x79\x4f\x62\xfa\x3e\xf4\x2c\x0f\x4d\xdf\x45\x26\xe1\xf5\xd9\xd7\x5d\x42\x79\x7b\x4f\x46\x86\xfd\x29\xb7\x1a\x2b\xcb\x7a\x94\xe9\x5f\x90\xa6\x37\x77\x2e\x79\xc5\xef\x1b\x72\x43\xa3\x92\xe0\xd0\x33\xe2\x74\x34\x76\x9d\xaf\x74\x59\x9d\x9b\x77\x4f\xd1\x77\xf8\x46\x3f\xa1\x32\x62\x0d\xa4\x7e\xa5\x79\x2f\x57\xa1\x8f\x94\x00\x73\xda\xab\xf5\x49\xa5\xc4\xab\xa2\x83\xee\x88\xc8\x1a\x8d\x20\xac\xd1\x18\x46\xad\x90\x08\x2a\x3c\x08\x54\x77\xc4\x82\xd6\x78\xa9\x60\x2d\xab\x0d\xc8\xd4\x78\xa5\xbe\x2d\x45\x0c\xa8\x5f\x5b\x8f\x41\x20\x52\x94\x6a\x33\x67\xaf\x2e\x5b\x3c\x4d\x81\x6e\xf7\x0f\x2c\x95\x4b\x1a\xed\x60\x4a\x4c\x33\x34\x06\x3b\x10\x15\xe4\x8e\xd2\x8d\x97\x80\x3a\x42\xda\x57\x16\x4f\x93\xf4\x33\x09\xf8\x32\x2f\xdd\xd0\x37\xaf\x33\x50\xb6\x75\x0b\x68\x90\xc1\x14\x53\xc7\x6b\x02\xfa\x98\xf4\x29\x4a\x23\x06\x62\x6f\xd7\xcb\x7b\x50\xbb\x44\xc6\x24\x83\xeb\xce\x67\x49\xcc\xf6\x7b\x3d\xf2\xa8\xdc\x1f\xdd\x87\x27\x23\xc4\x7e\xd0\x41\x37\xf6\x0b\xf0\xd4\x51\xd4\xa3\xf3\xc8\xf3\x3c\xba\x42\x61\xb0\xd9\x88\x76\xd1\x3e\xba\x45\x43\x29\x10\x6f\x75\x49\xf6\x7d\x18\x4e\x1a\x0a\xde\xd5\xa0\x34\x55\x4e\x07\xf0\x6e\x0c\x72\x27\x91\x89\xb1\xbc\x81\x36\x07\x06\x58\xa6\xd8\xee\xd4\xac\xc6\x2b\xcb\xcf\xf7\xeb\x24\x9f\xdb\xd2\x6e\x67\x18\xa4\x5a\x78\xac\x55\x81\xb1\x7d\xed\xf6\x88\x80\x46\xe9\xa8\x54\x1f\x94\xcb\xb4\xcf\xa6\xeb\x59\x92\x2d\xd8\x77\xb1\x27\x1b\x5a\xf3\xd9\x16\x55\x99\x20\xb0\x0b\x79\x9d\x99\x91\x3b\xc7\xb0\x62\x73\x25\xe0\x61\x39\x39\x20\x16\xa1\x5d\x47\x6a\x38\x87\x18\xd4\x49\x36\xc7\x3b\x23\x2f\xd2\x1a\x3b\xc1\xc0\xdb\xe3\x79\x41\xf8\x33\x9f\x6e\xdf\xc4\xdd\x5f\xcc\xee\x9e\x3f\xec\xae\x58\x20\x49\x82\x78\x63\x02\xf6\x04\x1b\xe0\xe7\xe2\x35\xfb\xf9\x99\x8c\x64\xfe\x49\x1b\x21\x63\x08\x5c\x05\xb6\xd7\x4b\x2b\x30\x16\x35\x76\x98\x7c\xb1\x53\x5e\xc4\xba\x71\xba\x96\xb7\xbd\xc7\xd7\xb2\x96\x4b\x69\xe6\xcb\xd3\x84\xd5\x23\xff\x94\x24\x2f\xc8\x2d\x3a\x95\xc5\x4a\xcd\xc1\x18\x46\x7a\x72\x8f\xd8\xc4\x25\xb8\x9d\x79\x55\x11\xa9\xaa\xd2\x6b\x0d\x18\xa1\x81\x71\x9a\xa7\xa2\x6b\x5a\x66\xba\xde\xe9\x32\x73\x29\x58\x4f\x24\x6c\xe7\xe7\xee\xa6\x97\xfa\xb5\xd1\x9e\xf7\x2e\x82\x23\xbb\xe9\xa2\x53\x37\x4d\x20\x5e\xc4\xde\xd3\x32\x00\x66\x58\x64\xde\xba\x2d\x12\x57\xd1\x0b\x3e\xef\xb5\xe6\x71\x79\x3c\x39\xf5\x96\xbf\x4c\x5d\x4a\xb5\x46\x98\x5d\x95\xe4\xde\xb2\x73\x25\x82\xe9\xb2\x4f\xa3\x27\x9a\x12\xf4\x52\xbd\x7a\x3a\xbe\x6a\xaf\x4b\xaa\xc0\x0b\x2c\xa1\x79\x0c\x31\xe0\x98\x26\x73\x7a\x99\x3b\xe0\xad\x28\x58\xd8\x2b\x23\x2d\x71\x29\x4d\xc5\xfe\x5e\xd9\x73\x45\xcf\x19\x17\xf6\x5d\xa8\x29\xd3\x9a\x69\x19\xa9\x97\x17\x2d\x8e\x52\xdb\xa9\x29\x49\x17\x62\xdb\xdf\x54\xcd\x51\x4d\xb5\x50\x5e\xfc\xde\x10\xcb\x26\x2d\x87\x92\x26\x7a\xe9\x42\xcb\xc3\x2d\x78\x98\xe0\xeb\x5c\x38\x0f\xc0\x3b\x25\x20\x63\x4b\x51\x79\x95\xe5\xf2\x7d\x97\xdb\x07\xf5\xa2\xc9\x94\xc6\xc7\x97\x75\x5e\xf4\xc0\x2b\xdf\x44\x31\x03\x40\x17\x2b\xbc\x73\x0f\xc6\x96\x79\xf0\x93\x23\x88\x57\x37\xb4\x09\x7a\xb2\x02\x14\x3e\xc1\x8a\x7a\xbf\x70\xd5\x10\x23\xa3\x1c\x12\x26\xad\x2a\xfe\xa8\x92\x75\xd7\x92\xd3\x19\x78\xf2\x09\x01\x20\x7a\xa5\xc3\x89\x38\x20\xdc\x9e\xea\xdb\x10\xc1\x5c\x30\x94\xb4\x86\x26\xcc\xea\xe1\x59\xa7\xf6\x04\xde\xb1\x1b\x50\x39\xd6\x0d\x94\xde\xf0\xb9\x6a\x99\x8e\x23\xc1\x96\x04\xde\xe2\xbc\xb8\xad\x22\xd8\x1c\x36\x3b\x06\x1b\xde\x1d\xe6\x54\x52\x31\x42\x2a\x43\x11\x73\xb6\x27\xf5\xa7\x2b\xd3\x80\xc5\x3e\x0c\x3b\x10\x7f\x5d\xf6\x33\xad\x8b\xff\x3f\x7b\xff\xad\x6b\x31\xd2\xac\x09\xa2\x0f\x44\x83\x5a\x99\xd4\x5a\x6b\x7a\xd4\x5a\x2d\x6a\x3e\xfd\x45\xd5\x7f\xee\xa9\x6a\x60\x06\xa7\x07\x53\x03\x94\xd1\x06\x8d\xbd\x91\xeb\x63\x22\x33\xc4\x17\xc1\x88\xcc\xf8\xae\xc0\x82\xc1\x6e\x8b\xb6\x4d\x0c\xeb\x35\x5e\x22\x21\x69\x39\x1b\xe5\xeb\x90\xc3\x81\xa0\x69\x27\x41\x74\x5c\xef\x99\x65\x9b\x3e\x45\x49\x6d\x28\x61\xaf\x6d\x0f\x3c\xfe\x58\x45\x1c\xc1\xb3\x16\x8f\xb9\xf3\xc1\x51\x6c\x18\x81\x09\x40\xb0\x21\x86\xab\x94\x58\xe3\x1f\x3d\xa9\x6d\x39\xfe\x65\xd7\x2f\x17\xea\x5f\x7a\xb7\xef\x17\x03\x0b\xc1\xf3\x03\xd2\x7e\x28\xf3\x5f\x2d\x6a\x21\x0f\x23\xc2\x2f\xf1\x5c\x41\x4f\x90\x7a\x90\x01\xd6\xd8\xf5\xc2\xc9\xbc\x7b\xff\x79\x5f\xda\x61\xa4\xd0\xab\x82\x33\x08\x6d\x32\x88\x63\x9b\x78\xe1\x21\xae\xe5\x66\x6d\xeb\x40\xc2\xe4\x88\xf6\x5a\x3a\x75\x1c\x80\x4f\xe9\xf8\x5d\xe0\x4e\xd2\xf8\xfd\x71\x67\x51\x38\x73\xf1\xa1\x49\xe5\xb2\x3d\xa6\xc9\x1f\x04\xba\x3f\x2b\xad\x10\x73\x4f\x6d\x1b\x81\x16\x04\xc7\x3f\x07\x15\x98\xe7\x13\x18\x0e\x20\xce\xcf\xbf\x61\x54\xc2\x7c\xd1\x61\xb2\x81\x01\xb9\xe8\x50\x92\x3c\x81\x34\xd6\xfa\x3d\xa4\x72\xdd\xbc\xb3\x8d\x72\x08\x2f\x68\xf2\x68\xbe\x75\xbd\x4c\x70\xd5\x0e\x57\x6f\x13\x83\x56\x58\x37\xbc\x1e\xf8\xb9\x8c\x76\x59\xcb\x41\x56\x8b\x27\x0b\x4d\xaa\xc8\x3f\xae\x76\x98\x9a\xdd\xd8\x4c\x73\x1c\x5e\xf3\x0a\x87\x11\x9e\x92\xaa\x26\x96\x31\x1b\x00\x09\x10\xee\x32\x8d\x61\x68\xbc\x8d\x9d\x7e\xdc\x23\xb2\xd4\x74\xf6\xd5\xa2\xb2\xd1\x2d\x6c\x8c\x5b\xec\xbb\xe6\x33\xaa\x20\xfd\xa6\x4c\xfa\xf5\x9b\x06\x7f\x97\x39\xcc\x32\xc6\x1e\xef\xa3\x8d\x48\x18\xac\xee\x33\xf5\x78\x04\x3c\x24\xba\xd1\x8c\x90\xa5\x3f\x17\x34\x79\x58\x50\xc7\x53\x59\x3d\xb4\xa3\x55\xa7\x63\x80\x0c\x68\xbd\x8d\x92\x6f\xb5\xf7\x77\xfd\xe7\x66\x51\x77\xd8\x3e\x67\x8d\xad\x90\xce\xb8\x49\xe2\xbb\x01\x6f\x5d\x33\x8d\x26\x50\xb2\xe8\x09\x00\x4e\xb6\xe0\x11\xe6\x1f\xb9\x10\xc7\xca\xde\xed\x9f\xa4\x63\x36\x03\x41\xdd\xe1\xef\x27\x11\xcf\x4e\xb4\x40\x7e\x6f\xf8\x8c\xba\xd5\x06\xff\x80\xbf\x97\x55\x8b\x2c\xfc\x3c\xd3\x93\xb1\x3a\x82\x1c\xe0\x37\x28\x35\xfe\xdb\x7b\xb7\xeb\x4a\xf2\x7d\x4d\xf2\x5c\x62\x0f\x4d\x67\xa8\x6a\x04\xc8\xec\x2c\x97\x31\xe9\xdc\x81\x60\x92\x87\xf5\x5f\x47\x72\xfa\x68\x23\x02\xff\x43\xdd\x9a\xe4\xc0\xee\xf8\x42\x24\xaf\x63\x06\xec\x1a\x9d\xcf\xdc\xee\xa9\xe7\x46\x6c\x3d\x6e\x59\x64\xe4\x09\x6d\x2e\x62\xc7\x5b\x2b\x18\xe6\x66\x63\x78\x3f\x19\xe2\xa8\x80\x3f\x05\xf3\x9f\xe4\x8c\xc7\xbf\x8c\x33\xd6\xe9\xdf\xaf\xfc\xff\x09\xb0\x10\xd8\x1e\xf5\x4d\x59\xae\x96\xbc\xc6\x22\xcd\x28\xdc\x09\x2d\x3c\x6a\xd2\xb1\x81\xe0\xac\x21\x82\x6f\xcd\xc1\xc6\x75\x93\xaf\xc2\x11\x9f\x67\xaf\xd5\x00\x53\x0b\x9a\x5b\x96\x56\x69\x49\x32\x37\xe6\x49\xc8\x5d\xaf\x16\x65\x5d\xef\x23\x53\xdb\xaf\xed\x40\x7a\x25\x69\x54\x24\x91\x5a\xe6\x0a\x09\x7b\xc7\x26\x51\x6e\x5d\x75\x45\x51\x00\x41\xb7\xb2\x65\x31\x02\x5d\xa3\x9f\x1f\xce\xbc\x66\xca\x57\x3b\xee\xf5\x66\xdf\xe0\xcf\x80\x96\xeb\x8d\x76\x57\x2c\x63\x55\x58\x79\xe5\x75\x67\x6f\x0c\x3f\x48\xf3\x86\xe9\xca\xf2\x4c\xad\x62\x4f\x65\x85\xb6\x61\xd4\xcf\xe7\xcd\x37\x9f\x8e\x60\xf6\x70\x7b\x6a\xc0\xf1\x67\x42\xa4\x8c\x9b\x06\x58\xc3\xa8\xb8\x18\xcd\x1a\xf3\xde\xd9\x76\x4a\xa7\xa1\x4e\x47\xe8\xc1\xd9\xc4\xa4\xc8\xe4\x99\x6d\xef\xea\x56\x2b\xb2\xac\x71\xde\xb1\xb9\x7b\x1c\x8a\xb6\x73\xa6\x0d\x4f\xb3\xec\xd3\x77\x83\xd7\xb9\x1b\x06\x33\xcc\xd0\x70\x0e\xfb\x85\x35\x04\xb0\x91\xc0\xc6\xa4\xc4\x4e\xd0\xd3\xc8\x72\xb0\x0d\x70\x90\xb3\xa7\x50\x28\x6f\xf9\xbd\x5c\x3a\x5a\x0a\x9d\x08\xd2\xc9\x3f\x77\x79\x72\x5c\x77\x78\x68\xdc\xa2\x57\xc7\xa5\x58\xff\x2b\x36\xcc\x56\x09\x5e\x97\x4b\x82\x3c\xfa\xe3\x64\x98\xb8\xcb\x71\xac\xe4\xec\x50\xa8\x1d\x3c\x56\x8a\x6e\x00\x21\x10\xe9\xf8\xca\x4a\x3e\xb4\xa8\xb8\xe7\xd7\xed\x46\x47\x43\xd8\x0b\xc5\x9d\xe1\x88\xf5\xc0\x92\x63\x43\x3c\xa2\x7c\x8b\x8f\xb0\x05\x46\x08\x65\x73\x60\xb2\x7a\xa4\x4d\xd4\x53\xa2\x1d\xf6\xb1\x91\xf5\x4d\x8c\xf7\x40\xc1\xde\x45\x14\x0a\x4f\x0c\x4e\xc7\xfd\x04\xb4\xa4\xcc\x59\x6f\x53\x9e\xb1\xbc\xa9\xd9\xf1\x31\xa4\xbd\x54\x2f\xed\xcc\x71\xef\x9f\x4b\xc8\x83\x3d\xb8\xbb\xc5\xc4\x5b\x91\xde\x6c\xb3\xce\xe1\x0c\x72\xdf\x9e\x0f\xd8\x33\xe5\x13\x08\x3d\x66\x7f\x28\x0b\x42\xc3\xf9\x7d\xd2\x31\x43\x5e\xc5\x8b\x4e\x08\xd0\xf8\x59\xe0\xc2\xd8\xd1\xfe\x06\x9a\x8d\xb3\x3d\x2f\x3b\xab\xf7\x2a\x74\x9e\xec\xf5\x7e\x77\xe8\xf1\x3a\x50\x5e\x73\xbe\x44\x73\xc5\xe1\x88\xf2\x01\x37\x34\xcd\xdd\x1c\xec\x29\x56\xe8\x50\x7b\xc1\x0b\x5f\x5d\x65\x85\xe6\x58\x93\x17\x32\x00\x90\x5e\x9e\x35\xe9\x3f\x4f\x1d\xbd\x6b\x7e\xe4\xc2\xc0\xc9\x4c\xe6\x1f\xf6\x65\xff\x32\x0e\x59\x8a\x7f\xe9\x21\x45\xff\x20\x84\x49\xea\x55\x85\xba\x70\x22\x85\xad\x0d\xad\xe7\x26\x4b\x9e\x15\xca\xb5\xe3\x04\xd8\x5d\x84\xd4\x2d\xcb\x2b\x68\x72\xa5\x7a\x40\x77\x27\xab\xaa\x5d\xd7\x57\xc4\x74\xeb\x73\x4e\xcc\x78\xee\x64\x85\xe4\xc6\x6b\x95\xf3\xbe\x83\xd0\xe3\xc2\x63\x84\x76\x18\xcd\xea\x11\xf0\xbe\xaf\x58\xdf\x34\x99\x5e\x91\xc4\x2a\x13\xa7\x50\x70\x07\x6c\x0b\xb0\x3d\x41\x51\x2a\x35\x2d\x7f\x87\x13\x2a\x30\xcd\x35\xd3\x00\xda\x2d\x4a\xe7\xeb\x38\xc6\x1b\x85\x34\xe4\xde\xe8\x4f\x58\xbc\x9a\x99\xae\xca\x43\x05\x3d\x7e\xe2\x9f\xd7\x17\xb4\xb4\x5c\x54\xda\xb5\x9c\xcb\x51\x3c\x40\x5a\x33\xa6\x16\x5f\x75\x49\x95\x2f\x79\x82\xc2\x61\xc5\xa1\xa9\x07\x0b\xf3\xbe\x1d\x77\x70\xc7\x71\xc2\xa0\x4c\xb0\x20\x8e\x1c\x22\x4c\x50\x77\x1f\x51\xdd\xcd\xf1\xa0\x7c\x7d\x67\x41\xfd\xd8\x1f\x3c\x87\xfb\x47\x3d\x4a\x8a\x14\x38\x06\x0b\x4c\x75\x9f\x81\x8b\x7d\x21\xee\x43\x1b\x46\xbf\x1a\xa5\xfa\x58\xf1\x1b\xfb\xf7\x50\xdc\xca\x50\xdd\xf5\xe6\xc0\xce\xe1\x98\x2c\x4a\xe1\x5f\xa1\xc0\x98\xf8\x3b\x9c\xea\xd9\xbd\x9c\xf0\xdc\x77\x4f\x31\x31\xaf\x01\x91\xa8\xe4\x9b\xf1\x0b\xba\x51\x25\x93\x99\xf0\x8e\xf3\x75\x7c\x06\x75\x2e\x74\x25\x86\x37\x97\x2a\x93\x16\x79\x7b\xb3\xb8\xc7\x9b\xcd\x19\x7d\x8b\x5f\xae\xe2\x36\x07\x9c\xe9\x89\x3b\xde\x42\xaa\xe2\x16\x52\xe0\x5b\x63\x99\x05\x79\x8d\x80\x32\xe5\xc8\x26\x90\x68\x8a\x47\x9b\x6a\x21\xaf\x21\x87\xe0\x96\x2e\x98\xcb\x2e\x0f\x92\xb0\xa4\x17\x7e\xe6\x23\x28\xd1\xbc\x0f\x1e\x66\x40\x81\x11\xd9\x65\x15\x14\x9b\xe3\xe7\x43\x46\xa0\x9a\x35\xef\x4d\x50\xde\x3b\x20\x89\xc8\xdf\xf3\x2c\x80\xa9\x01\x2d\xca\x92\xb1\x6b\x5a\x58\xf0\xbb\xdf\xc9\x39\x0c\x65\x28\x7d\x36\x80\x26\x60\x67\xad\xec\xd5\xf7\x99\xd2\x32\x92\x9a\x1c\xbe\x7f\xc0\x8a\x22\xe5\xd8\x1e\x72\x18\x08\xf6\xda\x46\x49\x80\x99\x52\xb8\xb6\xc1\xfd\x1c\x66\x36\x27\xe6\xaa\x0e\x9d\xb8\x1f\x21\xc2\x7f\x8c\x51\xad\x23\xcd\x8c\x7e\x80\x76\x51\x7e\xc2\x30\x43\x70\x56\xd5\xa3\x8a\x18\xf9\x0f\xe7\x44\xd6\x7f\x5b\x9e\x73\x6a\xff\xca\x73\x42\x7f\xe6\x39\x13\xdb\xb7\x51\x7c\x4b\x9e\x2c\x22\xfc\x91\xcf\x56\x53\x8b\xa4\xbc\x59\x10\x71\x10\xa9\x1f\xe3\xb2\xc4\x2f\x5f\xe2\x73\xaf\x21\x11\x6c\xdf\x0d\x09\xb0\xe1\x27\x6e\x67\xb3\x79\x6c\x75\x32\xaf\x8e\x79\x82\xcb\xee\x87\x9c\x41\x9d\x4b\xab\x5a\xaa\x92\xd3\x75\x02\x06\x74\x6c\xa9\x34\xc8\xe8\x43\xd1\x14\xd9\x7f\xfc\x3c\x4f\x88\xe8\x79\x5b\x8b\xcd\x3b\x14\x06\xf0\x9b\x8b\x5f\x4f\x90\x58\x94\xa1\x67\xd4\x45\x79\xbd\x8b\x4e\x0e\xf4\x3f\xa9\xa7\xe2\x2b\x9f\x20\x79\xbc\x92\xd0\x7d\x5a\x75\xfd\xad\x93\x3f\x4a\xd3\x39\x01\x96\x31\xe1\xa7\x69\xa7\x66\x7e\xf4\x03\x3a\x52\x48\xf5\x52\x00\x40\x2d\x11\xa6\x5e\xa0\x0c\xde\x25\x83\xe1\x44\x83\x0c\x97\x4c\xd3\xe2\x2b\x9b\xdd\xc9\x7c\x48\x79\xd7\x63\x6e\x52\x49\x44\x7d\x86\x86\x4b\x0b\xc8\x19\xb5\x33\x30\xed\x2a\xed\xaf\xd3\xb8\xdc\x31\xae\x02\xd6\x2b\x81\xfe\x72\x74\x2d\x7f\x27\x69\xd8\xb6\x30\x82\x78\x97\x13\x91\x25\x40\xaa\x6a\xba\x9d\x2c\x37\x44\x4f\x11\x93\xd1\xdf\x20\xd2\x48\x58\x3e\xe4\x09\x66\x47\x58\xd2\x23\x3d\x81\xed\x03\x83\x8b\xbe\x5c\x66\x82\x61\x77\x8c\xba\x7f\x07\xbc\x6b\x50\x89\xed\xa7\x3a\x25\xd8\x00\x01\x0a\xcf\x4b\x6e\xbd\x4d\x2d\x74\xe2\x4d\xd5\x3b\x05\x50\x4b\x54\x95\x70\x4a\xd6\xba\x0e\x27\xd4\x8d\x33\x2b\x67\x2b\x0c\xcd\x61\x99\x02\x50\x4a\x4f\xf2\x08\x7c\x0f\xf3\x6d\x27\xbc\x45\x0a\xc0\x49\x5c\x06\xab\xcc\x6d\xbe\xa1\x2a\xc9\x2b\x08\x1e\x9e\xc5\xb1\xb3\x77\xc8\x90\x8c\x92\xd0\x65\xb8\x74\xc8\xa1\x36\x03\xd9\x64\xb3\x15\x77\x1e\x76\x53\xeb\x8c\x6e\x9f\xe1\x09\x3c\x7c\x68\xdf\x88\xe0\xbc\xa2\xd0\xcb\x7c\xd3\xe6\x6b\x62\x4e\xf0\xab\x85\xe1\x9c\xf4\xbe\x55\xfd\xaa\x75\xc6\x04\x22\x76\x26\x5d\xf2\xec\xc1\x1e\xac\x38\x62\x7c\xc3\xe3\x8b\xde\x11\x06\x26\xdb\xac\x93\x00\x3a\xf0\x57\x14\x8c\x7e\x88\x3a\x8e\xea\x0a\xfa\x83\xcc\x0d\x4e\x79\x0c\x34\xe2\x54\xcd\xa2\x44\xac\x7e\x80\x1d\x77\x6a\x41\xec\xa8\x22\x34\x09\x0a\x9c\x76\x92\xca\x3e\x53\x30\xb2\x01\xf0\xbe\x40\x35\xb3\x01\x73\xde\x9b\x71\xe7\x78\x01\xd2\xcf\x7d\xa9\x33\x79\x85\xb1\x38\xb1\xb8\x6e\xf5\x70\x1d\x56\xf3\x98\x41\x5e\x62\xf0\xe0\x84\xb2\x5c\x94\x51\x22\x9a\xbf\x8f\xcb\xde\x88\x19\xa6\x44\xbd\xa2\x8a\x1b\xea\x9c\xf6\xee\x04\x30\xf9\xdc\x5b\xac\x07\xcb\x93\x4d\x15\xa9\x5f\xba\x85\xae\x1b\x87\xa0\xdc\x7e\xd1\x11\x78\x53\x74\x4f\xd1\x08\xb9\x93\x89\x5d\x24\x61\x05\x9b\xc4\x78\xbf\xc9\xb0\x86\xf9\xf0\x64\x91\x32\xac\x9d\xc6\xb1\xd2\x87\xa8\x08\xc1\xa8\xfb\x4b\x76\x95\xb7\xce\xde\x65\x99\x6c\xdb\xba\xc1\x5f\xdd\x05\xdc\xb6\x12\x02\xcb\x8b\x26\x0b\x54\xcf\x0e\xba\x66\x9c\x84\xc1\x3e\x2a\x8f\xe9\xd9\xdf\x73\xea\x1f\xf5\xbb\x6b\xfb\x2f\x8b\x21\x5b\xf3\xaf\x18\x72\x3c\x7e\x02\x24\x04\x0f\x08\xa6\x39\x9f\xc5\xe6\xef\x4a\xbf\x52\x19\xf2\xc4\x8a\xa5\xe6\x49\x9c\x91\xd3\x10\x45\x49\x08\xe1\xac\x1f\xa9\x64\x29\xe6\xc2\x30\xa6\x74\x29\xc6\xc6\x30\xd5\xb2\x59\x17\x10\x9a\x05\xb2\xb9\x31\xd0\x7c\x3f\x76\xbc\x69\xf0\x93\xc3\x1a\xa6\x33\xf7\xd4\x9f\x03\x57\xa8\x8c\xbc\xaa\x27\xa8\xa6\xc2\xef\xa8\x3d\xd9\x40\x4d\xd1\xeb\x9b\x16\xe5\x84\xf0\x45\x19\x5d\x33\xa9\x7f\xc3\x23\xca\x13\xa7\xfc\x32\x72\x9e\xe8\x73\x6c\xa8\x57\x4f\x21\xfa\x8d\x2d\x13\xc7\xf9\xa6\x3f\x60\xdb\x40\x3a\x7b\x87\x80\x2c\x02\xeb\x5f\xd9\x52\xf9\x17\x22\xa0\x77\x39\xec\xcc\xe9\x9d\xb0\x15\xe2\xa3\x6b\x9e\xb7\x94\xe3\x2f\xa0\xc7\xaa\x93\xec\xae\x8d\x2a\x9b\x1d\x9a\x4a\x48\x2d\xc2\x6b\x39\xa4\xe4\x98\xd4\x3c\x6b\x82\xe1\x73\x60\x2c\x1d\xdc\x0e\xec\x07\x63\x39\xb1\x68\xe2\xba\xbc\x37\xcc\x6e\x61\xfe\x28\x71\x2e\xed\x30\xf3\x26\x3d\xa7\x33\x4a\x2e\x1e\x46\xe2\x0d\x95\x17\x74\xd8\xa8\x29\x02\xe0\x7d\xc0\x78\xd7\x35\xa4\x28\xe5\xb9\xdc\x46\x0d\x1c\xd3\x47\x06\xad\x55\xb5\xc8\x7a\xde\xa3\x04\xfd\xc0\x84\xd9\x80\x06\xf2\x27\x79\x5d\x02\x19\xb9\x58\xdc\x8e\x3b\xca\xe5\x69\x71\x81\xa1\x8c\x99\x78\xd5\x6f\xa2\x57\x39\xad\x73\x9d\x34\x94\xfa\xed\x76\x61\x5d\x9b\x6a\xa1\x68\x1c\x09\xd7\xad\xab\xfb\xa4\x3d\xb2\x1b\x0a\x77\x0d\x1a\x5a\x34\x82\x6f\x60\xd4\xd4\xa4\x8c\x4b\x64\x52\xbf\x1b\xd8\x6d\x88\x27\x6c\xd9\x99\x92\xf3\x93\xcc\x86\x73\x3b\x23\x0d\x19\x98\x54\x9c\x10\xb3\x94\xcc\x57\xa8\xfc\x94\x41\x46\x35\xc4\x12\x42\xfc\x61\x85\x70\xdb\xc2\xfa\x39\xba\x0a\x9c\x14\x78\x46\x31\x0f\xf2\x84\x63\xca\xce\x69\xad\x51\x00\xfd\xc9\x2f\xb4\x10\x5d\xea\xe9\x1f\x82\x71\x80\x1c\xf0\x9f\x1d\xdc\x74\x5a\xab\xec\xb1\x6b\x11\xce\x60\xb9\x8d\x46\xda\x06\xd9\xbe\x03\x66\x96\x90\x94\xf1\xe4\x29\xdb\x72\x6b\xe5\xcf\xcd\x9b\x62\x15\xab\xad\x0c\xd6\x71\xbd\x9c\x08\x13\xdb\x89\xe9\x9e\x14\xdc\xef\x1d\x63\x97\x88\x33\xc0\x6d\xda\x05\x3c\xde\x04\xb4\xe4\x1d\xee\xb7\x49\x4c\x12\x95\x55\xbf\xa5\x8d\x46\x48\x01\x4f\x01\x4a\x48\x87\x4d\xcb\x8a\x26\xec\xa6\xea\x85\xee\x3e\x5e\x76\xec\xcd\xc1\x78\x33\x17\x4d\xc3\xd9\xaa\x26\x42\x11\x67\x9b\x54\x79\xce\x38\xde\x3b\x65\xb8\x7e\x68\x32\x8f\xf4\x58\x31\x8c\xc3\xa8\x6d\x27\x65\x07\x4f\x33\xd6\x3f\x5c\xf3\xb0\xce\xff\xb2\x9a\x87\xe9\xf8\xab\xe6\x81\x3e\xac\x3f\xe2\xd5\x38\xb6\x57\x88\x63\x82\x68\x52\x73\x0e\xc2\x1e\x96\x31\x4d\x5f\x04\x06\xad\x95\xa8\x5a\xe1\x89\x6c\xd3\xc1\xc6\x16\x7a\x5a\x80\x46\xa5\x26\xf8\x1e\x85\x64\x1d\x42\xef\xc7\x39\x42\x85\x83\x1c\xed\x17\x3d\xa6\x04\xf3\x03\x9d\x22\x56\x0f\x7f\xcf\x0c\x4f\xd0\xa2\xa4\xfe\xac\xbc\x29\x05\x56\x15\x80\xc0\xf0\x87\xcb\xfb\x04\xe5\x49\x83\xd0\xb5\x2e\xad\x4f\xa4\xa8\x11\x9b\x48\x1e\xae\x30\xd4\x5c\x68\xad\x4f\x47\x57\x8d\x25\xdb\xfa\x3b\x4e\xe0\x46\x37\x0a\x8f\xc9\x9a\x76\x9e\xbd\xe2\xc1\x75\x4a\x8d\x74\x7f\x4c\xba\x9e\x0b\x5c\x35\x6f\x88\xe1\x24\xe9\x22\x0e\xdb\xbb\xde\x4b\xe0\x35\x61\x89\x52\x3c\xa1\x2c\x59\xb6\x72\x6d\x3d\x8b\x1b\x63\xa1\x03\xcd\x9a\x79\xc4\x38\xd5\xde\x91\x64\x70\xc2\x13\xdb\x09\xd8\x72\x33\x76\x33\xd4\x82\xe2\x78\xb6\x53\xdc\xb6\x0d\x0d\x3a\x8f\x93\x32\xdc\x12\xa6\x90\x29\x03\x35\x1b\x0f\x3a\x1c\x67\x17\x8b\xba\xd4\x64\x21\xbf\xc6\x1f\x11\xbd\x99\x0b\x86\xc4\x69\x6b\xf6\x4b\xb2\x18\xef\x93\x63\xb0\x61\x46\xd0\xad\xc6\xa8\x22\x86\xcd\x07\xda\x11\xd6\x5a\x8a\xcc\x33\x88\xb3\x8b\x99\x0f\x96\xf9\xc4\x55\x4e\xe9\x49\x5c\x81\x0c\xcd\xa8\xba\x19\x71\x4f\x53\xb6\xa9\x9a\x35\xbc\x42\xf3\x69\x43\x6f\xca\x20\xbc\x87\xeb\x0d\xe5\xe6\x7b\xa2\x73\x48\x8a\xee\xe5\x4d\x41\xe9\x61\x67\x00\x47\x01\xbd\x76\x7d\x0e\x9f\xf2\x5a\x2a\x8a\xd3\x03\x9d\xb8\x50\xe5\x94\x2c\xa2\x4d\x6c\xbe\xde\xf1\x62\xa0\xfc\x52\xc2\xde\xc0\x03\x7b\xb1\x0a\xd9\xca\x29\x38\x5f\xae\xbb\xda\x2a\x6a\xd1\x67\xbd\x93\x66\x4d\xd1\x2b\x00\xbe\xe8\x15\x16\x0e\x95\x33\xbf\x5d\xda\x94\x8a\x8c\xc4\x04\xab\x92\xa5\xb7\x39\x7a\xfd\x6b\x9a\xfe\x86\x18\xe7\xb6\x01\x50\xaa\x1a\x4e\x91\xd7\xd5\x5c\x44\xa6\x11\x0c\x0b\x76\x53\x6d\x21\x59\xa7\x71\x3b\xf4\x35\x21\xbc\x98\xef\x92\x81\x58\xc7\x60\x1a\x11\xe5\x88\x75\xce\x4f\xb3\xa1\x11\x83\x66\x44\x1f\x2e\x3b\x8f\x6b\x89\x21\x07\x44\xe9\x5a\x10\xe3\x99\x59\x96\x5e\x8a\xf4\x59\x31\x63\xde\xe1\xa2\xac\x10\x18\x65\x29\xb8\x22\x9f\x9b\x29\x46\xac\x1f\xb2\x0c\x52\x02\xaf\x0f\x4a\x5d\xbd\x07\x1d\x12\x7a\x22\xf4\x2e\xe6\xc7\x1d\xe4\x48\xc1\xdd\x70\x12\xd2\x4f\x9b\x13\x21\xa0\xe8\x50\x1d\x3d\xd5\x9d\x5c\x88\xcf\x1e\xa0\x56\xe8\xfd\x4c\x1e\x6f\xc1\xe4\x31\x52\x6e\xc2\x40\x45\x76\x9c\x79\x3a\x69\xbb\x38\xcb\x5f\x6b\xb7\x2a\x65\x93\x48\xff\xe3\x2b\x25\x59\x08\x81\x97\x56\x20\xb5\x73\x64\xd0\xb4\x4d\xa6\x5a\x60\x1a\x9e\x4e\xc1\x41\x1e\x06\x61\x5a\x45\xf3\x3b\xb1\x2f\x3b\x8a\x37\x64\x1f\x86\x4e\x0d\x9f\x6a\xdf\x0e\x28\xfe\x9a\x76\xd5\x0c\x6a\x76\xc3\x10\xd1\x2f\x64\xa3\x2b\x5d\xb9\xbc\x9a\x61\x0c\x26\xcb\x8a\x79\x1c\x0b\x91\x9d\x92\x7f\xd6\xa7\xaf\xff\xb2\x58\x7a\x68\xff\x7e\x3d\xe0\x9f\x3e\xdd\xf6\x0d\xf2\xf5\xd2\x75\xfa\x7c\x9a\x37\xb3\x29\x62\x0e\xb1\xf6\x3a\xae\x6b\x7e\x00\xf3\x88\xf4\xa7\x1d\x17\xd8\x5e\x35\xc8\x0c\x1d\x20\x0a\x1d\xb1\x5c\x98\x72\x44\xb2\x2d\x75\x77\xc7\x06\xda\x12\x6c\x9b\x1f\xa8\xca\x34\xb9\xa8\x41\x1a\x1f\x7a\x40\x83\x59\xc1\x13\xa6\x2b\x77\x01\x10\x38\x4e\xe3\xdf\xf8\x8c\xbd\xa0\x7e\xa5\x8b\x9f\x35\x3e\xeb\xd3\x7e\xa5\x0f\xd1\x78\xd7\x51\xd2\x11\x9d\xf7\xad\x48\xf6\x0d\x5e\xca\xf4\xec\x16\xe0\xbd\x51\x49\x9c\xf9\x9e\xba\x1e\x39\xf4\x0c\xe3\x43\x2a\xe9\xa2\x05\xc2\x07\x7f\x2a\xc2\x07\x01\x41\x83\x28\x79\x89\xc9\x8f\x7f\xaa\x46\xa5\x03\x68\xe4\x00\x66\x51\x94\x50\x6a\x68\x4e\x07\x2e\xc5\xca\x6d\x8c\xd2\x78\x67\x26\x1f\x68\x8f\xba\x70\x56\x7f\xb3\xc0\x37\xa4\x26\x0d\x40\x07\x32\x05\xd6\x05\x06\xe8\x92\xec\x3e\xfd\x3c\xef\x39\x62\xa3\xce\xd0\x98\xac\x46\x0a\xd0\xfa\x1a\xd5\xea\x40\x05\x3a\x57\x75\x6e\xec\x86\xfc\x82\x62\xdd\x37\x92\x5c\x26\x4d\xd0\x1f\xeb\x82\xe1\xc8\x01\xb1\xc0\x23\xd9\xcb\xb7\xe9\x1b\x8f\x10\x0a\xb4\x26\x83\xfa\x8f\xe9\xec\xed\x28\xe9\xcc\x2c\x60\xd8\xc7\x29\x3a\xdc\x2c\x71\x7a\x77\x86\x79\xb1\x70\x47\x7c\x39\x07\x69\x27\xb3\x3f\xa6\xe2\x47\x77\x63\x1a\x89\x5d\xe9\xa1\xda\x89\x82\x45\x33\xbf\x5e\x66\xba\xeb\xc7\xf4\xe6\xc7\xfe\xb0\x1a\xbb\x6e\xa5\x29\x25\x1e\x4b\x02\x86\xdb\x53\x4e\xa0\x98\x23\x91\x22\x1f\xef\xb9\x5d\x72\x6e\xfc\x16\x12\xf5\xb3\xc1\xb5\xc7\xdd\x3b\xf1\x19\x38\x87\xc8\xca\x99\xea\x94\xb2\xa1\xbd\x29\x33\x03\x11\xc7\xe4\x8e\x06\xa3\x31\xd6\x91\x30\x1d\xc6\x42\x51\x49\x33\xa0\x7b\x77\xa2\x7a\x1c\x5a\xf8\xdc\xa4\x70\x0a\xa3\x7c\xdc\x3b\x7e\x70\xde\xed\xb9\xeb\xac\x41\x71\x6f\x2b\x86\x23\x13\x22\x3f\xf0\xe5\xc4\x7c\xb0\x4e\x0a\x40\x0e\xa1\x01\xf6\x8a\x31\x7d\x3d\x41\x8e\xfc\x92\x46\xec\xab\xc6\x4b\x08\x34\x7a\xbd\x5d\x7e\xe3\x7b\x4d\xe4\x00\x82\xba\xea\x84\x72\xc6\x3a\xd5\x9c\xf5\x99\x1f\x3b\x74\xb1\xd6\x65\xcc\xe4\x7f\xc5\xe5\xaa\x41\x48\x0b\xd4\xcf\x6a\x36\xf6\xde\xc6\x84\x62\xbc\x1d\x64\xb2\x32\x77\xf5\x9c\xe2\xbe\xca\xef\x43\x6e\xdc\xea\x83\x10\x4b\x16\x26\x0f\x9d\x7c\x2b\x2e\x17\x5d\x36\x59\xf4\x1f\x71\xb9\xa0\xdd\x79\xc2\x88\xb3\xa9\x9a\xb1\x3c\x04\xba\xc8\x3c\x58\xe9\x56\x3b\x48\xbd\x6b\x07\x00\x79\x82\x03\x48\xba\xa7\x08\xc1\xa5\x4e\x00\xd1\xe7\x59\x8b\x00\xab\x87\x64\xcb\x0c\x60\x0d\x98\xd5\x25\xe6\x25\x6a\x78\x32\xe4\x75\xc5\x25\x07\x2a\xb2\x73\x78\x8b\x3f\x6b\xc0\x5b\x33\x8c\x22\x64\x4a\x09\x4f\xc0\x75\x96\xff\xe4\x37\xd8\x75\x2f\xff\x5d\x3a\xbf\xfd\xbd\x16\x12\x36\x04\x48\x48\xea\xfc\x28\x35\x2d\x92\x8e\x45\x39\xdc\xa8\x51\x65\x66\xe5\x58\x01\x51\xa0\xe4\x5c\x3a\x2f\xcb\x2a\x5e\xad\x2c\xb5\xc5\xe0\xc4\x44\xfd\xda\xef\x9e\xc2\xbd\x8d\x5a\x18\xa8\x8a\x57\x25\x06\x10\x1a\x28\xf1\x7d\xd7\x35\x1a\x08\xd1\x34\x71\x59\x38\x36\xf7\xc7\x41\xd5\x3d\xb2\x26\x6d\xe0\x44\x35\x3a\x5e\xa8\x2e\xf2\xd1\x74\xc6\xf1\x1d\x26\x51\xf0\x94\x0c\x08\xf2\xc3\xf1\x4e\xeb\x4f\xfd\x0e\x9e\x46\x3a\xcd\xc2\x97\xf3\x72\x24\xc7\x96\x0b\x87\x37\x51\x0a\xba\x46\xde\xfe\x11\x78\x5d\xea\x3d\x66\x65\x18\xdc\xd1\xbb\x78\x00\xef\xd1\x98\xe4\x42\xde\x8b\x64\xfd\xb6\xe6\xba\x56\x9d\xcd\x44\xea\x8a\x7a\xd8\x0c\x98\x5b\xf2\x43\xd3\x35\xd0\xa9\xc6\xaf\x00\xfc\xb2\x00\x88\x5f\xcf\x39\xfd\x4d\x11\xe3\x8f\x6e\x9f\x49\xd2\x87\xc5\x23\x7f\x40\xf2\x5c\xe1\xfc\xfb\xa4\x6f\x6c\x62\x9b\xb7\xbe\x20\xb5\x7d\x6c\x42\xf9\x03\xd4\x46\xe5\x94\xe9\x25\xe8\xe3\x44\x90\xd3\x14\xbc\xad\x46\x72\xd2\x0e\xf3\xd3\x42\x52\xf0\x56\xcf\x01\xd1\x02\x00\xdf\xb3\x3c\xad\xd0\x8f\xc2\x60\xa0\x52\x81\x04\xfb\xb7\x62\x80\x7c\xcc\xb5\x84\xef\x43\x17\x54\x05\x2f\xdd\x8e\x80\x18\x3d\x73\x77\x52\x34\x8a\xa1\xc9\x7f\xc0\xa1\xbc\xdc\x32\xa8\xad\xad\x25\x5e\x4c\x4a\xe5\x87\x28\x10\xdc\x5a\x6a\x39\x27\xf4\x4f\x05\xc9\xe0\xb6\x25\x5f\xe8\xb6\xfe\xc8\x27\xf5\xb8\x31\x23\x79\x48\xca\x03\xb1\x28\x43\x5b\x3c\x58\xac\xe4\xb6\x4b\xc5\x5a\x91\xb8\x03\x0f\x98\xfa\x8d\x62\x53\xf0\x37\xb1\x00\x6f\xd9\x45\xa1\x7b\x5b\xec\xcc\xad\x3a\xb4\x58\x8c\x31\x99\x42\xab\xa7\x4a\xe3\x55\xcb\x73\x4b\x5e\x54\x08\xee\x32\x83\x06\xcd\x2f\xec\x30\xfb\x4a\x69\x3a\x26\x63\xcc\x16\x66\x2b\xa1\xb4\x2a\x62\x5c\xdc\x73\x39\x32\x88\x75\x48\x05\x66\x30\xcf\x34\x22\xe4\x8a\x31\xca\x39\x46\x9e\x92\xd1\x4e\x98\x95\x5d\xe2\x2d\xea\xd3\x6e\xac\xda\x5d\x5a\xd3\xe2\x59\x89\x0e\x74\x93\xdd\x84\x5a\x8e\x7c\xb6\x6d\xe4\x86\xdf\x8a\x99\x60\x22\x82\xc8\x99\x2e\x7b\x7c\xea\x0c\x6c\x44\x22\x16\x5d\xb0\x89\x28\x5c\x1d\xab\x04\xae\x23\x93\x19\x69\x98\xd0\xc9\x77\x7b\x10\xc1\x48\x9a\x16\x99\x34\x4e\xe5\x86\xf1\x37\xb7\x55\xfe\x02\x7f\xe6\x91\x9e\x11\xd9\x06\x9b\xa4\xdc\xa4\x61\x6e\x5e\xe0\x21\xca\x64\xee\x9a\xb0\x7a\xa5\x70\x1f\xf8\x28\xb5\xb5\x53\x32\x83\xc3\x0a\xcb\x99\xa3\xa6\xf9\xe3\xd5\x9a\x51\x2a\xf6\x74\x7f\xc5\x2f\xc1\x1f\xc9\x41\x5c\x51\x65\xfa\x11\x82\x14\xca\xe6\x8a\x41\x0d\x38\x96\xde\xe0\xc0\x65\xe7\x01\xa5\x62\x41\x15\xce\x01\x83\x8f\x49\xba\x53\xa6\x26\x88\x1d\x0e\xad\x16\x19\xaa\xed\x5e\x82\x39\x59\xc5\x47\x96\xb1\x4e\x53\xba\x67\x30\x51\xf9\x0b\x1d\xcd\x46\x3b\xc7\x05\x71\x89\xd7\x8c\x33\x99\x04\xb4\x05\xea\x07\x35\xe4\xad\x85\x77\x23\xab\xbf\x43\xd6\xcf\x8e\x6b\x20\x91\x19\xa0\x53\x2c\xf5\xad\x58\xa5\x04\x77\x84\x38\xf7\x39\xb0\x27\x27\x25\x0b\xfb\x02\xa6\xf8\xe7\xac\x83\x83\x55\xc1\xab\x68\x9a\x1d\x40\xbb\x3e\xfc\x40\xc8\x4b\x18\x76\x57\x65\x3b\x38\x4e\xd0\x4a\xee\x7f\x38\x26\xf9\xb7\xdd\x46\x1c\xfe\x65\x7a\x86\xe3\x12\xa6\x3f\xe8\x86\xfd\xf9\x81\x38\x35\xaa\x86\x04\x5b\xec\x88\x12\xba\x32\x84\xc5\xea\x3f\xe7\xc9\x26\xb5\xc8\x92\xfb\x3c\x51\x7e\x85\x46\xba\x8b\xf5\x2b\x3c\xdc\x93\x5f\x9b\x03\x55\x95\x24\xf3\x43\x2f\x7b\x0e\x57\xde\xd5\x0d\x79\x04\x95\x95\x9b\x78\xea\xea\x2a\x37\x5a\x81\x8b\x3f\x2d\x9d\x2a\xa0\xaa\xfe\xa0\x1c\x30\xd1\x22\x00\xc2\xcd\x48\x91\x23\xe1\xfd\xca\x23\x8c\x80\xe0\x65\x23\xe0\x67\x39\x99\x88\x9d\x3c\x29\x45\x26\x41\x57\xa0\xbe\x34\xb5\x39\x91\x43\xb0\xdb\xac\x98\xc5\xc9\x2d\x1b\x95\x06\x59\xe3\xea\x08\x2a\xb3\xca\xaa\x7f\xbe\xc3\xa7\xd1\x54\x29\xd0\x94\x05\xe5\xba\x01\x06\x66\xf3\xc3\x2e\x14\xe1\x7b\xb8\xbe\x3d\xc7\x3d\xe8\xd2\xdb\xeb\x29\x2d\x8c\x0c\xfa\x29\x17\x6d\xf1\xd9\x96\xfc\xec\xf0\x39\xed\x59\x87\xb9\x13\xce\x84\x5c\x3d\xc9\xfa\x52\xd2\x40\x59\xb0\x7c\xab\xc2\xc4\xfd\x8a\xf7\x02\xa9\x02\xf5\xec\x64\xbd\x05\xee\x00\xcb\xe9\xc4\x2c\x13\x15\x4a\xcc\x7f\x27\x05\x68\x9d\x02\x4e\xb7\x45\x00\x44\xe0\x74\x74\x7e\x9f\xe5\xf1\x1e\x34\x63\x2f\x54\xbf\x19\xb1\x4a\xb5\x3a\xba\x7e\x52\xbd\xb2\xcd\x56\x7a\x88\xd4\x71\x5d\x71\x93\xb1\xb0\x4f\x33\xc9\xbb\xa0\x84\x28\x9c\x42\xd5\xd7\x5f\x06\xa5\xcd\xa9\x44\x55\xb3\xf1\xdd\x4d\x8e\x09\xcb\xa6\x21\xf1\x74\xd2\x40\xf3\x0e\xaf\x7f\x1a\x9e\x0b\xaf\x88\xc9\x1d\x1d\xea\xc6\xbe\x24\x0a\xa9\x12\xc2\x8e\xdb\x7d\x25\xf7\xb3\x35\xe2\x67\xbe\xc9\x59\xa6\x4a\xac\x30\x7c\xf9\xb3\x8e\x0e\xa3\x29\x0d\x3f\xb1\x72\x35\xf0\x7e\xa3\x00\x9b\xa6\x6d\x9a\x7e\x99\xcc\xda\x4c\x42\xf3\x6e\xa7\xbe\xc3\xdc\x22\xce\x48\x82\x15\x4a\xa5\xab\xeb\xd0\x2f\x9c\x3e\x44\x73\xe0\x29\x22\xaa\x3e\x8a\xa7\x04\x3b\xd7\x33\xcb\xd3\x46\xa6\xaa\xb3\x8a\xba\xa3\x49\x15\xf7\x20\x44\x2d\x49\x3a\x58\x5a\x42\xe0\xf2\x38\x0a\x60\x3e\x18\x53\x82\x43\x58\x12\x94\x18\x24\x07\x1b\xa2\x7a\xde\x1b\x11\x5d\x68\x4f\x7a\x17\x0b\x60\x6a\x24\x0e\x17\x00\x6d\xac\xa1\x2d\x7c\x2c\x5b\x69\x9a\xd0\x2e\x58\xf9\xab\x1d\xdb\xc1\x3b\xc4\x10\xf3\x77\x91\x95\xbc\x87\xf8\xec\xef\x5d\xb1\x39\x46\xe4\x27\xee\x77\x55\x23\x72\x7e\x4e\x15\x26\xad\x26\xc2\x5f\xf1\xc4\x30\xa6\xae\x98\x71\x8b\xc3\xc6\xef\x30\xa3\xe3\x62\xe9\xa2\x01\x5a\x87\x61\x8f\xa8\xd7\x74\xa4\x97\x41\x1f\x95\x1a\xb6\x48\xf8\x58\x10\x88\xa9\xe0\x0d\xc2\x1b\x33\x95\x91\x8c\x68\xe8\x2e\x9d\xe5\x70\x2c\x6d\xe6\x2e\xcd\x78\xd9\x53\xb0\x9f\xe9\x6d\x33\x09\x1e\xf0\xd5\x0c\x92\x6a\xdf\x69\x5c\xd7\x5e\xc5\xf5\x03\xd2\x05\xd1\x47\x03\xb3\xe7\x3b\x26\x55\x11\x55\x4d\x09\x12\xc3\x8d\x41\x07\x6e\x4b\x67\x15\xe8\x3f\x6c\x06\xb6\x7f\x59\xd4\x31\xff\xcd\x0c\x50\xc7\x09\x41\x4c\x60\x07\xf8\xbe\x62\xb0\x39\x7c\xee\xb3\xd6\x5e\xba\x75\x50\xa8\x28\xce\x26\x08\x6a\x90\x26\xb1\xc0\x5d\xf9\xcd\x45\x4f\xb2\x9f\x2c\x0f\x30\x6c\x20\xfe\xf8\x1f\x37\x47\xac\x23\xa8\xa5\x12\x75\x0d\xeb\xfd\x88\x75\x73\x55\xb8\xca\xdb\xe7\x27\xd0\x06\x99\xa5\x93\xf7\x73\xb0\x05\x87\xf0\x5a\x36\xe6\xd8\xb6\xed\xa8\x94\xba\x4c\x51\x92\xdf\x43\xd1\x92\xb6\x9a\x7c\xf9\x4c\xf1\x10\xa0\x99\xb0\x70\xbb\x0f\x7c\x54\x04\x7b\x13\x02\x03\x3d\xb7\xaa\xc5\xe1\xf8\x57\x56\xfd\x7a\xc0\x8f\xc9\x28\x9f\x55\x00\x2a\xd6\xfa\x8c\xa9\xc9\x39\x66\x4a\x6a\x54\x8c\x49\x0f\x45\x4c\x10\xf9\x43\xeb\x85\x0f\xdd\xa2\x79\x0f\xa0\x70\xe5\xc2\x83\x14\xc6\x6d\x01\x1e\xa4\x24\xc8\x5e\xa7\xb0\x23\xf7\xa9\x84\x4a\x7d\x07\x18\xa5\xbf\xfd\x50\xe8\x18\x53\x48\x12\xe7\xe6\xe4\x51\x48\x5f\xb5\x51\x1c\xad\x5e\x62\x0a\x6b\xe8\xd3\x4e\xa1\x42\x4e\xb1\x24\x9a\x04\x7a\x3e\xcf\x3a\x80\x6e\x86\xe5\x3c\x4f\x99\x8c\x3d\x12\x9a\xcd\x3b\x97\x8d\x01\x51\x1a\xdc\xef\x54\xf4\x23\xfd\x25\x2f\x67\x21\x4b\x7e\xae\xed\x2b\x8a\x9c\x8c\x92\x4e\x2b\x44\x95\x44\x57\xe3\xe9\xfd\xf8\x4f\x42\x40\xae\x4d\xd1\xf5\xce\xe5\xd2\x41\x08\x92\xd5\xd4\x25\x39\x7b\xd2\x13\x11\xc3\x69\x3b\x91\xd2\x4f\x5e\x03\xa5\x1a\xe2\x35\x9f\xd5\x14\xf3\x83\x95\xdc\xcf\x05\xe3\x0b\x60\xc6\xe4\x23\x52\x67\x6a\x41\x71\x34\xa5\x61\x77\x56\x1c\x99\x87\xd0\x13\xeb\x23\x0c\xa6\xb8\x16\x9e\x3b\x98\x50\x92\x6c\x6d\x64\x3a\xe5\x04\x45\x1c\x17\x51\x54\xe4\x19\x22\xa2\x51\xc1\x62\x2c\x23\x33\xac\x91\xcc\x3b\xcd\xbe\xdd\x83\xa7\xc4\xa5\x3a\x7a\x7c\x4f\xec\xda\xe7\x8f\xa7\x1f\xe1\x1a\x0d\xf2\x05\xef\x07\xa7\xab\x1c\x8c\xe1\xbc\x80\x47\x3a\x01\x8b\xf9\x95\x29\xf3\xa0\x8b\x68\x9e\x0c\xf6\xce\xa4\x23\x73\x48\x9b\x27\xeb\xef\xbc\x84\x74\xe9\x3b\xd0\xa1\x62\x54\x3b\x28\x60\x13\xf7\xc2\x4a\x30\x7d\x88\x59\x10\x56\x0b\x09\xe7\xbb\xc7\xb4\x72\x59\x4f\x63\x92\xb6\x42\xb3\x44\x2e\xd2\x68\x26\x47\x58\xa8\xfb\xd7\x7e\xd7\x42\xa3\x75\x47\xca\xa8\x8d\xbb\x22\xba\xa7\x01\xe3\xca\xb2\xdd\xb1\xe4\xcc\x6d\xa5\xa8\x6c\x77\x53\x77\xa9\xf6\x5e\xca\x24\xaa\x09\x16\x3b\x92\x9e\xef\x3d\x6b\xb9\xdc\x6d\x43\x91\x9f\x97\x6c\xe0\xf8\x1e\x37\xc6\x90\xe4\x02\x87\x88\xe0\x76\xcc\xf1\x25\xf8\x30\x04\xbf\xdf\x2e\x03\xa8\x23\x22\x5a\x42\x91\xcc\xcf\x3f\x9c\xd3\x21\x66\xa6\xc6\x1e\x42\xe4\x42\x98\x87\x20\x18\xb8\x92\xea\xb7\xb3\x06\x72\x31\xd8\x0b\xbb\x13\xc2\x93\xa0\x9b\x15\xa0\x9f\x2a\x37\x56\x82\x84\xf1\x2b\x24\xc6\xae\xe9\xf6\x30\xa1\xa9\x53\x5b\x52\x7f\xcf\xe5\xbd\x7e\xd4\xcf\xa9\x6c\xba\x0b\xd5\xe2\xe7\x69\x8d\x0a\xf8\x3f\xb1\x78\x93\x2a\x8f\x7d\x1b\x74\xc5\x86\x11\x9d\x25\x9f\x14\x8b\x7d\xf2\xfd\x9f\x8c\x58\x7e\xd9\xef\x5f\x66\x2f\xd6\xbf\xd3\x86\xff\xea\xde\x22\x28\xab\x79\xc7\x34\xee\xa0\x36\x65\x38\x27\x80\x75\x41\xd3\x38\xa3\xc8\x0e\xb2\xf7\xdd\xd9\xd9\xe3\x67\x77\x8e\x0b\x13\x40\xcc\x20\x31\x1b\xee\x7e\x5d\x90\x99\xdc\x0d\x8b\xcd\xb3\xf6\x9c\xea\x68\x1a\x13\x10\x10\x30\x51\x93\x3a\xff\x26\x6f\x1c\xb1\x98\xf3\x0b\x0a\xa0\x71\xfa\xfb\xd0\x8a\xa2\x24\xab\x28\xa8\x6c\xa3\xab\x8b\x6b\x2d\x79\x04\xc7\xcb\x58\xce\xfc\x8a\x62\xf0\xc3\x00\xf6\xf6\xc7\xfc\xba\xc9\x3c\x2e\x1b\x2a\x27\x5b\x42\x17\xe0\x46\x8a\x00\x8b\xa2\x38\xd7\x38\xb0\xd8\x1f\x5d\x02\xfc\x25\x4f\x51\xe1\xf1\x85\xf6\xa3\x2c\xc3\x74\x6d\x0f\xec\x09\x34\xd1\x8b\x4f\x63\x21\xe6\x68\x34\x83\xe7\x54\x69\x96\x60\xa8\x22\xce\x91\x0f\x27\xe6\x07\x43\x97\x6e\xdc\x8b\x4b\xa2\x49\x9d\xef\x32\xa3\x2d\x05\x21\x9c\x69\x01\x6d\xa1\xe1\x6d\x3a\x24\xc6\x50\xbc\xc3\x28\xe9\xb3\x31\x27\xd3\xb2\xb6\x62\x88\xc9\xea\x84\x4c\xc8\x62\x9c\xed\xa5\xbd\xf0\x5d\xf0\x5d\xc9\xf8\x91\xf3\x8e\x09\xa8\x0e\xc2\xe4\x27\x46\x51\xd3\xfc\x29\x39\xc3\x30\xe8\x02\x86\x1a\x62\xdf\xbc\xba\x90\x3f\x5c\x7c\xc9\xd4\x3d\xaf\x0e\xb3\x45\x8f\x00\x36\x25\x2e\xc3\x84\xa7\xd4\x86\x60\x83\xe2\xb4\x78\x8a\x5d\x3e\x4f\x1f\xdd\xe8\xed\x8a\x26\xd4\x06\xdf\x70\xa2\x3b\x18\x45\x11\xb2\x96\x0a\x17\x15\x7b\xc0\x49\x96\x27\x25\xc8\xeb\xde\xfb\xed\x79\x2a\xe7\xf8\x57\xde\xad\xa1\xaa\x2a\x17\xf5\x82\x47\x18\x5c\x6b\x0a\x08\xb6\x76\x12\x51\x35\xe4\xba\x8d\xe2\x90\xaa\xea\x21\xf8\xe5\x30\x1a\xda\x86\xbf\xff\x0a\xdf\xf1\xbe\x27\x05\x81\x19\x92\x42\x86\x10\xa4\xdc\x93\xca\x46\xa2\xaf\x05\xc6\xeb\x06\x99\xc5\x26\xb7\xa8\x81\x84\x3c\xb7\x2c\x81\x29\x6b\x79\x9f\x82\xaf\xe0\xf1\x53\x77\x54\x59\xd7\xd8\xfb\x8d\xa2\x39\x48\x88\xb9\xcb\xab\x49\x5f\x61\x53\x18\x25\x92\x34\x50\x85\x4e\x20\xf5\x46\x45\x4a\x13\x82\xd9\xf4\x14\xa0\x72\x50\xda\x47\x20\xb5\xc2\xf1\x35\xd8\x09\x7a\xa0\xb8\x19\xe1\xfd\xd9\x29\xa0\xbc\xe5\xe7\x2e\x6f\xd6\x02\x93\xfe\x22\xdd\x9e\x47\xec\x5d\x09\x9e\x2a\xcc\x2c\xbd\x01\xb0\x6b\xd0\x41\x4e\x4b\x8e\x15\x0d\x0c\xdb\x50\x72\xef\xfe\x90\x92\x4e\x5a\xa8\xf5\x47\x76\x74\xf7\x7a\x06\x78\xec\x6a\x20\xf6\x0a\x38\xfa\x97\x6e\x02\x17\xa8\xe7\x40\xfa\xdf\x0f\xfe\xb2\x96\x4b\x46\x96\x90\x55\xc6\x15\xec\xbb\xce\x73\x83\xfd\x74\xf6\xdb\xf3\x40\x0b\x15\x68\x63\x1b\x67\x28\x00\xef\x69\xa2\x20\xc9\x14\x66\xb3\x56\xed\xd6\x62\x95\xc8\x1b\x69\xcc\x32\x3e\x04\x93\x4b\xce\x44\xf3\x77\xf0\xbb\xe6\xd7\xa1\xf7\x53\xab\x4d\x69\xc0\xdc\x35\xef\xbe\x18\x45\x85\xd1\x2b\x1b\xdd\xb3\x37\x6f\x4f\xca\xe3\xb0\x90\x95\xef\xb9\x65\xe3\x58\xd1\x96\x22\x71\x63\x9e\x76\x3e\xb6\xc3\xe2\xa6\x68\xa7\xa1\xa4\x01\x1d\xe0\x7c\x86\x31\xb6\xfb\x05\xd2\x6f\x3c\xd9\xe6\x1f\xcd\x6e\xfe\xf2\x7f\x97\xd9\xe8\xfe\xff\x89\x8e\x4d\xf8\x33\xda\x18\x85\x00\x9c\xb2\x06\xaf\x91\x57\x6d\x63\xfd\x7e\x94\x03\x1a\xba\x6d\x0f\x85\xf8\xec\x6d\x80\xa1\x11\xbc\x38\x61\xbb\xa8\xd0\xe8\x88\xc3\x23\x39\x55\x4e\x24\xb5\xc3\x4f\x20\xf3\x17\x3a\xca\xea\x86\x5a\x15\xfb\x83\x51\x58\xb4\x48\x01\x74\x1a\x2e\x8b\xaa\xe2\x43\x31\xe5\x53\x6d\x55\x24\x8a\xd6\x16\x9c\xe4\xbc\x12\x79\x14\x00\x36\x70\xf9\x16\x61\x4c\x46\xe0\xf3\x5a\xe8\x55\xee\x67\xa8\x6d\xd7\x2c\x90\x72\x8a\xa0\x10\x49\xa1\xbf\xf1\x5d\xc8\x3c\x64\xbb\xc2\x93\xde\xba\xdf\xc3\x7b\xf9\x96\x29\xcc\x15\xbb\x02\x0b\x40\x9c\x76\x5b\xae\x17\x57\x53\x4b\x58\xf6\xc9\x36\x96\xd9\xb4\x0f\x73\x06\xcb\x18\x18\x33\x67\x9e\xce\x39\x24\x74\xa9\xe6\x3e\x1f\xbb\xc3\xbd\x07\xa5\xb9\x15\x30\xa0\x38\xb0\xa1\xac\x6d\x6d\xb8\xd7\xdb\x88\x94\x45\x1e\xfb\xbe\x0a\xcd\x69\x54\xd1\x8f\x38\x79\xdf\x50\x1b\x5d\x0a\xc4\x5b\x31\x9f\x2f\x8b\x6e\x8e\xf1\x27\x79\xbd\x25\x02\xd6\x1a\x0f\xc9\xd5\x45\xef\x42\x4d\x9c\x87\xb9\x44\xbe\x59\xd8\x4a\x11\xd7\x84\x5e\x58\xcd\x61\xfc\xcf\xae\x6f\xec\x9c\x7b\x38\x36\x09\xf5\x62\x33\xe7\xe8\xb9\xf6\x0b\x62\x0d\x43\xf7\x30\xc0\x6e\x53\x54\x19\x0c\xf5\x2f\x90\x25\xd1\xaa\x74\x6e\x7f\xaa\x95\x96\xe9\xb9\x50\x27\x82\xd2\x66\x7a\x58\x09\x45\x4f\x6b\xb9\x92\x29\x18\x85\xfe\xcd\x3d\xdb\x31\xfd\xc1\x26\xc2\x89\x4a\x42\xd5\xc2\xbb\xa6\x42\x49\xec\x12\xd4\x1e\x2a\x67\xff\x29\xed\x77\x27\x14\x2f\xb0\x72\xba\x75\xba\xab\x0d\x5d\xe1\xf0\xf5\xc5\xb0\x4f\xd6\x39\x7e\x81\x25\x20\x47\xe0\x2b\x67\xc5\x77\xd1\x17\xd3\x78\xa9\x8d\x7c\x8c\x77\x87\x55\x6b\xd2\xd5\x9d\x13\x35\xd3\xa2\xa7\xb7\x1d\x11\xb2\x23\x41\xa4\xde\x14\x56\xa3\x59\x50\xd0\x8c\x8c\x66\xf9\x07\x28\x00\x10\x5d\xdf\x4c\x17\x44\x01\xe9\x30\x02\xfd\x04\x1a\xda\xe7\xd7\x32\xed\xdd\xbe\xa6\xa1\x6c\x84\x02\xef\xa5\xa5\xbc\xd0\x3f\x2e\x05\xb1\x50\x31\x34\xe6\x84\x62\xa9\x5f\x03\xb2\x44\x3c\xaa\x1d\xa0\x95\x13\x74\x59\xf8\x7e\xbd\x36\x73\x8e\x95\xa8\x0b\x0f\xf0\xcf\x09\xbb\x6f\x77\x07\x13\xae\x67\x06\xbf\xd0\xa6\x78\x20\xc5\xc6\xeb\x57\x82\x2d\x8e\xb8\x82\xce\x5a\xfb\xa0\xf1\x9b\x14\x5c\x1c\xa2\x2a\x3f\x00\x73\x8d\x8e\x05\xea\x11\x67\x72\x06\xab\x4f\xe9\x76\xbd\xdb\xad\x8f\xd3\xcf\x00\x01\x52\x0f\x80\xa2\x20\x47\xf7\xd7\xc7\x2d\x05\x8e\xa1\xee\x6a\xf8\x72\xe9\x51\xdc\x8c\xd6\xde\x59\x4f\x79\x50\x20\xe3\x24\xcc\x77\x51\x5b\x3e\x9d\xc4\xd5\x08\xff\xac\x3a\x1f\xff\xb2\x02\xa5\x0a\xff\x4b\x9f\x21\xd8\xfe\x33\x71\x39\xa7\x53\x89\x8b\xde\xd5\xe8\x89\x78\xde\xd1\x41\x0b\x8d\xfc\x0a\xd9\xf2\x10\x54\xc5\xab\xd5\x25\x5f\xb7\x0a\xb6\xbe\x2d\x5f\xb0\x09\x3a\x4d\x8a\x98\x1c\xd6\xa0\x43\xc0\x38\x9a\xa8\x49\x6d\x1f\x6a\x9b\xfb\xbb\xf2\xd9\x1d\xe7\xf6\x40\x08\x44\x94\xeb\x17\x78\x29\x8a\x24\x6d\xdb\xa0\x3e\x12\x5e\x39\x4e\x6b\x31\xf0\x8f\xdd\xfa\xa9\x75\x2c\x7c\x08\x11\xf6\x35\x32\xcd\xbb\x89\xff\x6c\x4d\x8b\xf2\x70\x7d\x48\xa0\xd2\xf0\xf8\x44\x86\xd7\x38\x4c\xbf\xc4\x4b\xca\x28\xdb\x4e\xa5\x59\xcb\x22\xb3\x43\x54\xe8\xac\x7f\xe1\xe0\x65\x36\xcf\x56\x5c\xc3\x25\xd2\x69\x31\xab\xd6\x94\x0d\x83\x25\xeb\x18\x0c\xa2\x4b\xd0\x44\x23\x4f\x34\x81\xe2\x6b\x67\x66\xda\xdb\x9d\x26\x75\xc8\x1f\xc2\x20\x3c\x1c\x88\x26\x0d\x11\xae\x73\x45\x0a\xfa\x0d\x06\x64\x9e\x35\x06\x8a\xc3\xc2\xeb\xa4\x98\xa9\xe0\x01\xcf\x2b\x1b\xee\x00\xcc\x15\xb9\x78\x9b\xed\xf7\x66\x41\x46\x0b\x3f\x0d\xc5\xdc\x5e\x36\x93\xb1\x09\x35\x4e\xc6\xa1\x9b\x14\x58\x76\x69\x72\x3f\x03\x99\xd0\xc0\xbd\x86\x2d\x67\xa8\x29\x10\xc6\xe0\x7b\x7b\xcf\x45\xfb\x43\x9e\xb7\xa2\xb3\xfd\xae\x3c\x62\x06\x4c\x3f\x97\x28\x96\xe3\xea\xe0\xd0\xfb\xba\x46\xa2\x25\x9c\xc3\x95\x91\x89\x8f\x68\x8d\xe0\x50\x05\x54\x78\x87\xa4\x5e\x45\xec\x0a\x3a\x1d\x75\x4c\x8f\x14\x8d\xca\x63\x1c\x97\x95\x23\xf4\x07\xcb\x1b\x0d\xb3\x40\xb8\xb0\x8e\xdb\x77\x18\x20\x3c\xe2\x7e\x7d\x84\xfc\x91\xfd\x44\x26\x37\x6e\xc9\x34\xc2\x14\xaa\x16\xd1\x12\xe6\x2d\x72\xfb\xb5\x2f\x38\xc6\x39\x4b\x53\xce\x34\x21\x0b\x17\x9b\x78\x94\xdd\x7b\x88\xf8\x0c\x27\x2c\x6a\xbc\xdd\xbe\x66\xed\x39\xca\x1e\x2e\x72\x16\x53\xfa\x30\xe6\x6a\xb3\x94\x1a\xb4\xaf\x3d\xcb\x11\x9f\xf1\x6b\xad\xc2\x55\x2a\x32\xfa\xa7\xaa\x98\xa1\x59\xb8\x21\x1c\x17\xe6\x7b\x31\x4b\x86\x60\xfe\xa3\x3a\x47\x37\x3e\x20\x1b\x27\x37\x8d\xf2\x6b\x59\xf0\x8d\xde\xdc\xf1\xb9\xab\x9b\x6b\xaa\x38\xaf\xd0\xed\x17\x5a\x78\x3a\x04\x3c\x48\xf7\xaa\xe4\xea\x76\x66\x4d\x04\x67\x75\x34\xe2\x07\x30\x9f\x3f\x49\x45\x9f\x93\xcb\x43\xfc\xef\x77\xa8\x16\x10\xdf\x8a\xc1\xb0\xd1\x4a\xcf\x1e\x20\x36\xd9\xf2\x4f\x52\xf0\x3d\xdb\xff\x65\xd5\xef\xaf\xba\x86\x62\x0b\x45\x02\x6c\x58\x93\x79\xe5\x1e\xde\xfe\x67\x3c\x8e\xe5\xf1\x7f\x2a\x8e\x19\xfe\x06\x2b\x99\x6d\x13\xe4\x18\x4b\x8e\xed\xd2\xa8\x5c\xf3\x1e\xea\x48\xf2\x04\x95\x8e\x5d\x53\x1e\xea\xc2\x2f\x34\x0d\x01\xbe\x1d\x24\x5c\xb2\xa0\x25\x8a\x29\xf4\xab\x01\x0f\x12\x74\xfd\x25\xdf\x38\x28\x3d\x05\x28\xfc\x83\x59\x73\x7b\x14\x12\x3c\x96\x92\xd0\x54\x12\xbc\xe7\xb3\x41\x54\x3c\xd4\x25\x91\x7b\x25\x53\x40\xfc\xf1\x77\x1e\x85\x50\xe2\x51\x9d\x22\x37\x44\x25\xc1\x77\x29\xed\xb4\x32\x88\x43\x8e\xa8\xa3\x22\xb6\x66\xc0\xb1\x7c\x8e\xaa\xa3\xc2\x07\xa7\xf1\xc2\xbd\xc1\x0b\x8f\xc2\x27\x88\xde\x0b\x90\xe9\x27\x88\xe1\xdd\x8d\xd1\x33\x8f\xd1\x51\xf7\x1f\x8f\xd9\x41\x8f\xc9\x2f\xb0\xd9\x2f\xaf\xf9\x32\x8d\xc2\xfd\xd7\xd3\x63\x8d\x2d\xab\x43\xda\xaf\x9e\x2b\x24\xff\x3d\x9f\x62\x72\x27\xdb\x53\x97\x52\x76\x6f\xab\xa3\xae\x12\x2d\x51\x7d\x2e\x3e\x7d\xa2\xdf\xf4\xa5\x1e\xcb\x1f\x70\xfd\x63\x5e\xfd\x53\x5e\x3d\x56\x87\xb4\x83\xbf\x2a\xc2\xa1\x24\x6e\x8e\x7c\x36\xfa\xbf\xe1\x0a\x69\x6c\xfe\xe1\xc8\xee\x52\x1a\xaf\xbc\x63\xdf\x54\x4a\x88\x24\x52\xaf\x32\x76\x68\xa5\x53\xfe\x5a\x03\x09\xbe\xff\xfe\xce\x7c\x36\xce\xff\x5a\x93\x33\x41\xe8\x43\x47\xdb\xb6\xe0\xa8\x47\xef\x99\x4b\xe9\x58\x2c\x8f\x9e\xb3\xf8\x56\x2c\x8f\x59\xd3\xf7\xa1\x2e\x93\x5d\xa8\xe0\x97\x4b\x47\xf0\x4f\x9f\xfe\xb3\x56\xfa\x9f\xfb\x49\x63\x49\xcc\x5c\x86\x87\xdd\x3a\x02\x1f\xfa\xfb\xd7\x3b\x0b\xd4\xf5\xd2\x28\xa1\x95\xa9\x85\x4a\x99\x21\xf4\x97\x3e\x8b\xf7\xbf\xf7\xbf\xcf\x11\xe8\xaa\x24\xf1\xd6\x3f\xe1\x34\x38\xfa\x0b\xe5\xf1\x4e\x3d\xda\x4b\x63\xf3\x2a\x63\xb5\xff\x43\x96\xd2\xce\xe8\x14\xb9\x3d\x0a\x7e\xe5\x8b\x29\x6c\x4b\x89\x7e\x43\x89\xbe\x72\x1e\xea\x9c\xff\xcc\xbf\x09\xa4\xf6\x2a\x25\xfa\xcb\x24\xfa\x56\x04\xd3\x37\x3b\x66\x09\x91\xf1\x4c\x25\x1a\x2d\xde\xe1\x3f\xbf\x17\x60\xd3\x1a\xc6\xb3\x40\xdd\x36\x9f\xcc\xd1\x0b\x1c\x5a\xf9\x43\x56\x38\x7c\xcd\x22\x87\x30\x78\x93\x37\x7c\x96\x35\x20\x55\x32\x7c\x01\x37\x7c\x51\x34\xfc\x06\x35\x21\x53\xb4\x7c\xe5\x35\x7c\x07\x71\xbe\x96\x35\x07\xe7\x6f\x78\xee\x95\xa0\xe1\x91\x46\x38\xf4\x37\xbc\xe1\x7f\xc5\x33\xff\x47\x3c\xbb\x63\xa8\x3f\xf6\xc7\x0f\x20\xc2\x95\xc2\x37\x8b\xd3\x31\x15\xd2\x37\x47\xa0\xe6\xbf\xd6\x90\xc8\x22\xfc\x2b\x25\xf1\x4c\x90\x50\x75\x79\xa8\xfb\x63\xbc\x3e\x8d\x6b\xca\x2f\xb7\x01\x19\x8f\x21\x08\x9f\x15\x24\x8f\xe1\x0f\x8f\x11\x04\x8f\xc5\x17\xa8\x03\x05\xb8\xd1\x2b\x8f\xc9\xa7\xbc\x25\x08\x88\xcb\x29\xff\x8d\x97\x4a\x74\x5f\x46\xf0\x98\xcf\xee\xdf\xf0\xdc\xff\x05\xcf\xf9\x9f\xf1\xae\x3f\xe6\xae\xa3\xff\x17\xb2\xf8\x87\x8c\x72\xf4\x9f\xf2\x18\x0c\xae\xf4\x9f\x71\xff\xd1\xb7\x3f\xf5\xcf\xc7\x1a\x9b\xa7\xb1\x42\x12\xfb\x0c\x09\x21\x45\x0a\xcf\x3f\xf4\xbc\xe8\x14\xd0\x5e\x48\x24\x0e\x0a\x86\x61\xd4\xc2\x0b\x5c\x36\x94\xfb\xac\x15\xd5\xd2\x7f\x4c\x56\xe4\xe1\xfc\x1d\x0a\xf0\x38\xae\xf2\x38\x8e\x48\x6a\x14\x28\x4f\x7e\x41\xc3\xa7\x8b\x99\x6c\xae\x0a\xc1\xd8\x60\xb8\xb1\x7c\xdd\x2c\xd8\x3a\xbe\x0c\xde\x62\x6b\xb8\x82\x5a\x8b\xac\xf3\xb0\x7d\x6b\xb8\x8a\x28\x38\x1e\xc7\x8c\xce\xa3\x25\x52\xd3\x74\x01\x5a\xa1\x72\x3e\xd7\x31\x92\x8b\x07\x2c\x04\xf4\x40\x4f\xf4\x94\x8f\x1f\xbe\x62\xdf\xf8\x89\xa6\xf0\x24\xd3\x7a\x56\x60\x3f\xf9\x5e\x7a\xe3\x76\xca\x8c\xb0\xc1\xdc\xbc\x0f\x15\xa4\x45\x22\xf7\x65\x97\x67\x59\x99\xd9\x60\x9b\x87\x95\x42\xc7\x6e\x90\xc5\xf5\x95\x56\x81\xbf\x26\xae\xf3\xcc\xee\x8b\x2e\xa3\x0e\x3b\x38\x70\x88\xfd\x88\x6e\x58\xa1\xb4\xd7\x11\x35\x96\xbf\xd5\x47\x20\xc2\xca\x08\x32\xd8\x98\x26\x4c\x89\x38\xea\x76\xa0\x55\x3c\x35\x69\x1d\xa5\x6e\xac\x9a\x8f\x21\x3b\x98\xda\x0d\x5c\x28\x9e\xba\x82\x36\x74\x34\x90\xcf\x7e\x3a\xb7\x68\x14\x4f\x56\x72\x8b\xb9\x83\xae\xab\x58\xc1\x7d\x30\xc2\xf4\x46\x7c\x37\xd5\x47\xbd\xed\x76\x84\x0b\x6a\xe6\x9b\xab\x8d\xc5\x53\x78\x3a\x4c\x34\xe9\xad\x22\xee\x4b\x69\x61\x41\x0d\xa9\x05\xc9\xa5\xaf\x8d\x81\x3b\x03\x94\x44\xd8\x3c\xe2\xa5\xad\x6e\x38\x3d\x4d\x44\x4c\x67\x30\x2d\xe2\xc6\x62\xa2\x29\x24\x35\x16\x6a\xf1\xd0\x51\xc2\x72\x6f\xa1\x70\xf3\x6a\xe6\x4b\x1f\x44\x2b\x8f\x27\x10\x87\xa5\x2d\xc2\x43\x37\xd1\x46\x05\x09\x9d\x4e\xca\x01\x4a\x54\x3b\xe9\x2f\x16\x21\x65\x97\xaf\x04\x98\x2a\xb6\x84\xa8\x36\x63\xda\x25\x34\x0c\x47\x54\xb5\x48\x24\x6d\x33\x35\x80\x61\x6c\xdd\x77\x69\xa4\x36\xdf\x1e\x4b\x89\x19\xc3\x3a\x84\x5b\x62\x36\x7e\x0b\x8b\x26\x0f\x87\x41\x00\xf0\x60\x17\x98\x28\xbb\x6a\x28\xfb\x90\x03\x4a\xb7\x4b\x43\xb6\x2c\x6f\x09\x25\x40\xfb\xa5\xfb\xf8\xdb\x6f\xee\xaa\x87\xf5\x32\xac\xd5\x78\x28\x73\x8d\x9a\x0e\xc4\x19\xb2\xd7\xa2\x69\x06\x02\xa1\xe3\xe7\x60\x84\x02\x8f\x61\x11\x03\x81\x2b\xb4\xf3\x6e\xa3\xd8\xab\xaf\x30\xc3\xc3\x4f\x97\xb3\xc6\x39\x1f\xeb\x17\x50\x93\xfa\x76\xa8\x5f\xc0\x16\x06\x8c\x74\x00\x11\x33\xf9\x50\x0e\x48\xd9\xf2\x07\xf3\xbf\x1f\xa3\x1f\xd4\x31\xfe\x20\xee\x37\xe4\xaa\x21\xfb\xcb\x4a\x7b\x03\xbe\xeb\x19\xdc\x50\x3a\xc0\xb8\x6a\x39\x7b\xad\xc6\x8d\x09\x7a\x9c\xb3\x49\xd0\x07\xde\x49\x7a\xe2\x8f\xdc\x91\x0d\xbd\x98\x90\xcd\x63\x32\x6c\x69\xa2\x2c\x4a\xb2\xd9\xb6\x2d\x89\x4f\xad\x6f\x0c\x75\x33\x66\xb9\xb9\x3b\x28\x0c\x46\x24\x23\xef\xe6\x81\x9f\xb3\x29\xa2\xe6\xa0\x7d\x63\x5b\xa7\x89\x73\xb6\x16\xab\xbd\xd0\x6b\x99\xff\x1a\x8a\xef\x19\x8b\xdd\xc5\x46\xd0\xd5\x69\x97\x76\xb2\x8a\x86\xa1\xc0\xf3\x13\x7c\xd8\x86\x91\x87\x88\x23\x02\x9b\xe1\x7d\xeb\x1f\x25\x13\xc5\xff\x21\x13\xff\x87\x4c\xfc\x1f\x32\xf1\xff\x98\x4c\xb8\x83\x81\x39\x7d\xf2\x9a\x7c\xf8\x87\xf3\xc7\xfe\xe3\xfc\x47\xd6\x15\x52\xce\xe4\x4d\xc1\x80\x84\x3f\x1c\x2b\x64\x04\xca\xff\x16\x99\xf8\x0b\x2f\xfd\x1f\xf1\xfe\xdf\x91\x89\x55\x72\xbe\x96\x33\x7b\x05\x32\xa0\x3f\x9c\x7f\xf3\x1f\xe7\x1f\x88\x82\x3b\xfc\xf1\x3f\xe7\x73\x7c\xe1\xb1\x7c\xe7\x71\xba\xff\x1d\x32\xf1\x17\x9e\x29\xfc\x8f\x78\xff\xdf\x90\x89\xa1\x86\xdf\xca\xf8\x83\x4c\xe4\x7f\x91\x09\xf3\xbf\xc8\x04\x74\xe8\x81\xbe\xb2\x34\x7c\x2e\x65\x18\xd9\xd3\xf2\x0b\x94\x67\x81\x42\xaf\x33\x3d\xe1\x31\x92\x44\x16\x50\x74\x84\x82\x12\xec\x66\x80\x03\x2c\xaf\x4f\x9a\xde\x95\x78\xd6\xe5\x34\x55\x09\x06\x45\x88\x3a\x28\xd2\xc6\x3e\x83\xce\x11\x41\x00\x1c\x81\xe9\x51\x45\x88\x46\xaf\xba\xea\x3b\xe3\x6b\x26\x7f\xf3\x3c\xff\xc6\x5f\x20\x06\xe1\xb4\xa3\xc6\x55\x22\x79\xaf\xbc\xd5\xe7\x86\x3a\xcb\x40\x9f\xc4\x7c\x0b\xd1\xb7\xfd\x04\x1f\x15\x40\x0a\x01\x4a\xfe\x44\x0b\xb8\x49\x75\x34\xf2\x43\x02\x2a\x5b\xc5\x27\x2b\x4b\xa7\xa2\x03\xe7\xdd\x1e\x09\xcb\x64\x8f\x1b\xa6\x22\xde\x29\xe8\x23\xdd\xa0\x7d\x25\x93\xde\xef\xf6\x38\x04\x4d\x51\x73\x57\xf7\xfa\xe4\x55\x5e\x4a\x7e\xdb\x45\x08\x2d\xfb\xef\xbc\xf8\x86\xb8\x64\x35\x12\x99\xf5\x27\x82\xcc\xef\xa9\xc0\xa5\x9b\x77\x02\x48\x7e\xef\xb2\x71\x5d\xc0\x5e\xa6\x65\x01\xa4\xf8\x8b\x8d\x7e\x8e\x0a\x28\x7a\x15\xc6\x72\x6c\xc8\xc4\xcc\x99\x52\xb6\xcd\xfb\xec\x07\xd9\xef\x71\xdc\x93\x2d\x1d\x11\xaa\xd1\x28\x9e\x7f\xdd\xab\x78\xb4\xd8\xb9\x58\xa2\x51\xbc\x64\xed\xee\x46\x06\x7a\x21\xec\xc8\x84\xa9\x23\x6c\x16\xb6\x01\xb2\xd5\x9b\x5f\x6a\xb3\xea\x99\x98\xb4\xb3\x0a\xd9\xed\xb6\x95\x9d\x45\x24\xd0\x00\x97\xb2\x0e\x61\x67\xb8\x5a\x17\x3b\x9a\xa6\x4c\x5b\xce\x06\x0e\xd8\xc5\xf8\x35\xb7\x9c\xe5\x4a\x18\x72\x0f\xd2\x97\x3f\x4d\xbc\x27\x82\xf4\x53\x64\x1d\xc7\xd2\x76\xa4\x06\x29\x34\x5c\x6e\x2b\x25\x30\xf2\x2c\xdd\xb4\x90\x56\x66\xa2\xe9\x78\xee\x45\x0d\x33\x89\x05\xae\xd1\x14\xa4\x51\xb8\x67\x71\x18\x61\x77\x94\x63\x35\x39\x39\xd2\xe6\xc6\x58\x20\x38\xfb\xf9\x09\xd8\x8b\xca\x97\x9f\x87\xd7\xaa\x67\xdc\xc2\xe2\x44\x8b\xca\x94\x74\x06\x79\xf8\x87\x66\x1d\xb9\x05\x1c\x8b\x49\x9b\x05\x50\x3b\xb8\x27\x05\x96\x12\x26\x23\x29\x7f\xb6\x22\x23\x89\x9b\x42\x2f\xa2\xa5\xc0\x1e\x7e\xac\x3c\x23\x17\x3c\xad\x86\xf4\x40\xbc\x9f\xb9\xe8\xfc\xd5\x77\x2d\x09\x6a\xf9\xe6\xd2\x50\x2e\xe0\x2d\x74\x0d\xff\x5e\x8f\xfe\x35\xd8\xdb\x09\xde\xb5\xf4\x69\x5b\x97\x18\x6d\x31\x95\xae\x22\x65\xd5\x64\x9e\xae\xd8\x96\x45\x5c\x77\xd3\x25\x59\xe6\x0a\x3f\xdf\x75\x05\xa1\x9c\x29\xa3\x52\x73\x2f\x4c\x71\x83\x9c\xf5\xd2\x14\x9e\x4d\xd4\x33\xe7\x16\x6a\xb1\x66\x38\x67\x86\x01\x99\x8d\x34\x4f\xcb\x51\xc3\xc7\xbc\x66\x3f\xce\x96\xbe\x42\x3e\x03\x72\x07\xe3\x2d\x57\x20\x16\xc2\x1d\xf7\xf5\x33\x06\xda\xb7\xec\xfa\x07\xd4\x9d\xae\x72\xba\x98\xfc\x50\x3f\xf5\x34\xb3\x50\x48\x20\x53\xef\xc8\x99\x6c\x03\xf0\x87\xcd\x6d\x30\xfa\x38\x09\xbc\x06\xd5\x82\x61\x8c\xdb\xc8\x76\x22\x0a\xb4\xf2\x9f\x6d\x4b\xda\xb7\xf1\xdf\xc5\x25\xda\xff\x3e\x9e\x8d\x1a\x8a\xe3\xcf\xb6\xfc\xe7\x07\xa4\x6f\x6c\x0c\x4b\x06\x9b\xac\x6b\x65\xde\xb0\xfa\xac\x80\xa0\x76\x9b\x22\x78\xb1\x8d\xc8\x8b\x97\xe7\xc5\xd8\x41\x29\x89\x1e\x2c\x3e\x8a\xeb\xb2\x71\x3a\x8a\x0e\x2d\x85\x25\x2f\x98\x4a\x2b\xa9\xcf\xc0\xef\x37\x32\xcd\x55\x3a\x1b\x14\xfa\x3b\xcd\x74\xb4\x26\x73\xe1\xdb\x6f\xfc\x3e\xb4\x04\xe9\xef\x42\xbd\xe5\x7e\x28\xae\x05\xb7\x31\xd1\x90\xd8\x40\x0b\x41\xdd\x73\x19\x02\xb6\x3e\x04\x7f\x25\x01\x9e\x44\x66\xc2\x54\x4e\xba\x86\xe8\x03\x74\xb6\xec\x36\x28\x3c\x00\x94\x55\xe0\x7a\xde\x64\x8f\x12\xf6\xa8\x09\x06\xf3\x15\x87\xa6\xa2\x99\x24\x66\x93\x21\xf7\x21\x54\x02\x77\x21\x75\xc7\x60\xfc\xd6\x28\x5a\x89\x36\x54\x8a\x4e\x18\x10\x83\xb1\xee\x3c\x88\xfa\x65\x7f\xa0\xa0\x13\x97\x68\x53\x57\xc9\x78\x70\xde\xfc\x2c\x7e\xc3\x33\xc5\x5e\x32\x0a\x61\x22\xb6\x01\xc7\x57\xd3\x0d\x19\xb6\x8d\x15\xcc\xe8\xf8\xd2\x63\xfd\x93\xe0\xe2\x14\x47\x36\x8b\xd6\x4e\x7b\x32\xc5\xf6\xf4\x84\xe0\x32\x8e\x46\x9b\xc6\xe9\xdf\xce\x49\xdd\xa1\x72\xbc\x4f\x77\x97\x4b\xca\xec\xa2\x8b\xf4\x03\xaf\x33\x2f\x12\xd8\xa5\x25\x34\xf6\xb2\xda\x2e\x33\x9b\x0c\x02\x12\x7a\xbd\x33\xf1\xb9\x4e\xf2\x57\xaf\x94\x88\xaf\x11\x7f\x00\x9b\x69\xac\x88\xd2\xf5\xb2\x74\x97\x65\xc4\x5d\x26\x80\xa2\x20\xb7\x30\x96\x8d\xcf\x61\xe9\xd3\x5e\xb9\x38\xb0\x3a\x34\x4d\xe7\x10\xc9\xf5\x23\x43\x02\x02\xe8\x8f\xcc\x06\x06\x69\x6a\x99\x2e\x5c\x91\x6a\x2d\x5c\xc4\xc3\x0a\x1b\x1d\x46\xa4\xcf\x53\x03\x36\x71\x7f\xc7\xe1\xdb\x9d\xe7\x57\x64\xce\x04\x61\x6d\x19\x0d\x2e\x85\x1a\x5f\xbd\xd2\x3f\x07\xad\x19\xf1\x3b\x69\xbb\x25\x80\xc8\xa8\xfb\x91\x00\x57\x89\x2d\x73\xa4\xcf\xb5\xe9\xa1\x9c\xd1\xed\xa3\x17\xbf\x86\xb7\x0d\x52\xd6\x6e\xac\x4a\x32\x65\x93\x66\x72\x5e\x97\x82\x8f\x90\x2b\xa4\x0d\x7b\x54\x1f\x69\x8e\x02\xab\x6b\x2f\x9b\xcc\xd0\x20\x39\xa4\xf2\x62\xe2\xfd\x00\x0a\x02\x36\x89\x8b\xaa\x74\x01\x53\x97\x66\x19\x52\xd0\xfe\xe2\x07\xd8\xdd\x5f\x8c\x10\x6d\x8c\x03\x61\xf6\xf8\x95\xf3\xc1\x49\xb2\xd9\x59\xcc\x17\xa5\x8d\xa0\x39\xb8\x73\xe0\xa3\xb2\xe9\x4b\x9f\x67\xb1\xe7\xf8\x85\xfb\x22\xd6\xed\x63\x5e\xba\x0d\x90\x92\x30\x56\x33\x84\x51\x20\x00\xe3\x13\x83\x5f\x0e\xf1\xab\x68\xae\x83\xff\x4d\xe9\x54\x8b\xc7\x57\xdd\xad\x9c\x14\xf5\x1d\x24\x8c\x91\x4e\x61\x96\x3a\xa3\x2e\xca\xff\x64\x20\x70\x34\xd9\xbf\x4b\x77\xff\x6f\x8e\x7f\x47\x70\x0d\x41\x14\xdd\x95\xba\x35\x47\x90\xd5\x90\x08\xb5\xf0\x04\xc7\xcf\x03\xe5\x9e\x97\xef\x59\xd9\xe2\xaa\xd6\x4a\xb0\x21\xcd\x5e\x9a\xc2\x07\xef\xd1\xf4\x61\x72\x50\xb4\x5c\x98\xb8\x56\x0c\x12\x4d\x0a\x0f\x1d\x72\x91\x46\x3f\x4c\x6e\x44\x53\x38\x45\x81\xcf\x63\xc6\x65\x9e\xaa\xcf\xaa\x40\x0b\xa0\x49\xf4\xba\x52\x61\x7f\x31\x35\x99\xb7\xd2\x36\x4e\xc2\x1d\x3c\x27\x71\x10\x5a\x15\x06\x16\xb0\xd3\xe2\xb7\x8f\xbf\xc3\x6e\x9d\x11\x41\xc3\xb4\xa0\xc0\xe3\x47\x2b\xf0\x6b\xc8\x0d\x24\x30\x94\xfc\x63\x0d\x08\x1b\x43\x91\x69\x97\x04\xa5\x6a\xcf\xe3\x9d\xd0\x44\xd7\x5a\x0b\x29\x89\xd4\x8a\x27\x95\x47\xe2\x82\x9f\x7c\xdc\x02\xb4\xd2\x0b\x74\x45\x42\x31\xed\x7f\x04\xd0\x38\xcd\xbd\xcf\xed\x27\xf9\xe7\x46\x98\xed\x4e\x0c\x49\xba\xc5\xfd\xad\x43\x92\xd8\x0a\x23\x1a\x10\x90\x55\xcf\x77\xb4\xc3\x92\x74\xfc\x02\xcd\x74\x77\x6d\x58\x2b\x45\x61\x57\x4d\x71\x0f\x05\x56\xc9\x22\x26\xdb\xd8\x6d\x0b\xd0\xb0\xda\xf8\xc6\xf9\x81\x4b\x25\x09\xf9\x62\x26\xeb\x3f\x51\x59\x58\xe3\x9a\x1b\xf8\x5d\x15\xcd\xda\x26\x1b\x85\xa4\x08\xb5\x14\xa1\xe8\xa6\xe5\xfa\xc6\xc7\x7d\x71\xb7\x61\xc4\x9b\x17\x18\xc5\xe2\x07\xae\x98\x14\xa3\xec\x1c\x7d\x37\xcb\xe8\x36\xd2\x52\x1d\x1b\x6a\xfd\x84\xe0\x80\x33\xb6\xd5\x36\x34\xee\xe6\x47\x4b\x36\x91\x7e\x9d\x7c\x73\x95\x6d\x37\x5e\x00\x92\xde\x17\x23\x73\xad\x09\xa2\xd8\xd3\x0f\x5e\x30\x05\xfc\x2e\x8f\x73\x73\x18\x7f\xc2\x21\x11\x0e\x67\x3b\x77\xa5\x4a\xb8\x29\x39\x4e\xf3\x2e\xa4\xea\x9d\xbf\x14\x7a\x2c\xfb\x93\xbe\x18\x9e\x79\xbb\x56\x17\xf2\x5f\xc4\xa4\xad\xb5\x84\x2b\xfa\x11\xdd\xc6\x06\x1d\x0b\x33\xd8\x2c\xd4\x37\x27\xec\xf9\xa0\x83\x06\xe6\x37\x02\x3e\xe3\x3d\xff\x00\x8b\x2f\x7c\x2b\x5c\x52\x13\x7d\x70\x94\x4c\x18\x19\xc3\x42\xdd\xf4\x3d\x90\x19\x80\x91\x16\x24\x02\x30\x2e\xc2\x9b\xdd\x3c\xbb\x20\x67\x47\xf8\x52\xed\x13\x8c\xc9\x3c\xbf\xeb\xa1\xc8\x26\xe1\x24\xee\x89\x05\x2d\x54\x2f\x2e\x12\x77\x09\xad\x5a\xf8\x32\x41\x15\xb3\x78\xc2\x2a\xb1\x80\xa3\x16\x48\x42\xfd\x98\xf4\x25\x5d\xbe\x15\xba\x13\x9c\xe9\x12\xe9\x98\x10\x5b\x52\xc4\xc0\x2e\x79\x01\xa9\xd0\x2d\xc3\x1b\x6b\xa1\x91\x76\x1b\xda\x4a\xd3\x9a\x62\x88\xed\x24\x6d\x0d\x87\x10\xce\x6f\x10\x9e\x23\x24\x07\x1b\x6e\xad\x61\xdb\x2f\x14\x20\x21\xab\x86\x58\x77\x40\xc2\x72\x09\xb3\x5d\x9a\xf6\x7a\x26\x5c\x68\x59\xc0\x36\xa0\xd6\x4c\x01\xba\x46\x3c\xbb\x4f\x6f\x69\xfb\xaa\xeb\x73\xb7\xaa\xc3\x9e\x39\x82\x46\x70\x5c\x8d\x4c\xda\x8e\xb6\xb4\x99\x9c\xb5\x28\x7d\x9e\xd1\xb3\xa3\x11\x75\xee\x66\xce\x94\x5f\x44\x39\x46\xcb\xe3\x18\x72\x05\xf9\x03\x46\x18\x3d\x91\xfb\x86\x5d\x98\x62\x30\xac\xb5\x75\xa8\xd0\x93\x39\xf3\x9f\x6f\x81\xff\x5c\x0d\xe1\xd1\x7c\xff\x32\xdb\xf1\xf7\xd6\xa5\x3f\xdb\x91\x13\x3b\x37\x3e\xcf\xaf\xcb\x43\x99\xc5\x63\x18\xd6\x2e\x8b\xc3\x68\x39\x11\xd1\x0d\x84\x19\xdc\x17\x42\x3d\x1b\x1d\x5c\x64\x90\xa9\x01\x16\xa6\x29\xaa\xab\x31\xa8\x2f\x44\xc1\x75\x02\xd7\x64\x3d\xa7\xe4\xa3\x51\x77\x4c\x64\xdc\xcf\x8a\x9a\xab\x74\x4f\xaf\x82\x14\x17\xeb\xc7\xef\x9f\x41\xe2\xdf\x5c\x5b\x53\x38\x4d\x47\x90\xbc\xd7\xef\x05\x00\x94\x78\x6b\xab\xf2\xe0\x6d\xfb\xf8\xe3\x92\x11\x9b\x24\x98\xd5\x1e\x23\x94\xff\xe5\xc8\x2e\x57\x0f\x78\x16\x85\x1c\x31\x65\x9e\xc6\x28\x34\x58\x08\xc0\xa2\x7b\x67\xa2\x5f\xeb\xcf\xf2\xe9\x10\x04\x40\xe3\x1d\x86\xa0\xfd\x27\x7e\x56\x38\xf6\x6c\xa9\x59\xa9\x29\x67\xdf\x15\xfa\x64\x85\xdf\x22\xe0\xa5\x6c\x4f\x77\xa9\x0a\xa0\x2a\x0c\x4f\x79\x84\x0c\x2e\xe5\x63\xfa\x2d\x8e\x1d\xde\x61\xf5\xe6\x07\xd7\x5c\x7c\x7e\xb0\xd2\xae\x7e\xf0\xad\xd6\xa8\x0f\xb4\x61\xa5\x70\x47\xcc\xf3\x73\x05\x4d\xe1\x64\x61\x5f\x92\x24\x36\xe2\x6b\x2c\xa2\x69\x3b\xf5\x66\x4a\x48\xf8\xe5\x06\x09\x2c\x20\x66\x60\xdc\x46\x37\xd2\x75\x36\x78\x63\x95\xcc\x4f\x48\x2a\xa8\x94\x56\x42\xbe\xaf\x49\x5e\x73\x99\x83\xa3\x9a\x36\x66\x91\x1b\x64\xc7\x7a\x13\xc1\xfe\x3c\xf5\x76\x10\x96\xc0\xfd\x09\x37\x53\x09\x15\xf7\xb6\x9b\x88\x3b\x37\x4c\x75\xc6\xf2\x55\x5e\x6e\x43\x3b\x94\x6d\x41\x38\xab\x71\x11\xa5\x60\xd6\xe3\xee\xaf\xa2\x59\x88\x8e\x24\xbb\xa6\x17\xa6\x90\xdf\xf2\x84\x7a\x1c\x15\x0e\x6f\x37\xd0\xdb\x8e\x55\x08\x40\xa2\xd3\x1a\x2d\x72\xff\xeb\xce\x4f\xe1\x87\x49\xf6\xcc\x4d\xe0\x7c\xb1\x71\xbc\x42\x28\x92\xb3\x40\x4c\x86\xf2\x8b\x32\xb9\x63\x1e\x90\x06\x0d\xf4\x93\xd0\x04\x4e\x12\x89\x7e\xca\x59\x76\x0c\x4f\x2d\xc4\xc2\xb8\x88\xeb\x72\x93\x63\xf4\xdd\x8e\x72\xca\x0b\x77\xde\x6a\xbf\x1e\x17\xb7\xa2\x1f\x57\x2f\xd3\xb4\x18\xeb\x02\x6a\x78\x53\x6b\x76\xea\x1d\xc4\xad\xd8\xcb\xc5\x34\x43\x43\xa2\xd3\xce\x1e\x9b\x1c\xb3\x08\x0e\x80\x03\xc8\x49\x36\xd1\xdd\x51\x2b\x29\x8b\x3a\x97\x4f\x7d\x3d\x15\x7b\x11\x2e\xb4\xa6\xbf\xd3\xdd\x95\x7b\xfa\x6d\x07\x9f\xad\x9b\xb6\xca\x2a\x86\xa0\xcd\x99\x93\x34\x44\xc6\xd2\x80\x2b\xb9\x7f\xd0\x98\xdd\x6c\x66\x53\x8b\x0d\x05\x36\x4b\x55\x92\xf0\xa8\x96\x3f\x31\xd4\x55\x72\xa0\x0a\xea\x09\xe6\x66\x0d\x97\x72\xe4\x3d\x29\x17\x93\x9e\x4a\xb0\xd7\x58\x2d\x09\xa2\x47\xb9\x46\x5f\x45\xb4\x3f\x06\xad\x6f\x39\xf5\x19\x27\x3c\x02\x4c\x0d\xfc\x4a\xe4\x7f\x65\xc3\x97\xa3\x42\xdd\xcc\x87\x3b\x2f\xa2\x3d\xfb\xed\x56\x0a\xe9\x58\x7c\x5a\x58\x3f\x28\x95\xd1\x0d\x69\x15\x9e\x55\xc8\x6f\x83\x89\xe3\x1c\x50\xd1\xb4\x1f\x46\xc1\x6e\x13\x58\x87\xa5\x28\x92\x45\xc0\x12\x35\xc0\x85\x32\x38\x0c\xcc\xd9\x0f\x84\xb8\x10\xc2\xbe\x15\x83\xd1\x7a\xd4\x06\x91\x24\xd0\x9a\xe4\x1f\xe5\x1b\x5d\xfd\x2f\x2b\x21\x98\xdc\xbf\x9f\xe5\xfc\x9f\x4a\xc2\x2d\xf9\xe4\x68\x3f\xc6\x5f\xa2\x9a\x45\x14\x08\xe3\x1b\xa8\x7b\x66\x4a\x2d\xcd\x42\x0d\xac\x2f\xd0\x45\x0b\x2f\x49\x09\xf9\x2f\x7c\xd8\x36\x3e\x65\xaf\x9d\x10\x3c\x91\x58\xd5\x75\x56\x26\x61\x79\x21\x5a\x33\xc1\x16\xda\x61\x2f\xc3\x35\x7f\xfb\xef\xaa\x2c\xcc\xa8\x53\x9e\xf3\xa3\x3c\x3b\xab\xba\x20\x51\xc2\x56\xbe\xce\x62\x48\xd2\xb2\x65\xe4\x55\xb9\xc2\x93\xca\x06\x39\x87\xdd\x61\xb4\xa5\x16\x97\x13\x24\xc3\xdf\xc1\x78\xee\x7a\x85\xe6\x3b\xf7\x30\x5a\x13\xb1\xd5\xf6\x0d\x25\x33\xa3\xe1\x2b\x4e\xf9\x82\xba\x05\x5c\xe8\x99\x04\xb6\x3f\x30\x32\xe7\xe7\x40\xa1\x01\xd0\x5a\xbe\x92\x46\x00\x6d\x7e\x9d\x18\xf8\x74\xaf\x9c\xcf\x45\xc2\xdc\xb5\x0b\xd3\x69\x93\x4b\x20\xbf\x58\xb4\xbe\x7b\x4d\xe5\x97\xb4\x1a\x2f\x4f\xfd\x1a\x12\xf2\xbb\x1c\xbe\x64\xc7\x5b\x49\xb3\xd3\xc1\xcf\xba\x85\x91\xe3\xee\x96\x00\x13\x80\x39\x09\x60\x53\x71\x39\x53\xe1\x77\x80\x3d\x10\x6a\x8a\xbf\x87\x0a\xcd\x33\x25\x69\xa2\xa7\x37\x90\x6f\x98\x7b\x99\xee\x8d\x1b\xbb\x91\x99\x44\x48\x14\xb0\x9b\x53\x66\x66\x1c\x7a\x0b\x7b\x81\x1f\xa4\x36\x66\x8c\x2c\x3b\x11\xdb\x89\x87\x6c\x60\xe1\xbc\x4c\xe1\x64\x87\xd8\x33\x10\x6b\xcb\x84\x99\x74\x6b\x51\x30\xb7\x22\x05\x2f\xc2\x85\xaa\x98\x2a\xf3\xa0\x8d\xaf\xca\x6c\x0f\xea\x63\xa0\x62\x48\x93\x3a\x54\x91\x12\x79\x1f\xae\x35\x0a\xbe\x96\x6d\x8e\xbe\x7c\xec\xe1\xbc\xc7\x25\x2d\xf5\xf3\x15\x9e\xda\xa1\xbb\x7a\xaa\x90\x87\xa4\xc3\x28\x29\x5c\x1b\x86\xaa\x16\x9f\xa0\x16\x30\xd2\x80\xcd\x65\xc8\xd5\x81\x7d\x05\x67\x24\x0e\x1d\x58\x4e\x46\x01\x8c\xe0\xce\xc5\x76\x4e\xf2\x4c\xd5\x0a\xd0\xdb\x1a\xe8\xc1\x64\xac\xe2\x5d\x89\x67\x70\xa2\x0e\x2c\x86\x65\x68\x50\xda\xb9\x35\x53\xe4\xfb\x47\x89\x56\xeb\x50\x08\x6a\xe1\x6e\x1d\x11\xc4\x11\x48\x0c\xdf\x9a\x2f\xea\x9a\x2e\xdf\x17\x26\x06\xcb\xfa\x53\x3a\x94\x4a\xf4\x89\xbf\x5b\x8e\x5e\x5b\x2a\xab\x61\x35\xb0\x23\xe0\xb9\x64\x47\xbb\x98\x92\xe6\xc3\xc6\x21\x56\xa1\x9c\x3e\x65\xe4\x0b\x69\x2d\x6c\xe0\x6d\x68\x23\xfa\xe3\x54\x4b\xf9\xfc\x90\x60\xf8\x1d\x71\xf1\x73\x4c\x78\xde\x1c\x92\x7e\x85\xf8\xf6\x27\x02\x1f\x17\x36\xc3\x8d\xc2\xc0\x05\x07\x4f\xef\xa4\x83\x19\x42\x1e\xc3\x97\xc8\x02\x1b\xca\x59\xd0\xcd\x94\x00\xe0\xa0\x3f\x39\x04\x06\xe2\x22\x57\x76\x49\x33\xf0\xf6\x55\xc1\xa2\xad\xdd\xf8\xd0\x4f\xa1\x47\x5f\xd3\x00\x27\xf8\x55\x61\x7d\x3a\xdb\x60\xd0\x39\x67\xc2\xef\xfe\x8b\xb4\xf8\x29\x0f\xbb\xb9\xbc\xe2\x0e\x98\x09\xa7\xe2\x14\x47\x22\x98\x70\x5e\xfb\xe8\x6a\x37\xf8\x3a\x9c\xa2\xa4\x5c\xe8\xe0\xef\x90\xed\xfd\xba\x19\x0e\x3b\x39\x7a\x6b\xe7\x3d\xbd\xfe\xe1\xa6\x84\xe3\xf9\x97\x75\x25\x54\xea\x7f\x27\x12\x82\xdf\x61\x49\xb0\xe0\xd8\xf5\xfe\xc6\xdd\xfb\xb1\xcd\xa9\xa8\xde\xcb\xb5\x29\xcb\x0a\x22\xa7\xad\x9a\xac\x2f\x44\xd5\xac\xc2\xcf\x9c\x29\x4e\x6e\x64\xaa\x19\x52\xa5\xf3\x3d\x25\xd6\x5b\x95\x89\xb8\x66\x58\x8c\xc6\x35\xbc\xce\x65\x3d\x0d\xa1\x3f\xec\xa5\x01\x05\x2e\x41\x99\xfb\x89\x39\x6a\xf8\xf6\x3c\xf7\xc3\x37\xae\x8e\xf7\xce\x09\x50\xdb\x24\x54\x4b\x22\xd2\x38\x27\xfb\x72\x1f\x31\xd6\x65\x49\x07\xe7\xaf\xbe\x7e\xbf\xbe\xda\x09\x92\x40\xaa\x1c\x3d\x3e\x87\xa0\x4f\x51\xbd\xed\x7d\xb3\x6c\x0e\x30\x58\x61\x7a\x9e\xb5\xed\xb0\x63\x0c\x70\x4b\x9a\x76\xeb\xcb\xd8\x48\x2f\x00\x8b\x5e\x14\x25\x6c\xbd\xa2\x2b\x87\x57\x4a\xa9\x4b\x26\x90\x59\x3e\x3c\x6d\xcc\x14\xac\xd8\x2b\xc2\xef\x99\xda\xcb\x44\x96\x2d\x8a\x05\x12\xa2\xed\xbd\xbe\x33\x9f\xd6\xd7\xf9\xf5\xa0\x18\x0f\x24\x5e\x38\x99\x27\x18\x95\x11\x07\xd4\xf3\x0e\x36\x03\xca\x7d\x09\x12\xa0\xee\x16\x6f\x2f\xac\x07\xd2\x91\x32\x53\x61\x0c\xe2\x57\x7a\x1a\x69\x81\xa5\x66\xa1\xfe\xf4\x08\xd9\x53\x30\x2a\xc8\x92\xc6\xc5\x19\xa3\x0a\xcf\x09\x62\xac\x55\x76\x8c\xc0\x43\xd4\xaf\x73\x78\xe4\xd7\x59\xbf\xea\x79\xdd\x25\x29\x50\xee\xda\x99\x5c\x97\x18\xa6\x4f\x9b\x8c\xbc\x9a\x54\x42\xd0\xc8\xe0\x4a\xf6\x5a\x1e\x4d\x2d\x50\xc2\x77\xd9\xd1\xe8\xb2\x0c\x51\xd9\xb7\x37\xb7\x8d\xa7\xb6\x21\x29\xe0\xb5\xe7\x35\x32\xcb\xab\x17\x00\x93\xf6\x17\x8d\xb5\xb6\xdf\xed\xda\x71\x2e\x4d\x64\x42\x40\x2f\x38\xe0\x08\x68\x83\x2c\x57\x18\xf1\x13\xe2\x15\x08\x92\xb3\xce\x44\x5d\xbf\x70\xcd\x07\x8f\xfe\x01\xe5\x62\xff\x60\xc1\x8a\xd2\xcc\x81\x5e\x71\x79\x1a\xc4\x2e\x5c\x61\xd9\x05\x46\xc1\xce\x2b\x6d\xd5\xf5\x13\x0d\x1b\x28\xbc\xd8\xcd\x37\x00\xc2\x50\xd7\xc8\xe6\xea\x03\x0e\x33\xd2\x0c\x85\x90\x4c\xa8\x81\x52\x08\x93\x45\x17\x30\x17\x93\x03\xa1\xf7\x21\x61\xb2\xaa\x53\xcb\xcb\xbf\x04\x65\x0a\x17\xb3\x56\x84\x91\x18\x7c\x05\x23\x14\xfe\xd1\x15\x74\x99\x8d\xf7\x6b\x69\xeb\xe6\x7e\x6b\xc5\x0d\xdb\x95\x9e\x9b\xff\xe6\xf3\xea\x6e\x0f\xf8\x43\xb8\xfe\xba\x6e\x86\x67\x54\x0e\x24\xc7\x8f\xf9\x9c\xe9\xfe\x27\x1d\xf1\x9d\x5d\xff\x2e\x5d\x5b\xc5\xbf\x93\xf7\x3f\x4b\xf9\xec\xf8\x58\xb5\x3c\x86\xee\x2d\x70\xb4\xd0\x31\xc4\x52\x89\x1d\xd6\xe4\x1c\x76\x87\x08\xcd\x06\x58\xca\xe2\xa5\x16\x30\x6a\x2c\x07\x31\x65\x97\x04\x1c\x1b\xfe\x7f\xcc\x7d\x79\x93\xab\x46\xb6\xe7\xff\xfd\x29\x88\xf2\xf4\xb8\x7b\x64\x01\xc9\x4e\xdd\x7b\x3d\x0f\x09\xb4\x82\xf6\x0d\x4d\x4c\xbc\x60\x07\x89\x4d\x80\x58\x54\x53\xdf\x7d\x22\x41\x52\xed\xb6\xfb\xb5\x5f\x84\xc3\xbe\x25\x29\x97\x93\x67\xf9\x9d\x5f\x26\x14\xaa\x53\xba\x86\xd2\x49\x8e\x31\xab\x4e\xe7\x4e\x67\x91\x2f\xc7\x7d\x96\xb4\xf3\x34\xc9\xb8\x69\x16\x69\xe9\x11\x2f\x03\xb3\xa5\xb3\x97\xb8\xbc\xe4\x01\x27\x91\x98\xb1\x38\xcc\x8e\xa1\x57\x9d\xfd\x2d\x3e\xe9\x55\xc4\x28\x12\x8f\x92\xe0\x9c\xa7\x7e\xbc\x1b\xf1\x31\x29\x73\x4a\xe7\xb4\xf1\xa9\x29\xaf\x0e\x4a\xcd\xe2\xe2\xdd\x79\xe1\x1b\xfd\x29\x3b\x9e\xc9\xae\xbd\x12\x37\xeb\x53\xb1\x76\x3c\x67\xa4\x54\xd4\xd6\x0d\x18\x5f\xda\x0d\x0e\xa5\x6a\x93\xbb\xb0\x53\x2d\x26\xf8\xbc\x83\x11\x63\x6d\xc0\xea\x99\xe2\xaf\xcb\x68\x31\x12\x8c\xea\x34\x76\xcd\xa9\xe6\x66\x6c\x4b\x1c\x51\x7c\xd8\x22\x8c\x7c\x15\x16\x55\xb8\x33\x52\xbd\x75\x94\x8b\x11\x95\x38\x76\xa0\x88\x62\x7f\x7b\xca\x43\x6b\xd7\xdd\x2f\xf9\x89\xc8\x06\x51\x4e\xbb\xfc\x44\xe4\x68\x85\xaf\x38\x46\x8c\xb3\x88\x4e\xd6\xc7\xf3\x88\x9a\x55\xa4\x2a\x8e\xe2\x8a\x99\xf7\x47\x33\xad\x3a\x75\x5a\x93\x83\xdd\xa2\xc8\x9d\x4c\x10\x78\x86\x1b\xc5\x74\x7f\xb4\x93\xc9\x2e\xed\xac\x4f\xfb\xb3\x23\x0a\x4c\x57\x97\x4d\xc1\x13\x0a\xcd\x3a\x82\xfd\x9a\x97\x83\x19\xb7\x70\x99\x25\xcb\xf5\xd3\x7e\x79\x98\xc6\x7c\xcf\xbc\x8c\x47\xda\x66\x3f\x74\x3b\x4e\x5f\x58\x5e\xc6\x04\x28\xb0\x42\x4f\xc2\xee\x91\xb3\xce\xbb\x96\xa4\x08\x07\x4d\xdb\x9f\x67\x03\xb3\x58\x9b\x83\x4d\x4f\xf5\xcf\xe7\xfe\xac\xdf\x9d\x2e\x8a\x42\x3d\x38\x74\x72\x9a\x16\x86\xb1\x38\xb6\xc8\x75\x89\x0f\xa5\x3c\xcc\x82\x74\xd2\xa7\xf6\xc1\x5a\xab\x64\xac\x10\x8a\xf1\x60\x3d\xb1\xf7\xf6\x6a\x3c\xc1\xf7\x0b\xad\xe0\xbb\x91\xcd\x9d\x46\x58\xac\x08\xd5\xa0\xa2\xc7\x47\x41\x59\x1d\xd3\xa5\x34\xca\x42\xc5\x0a\x15\x56\x52\x36\x8a\x56\xe8\xd6\x41\xb9\x8c\x16\x2e\xc3\xea\x3b\x49\xf5\x86\x3b\x49\xd8\xac\xb6\x34\xbe\x94\x04\xf7\x72\x2a\xec\x53\xd2\x31\x76\x25\xb5\x99\xba\x6a\x40\x2d\xd2\x89\x33\xd0\xd3\x51\x6f\x5a\xed\x57\xe9\x1c\x28\x93\x96\x6b\x44\x6e\xb4\xf6\x8f\x3d\x4f\x59\xb5\x56\xf3\x5e\xac\x14\xbb\xe9\xa1\x1f\xef\x1c\xa9\xb5\x2b\xfa\x47\x30\xa1\xe3\xde\x28\x1b\x4f\xba\xd6\xe9\xec\xa8\xfd\x73\xdc\x5d\x74\xf4\xae\x38\x8d\xf1\x71\x67\x64\x50\x9b\x68\x46\x9a\x55\x67\x3a\xd9\x72\xe7\xca\xec\x38\x9d\xc1\x7a\xe5\x9e\xe6\xe3\xee\x91\x0c\xa4\x3d\x26\x47\xeb\x7e\x6b\xd1\xf1\xa2\xd1\x94\xdd\x68\x89\x50\x48\x42\x98\x1d\xd4\x99\xb7\x5e\x6f\xf9\x81\x4b\xe9\xc4\x82\x3d\xf2\x07\x9e\x73\x27\x24\x5b\x6e\x4b\xce\xee\x0b\x19\x69\x0d\x05\x73\xa3\xc8\x61\xeb\xbc\xce\x5b\x3a\x31\x5e\x58\xcb\xee\xfe\xb0\x1f\x79\x1d\x5e\xdf\xf0\x87\xe1\x85\x88\xec\x04\x74\xc6\x79\x6e\xb2\x7d\xde\x5c\x74\x39\xdc\xd7\x2c\x7c\x70\x99\x66\x2d\x63\xbb\x09\x93\xe5\x58\x4c\x94\x51\x75\xf4\xec\x62\xd2\x89\xbb\x8e\x84\xad\x05\xdf\x97\x76\x67\x3b\x10\xcf\xdc\xde\xb7\xed\x3c\x0f\xb8\xdd\x72\xce\xe3\xf5\xdf\x3c\xc2\xe3\x1e\x6b\xe0\x5c\x44\xcd\xfe\xe4\x9b\x02\x45\xf0\x15\xaf\x3c\xbc\x22\x96\x34\x77\x5a\x65\xe0\x7f\x33\x5c\x2d\x49\xad\xec\xc7\x39\xb3\xb9\x5f\xfe\x4e\x76\xd3\xdc\xa9\x2b\xc6\xca\x5a\x65\x25\xff\x49\xfc\x8c\x94\x81\x1f\xa6\x3f\x7e\x76\xb3\x2c\x7e\xc4\xb0\xa2\x28\xd0\x82\x44\xa3\xc4\xc1\x08\x1c\xc7\xa1\x98\x9f\x91\xdc\xb3\x8a\x4e\x54\xfe\xf8\x19\x47\x70\x84\x25\x10\x80\xe3\xf7\x72\xaf\x95\x6f\xfd\x5e\x59\x5a\xf0\xc7\xca\xd2\x92\x0c\x4a\x34\x45\x69\x01\x0e\x9a\x8a\xb4\xd7\x26\xf8\x0e\xc5\x71\xfa\x4f\x2f\x47\x6b\x11\x86\x69\x51\x9f\xd7\x43\xfd\xa4\x3c\xab\x85\x1b\xda\x57\xe5\x5f\x49\x40\x7e\x2c\xff\xaa\x1b\xb8\x69\x7e\x3e\x9e\xa2\x3e\x29\x17\x4b\xe8\xc0\xfc\x42\x1d\x9a\xfd\x58\x9e\xd5\x60\x79\xd3\xf8\xa2\xbc\x2c\xc3\x7f\xac\xa6\xab\x6b\x1c\xa5\x7f\x55\x5e\x16\x7c\x2c\x77\xab\xe9\x0c\xa7\x7d\x31\x9e\x27\xa9\x8f\x15\x60\x0d\x8a\xe6\xb9\xff\xf6\x72\xb1\x1b\x9e\x1f\xa0\xc4\x06\xb8\x14\xfd\x79\xcd\x58\xf0\xbb\x35\x63\x3f\x8a\xf8\x57\x0b\xc7\xbe\x97\xcf\xa3\x00\xe1\x01\x0a\x64\x0a\x65\x11\x96\x40\x69\x97\x44\x79\x9f\x40\x39\x04\x10\x75\x3d\x75\xaa\x0d\xdf\xb8\x14\x4a\xfb\x24\x4a\x22\x80\x44\x08\x94\x6f\x03\xd2\x25\x51\xce\x6f\x53\x28\x83\x00\x0e\x65\xdc\x36\x25\x03\x16\x61\x59\x94\xf0\xdb\x24\xca\x22\x80\x44\xf9\x01\x8f\x82\x4b\x40\x10\x28\x40\xf0\x4d\x2d\x9b\x46\x59\xbf\xae\x38\x4e\xa0\xec\x4d\x36\x0b\x5b\xf3\x46\x08\x89\xd2\x1b\x96\x41\xa9\xab\x0c\x0a\x65\x61\x1b\x5b\x7f\x6c\xc3\x8f\xf9\xad\x8d\xa9\xcb\x89\xb3\x08\xee\xb7\x19\xd8\x07\xa7\x53\x28\xf0\x29\xa8\x39\x89\x72\x08\xd5\x14\x8c\xe7\x5c\x4a\x66\x88\xda\x44\xb7\x4d\xa1\x2f\xd5\x7a\xff\x4e\x90\xb6\x6d\xff\x6e\x6d\x6a\xe2\x8f\x91\x00\xe0\x6e\x24\x40\xe3\x28\x4e\x90\x0d\x0f\x5c\x5b\x89\x97\xd6\x7f\x8b\x08\x1a\x2e\x79\x8f\x47\x86\xa4\xf8\xcf\x4b\x47\x7f\x04\x2f\x8b\x03\x92\xd1\x7f\x13\xbc\x5f\x7a\x82\xfc\x83\x9e\x00\x28\x0d\xc0\xd5\x17\x00\x65\xc1\xb5\x4a\x37\x43\xa3\x44\xdd\x4e\xbc\xb4\xff\xf5\xbd\x71\xcf\x13\x86\x42\x49\x84\xa6\x51\xda\xb8\x55\xe6\xaf\xeb\xcd\x93\x6d\x1a\x05\xf0\x85\x45\xc9\xba\x92\x7b\x9d\x23\x10\x7a\x5c\x9d\x3d\xec\x92\xe0\x51\x06\x61\x48\x94\x41\x08\xd8\xc7\x50\x06\x9c\x89\x12\xcd\x0c\xa6\xcd\xa1\x74\x9b\xa8\x6b\xe5\x37\x25\xd9\x39\x98\x04\x6d\xd0\xa6\xe1\x2a\x4c\xfd\x52\xcb\x83\xab\xc2\x71\x80\x45\x9b\x1a\xf3\x08\xd1\xd4\xc6\x6f\xf2\xe8\x5a\x25\x1e\x34\x05\xe9\x51\x06\x81\x39\xc0\xa2\xa0\x49\xc5\xba\xac\x3f\x81\xb7\x01\x4a\x23\x4c\x53\xcc\x1d\xe6\x20\xd5\xae\x6b\xb7\xf3\xf5\x1b\xa6\x16\x84\x12\x08\x83\xf2\x75\x9d\x7a\x1c\x25\x11\x3c\x68\xf3\x28\x8f\x00\x1a\x25\x0d\x94\x6e\xca\xd7\x43\x7b\x91\xba\xda\x3c\x51\xbb\x81\x6d\xcc\x87\x62\x01\x4a\xb4\x99\xba\x19\x00\x94\x87\x3c\xc1\x22\x44\x5d\x20\x9e\x42\x50\x0a\x61\x51\x0e\x4e\x25\x10\xaa\xd6\x80\xad\x4d\xa2\xa1\x26\x4c\x9b\x40\xd9\x80\x80\x7c\x00\x5c\x80\x02\x03\xaa\x42\xd5\xf5\xe6\x89\xa6\xea\x7c\xbb\xae\xd9\xcf\xb4\x01\x4c\xf0\xf6\xbd\x52\x3d\x59\xeb\xe1\x02\x94\xde\x90\x5c\x53\x99\x1e\x47\xea\x0a\xfb\x57\x2b\x50\xf6\x12\x50\x08\x5e\x6b\x0f\xe7\xe2\x8d\x97\xea\xe0\xbd\x96\x5f\xcf\xcd\xeb\xe1\x50\x79\x1a\x25\x5d\x94\x37\x3e\x0c\x6b\x83\x5a\x33\x18\x93\xba\xa0\x7f\xed\x49\xa8\x48\x1b\x5a\x68\xa0\x2c\x4a\xc0\xe8\x40\xed\xa0\xbb\xae\x75\xf7\xeb\x0f\x4d\x94\x98\x3a\x08\xcd\x14\xb2\xfe\x04\xa0\xc6\x4c\x53\x89\x9f\x6a\x54\x46\x69\xb4\x99\x72\x2d\xf5\x5f\xff\xcf\x40\xa4\x34\x62\x78\x68\x0b\xc4\x0c\xec\xe5\x51\x0a\xca\x82\x3a\x73\xb5\xc2\x75\x49\xff\x5a\x3f\x12\xc1\xaf\x35\xff\x01\x44\x56\xa3\x6f\x1b\x2a\x09\xad\xbd\x01\xa1\x66\x69\x0e\x82\x8f\x32\xa0\xb9\x64\x13\xe6\xda\x55\x3c\x0a\xe3\xc9\x34\x16\x7d\xa9\x0a\xd9\x04\x0b\x0a\xae\xcd\xa2\x11\x02\xea\x52\xbb\xfc\x1a\x86\xdb\x10\x0e\x4e\xab\x1b\xa1\x3b\xdc\x36\xca\x37\x6b\x36\x6a\x93\xed\x1a\xc0\xa0\x66\x77\xe8\x6c\xce\x68\x43\x9c\xa3\xa0\x5d\x8f\x21\xda\x74\xed\x57\x68\x15\xdc\x48\x70\x88\x29\xf8\x01\x34\xc8\x87\x2d\x24\xca\xa0\x00\xa1\x21\xd6\x14\x12\x0e\xa2\x00\xca\x18\x28\x8d\x12\xf5\x12\xc4\xcd\xc5\x57\x47\x35\xea\x41\x67\xd7\xd1\xe0\xa1\x72\x44\x13\x2c\xe8\x24\x18\x59\x18\xb6\x1c\x40\x38\xf0\xf5\x60\xa2\x99\x53\x1b\xf1\xe2\xcf\x9a\x15\x6a\x65\xe9\xab\x7f\x41\x93\x97\x97\xa0\x4d\xa3\x24\xd4\x01\x7a\x06\x7a\x95\x81\xe9\x08\x93\x13\x42\xb2\x09\x33\x7d\x17\xd6\xae\xe3\x42\xdc\xa5\xd5\x71\x43\xf9\xba\xb5\x71\x30\x0b\x1d\x3c\x00\xac\x51\x77\x34\x71\x78\x19\x4f\xd5\xeb\x12\x8d\x18\x12\x46\xaf\x96\x8c\xdc\x38\xa2\xce\x1a\x0a\x01\x06\x0a\x10\x0a\x06\x08\xe1\xeb\xe8\x52\x90\x29\x58\x84\x43\xe0\x58\xa8\x3c\xdc\xa4\x01\x8f\x12\x6d\x0a\x6a\x47\xb7\x49\x94\x47\x41\x9b\x83\x1a\xb2\x30\x53\xeb\x5c\x6f\xd8\x0e\xba\xb6\xce\x13\xc8\x16\xe4\x25\x80\x13\xb8\x7b\x22\xd3\x4d\xb4\x09\x04\x87\x1a\xc2\x4c\xa3\x8d\xc6\xfa\x17\x5f\xd4\x4e\xaa\x29\xc2\x80\x03\x91\x5a\x73\xaa\x49\xb6\x7a\xc5\x5a\x0a\x0c\x6d\xbb\x16\xd4\xa0\x89\x82\x2e\x85\x79\x00\x9d\xdf\xbc\xd0\x35\x8c\xae\x70\x68\x32\x0f\x2e\x43\xd7\xcb\x50\x28\x85\xd4\xf4\x09\xc5\x41\x0d\x60\x8c\x79\xa4\xa6\x49\x14\xda\x5b\xf3\x11\xe4\xab\x1b\x68\xd9\x36\x55\x03\x11\x1a\xce\x35\x54\x4c\xd6\xbc\x45\xa0\x64\xbb\xa6\x6d\xba\x49\x42\x1e\xe5\x20\xc9\xc3\x2c\x84\x10\x84\x2a\xbe\xd2\xb3\x7d\xb7\x97\xbd\x42\x1c\xf2\x66\x63\x13\x85\xf2\x01\x45\xd5\x04\x4c\x34\x3e\x23\x6f\xac\x03\x6e\x69\xf2\x42\x4e\xd0\x26\x2a\x87\x44\x07\xad\x69\xc4\x41\x4a\xc1\xf3\xda\xaf\xed\x7a\xe9\xc6\xd9\xd0\x6a\xe2\x12\xb0\x35\x17\x50\x2e\x94\x01\xdb\x1a\x9a\x44\x41\x03\xc6\x1a\x90\x74\xcd\x7a\x6d\x00\xe5\xbe\x52\x81\xba\xc1\xba\x7e\xf9\x40\x39\x30\x76\x50\xce\x95\x1e\x1a\x78\xb1\xd0\xe8\xab\x65\xfc\x8d\x30\xe8\x5a\x14\xd7\xbe\x49\xac\x5d\xcb\x34\xb8\x6e\x28\x83\x42\xe0\xe2\x74\xc3\xa0\x4c\x93\x13\xe4\x6f\x4e\xe7\x9a\xe9\xd4\x45\x01\x34\x42\xb3\xc6\xeb\xe0\xb3\x75\x32\xc0\xf0\xd5\x3a\xd7\x20\xad\xdd\x4e\xd6\xcc\x52\x6f\x20\x46\x13\x13\x0a\x0a\xaa\x01\xc2\xd7\xae\x80\xf4\x56\xf3\x42\xbd\x52\x83\x5e\xae\x99\xd1\xa8\x0a\x37\x58\x03\xdc\xc6\x72\xd7\xb1\xfc\x9d\xca\xa8\x57\x54\xf6\xc2\xf3\x75\xcc\x58\xe3\x46\xf4\xe4\x9d\x76\xb8\x3a\x62\x48\xad\x36\xd3\xec\x70\x24\xfc\x0c\x61\x7f\xf3\xb5\x02\x18\x84\xc1\x21\x19\x5e\xb3\x81\x68\xd7\x0c\x03\xd7\x85\xb0\x6d\x76\x7d\xe4\xbe\x2b\x82\xe6\x88\x60\xd4\x11\x46\xc1\x95\xb6\x48\x68\xc7\x0b\x7d\x41\xeb\xae\xfb\x53\xcd\xe2\x70\xfd\xc6\x14\x94\xbb\xb1\x1e\xdc\x9a\xb8\x37\xe4\x51\xef\x28\xb7\x36\x98\x8b\x35\x52\xae\x5b\x4b\x8d\x39\xfe\xaa\x21\x40\x6a\x69\x10\x82\x0a\xe0\x11\x86\x68\xe0\x07\x97\xab\xb7\x24\xa6\x09\x67\x13\x64\x70\xdd\x71\x1a\x8e\xbe\x9a\x01\x93\x09\x66\x04\x79\x23\x3a\xb2\x7d\xdd\x84\x6e\x1b\x76\x1d\xc3\x2b\x29\x5f\xdd\xfd\xe9\xa5\x15\xf9\x72\x69\xf5\xe5\x01\x97\xfa\x63\x07\x5c\x78\x45\xc6\xf0\xcd\x01\x97\xa5\x50\x02\xbf\x1e\x70\x69\x0e\x65\xeb\x76\xe2\xc7\xcf\x1c\x8b\xb2\xf8\xbf\x7b\xc0\xfd\x78\xdd\x6f\xf3\x96\x6d\x33\x5f\x5c\xc8\xb3\x1f\x2f\x9c\x6d\xce\x32\x6d\xfa\x8b\x0b\x73\xf0\xf1\xf4\x6c\x93\x16\x63\x7f\x7e\x7a\x46\x19\x40\x7c\xbc\xb1\x60\x98\xba\xa5\x7f\x75\x21\xff\x71\x38\x69\x18\x5f\xdd\x87\x60\xe9\x4f\xee\x2b\xb0\x3a\x67\x7e\x71\x9f\x80\xfb\xe4\x3e\x87\xa1\x69\xc0\xf8\xea\x3e\x01\xfb\xf1\xfc\xaf\x1b\x1c\xa7\x7f\xa1\x3e\x4f\x7c\x1c\xaf\x59\x8c\xa1\x7d\x35\x9e\xf9\xe4\x62\xc4\xa6\x4c\xfe\xf3\xf1\x7f\xe6\x7d\x05\xb7\x4d\xb0\x1b\xf0\x39\xee\xa9\xdf\xbd\xa5\xf0\x66\xf6\xbf\x7a\x37\xe1\xd6\x00\xb5\x3d\x44\x5e\xf8\xe3\x67\xdd\xca\x2d\xff\x6e\x45\x9a\x3b\x7f\x27\xa5\x87\x7f\xe7\xb6\x61\xe9\xff\xc5\xbe\x8f\x14\xbc\x29\x0f\x9f\xf4\x24\x69\x8e\x05\x5a\xb0\x27\x55\xa2\x85\x5f\x86\x5d\x42\x09\x86\x2b\xe9\xb8\x56\x1d\x69\xd1\x9b\x4b\x49\x49\x4b\xdc\x78\xe5\x01\x1d\x73\x59\x5e\xc0\xa8\xe5\x96\x0c\xbb\x13\x4b\x75\x9c\x8e\xba\xdf\x48\xca\x1a\xab\xc8\x09\xb9\x67\x15\x76\xba\x12\xb1\x3e\xe3\x1f\x89\xe4\x5c\x10\xf8\x65\x61\xae\xb1\xdd\x86\x07\x9b\x4d\x1f\x0f\x96\xf3\x31\x46\x86\x40\xc3\x0e\xc7\x8a\x31\x99\x5d\x4a\xf6\xb9\xed\x6e\xd9\x9a\x15\xf4\x84\x91\x77\x07\x59\xee\x9f\x43\x0d\x63\xb9\x68\x3f\xb6\x92\x7e\xaa\x8e\xb3\x44\x94\x00\x73\x1e\xf5\x65\x20\xf3\x8e\x34\x9d\x1a\xaa\x49\x98\x32\xb0\x27\x45\xa2\xcb\x18\xa6\xed\x26\xec\x08\x58\xf6\x4c\x09\x8e\xeb\x93\xd4\x13\x8e\xb8\x80\x6f\xf6\x13\xbd\x27\x69\xf3\x6e\x27\x35\x86\xc7\xdd\x81\x67\xe9\x8a\x9c\xc8\x27\xbe\xac\x2c\x6e\xd6\x39\x0a\xa1\x37\x98\xf6\x62\xb7\x75\x20\xac\x2e\x95\xa4\x66\xd4\xa1\xe4\xb4\x77\xd6\xfb\x3e\x36\x38\x71\x8b\x2c\x57\xb7\x71\xb9\x9a\x7b\x34\x11\x81\x43\xbe\xf5\xfa\xaa\xb6\xd8\xcb\x38\xa6\x9d\x45\x67\x7a\xec\x62\x7b\xae\xa3\xca\xc4\xec\x54\x7a\x66\x0c\x7a\xfb\xa3\x1b\x89\x65\x6c\x69\x3b\x01\x5b\x1f\xce\x07\x8c\x1a\x44\xd3\x72\x3c\x3e\x78\x53\xcf\x3a\xb2\x8b\xf5\xd2\x5d\x4c\xe6\x5b\x6d\xa2\xf6\xe6\x67\x45\xb3\x13\xb5\x5b\x7a\x05\x15\x5d\xf6\x63\xfb\xa4\xab\x23\x5c\xca\x17\xa6\x0f\xc4\x79\x55\xad\x52\x6e\xd7\x9d\xac\x04\x66\x2d\xc9\x4a\x91\x8b\x95\x1c\xef\xb7\xc3\xfd\x64\xe2\x4f\x64\x7f\x3e\x1d\x13\xb2\x32\x5a\x8c\x5a\xb4\x70\x3c\xef\xc1\x92\xed\xf6\x7a\x97\xd1\xe5\x48\x33\xfd\x70\x7d\x98\x6f\x7d\xf5\x78\xea\x46\x9d\x6d\x4f\x8f\x42\x69\xa3\x1a\xb2\x2c\x50\xe6\x24\xec\x30\x04\xd5\x9f\xa7\x62\x67\x3b\x74\xec\xfd\x48\x72\xca\x63\xd4\x75\x2f\xcb\xde\x36\x0f\xa9\x4d\x3c\xb7\x02\x31\x20\x36\xc5\x6e\x9e\xee\x46\x45\x0f\xb8\x8c\xd1\x72\x4a\x7f\x4e\x1f\x9c\xa5\x27\xad\xa5\x0c\x2f\xcc\xa1\xc5\x66\x8a\xb4\x6c\x85\x52\x9f\xd0\xba\xb2\x37\x52\xa6\xc3\xe1\x76\x98\xf0\x16\x2e\x4a\x92\x2c\x28\xeb\xa4\x58\x9c\x0d\x77\x23\x54\xab\xb1\x17\xac\x8b\x29\x4b\x8f\x02\x66\xd3\x23\x3b\x39\xeb\x05\x53\xed\xd0\x2a\x4d\x76\xdd\x1b\x6f\x96\x58\x67\x36\xea\x01\x1d\x93\xa8\xcc\x59\x25\x12\xc5\x8f\x18\x7c\x4a\x1f\x0d\x2b\x9a\x9c\xa2\xc2\x3b\x9f\xd5\xb1\xc6\x39\xee\x60\x27\x50\xdc\x9a\x57\x56\x84\x30\x77\xaa\x45\xbe\x5a\xb9\x12\x89\xeb\x73\x4f\x5b\xf6\x35\xaa\x92\x95\xd1\xa4\x17\xb5\xc4\x13\x46\x18\x83\x8c\xea\xaa\x7e\x51\xf5\x6c\x62\xc9\x74\x06\x45\x91\x28\x05\xa6\xe5\xa2\xbe\xa0\xbb\xe0\xc8\xba\x40\x9d\x53\xe3\x01\x29\x04\x76\x4b\x30\xf6\x95\xa4\xef\x67\x39\xdf\x1d\x66\x97\xb9\x08\x7c\x5e\xd2\x33\x75\x7a\xc8\x59\x2a\xc7\x4c\x72\xca\x2f\x94\xd9\x4a\x4c\x52\xa9\xe8\x0f\xb7\x13\xee\x44\x54\x47\x76\x37\x51\x17\x29\x3f\x4a\x16\x39\xb9\xa1\x84\x8e\x20\x2e\xfb\x0b\xc6\x9a\xe3\xd8\x64\xfe\x67\xfe\xca\xb2\xf4\xd3\xf2\x2f\x46\x12\xfe\xeb\xbf\x5a\x78\xea\x49\xd2\x7a\xb6\xd9\x99\x33\x15\x3b\x5b\xdb\xfd\x30\xf2\xd4\xbd\xb7\x54\xc7\xaa\x3b\x32\x18\x49\x37\xcf\x83\xa9\xeb\x78\x87\x88\xcc\xb0\x62\x00\x2e\x4c\x07\x1f\x09\xee\xb4\x52\x86\xb2\x5b\x46\xd4\x71\xd4\x3f\x02\x61\xb9\x12\xca\x62\xdb\xc3\x95\x38\xa6\xcd\x81\xc1\xe7\xbd\xf5\x45\x2d\x3c\x53\x8b\x4e\xc1\xa9\xc5\xf1\x34\x5f\x5e\xf4\x4b\x3f\x9b\x18\x25\xc3\xcf\x56\x4b\x82\x91\x56\xc1\x3c\x5b\xf2\x09\x35\xa8\xb0\x32\x67\x95\x2d\x7b\xd8\xb4\x32\x97\xae\x2e\x1b\x43\x53\x67\x3b\xac\xd5\x1a\x66\xfc\x99\x9a\x08\x79\xab\xbb\x59\x30\x59\x67\xbd\x5e\x9d\x94\x51\x2a\x1a\x8b\xcb\x61\x3f\xdd\x2b\xdc\x96\xdf\xcb\xe3\xb2\x85\xed\x44\x9d\xb2\x68\xec\x38\xa0\x87\x21\xee\xc7\x43\x75\xdb\x5f\x6b\x5d\x5c\x5d\xed\xc3\x4e\x57\x90\xc6\xd1\x66\x41\xca\x24\x13\x89\x11\x3b\xd1\x53\xc7\xdf\x17\xfa\x49\x64\xbc\xf9\x78\xba\xeb\x29\xc6\x78\xbd\xb1\x3b\xc7\x8e\x10\xcd\x5d\x5f\xa4\xcb\x52\x11\x63\x6c\x90\x2c\x73\xf2\x04\x46\x8e\xba\x25\x2f\x78\x89\x8f\x77\x97\x63\x57\x1d\x69\x8b\xbd\x7f\x48\xce\x04\xa9\x0d\xb6\xab\x8b\xec\x69\x81\x50\x55\x59\x8e\x4f\xf9\xb5\x6a\xda\xf4\x4c\x48\x4e\x7e\x1c\x77\x6c\x65\x6d\x9f\xa9\x48\x90\xa5\xe4\xb4\xef\x8c\x8d\x75\xa9\xf4\x16\xdd\x81\x14\xe3\xa2\xb3\xa5\xe5\x88\x9a\xf0\x93\xe1\x04\x98\x3d\x7c\xb7\x4b\x37\xbd\xe9\xba\x9a\x8d\x56\x97\xa8\xb5\xed\x08\x13\xd1\x33\x0f\x31\x97\x39\x83\x7e\x9f\x34\x70\x31\x1c\x51\xe7\xe1\xc2\xa6\x8c\x69\xb7\xa3\x6d\xe9\xf1\x41\xe5\xca\xe3\x5e\x66\x89\x32\x1e\xf1\x73\xa3\x77\xa1\xf5\xcd\x69\xb0\x1e\xf5\x07\x7b\x99\x50\xb3\x49\x30\xf6\x70\x46\xed\x56\xde\xa6\xa7\x53\x29\x96\x4b\x63\x65\x25\xd8\x20\xa6\x2c\x73\xda\x67\x02\xc5\x03\x97\x05\x53\x48\xb1\xb9\x2e\x76\xad\x5c\x16\xb3\x63\xf7\x32\x88\xc6\x6c\x9c\x19\x0a\xa3\x55\x72\xd0\xd7\x0e\x79\x66\x95\xd4\xcc\xf7\xaa\x68\x78\xec\x2d\x0e\xc1\x5a\x12\x96\x96\xdf\x21\x92\xdd\x7c\xb1\xb4\x0f\xeb\xee\x8a\x9f\xf9\xdb\x38\xd8\x12\xc0\x5b\xf5\x2f\x5d\xa1\x92\x8e\x6b\xaf\x9c\x2d\x4e\x3b\xd7\x22\x36\xd4\x65\x6c\x5c\x74\x33\xa8\x74\xe7\x18\x8f\x70\xa3\x3f\x3d\x0b\x8c\x4a\x28\xab\x6e\x3a\x8e\x3c\x7a\x90\x4e\xc6\xec\x84\x54\x26\xad\x73\xa1\x6a\x5b\xbd\x54\xed\x48\x96\x8f\x17\xb3\x34\xac\x82\xf1\x13\x75\xab\xed\xdd\x80\x9b\x0d\x06\x7d\xf2\x62\xdb\x31\x58\x17\xa3\xe5\xe0\xc2\xe7\xf9\x71\xcd\xcd\x22\x53\x37\xe6\xaa\xaa\x2e\x69\xbf\x54\x8f\xe5\xea\xd8\x37\x37\xe2\xdc\xdc\x80\x51\x0a\x4e\x33\x47\x15\x99\xd1\xf0\x3c\x94\x58\x27\xdd\x6d\x2c\x7b\xe8\x0e\xcf\x0a\x4e\x1f\x59\xb3\x50\x74\x4b\x09\x5c\x8e\xd5\x00\x77\xb6\x87\x8a\xb6\x51\xab\x38\x49\x46\xb2\x73\xb0\x88\x49\xd2\x02\xd9\x45\xdd\x09\x93\x50\x0c\x13\xf2\xb2\x70\x07\x07\x92\xdd\xe4\x15\x51\xc4\xbb\x41\x36\x11\x4c\x1a\x2b\xe6\xaa\x20\x32\x5b\xe5\xbc\x22\xba\x45\xb4\xf9\x53\x09\x22\xf8\x8b\x7d\x11\xc9\xf3\x5f\xd5\xd8\x6d\xfe\x3c\x51\xe9\xb6\x1c\x72\x4b\x64\xa0\x8f\xa7\xd2\xa9\x1a\x2e\xab\x70\xdd\x1b\xa5\xcb\xe9\xd2\x9d\x14\x5d\x2d\xf0\xd4\xbd\x24\x92\xb2\x33\x3c\x1a\xe7\x32\x9a\x60\x5e\x77\x6f\xcd\xf6\x9e\xda\x17\x09\xad\x2f\xb6\x3c\xbc\x47\x8f\x95\xae\x5b\xfa\x1b\x4d\x3b\x0a\x63\xa2\x3a\x1a\x42\xd6\xda\x5e\x4c\xf9\xcc\x5e\x8e\x65\x44\x6e\xf7\x32\x15\x9f\xb9\x60\x67\x07\x96\xa5\x92\x1c\x47\x9f\x1d\x86\x4d\xa2\x59\xcf\xa5\xc3\xdc\x60\x88\x80\x77\x0f\xd1\xa2\x45\xcb\x4a\xcc\x2a\xc9\x51\xb5\x49\x16\x3f\x6d\x32\x23\x6a\x6d\xb2\xee\xba\x17\xeb\x87\xd6\xa1\xbf\x68\x8d\xf4\x6d\xc8\x32\xd3\x6a\xce\x59\xb3\x22\xdd\x0b\xab\xb9\xce\x2d\x30\x57\x0b\xf7\xce\x70\xe2\x1c\xf8\xe1\xc9\x3a\x77\x7a\xdd\x02\x8c\x33\x7e\xaa\x74\xc2\xc9\xb6\x9b\x12\xd4\xae\x38\xf6\xb1\xf9\x58\x5d\x4b\x5e\xff\xb0\x11\x66\xf3\xc8\xc6\x92\x13\xce\x72\x64\xbc\x74\xa5\x15\xb9\x96\xe7\x11\x57\x5e\x70\x6f\x49\xf7\x34\x61\x12\x24\x83\xf9\x80\x10\xa3\x93\xda\x12\x97\xf2\xf2\xc2\x2c\x2e\x96\xb1\xf5\x43\x91\xaf\x82\x35\xc5\xca\xea\xc1\xa4\xa6\x74\x67\x77\x12\x57\x7d\xaa\xa7\x90\x93\x78\x25\x1d\x63\x73\x44\x27\x05\x2e\x44\x85\xbc\x50\x74\x77\x6d\xc7\x34\xe7\xac\xa6\x9a\x88\xad\x07\xc1\x64\x3e\x1b\x32\x6a\x90\x8f\xb7\x8b\x1d\xb8\x48\xcb\xc1\x7a\x84\x45\x9d\x94\x08\x83\x99\xd6\x52\x9c\x02\xdf\x0f\x15\x32\xdb\x57\xfd\x68\x54\x54\xce\x65\x3e\xe9\x10\x87\x49\x35\x1a\xee\x77\xac\xd7\xc1\xfd\x78\x16\x29\x2c\xbe\xee\x07\xb3\x1d\x77\xe9\xae\x5b\x49\x9f\x9b\x88\x9b\x72\x50\x98\x5e\x97\x0e\xc6\xe9\x6c\xdd\x5b\x4f\x30\x27\xcf\x64\xd9\x26\xf9\xb4\x77\xd9\x9c\xb4\x09\xa9\x26\x5d\x66\x75\xe8\x68\xe7\x93\xbb\x73\x27\x02\x58\xcd\xa3\x93\x1f\x6d\x58\x51\x6b\xc5\x87\xfd\x09\xf4\xd2\xdd\xba\xab\x05\x3d\x82\x3f\x30\x72\xae\xba\x36\xe9\x0d\x97\xf0\x30\xd9\xcb\x79\x71\x6f\xe5\xd1\xd9\x5d\x5c\x2e\x33\x7b\xda\x6f\x91\x6e\x2c\xf0\x6b\x7e\x5d\x79\xd1\xd4\x5f\x8d\xd8\xb8\x67\xad\xba\xf3\x25\xb3\xe8\x5f\x86\x96\x5e\xd9\xad\xe8\x42\xc7\xcb\xcb\x36\x0b\x96\x5b\x20\x4d\xf9\xd8\xcd\xe7\x38\x9e\xfa\x9d\x45\x86\x71\xa7\x05\x29\x46\x5b\x73\xa7\x7b\xc6\x65\xed\xad\x2e\x26\x4d\x88\xad\xcc\x94\x83\x6a\xd5\x01\x54\x50\x82\x44\x11\xc6\x1b\x63\x11\x4b\xc2\xea\x90\xa4\x67\xc9\xb7\x2c\x6c\xb0\xeb\x07\x61\x6f\x51\x75\xa6\x7d\x91\xc4\xbb\x58\x28\x89\x87\x89\x93\xb2\x5d\x31\x4e\xd5\x20\x1c\xf4\x49\x75\x66\x39\x9d\x6e\x3e\x48\xf9\x48\xb5\x03\x2e\xec\xf3\xe6\x48\xa3\x77\xd4\x98\x13\x84\xf9\x65\xbe\xa3\xc6\xcb\x09\x59\x18\x7f\xea\x97\x0a\xab\xbf\x5a\x2e\x9b\xe5\x4b\x8d\x51\xff\x5a\x17\x45\x57\xd8\x80\x56\xf1\x7d\x9c\x9d\x09\x20\x14\xdb\xc2\x55\x63\x7b\x29\xf6\xdc\xd6\x31\xcf\x17\x26\x37\xc1\x07\x36\x35\xc4\xca\xad\x69\x63\x73\x40\x73\x3d\x7c\x1e\xcd\x5b\xdd\x4d\xda\x1b\x6b\xf2\x72\x1e\x67\x98\x19\x07\xf9\x25\x5b\x4d\x2f\x97\x63\xc5\x18\x56\x36\x8d\xb7\xc6\x7e\x9f\xeb\x53\x52\x99\xd2\x34\xa0\x96\xe5\x45\x5a\x93\x09\xcd\x62\x64\x3f\xde\xfa\xbe\x82\x65\x33\x2a\x95\xc9\x95\x96\x2c\xa6\xbb\xf3\x32\xc2\x96\xdb\x51\xbe\x63\xc1\xfa\xcc\xe1\x5d\xdb\xf5\x13\x6c\x45\xad\xcd\x6d\x4f\xd8\xd8\x66\x18\xa4\xab\x75\x96\x9b\x33\x92\x9e\xae\xab\xf9\x78\x13\x8e\x9c\x9d\xd8\x59\x19\x07\xde\x33\x84\x74\x65\xc9\x5a\xc9\x1e\x30\x9c\x26\x4e\x0a\x07\xd6\x87\x62\x0b\xe6\xa3\x9d\xe4\x2a\x3d\xfc\xa4\x86\x13\x1e\xb7\xcd\x30\x37\x23\x47\x0d\xf2\xd1\x6c\x8d\x63\x9b\x8e\x10\x8b\x94\x6b\x88\xc9\x76\x61\x54\xde\xd1\xee\x00\x36\x4d\x2e\xce\x96\xd5\xf9\x85\x0b\x72\x29\x2f\x45\x7f\x48\x65\x9b\x2a\xd3\x3a\x4b\x49\xca\x82\xad\x8b\x97\xe9\x5a\x29\xe2\x22\xdc\x1e\x4e\x82\x6f\x94\x91\xe3\x0d\x4c\x50\x78\xf3\xaa\x7b\xe6\x58\x6f\x88\xb5\xd2\x51\x66\x33\xad\xc9\x2e\x75\x62\x93\xed\x6d\xbb\x4a\x87\xc6\xc7\xf9\x51\x55\xfa\x8a\x2e\x9b\x7b\x47\xf6\xed\x43\x6b\xcc\x8f\xa9\x56\x2f\xec\xcd\x89\x92\xdd\x86\xd9\x30\xa5\x71\x41\x0f\xbc\x7e\x21\x0f\xe5\xac\x75\x6c\x49\xf9\x25\x5f\x4e\x86\x83\x8b\xe9\x39\xe6\x08\x13\x82\xdd\x7c\xe1\x7a\x83\x9c\x9e\x4d\x97\x85\x1a\xf4\x5b\xc6\x69\xb6\x89\xf0\xc1\x49\x2c\x0f\xdc\x79\x35\x26\xf2\x10\x0c\x6c\xad\x35\x0a\xcc\xe1\x31\xcf\xf6\x18\x65\x4f\x67\xbb\x35\xb9\x9d\x89\x71\xcf\x9a\x6c\x37\xd5\x7a\x9c\x54\x5d\x6f\xd8\x57\x26\xd4\x25\x1d\xf0\x9c\x53\x05\x64\x77\x68\x4c\x57\xc5\xaa\xb5\x1b\x98\xbb\xc4\x9c\xcf\x07\xc2\x3e\xca\x24\xee\xd8\x99\xc5\xcb\xd3\x6c\x32\xc8\x3a\xd3\x84\xe2\x06\xeb\x40\x9e\x1a\xbb\xc5\x68\xc5\x9b\xdb\x89\xd2\x57\x47\x3d\xbd\xe2\x41\x3c\x98\x0a\xb9\x56\x1d\x97\xda\x70\xe5\xb4\xf4\xc2\xb2\x4d\x37\xc9\x2c\x71\xb1\x52\x96\x45\x95\xf4\xba\xce\x90\xe3\x24\x9c\x66\x06\x55\x8b\x12\x5c\xc2\xd8\xcd\xf7\x32\xb9\x80\x07\x6a\x79\x6d\xb1\xf6\x69\xb7\xed\x4d\x98\x3f\x73\xbf\xbc\x78\x7f\xb1\x7a\x82\x01\x7f\x3f\x4f\x1f\xf1\x2c\xc7\x71\x61\xed\x1a\x2d\x45\x65\xcc\x69\xe0\x58\xbd\x91\x03\x7a\xd1\x66\x13\xaf\xb7\x7e\xaf\x8b\xa7\xc4\xb0\xd7\x03\x87\xb2\xa3\xbb\xe3\x03\xd5\x59\x96\xaa\x99\x1a\x33\xd5\x90\x82\x79\x30\x14\x4f\xb8\x93\x4a\x8b\xe1\xc6\xab\xa8\x55\x2c\xb2\x9b\xde\xa5\x07\x06\x11\x7d\xb0\x08\x8d\xca\xdc\xe9\x69\xe2\xfa\x31\xad\x5c\xa8\xcb\xd9\xbc\x5c\x62\xbc\x88\x17\xab\x2e\x67\xcf\x92\x23\x8e\xad\xba\x4c\xcb\x16\x33\xd5\x33\xe4\x01\xcf\xae\xc0\xd8\x20\xf2\xb9\x68\xa4\xad\x64\x40\x5a\x6b\xa1\xdc\x5c\xc2\x10\xb7\x43\x20\x2e\x14\x4e\x6a\x79\x53\x33\xa7\x8d\x8c\xdc\x05\xfb\x3e\x53\x6d\xfc\xc9\x81\x49\x23\x7f\xad\x3b\x9b\x55\x86\x9f\xe8\x5e\x3f\xdb\x31\xf9\xee\xd4\x65\x36\x47\x7f\x25\xb5\xc6\xc2\x14\x9b\x4e\xc5\xc1\x72\x38\x9f\x2d\xe6\x71\xba\xeb\xb6\x8e\x47\xe9\x42\x48\xb2\x80\x57\x69\x96\x73\x54\x26\x5f\xaa\xb3\x91\xea\xdb\x4e\xe5\xa5\x42\xdf\x6e\xcd\x85\x25\xd1\xed\x8a\x8b\x85\xac\x8c\x94\xa0\xec\xb6\x3c\xae\x4b\x1d\x4c\xb9\x1b\x60\x17\x85\x9d\x4e\xc7\xbd\x7e\x9c\x19\x53\x06\xeb\xac\xe2\x11\x5e\x59\xf3\x0e\xae\xb6\x02\x7b\x3c\x3f\xef\xf7\x7d\xfc\x30\x77\xac\x85\xbe\xe5\x76\x66\x14\x44\x7a\xca\xcb\x13\x2e\x35\x8c\xd6\x7a\x36\x98\x54\x94\x58\x9c\xb8\xa1\x7f\x88\xb2\xe1\x70\x2e\x05\x34\x8f\x2d\xa2\x65\xa5\x80\xee\xf8\xb8\x1b\xef\x27\x9d\x80\x3d\x0e\x37\x4e\xa5\x30\x85\x23\x84\x4b\x67\x31\xe6\xf3\xd3\xdc\x1e\xcc\x3c\xa5\x27\x0e\x4e\x55\x6f\x93\xca\x0b\xbe\x1b\xe0\x11\xa5\x5e\x22\x41\x58\x26\xcb\x43\xd7\xf2\xe7\xf6\x62\xa6\x83\x8d\x41\x9d\x42\x5c\x52\x69\x99\xd8\xf2\x7d\x49\xeb\xc8\x46\x39\x77\x7a\x83\xb8\xaf\x1f\x95\xa1\x38\x62\x78\xab\x55\x1c\x46\xdc\x66\x77\x5a\x38\x63\xcf\xc4\x13\xd6\xce\xe6\x66\x79\x5c\xa4\xfc\xf2\x24\x10\x47\x47\x08\x00\xb5\x5c\x0e\xe7\x2e\x7f\x76\xcf\x72\x7f\xa6\x84\xe3\x51\x8a\xd1\xe3\xd3\x59\x06\x25\x3e\xc1\x17\xdd\xd4\xbb\x78\x4e\x24\x6a\xf2\xa9\x63\x0e\x22\xc5\xab\xf2\xc4\xef\xa4\x83\x4d\x09\x8a\xd8\x15\xa9\x4e\xd7\x2a\xa2\x53\xd9\x1f\x8f\xc5\x42\x70\xb2\x69\xc5\x8d\xce\xb6\x7a\x3e\xb6\x68\x27\xf2\xfb\x7d\xad\xbf\x2f\x0c\x90\x0e\xfb\x91\x78\x21\x85\xe9\x6c\xbf\xdc\xc8\xda\xc0\xd9\x14\x95\x19\x8d\x44\x05\x0c\x28\x51\x9f\x4f\xc5\xb3\xe3\x76\x48\x35\x9e\x8a\x14\x35\xb0\xa3\x81\x13\x9e\x29\x8b\x5d\x46\xf8\x59\xf0\xf0\x34\x1b\xc8\x23\x52\x38\x9b\x5c\x87\xd7\xe3\xc1\x99\xc9\x67\xd1\xf2\xcc\xaf\x32\xd1\x67\xb2\xf5\x39\xea\x79\x43\x75\xea\x9c\xf1\x16\xa0\x39\x65\x1c\x4c\xcb\x28\xc8\x2a\x91\x9c\x7b\x18\xa9\xac\x16\xac\xc7\x8d\x71\x49\xec\x83\xfe\x60\x4a\x8b\x12\xb9\xa3\xc4\x7c\xa2\xb9\x7b\x7f\x34\x2d\xa4\xe3\x54\x58\xe5\xe6\xcc\x20\x30\xcc\x2d\xc9\x60\x37\xa2\xfd\xde\x48\xeb\x71\x63\x4e\x5f\x66\x26\xae\xf6\xed\x70\x3a\xd2\x95\xbe\x55\x12\xa0\x64\x8c\xba\x5e\xd1\xd4\x1f\xce\xc4\xd1\x25\x61\x0d\xf9\xcf\xe1\x09\x3d\x32\x2b\xe4\xa9\xbe\x7d\xf9\xf8\x13\x49\x91\x2c\x69\x7f\xb3\xa3\x30\x6b\xdb\x5a\xe0\xf9\xd5\xe3\xc3\xc0\xf2\x73\x2b\xf3\x0c\x0d\x99\x58\x67\xeb\xe1\x17\xe4\xde\xf0\x0b\x22\x24\x9e\xe6\xff\x82\xa4\x5a\x98\xb6\x53\x2b\xf1\xae\x53\xeb\x05\x00\x15\x97\xdf\x7c\x2f\xb4\xda\xae\xe5\x39\x6e\xf6\x08\x50\x8a\xfc\x16\x68\x89\xe3\x85\x8f\xf8\xb7\x22\x4a\xcc\xb6\x9e\x58\xda\xf1\xb1\xfe\xd9\xd6\x7c\xff\x5b\xbb\xb0\xf4\xa3\x97\xb5\x33\xab\x6c\xa4\xb4\x35\xf3\x70\x4e\xb3\x47\x80\xe3\x7f\xff\xd6\x0e\xd2\xaf\x7a\x6e\xf3\xb4\xb8\xed\x7a\x8e\xeb\xc3\x05\x9b\x7b\xb2\x8f\x59\xa2\x85\x69\xac\x25\x56\x98\x3d\x6b\x77\x4b\x01\x60\x2d\x9d\xfc\x56\x8b\x33\x2d\x23\x4a\xb4\xcc\x8b\xc2\xc7\x30\x0a\xad\x67\xed\xd1\x8d\x72\x2b\xb9\x8f\xc5\x71\x1d\xb7\xf8\x0f\x63\xcf\xa1\x69\x25\xd0\xc0\x67\xed\x51\x33\x32\x2f\xb7\x7e\xd1\x1e\x73\x2f\xf5\x32\xcb\x7c\x37\xf7\x39\xcd\x92\x28\x74\x90\xa7\xda\x3d\x45\xe3\x0f\x16\xc7\x9f\x33\x4d\xf7\x2d\xe4\x49\x8f\x12\xd3\x4a\xa0\xc2\xbe\x16\xa7\x30\x38\xcd\x9b\x6f\xd7\x8e\x34\xd6\x0c\x2f\x74\x1e\xf1\x6f\x81\x56\x36\x77\x6d\x1b\xc3\x5f\xde\x36\xa2\x1e\x7d\x2d\xcd\xda\x86\xeb\xf9\xe6\x5d\xaa\x1e\x65\x59\x14\xb4\x7d\xcb\xce\xda\x89\x66\x7a\xe7\xf4\x91\x8c\xcb\x6f\x6f\x7b\x93\xda\x63\x2f\xdd\xcf\x59\xf2\x68\x7b\xc9\x5d\x58\xf6\x22\x2f\x8b\xe2\x47\x1c\xf6\x87\x99\xdb\x8e\xec\x76\x56\xc5\xd6\x3f\xac\xdc\x0a\xff\xf9\x66\xab\xb9\x3a\xc0\x66\x6d\xce\xd6\x9e\xdf\xcd\x07\x71\x89\xa4\x91\xef\x99\xc8\x4f\x26\x6f\xea\x16\xf1\x2d\xd6\x4c\x13\x9a\x88\x32\xb4\x15\x7c\xcb\xad\x04\x22\xcc\x6f\x6b\xbe\xe7\x84\x8f\x59\x14\x3f\xff\x14\x6b\x0e\xc4\x92\x66\xc2\xd0\xd4\xed\x6d\x2f\xb3\x82\xf4\xd1\xb0\xc2\xcc\x4a\x5e\x21\xfc\xf1\x27\x5c\x27\x35\x9a\x7c\x6b\xe3\x23\xf5\xb2\x28\xc3\x1b\x94\x61\x7e\xbb\xe9\x68\xdb\xdf\x4c\x2f\x8d\x7d\xad\x7a\xb4\x7d\xab\x7c\x8d\x62\x14\x10\x56\xf0\xed\x75\xdc\x68\x1c\xff\x06\xa1\xe7\xd9\x55\x1b\x66\x91\x15\x66\x8f\x30\x40\x56\x5b\xb7\xb2\xc2\xb2\xc2\xbb\x2d\x38\x02\xac\xe0\xad\xe2\x2f\x08\x6c\x54\x78\xd7\x7b\x05\xd2\x7d\x10\xaf\x99\x94\xa9\xbf\x1f\xf4\x16\x9e\xb6\x6d\xbf\x19\xd0\xf6\x23\x27\x42\x9e\xae\x59\x47\xa0\x04\x74\xe8\x35\xef\x50\xd6\x0a\x90\x97\x1f\xf8\x15\x40\x2c\x0a\xe8\x77\x9a\xb6\x03\x2b\x3c\x7f\xea\xe7\x37\x9e\xba\xc9\x85\x51\x43\xf0\x4f\x24\x98\x5e\x8e\x3c\xdd\xb2\x1e\x41\x99\x4f\x97\x31\xbd\xfc\x0d\x72\xef\xe3\xe1\x7f\x5f\xcc\x49\x73\x98\x4f\x9e\xef\xdf\x5c\xf9\xed\xce\x33\xdc\xdd\xe0\x1a\x6c\x28\x20\x3e\xb7\x2e\xcd\x9d\x9b\x2f\x1b\x41\xd0\x95\x28\xec\xaa\x2d\x6e\x87\x5a\x92\x44\x05\xf2\x74\xb3\xb8\x66\x87\x9f\xae\x31\xbf\xe1\xf9\x13\x2c\x5f\x61\x77\xcd\x26\xc8\x83\x57\x83\x6a\x38\x5c\xe7\xdf\xa1\xfc\x31\x67\x2c\xd3\xc6\x6d\xea\x1d\x7a\xbf\x5c\x26\x8b\xe2\xaf\x92\x1b\x76\xbd\xcf\xec\x97\x4c\x83\x08\x80\x1a\xa1\x30\x83\xdb\x9e\x11\x85\xbf\xbc\xbc\xfd\xf5\x7f\x21\x4f\x57\x76\x69\xc0\x81\x86\x51\xfd\xeb\xa1\x9a\xad\x91\xa7\xc2\xf5\x32\xab\x26\x26\xeb\x31\x8c\x8a\x44\x8b\xaf\x47\x4e\x57\x4b\xdd\x3b\x36\x59\x9b\xa3\x78\xf0\x66\x43\x09\xa2\x30\xaa\xa7\x3d\xff\x47\x60\x99\x9e\x86\x44\xa1\x5f\x21\xa9\x91\x58\x56\x88\x68\xa1\x89\xfc\xe3\x85\xe3\x68\x1c\x8f\xcb\x7f\x22\x4f\xbf\x11\x13\x2f\xac\x29\xf8\xd5\x88\xc2\x33\xad\x77\x31\xbb\x2d\x15\x27\x1e\x0c\xdc\x5b\x2a\xf9\x34\xba\xd7\xde\x5f\x5e\x6c\xfa\xe5\xcd\x4e\x89\xe3\xf8\x27\x91\xfc\x2a\x60\xaf\x47\x7f\x86\x1b\xd8\xaf\x7d\xba\x7b\xe0\xbf\xb5\xed\xfc\x1f\x37\xb1\xec\xff\xfb\xa8\xd9\x59\x43\x07\x0d\x17\x3d\x20\xff\x78\x40\xb4\x2c\x4b\xfe\x01\xbb\xff\x89\x3c\xfc\xf3\xe1\x39\x4b\x90\xa7\xda\xe8\x66\xaf\xf5\xc2\xd4\x33\xad\x47\x2d\x8f\x3c\xf3\x8f\x32\xf9\xeb\x7d\xf4\x6b\x36\x87\x96\x3c\xff\x07\xdc\xa9\x73\xcf\x2a\xe2\x28\xc9\x6e\x30\x32\xad\xdc\x33\xae\xbf\x72\x7c\x46\xcd\x36\xa4\x8f\x17\xe7\xc3\x4f\xcf\x28\xfc\xd9\x86\x58\x42\x9e\xea\xb7\xb6\x1f\x15\x8f\x0d\xb6\xea\xcf\xa9\x9b\x78\xe1\xb1\x0d\xae\xdd\xcd\xc7\x47\xf0\x8c\x06\x7e\x5b\x3b\x67\xd1\x8d\x39\xea\x7c\x78\x84\x2d\xcf\x68\xbd\x2f\xb6\x13\x2b\x8d\xa3\x30\xad\xb9\xf5\xb6\xa6\xee\x47\xc6\xf1\xd5\x16\xfa\x0d\x52\x01\x5c\xb2\x5d\xd6\x73\xef\xc7\x8a\x7b\x7b\x6a\x24\x91\xef\xc3\xe4\xc9\xa2\xb3\xe1\x3e\xff\xed\x3b\x56\x7f\x03\xe1\xd7\xbf\x7d\xc7\x20\x08\x7e\xfd\xdb\x77\x88\x92\x5f\xff\x86\x20\xdf\x21\xf1\x79\xe6\x8f\x87\x57\x58\x7b\x80\x1d\x9f\x77\xd5\xa4\xfd\x80\x18\xbe\x96\xa6\x3f\x1e\x6a\xd0\xd5\x2d\xbf\xfe\xcf\x50\x4f\xe3\x6f\xdf\x31\xd3\xcb\x7f\x63\x36\x44\xff\x55\xfa\x75\xc4\x55\xd2\xdb\xb4\x78\xf8\xf5\xbb\x86\x40\x54\xfc\x78\x70\xb3\x2c\x4e\x1f\x31\x0c\x2e\x85\x7a\xd1\x03\x92\x69\x89\x63\x65\x3f\x1e\xfe\x53\xf7\xb5\xf0\xf8\x80\x24\x96\xff\xe3\x21\x8c\xa2\xd8\x0a\xad\x04\x09\xa3\xc4\xb2\xad\x24\x81\x46\x08\x7a\x74\xce\x90\xe1\xac\xb7\xfc\x8e\x69\xbf\xbe\x52\xed\xbf\xb6\xf4\x4f\x5e\x98\x66\x9a\xef\xff\x2b\x2a\x0c\x9b\x29\xff\x8a\x12\x0d\x71\xfc\x89\x1e\xf8\x93\xd6\xfd\x37\xcc\xff\x54\x83\xdb\x7b\x04\xf9\xb0\xa2\xe3\x65\xee\x59\x47\x8d\x28\xa8\x17\xc7\x4c\x2f\x69\x7b\xa1\x69\x95\x6d\x37\x0b\x7c\xcc\x4b\xd3\xb3\x95\x62\xff\x8a\x22\xf7\xb5\x10\xe4\x3b\xdc\x90\x9b\x2f\xf3\x3c\x7c\xfd\x65\x9e\x87\xfb\x97\x79\x1e\xe0\xde\x0e\x38\x94\x42\x08\xf0\xf0\xeb\x77\xc3\x4b\x0c\xdf\x42\x8c\xf2\xc7\x03\x8b\xd2\x0f\x88\x51\xfd\x78\xa0\x50\xee\x01\x49\x7e\x3c\x80\x07\xec\xcd\x00\x00\x50\xf0\xc9\x88\xeb\x83\x11\x0f\x4a\xfd\xad\x04\x0e\xa5\x8c\x36\x5e\x3f\x1d\x48\xd7\x0f\x33\x11\xf5\x93\x8f\x74\xfd\xa4\x72\xfd\xd8\x2f\xde\x26\x11\x70\x7d\xc8\x95\x1e\xc0\x49\x97\x37\x62\x38\x94\x46\x78\x94\x1d\xd0\xb5\x1c\x04\x47\xb9\x36\x5e\x3f\x9c\xc5\xd6\xaf\x70\x11\x1c\x21\xea\x87\xcc\x38\x84\xaa\xff\x11\x08\x8d\x12\x1b\xfe\xbd\x24\x40\xa2\x54\x2d\x8a\x47\xf9\x9c\x45\x79\x83\x40\xa9\x36\x8e\x52\x70\x46\xad\x0f\x55\x3f\x10\x4b\x74\x01\x85\x02\x04\x5c\x1f\xe1\xe4\x11\x00\xd7\xbd\x4d\xbe\xbc\xf7\x02\x8d\xb2\x8d\x17\x00\x81\xf2\x9f\x3b\x8a\xbe\x39\x0a\xd0\x28\xf5\xd5\x10\xf2\x3a\x04\xff\x62\x08\xf1\xbb\xeb\x90\x77\x19\x5f\x2d\x43\xde\x15\x79\xb3\x0a\x84\xc4\x2b\xc0\x62\xda\x1d\xc9\xaf\x08\xef\xf6\xf6\xe5\xcd\x8d\x02\xaf\x5b\xde\x7b\x5e\x7d\xbb\x2f\xdf\x59\xf5\xba\xe7\xdc\x37\x99\x87\x2f\xd2\xa6\xb9\x58\x7b\x8d\xed\x21\x4c\x12\x24\xb2\x5f\x35\x3d\x3d\x21\x89\x16\x3a\x16\x82\x76\x12\x4b\x33\x8d\xe4\x1c\xe8\x29\xd2\x7e\x7e\x7e\x35\x06\x7b\x7a\x42\x3c\x1b\x41\x67\x10\x07\xcf\xcf\xf7\x7c\x7c\x7a\x42\xfe\x47\x12\x45\x19\xda\xd7\x32\xab\xd0\xaa\xf5\x42\x46\x9e\x9f\x9f\x9e\xae\x23\xff\x1f\x72\x4e\x7c\x29\x35\xb4\xd8\x42\x9e\x9f\x1f\x7e\x85\x1d\x13\x2d\x80\x1f\xa0\x87\x9e\x9e\x10\xcb\x4f\xad\xeb\x8c\x6b\x07\x6c\x0c\x4d\xe4\xcd\xf2\x4f\x4f\xed\xdb\xc8\xb7\x8a\xdf\x14\x7a\xdb\xfa\x6e\x3e\xdc\xda\xde\xfa\xe1\x6a\xcd\x00\x1e\xf0\x5e\x0f\x7c\x45\x7b\xf7\xd3\xd2\x03\x52\x9f\x17\x7c\x2d\xb3\x20\x75\xbc\x61\x0a\xa8\xc1\x07\x21\xd8\x9b\x18\xbc\x57\xe7\x4d\xf7\x55\x8f\xa5\x77\x79\x65\xda\x6b\x2d\xde\x9c\x54\xdf\x1e\x1c\xae\x07\x85\x87\x8f\xe1\x6e\x36\x5a\xa8\xdb\x55\xf0\x7b\x07\xbc\xd7\xe1\x95\x82\xef\xb7\xe7\xab\x1e\xef\x8f\x1e\x37\x9c\xd6\xed\x77\xb1\x59\xf2\x4a\x99\xcc\xbc\x4f\xbe\x9d\xc4\xdf\xb2\xec\x7b\x67\x5f\x39\xfa\xe3\x39\xa1\xd1\x2b\x33\xdf\x08\x7f\x23\xea\x05\x8e\x68\x47\x33\x8e\xb2\x17\x1e\x5f\x63\x0f\x42\x0f\x45\x5f\xe5\xe4\x67\xf2\x7e\xbb\xe5\x3b\xf6\x62\xdc\x4b\xc2\xc8\x5e\x9a\x79\xa1\xf3\x2a\x76\xff\x65\x17\x3c\x3d\xc1\xee\x5e\x12\x05\x52\x99\x35\xc9\x00\xd5\xfe\xb7\x9c\xf1\xc7\xb2\xf0\x6b\xb1\x9f\xa1\xf0\x3d\xfe\x3f\xcb\xa3\x5a\x89\xdf\xcb\xa3\x46\xcb\x46\x42\xc3\x21\xe2\x64\x59\x47\xee\xf9\xf9\xbe\xcf\x1b\x9e\x89\x5e\x4f\x17\xd8\x4f\xf7\x6c\x7b\x1b\xda\xaf\x36\xf9\xdb\xde\x8e\xdc\xf6\xfb\x87\x17\xbe\xf9\x82\xb8\x9a\xc3\xc4\xe7\xeb\xfc\x6f\xdb\xf3\xad\x50\x0b\xac\x1f\x77\xff\xbd\x73\xec\x3d\x93\x5e\xbb\xa8\x21\x89\xa5\x1b\x25\xd9\x27\x6e\x7a\xed\xfe\xcf\xa9\xeb\x0f\x85\xe4\x4d\xae\x7f\x09\xda\x37\x69\xfe\x2a\x73\xdf\x6f\x4b\xdf\xb1\xe6\xe8\xff\x1d\x83\x87\xa9\x5f\xff\xf6\xff\x03\x00\x00\xff\xff\x15\x51\x66\x61\x81\x6f\x01\x00") - -func dirIndexHtmlDirIndexHtmlBytes() ([]byte, error) { - return bindataRead( - _dirIndexHtmlDirIndexHtml, - "dir-index-html/dir-index.html", - ) -} - -func dirIndexHtmlDirIndexHtml() (*asset, error) { - bytes, err := dirIndexHtmlDirIndexHtmlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "dir-index-html/dir-index.html", size: 94081, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dirIndexHtmlKnowniconsTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x1c\xd0\x5d\x8e\xc3\x20\x0c\x04\xe0\xf7\x39\xcc\xbc\xec\x5e\xc8\x0d\x3f\xa1\x0d\x8b\x1b\x5b\x94\xf4\xf4\x2b\xe7\xe5\x43\x06\xa1\xd1\x98\x22\x1b\x28\xad\x94\x10\x94\xd9\xc0\x47\x57\x70\x03\x37\x8d\xd3\x0c\x4c\xe2\x60\xea\x15\x4c\x63\x0b\x7c\x81\xe9\x13\xf3\x2a\x60\x56\x03\xf3\xca\x60\x39\x26\x58\x5b\x01\x77\x70\x8f\xff\xbb\xf7\x03\x6c\x9b\x81\xcd\x06\xf8\x94\x29\xe0\x53\x6b\x90\x43\x03\x5f\xf9\x02\x8f\x1c\x51\xbd\x25\xb0\xbf\x26\xd8\x47\xa0\x3f\xc1\x6f\x50\xc1\x91\x4a\x60\x81\x83\xc3\x35\x88\xd1\x1d\xd4\x78\xd5\x5d\x41\xfd\xab\xa0\x6a\xdc\x59\x02\xf5\x02\xdf\x0e\x9e\x72\x82\xe7\x03\x3c\xbd\x80\x26\x11\x68\x77\x43\x7b\x1f\xa0\x57\x09\xbe\xa0\xdf\x1b\xf1\xe5\xe0\x47\x26\xf8\xe9\x13\x5c\x87\xdd\x2c\x70\x45\xa9\x2b\xf8\x36\xc5\x7f\x00\x00\x00\xff\xff\x1a\xae\x71\x74\x46\x01\x00\x00") - -func dirIndexHtmlKnowniconsTxtBytes() ([]byte, error) { - return bindataRead( - _dirIndexHtmlKnowniconsTxt, - "dir-index-html/knownIcons.txt", - ) -} - -func dirIndexHtmlKnowniconsTxt() (*asset, error) { - bytes, err := dirIndexHtmlKnowniconsTxtBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "dir-index-html/knownIcons.txt", size: 326, mode: os.FileMode(420), modTime: time.Unix(1403768328, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "init-doc/about": initDocAbout, - "init-doc/contact": initDocContact, - "init-doc/help": initDocHelp, - "init-doc/ping": initDocPing, - "init-doc/quick-start": initDocQuickStart, - "init-doc/readme": initDocReadme, - "init-doc/security-notes": initDocSecurityNotes, - "dir-index-html/dir-index.html": dirIndexHtmlDirIndexHtml, - "dir-index-html/knownIcons.txt": dirIndexHtmlKnowniconsTxt, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} - -var _bintree = &bintree{nil, map[string]*bintree{ - "dir-index-html": {nil, map[string]*bintree{ - "dir-index.html": {dirIndexHtmlDirIndexHtml, map[string]*bintree{}}, - "knownIcons.txt": {dirIndexHtmlKnowniconsTxt, map[string]*bintree{}}, - }}, - "init-doc": {nil, map[string]*bintree{ - "about": {initDocAbout, map[string]*bintree{}}, - "contact": {initDocContact, map[string]*bintree{}}, - "help": {initDocHelp, map[string]*bintree{}}, - "ping": {initDocPing, map[string]*bintree{}}, - "quick-start": {initDocQuickStart, map[string]*bintree{}}, - "readme": {initDocReadme, map[string]*bintree{}}, - "security-notes": {initDocSecurityNotes, map[string]*bintree{}}, - }}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} diff --git a/assets/bindata_dep.go b/assets/bindata_dep.go deleted file mode 100644 index 50459a4452d..00000000000 --- a/assets/bindata_dep.go +++ /dev/null @@ -1,9 +0,0 @@ -//+build never,!never - -package assets - -import ( - // Make sure go mod tracks these deps but avoid including them in the - // actual build. - _ "github.com/go-bindata/go-bindata/v3" -) diff --git a/assets/bindata_version_hash.go b/assets/bindata_version_hash.go deleted file mode 100644 index ac8bd502fe8..00000000000 --- a/assets/bindata_version_hash.go +++ /dev/null @@ -1,6 +0,0 @@ -// File generated together with 'bindata.go' when running `go generate .` DO NOT EDIT. (@generated) -package assets - -const ( - BindataVersionHash = "512eb789cd905714e03f29d4e04de7549e8c9c3e" -) diff --git a/assets/dir-index-html/dir-index.html b/assets/dir-index-html/dir-index.html index ec00da79880..49ac2bb1f1a 100644 --- a/assets/dir-index-html/dir-index.html +++ b/assets/dir-index-html/dir-index.html @@ -31,7 +31,7 @@
- +
diff --git a/assets/dir-index-html/src/dir-index.html b/assets/dir-index-html/src/dir-index.html index f3dfd632878..376c4cd7705 100644 --- a/assets/dir-index-html/src/dir-index.html +++ b/assets/dir-index-html/src/dir-index.html @@ -30,7 +30,7 @@
- +
diff --git a/assets/dir-index-html/test/go.mod b/assets/dir-index-html/test/go.mod index fde71afe910..c1cff1b746f 100644 --- a/assets/dir-index-html/test/go.mod +++ b/assets/dir-index-html/test/go.mod @@ -1,3 +1,3 @@ module github.com/ipfs/dir-index-html/test -go 1.16 +go 1.17 diff --git a/assets/dir-index-html/test/main.go b/assets/dir-index-html/test/main.go index c02523a9f40..43b4a098101 100644 --- a/assets/dir-index-html/test/main.go +++ b/assets/dir-index-html/test/main.go @@ -12,14 +12,15 @@ const templateFile = "../dir-index.html" // Copied from go-ipfs/core/corehttp/gateway_indexPage.go type listingTemplateData struct { - GatewayURL string - DNSLink bool - Listing []directoryItem - Size string - Path string - Breadcrumbs []breadcrumb - BackLink string - Hash string + GatewayURL string + DNSLink bool + Listing []directoryItem + Size string + Path string + Breadcrumbs []breadcrumb + BackLink string + Hash string + FastDirIndexThreshold int } type directoryItem struct { diff --git a/bin/check_go_version b/bin/check_go_version index 395af8a7994..74320010bc6 100755 --- a/bin/check_go_version +++ b/bin/check_go_version @@ -39,6 +39,6 @@ type ${GOCC} >/dev/null 2>&1 || die_upgrade "go is not installed or not in the P VERS_STR=$(${GOCC} version 2>&1) || die "'go version' failed with output: $VERS_STR" -GO_CUR_VERSION=$(expr "$VERS_STR" : ".*go version go\([^ ]*\) .*") || die "Invalid 'go version' output: $VERS_STR" +GO_CUR_VERSION=$(expr "$VERS_STR" : ".*go version.* go\([^[:space:]]*\) .*") || die "Invalid 'go version' output: $VERS_STR" check_at_least_version "$GO_MIN_VERSION" "$GO_CUR_VERSION" "${GOCC}" diff --git a/bin/collect-profiles.sh b/bin/collect-profiles.sh deleted file mode 100755 index eba6495f8c8..00000000000 --- a/bin/collect-profiles.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash - -# collect-profiles.sh -# -# Collects go profile information from a running `ipfs` daemon. -# Creates an archive including the profiles, profile graph svgs, -# ...and where available, a copy of the `ipfs` binary on the PATH. -# -# Please run this script and attach the profile archive it creates -# when reporting bugs at https://github.com/ipfs/go-ipfs/issues - -set -euo pipefail -IFS=$'\n\t' - -SOURCE_URL="${1:-http://127.0.0.1:5001}" -tmpdir=$(mktemp -d) -export PPROF_TMPDIR="$tmpdir" -pushd "$tmpdir" > /dev/null - -if command -v ipfs > /dev/null 2>&1; then - cp "$(command -v ipfs)" ipfs -fi - -echo Collecting goroutine stacks -curl -s -o goroutines.stacks "$SOURCE_URL"'/debug/pprof/goroutine?debug=2' - -echo Collecting goroutine profile -go tool pprof -symbolize=remote -svg -output goroutine.svg "$SOURCE_URL/debug/pprof/goroutine" - -echo Collecting heap profile -go tool pprof -symbolize=remote -svg -output heap.svg "$SOURCE_URL/debug/pprof/heap" - -echo "Collecting cpu profile (~30s)" -go tool pprof -symbolize=remote -svg -output cpu.svg "$SOURCE_URL/debug/pprof/profile" - -echo "Enabling mutex profiling" -curl -X POST "$SOURCE_URL"'/debug/pprof-mutex/?fraction=4' - -echo "Waiting for mutex data to be updated (30s)" -sleep 30 -curl -s -o mutex.txt "$SOURCE_URL"'/debug/pprof/mutex?debug=2' -go tool pprof -symbolize=remote -svg -output mutex.svg "$SOURCE_URL/debug/pprof/mutex" - -echo "Disabling mutex profiling" -curl -X POST "$SOURCE_URL"'/debug/pprof-mutex/?fraction=0' - -OUTPUT_NAME=ipfs-profile-$(uname -n)-$(date +'%Y-%m-%dT%H:%M:%S%z').tar.gz -echo "Creating $OUTPUT_NAME" -popd > /dev/null -tar czf "./$OUTPUT_NAME" -C "$tmpdir" . -rm -rf "$tmpdir" diff --git a/bin/container_daemon b/bin/container_daemon index 8fe429036a7..ae8725be5db 100755 --- a/bin/container_daemon +++ b/bin/container_daemon @@ -1,9 +1,10 @@ #!/bin/sh set -e + user=ipfs repo="$IPFS_PATH" -if [ `id -u` -eq 0 ]; then +if [ "$(id -u)" -eq 0 ]; then echo "Changing user to $user" # ensure folder is writable su-exec "$user" test -w "$repo" || chown -R -- "$user" "$repo" @@ -14,14 +15,11 @@ fi # 2nd invocation with regular user ipfs version + if [ -e "$repo/config" ]; then echo "Found IPFS fs-repo at $repo" else - case "$IPFS_PROFILE" in - "") INIT_ARGS="" ;; - *) INIT_ARGS="--profile=$IPFS_PROFILE" ;; - esac - ipfs init $INIT_ARGS + ipfs init ${IPFS_PROFILE:+"--profile=$IPFS_PROFILE"} ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001 ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080 @@ -31,9 +29,9 @@ else SWARM_KEY_PERM=0400 # Create a swarm key from a given environment variable - if [ ! -z "$IPFS_SWARM_KEY" ] ; then + if [ -n "$IPFS_SWARM_KEY" ] ; then echo "Copying swarm key from variable..." - echo -e "$IPFS_SWARM_KEY" >"$SWARM_KEY_FILE" || exit 1 + printf "%s\n" "$IPFS_SWARM_KEY" >"$SWARM_KEY_FILE" || exit 1 chmod $SWARM_KEY_PERM "$SWARM_KEY_FILE" fi @@ -43,14 +41,15 @@ else # Check during initialization if a swarm key was provided and # copy it to the ipfs directory with the right permissions # WARNING: This will replace the swarm key if it exists - if [ ! -z "$IPFS_SWARM_KEY_FILE" ] ; then + if [ -n "$IPFS_SWARM_KEY_FILE" ] ; then echo "Copying swarm key from file..." install -m $SWARM_KEY_PERM "$IPFS_SWARM_KEY_FILE" "$SWARM_KEY_FILE" || exit 1 fi # Unset the swarm key file variable unset IPFS_SWARM_KEY_FILE - fi +find /container-init.d -maxdepth 1 -type f -iname '*.sh' -print0 | sort -z | xargs -n 1 -0 -r container_init_run + exec ipfs "$@" diff --git a/bin/container_init_run b/bin/container_init_run new file mode 100755 index 00000000000..9d20660ccfd --- /dev/null +++ b/bin/container_init_run @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +# used by the container startup script for running initialization scripts + +script="$1" +if [ -x "$script" ] ; then + printf "Executing '%s'...\n" "$script" + "$script" +else + printf "Sourcing '%s'...\n" "$script" + . "$script" +fi diff --git a/bin/gencmdref b/bin/gencmdref index e8a9ea62e79..0b3140f64f1 100755 --- a/bin/gencmdref +++ b/bin/gencmdref @@ -3,7 +3,6 @@ import os import sys import datetime -import subprocess from subprocess import check_output diff --git a/bin/get-docker-tags.sh b/bin/get-docker-tags.sh new file mode 100755 index 00000000000..809dfa4c2dc --- /dev/null +++ b/bin/get-docker-tags.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# get-docker-tags.sh +# +# Usage: +# ./get-docker-tags.sh [git tag name] +# +# Example: +# +# # get tag for the master branch +# ./get-docker-tags.sh $(date -u +%F) testingsha master +# +# # get tag for a release tag +# ./get-docker-tags.sh $(date -u +%F) testingsha release v0.5.0 +# +# # Serving suggestion in circle ci - https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables +# ./get-docker-tags.sh $(date -u +%F) "$CIRCLE_SHA1" "$CIRCLE_BRANCH" "$CIRCLE_TAG" +# +set -euo pipefail + +if [[ $# -lt 1 ]] ; then + echo 'At least 1 arg required.' + echo 'Usage:' + echo './push-docker-tags.sh [git commit sha1] [git branch name] [git tag name]' + exit 1 +fi + +BUILD_NUM=$1 +GIT_SHA1=${2:-$(git rev-parse HEAD)} +GIT_SHA1_SHORT=$(echo "$GIT_SHA1" | cut -c 1-7) +GIT_BRANCH=${3:-$(git symbolic-ref -q --short HEAD || echo "unknown")} +GIT_TAG=${4:-$(git describe --tags --exact-match || echo "")} + +IMAGE_NAME=${IMAGE_NAME:-ipfs/go-ipfs} + +echoImageName () { + local IMAGE_TAG=$1 + echo "$IMAGE_NAME:$IMAGE_TAG" +} + +if [[ $GIT_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc ]]; then + echoImageName "$GIT_TAG" + +elif [[ $GIT_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echoImageName "$GIT_TAG" + echoImageName "latest" + echoImageName "release" # see: https://github.com/ipfs/go-ipfs/issues/3999#issuecomment-742228981 + +elif [[ $GIT_BRANCH =~ ^bifrost-.* ]]; then + # sanitize the branch name since docker tags have stricter char limits than git branch names + branch=$(echo "$GIT_BRANCH" | tr '/' '-' | tr --delete --complement '[:alnum:]-') + echoImageName "${branch}-${BUILD_NUM}-${GIT_SHA1_SHORT}" + +elif [ "$GIT_BRANCH" = "master" ]; then + echoImageName "master-${BUILD_NUM}-${GIT_SHA1_SHORT}" + echoImageName "master-latest" + +else + echo "Nothing to do. No docker tag defined for branch: $GIT_BRANCH, tag: $GIT_TAG" + +fi diff --git a/bin/mkreleaselog b/bin/mkreleaselog index d9f91833707..bbf570b7f63 100755 --- a/bin/mkreleaselog +++ b/bin/mkreleaselog @@ -45,6 +45,7 @@ IGNORE_FILES=( "*.pb.go" "cbor_gen.go" "ipldsch_*.go" + "*.gen.go" ) ########################################################################################## diff --git a/blocks/blockstoreutil/remove.go b/blocks/blockstoreutil/remove.go index 880f033656f..4440c2a6538 100644 --- a/blocks/blockstoreutil/remove.go +++ b/blocks/blockstoreutil/remove.go @@ -3,23 +3,24 @@ package blockstoreutil import ( "context" + "errors" "fmt" - "io" cid "github.com/ipfs/go-cid" bs "github.com/ipfs/go-ipfs-blockstore" pin "github.com/ipfs/go-ipfs-pinner" + format "github.com/ipfs/go-ipld-format" ) // RemovedBlock is used to represent the result of removing a block. -// If a block was removed successfully, then the Error string will be -// empty. If a block could not be removed, then Error will contain the +// If a block was removed successfully, then the Error will be empty. +// If a block could not be removed, then Error will contain the // reason the block could not be removed. If the removal was aborted // due to a fatal error, Hash will be empty, Error will contain the // reason, and no more results will be sent. type RemovedBlock struct { - Hash string `json:",omitempty"` - Error string `json:",omitempty"` + Hash string + Error error } // RmBlocksOpts is used to wrap options for RmBlocks(). @@ -50,17 +51,17 @@ func RmBlocks(ctx context.Context, blocks bs.GCBlockstore, pins pin.Pinner, cids // remove this sometime in the future. has, err := blocks.Has(ctx, c) if err != nil { - out <- &RemovedBlock{Hash: c.String(), Error: err.Error()} + out <- &RemovedBlock{Hash: c.String(), Error: err} continue } if !has && !opts.Force { - out <- &RemovedBlock{Hash: c.String(), Error: bs.ErrNotFound.Error()} + out <- &RemovedBlock{Hash: c.String(), Error: format.ErrNotFound{Cid: c}} continue } err = blocks.DeleteBlock(ctx, c) if err != nil { - out <- &RemovedBlock{Hash: c.String(), Error: err.Error()} + out <- &RemovedBlock{Hash: c.String(), Error: err} } else if !opts.Quiet { out <- &RemovedBlock{Hash: c.String()} } @@ -78,7 +79,7 @@ func FilterPinned(ctx context.Context, pins pin.Pinner, out chan<- interface{}, stillOkay := make([]cid.Cid, 0, len(cids)) res, err := pins.CheckIfPinned(ctx, cids...) if err != nil { - out <- &RemovedBlock{Error: fmt.Sprintf("pin check failed: %s", err)} + out <- &RemovedBlock{Error: fmt.Errorf("pin check failed: %w", err)} return nil } for _, r := range res { @@ -87,36 +88,9 @@ func FilterPinned(ctx context.Context, pins pin.Pinner, out chan<- interface{}, } else { out <- &RemovedBlock{ Hash: r.Key.String(), - Error: r.String(), + Error: errors.New(r.String()), } } } return stillOkay } - -// ProcRmOutput takes a function which returns a result from RmBlocks or EOF if there is no input. -// It then writes to stdout/stderr according to the RemovedBlock object returned from the function. -func ProcRmOutput(next func() (interface{}, error), sout io.Writer, serr io.Writer) error { - someFailed := false - for { - res, err := next() - if err == io.EOF { - break - } else if err != nil { - return err - } - r := res.(*RemovedBlock) - if r.Hash == "" && r.Error != "" { - return fmt.Errorf("aborted: %s", r.Error) - } else if r.Error != "" { - someFailed = true - fmt.Fprintf(serr, "cannot remove %s: %s\n", r.Hash, r.Error) - } else { - fmt.Fprintf(sout, "removed %s\n", r.Hash) - } - } - if someFailed { - return fmt.Errorf("some blocks not removed") - } - return nil -} diff --git a/cmd/ipfs/add_migrations.go b/cmd/ipfs/add_migrations.go index b5b6c31a137..58b62e4f777 100644 --- a/cmd/ipfs/add_migrations.go +++ b/cmd/ipfs/add_migrations.go @@ -9,7 +9,7 @@ import ( "os" "path/filepath" - "github.com/ipfs/go-ipfs-files" + files "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" "github.com/ipfs/go-ipfs/repo/fsrepo/migrations" @@ -37,7 +37,7 @@ func addMigrations(ctx context.Context, node *core.IpfsNode, fetcher migrations. if err != nil { return err } - case *migrations.HttpFetcher: + case *migrations.HttpFetcher, *migrations.RetryFetcher: // https://github.com/ipfs/go-ipfs/issues/8780 // Add the downloaded migration files directly if migrations.DownloadDirectory != "" { var paths []string diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 5de7e056eac..c1346059309 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -17,10 +17,10 @@ import ( multierror "github.com/hashicorp/go-multierror" version "github.com/ipfs/go-ipfs" - config "github.com/ipfs/go-ipfs-config" - cserial "github.com/ipfs/go-ipfs-config/serialize" utilmain "github.com/ipfs/go-ipfs/cmd/ipfs/util" oldcmds "github.com/ipfs/go-ipfs/commands" + config "github.com/ipfs/go-ipfs/config" + cserial "github.com/ipfs/go-ipfs/config/serialize" "github.com/ipfs/go-ipfs/core" commands "github.com/ipfs/go-ipfs/core/commands" "github.com/ipfs/go-ipfs/core/coreapi" @@ -169,7 +169,7 @@ Headers. cmds.StringOption(initConfigOptionKwd, "Path to existing configuration file to be loaded during --init"), cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"), cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd), - cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem"), + cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"), cmds.BoolOption(writableKwd, "Enable writing objects (with POST, PUT and DELETE)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount). Defaults to config setting."), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount). Defaults to config setting."), @@ -298,7 +298,8 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment } // Read Migration section of IPFS config - migrationCfg, err := migrations.ReadMigrationConfig(cctx.ConfigRoot) + configFileOpt, _ := req.Options[commands.ConfigFileOption].(string) + migrationCfg, err := migrations.ReadMigrationConfig(cctx.ConfigRoot, configFileOpt) if err != nil { return err } @@ -309,7 +310,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment // to construct the particular IPFS fetcher implementation used here, // which is called only if an IPFS fetcher is needed. newIpfsFetcher := func(distPath string) migrations.Fetcher { - return ipfsfetcher.NewIpfsFetcher(distPath, 0, &cctx.ConfigRoot) + return ipfsfetcher.NewIpfsFetcher(distPath, 0, &cctx.ConfigRoot, configFileOpt) } // Fetch migrations from current distribution, or location from environ @@ -427,7 +428,6 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment node, err := core.NewNode(req.Context, ncfg) if err != nil { - log.Error("error from node construction: ", err) return err } node.IsDaemon = true @@ -660,7 +660,9 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error corehttp.VersionOption(), defaultMux("/debug/vars"), defaultMux("/debug/pprof/"), + defaultMux("/debug/stack"), corehttp.MutexFractionOption("/debug/pprof-mutex/"), + corehttp.BlockProfileRateOption("/debug/pprof-block/"), corehttp.MetricsScrapingOption("/debug/metrics/prometheus"), corehttp.LogOption(), } diff --git a/cmd/ipfs/daemon_linux.go b/cmd/ipfs/daemon_linux.go index a1123b003aa..d06baf286b0 100644 --- a/cmd/ipfs/daemon_linux.go +++ b/cmd/ipfs/daemon_linux.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package main diff --git a/cmd/ipfs/daemon_other.go b/cmd/ipfs/daemon_other.go index 4ffdd8b8ef3..cb96ce1b90c 100644 --- a/cmd/ipfs/daemon_other.go +++ b/cmd/ipfs/daemon_other.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package main diff --git a/cmd/ipfs/debug.go b/cmd/ipfs/debug.go new file mode 100644 index 00000000000..5eeb590e2c5 --- /dev/null +++ b/cmd/ipfs/debug.go @@ -0,0 +1,15 @@ +package main + +import ( + "net/http" + + "github.com/ipfs/go-ipfs/profile" +) + +func init() { + http.HandleFunc("/debug/stack", + func(w http.ResponseWriter, _ *http.Request) { + _ = profile.WriteAllGoroutineStacks(w) + }, + ) +} diff --git a/cmd/ipfs/dist/install.sh b/cmd/ipfs/dist/install.sh index 34c5d59e9c8..470927159da 100755 --- a/cmd/ipfs/dist/install.sh +++ b/cmd/ipfs/dist/install.sh @@ -6,13 +6,16 @@ INSTALL_DIR=$(dirname $0) bin="$INSTALL_DIR/ipfs" -binpaths="/usr/local/bin /usr/bin" +binpaths='/usr/local/bin /usr/bin $HOME/.local/bin' # This variable contains a nonzero length string in case the script fails # because of missing write permissions. is_write_perm_missing="" -for binpath in $binpaths; do +for raw in $binpaths; do + # Expand the $HOME variable. + binpath=$(eval echo "$raw") + mkdir -p "$binpath" if mv "$bin" "$binpath/ipfs" ; then echo "Moved $bin to $binpath" exit 0 diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index de3ad1180fa..dfbf01bb3a6 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -19,8 +19,8 @@ import ( unixfs "github.com/ipfs/go-unixfs" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" + config "github.com/ipfs/go-ipfs/config" options "github.com/ipfs/interface-go-ipfs-core/options" ) diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index d975d18971f..6147a0cbf75 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -20,11 +20,12 @@ import ( loader "github.com/ipfs/go-ipfs/plugin/loader" repo "github.com/ipfs/go-ipfs/repo" fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" + "github.com/ipfs/go-ipfs/tracing" + "go.opentelemetry.io/otel" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-cmds/cli" cmdhttp "github.com/ipfs/go-ipfs-cmds/http" - config "github.com/ipfs/go-ipfs-config" u "github.com/ipfs/go-ipfs-util" logging "github.com/ipfs/go-log" loggables "github.com/libp2p/go-libp2p-loggables" @@ -71,21 +72,30 @@ func main() { os.Exit(mainRet()) } -func mainRet() int { +func printErr(err error) int { + fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) + return 1 +} + +func mainRet() (exitCode int) { rand.Seed(time.Now().UnixNano()) ctx := logging.ContextWithLoggable(context.Background(), loggables.Uuid("session")) var err error - // we'll call this local helper to output errors. - // this is so we control how to print errors in one place. - printErr := func(err error) { - fmt.Fprintf(os.Stderr, "Error: %s\n", err.Error()) + tp, err := tracing.NewTracerProvider(ctx) + if err != nil { + return printErr(err) } + defer func() { + if err := tp.Shutdown(ctx); err != nil { + exitCode = printErr(err) + } + }() + otel.SetTracerProvider(tp) stopFunc, err := profileIfEnabled() if err != nil { - printErr(err) - return 1 + return printErr(err) } defer stopFunc() // to be executed as late as possible @@ -138,7 +148,6 @@ func mainRet() int { // this is so that we can construct the node lazily. return &oldcmds.Context{ ConfigRoot: repoPath, - LoadConfig: loadConfig, ReqLog: &oldcmds.ReqLog{}, Plugins: plugins, ConstructNode: func() (n *core.IpfsNode, err error) { @@ -294,7 +303,7 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) { } func getRepoPath(req *cmds.Request) (string, error) { - repoOpt, found := req.Options["config"].(string) + repoOpt, found := req.Options[corecmds.RepoDirOption].(string) if found && repoOpt != "" { return repoOpt, nil } @@ -306,10 +315,6 @@ func getRepoPath(req *cmds.Request) (string, error) { return repoPath, nil } -func loadConfig(path string) (*config.Config, error) { - return fsrepo.ConfigAt(path) -} - // startProfiling begins CPU profiling and returns a `stop` function to be // executed as late as possible. The stop function captures the memprofile. func startProfiling() (func(), error) { diff --git a/cmd/ipfs/pinmfs.go b/cmd/ipfs/pinmfs.go index 8ea9d2dcc8e..021b0530b96 100644 --- a/cmd/ipfs/pinmfs.go +++ b/cmd/ipfs/pinmfs.go @@ -13,7 +13,7 @@ import ( logging "github.com/ipfs/go-log" pinclient "github.com/ipfs/go-pinning-service-http-client" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/core" ) @@ -36,7 +36,7 @@ const defaultRepinInterval = 5 * time.Minute type pinMFSContext interface { Context() context.Context - GetConfigNoCache() (*config.Config, error) + GetConfig() (*config.Config, error) } type pinMFSNode interface { @@ -104,7 +104,7 @@ func pinMFSOnChange(configPollInterval time.Duration, cctx pinMFSContext, node p } // reread the config, which may have changed in the meantime - cfg, err := cctx.GetConfigNoCache() + cfg, err := cctx.GetConfig() if err != nil { select { case errCh <- fmt.Errorf("pinning reading config (%v)", err): diff --git a/cmd/ipfs/pinmfs_test.go b/cmd/ipfs/pinmfs_test.go index e38e196beb3..2c79c20432c 100644 --- a/cmd/ipfs/pinmfs_test.go +++ b/cmd/ipfs/pinmfs_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ipld "github.com/ipfs/go-ipld-format" merkledag "github.com/ipfs/go-merkledag" "github.com/libp2p/go-libp2p-core/host" @@ -24,7 +24,7 @@ func (x *testPinMFSContext) Context() context.Context { return x.ctx } -func (x *testPinMFSContext) GetConfigNoCache() (*config.Config, error) { +func (x *testPinMFSContext) GetConfig() (*config.Config, error) { return x.cfg, x.err } diff --git a/cmd/ipfs/runmain_test.go b/cmd/ipfs/runmain_test.go index 8eecce3347f..360f2bc533d 100644 --- a/cmd/ipfs/runmain_test.go +++ b/cmd/ipfs/runmain_test.go @@ -1,3 +1,4 @@ +//go:build testrunmain // +build testrunmain package main diff --git a/cmd/ipfs/util/signal.go b/cmd/ipfs/util/signal.go index 393a953b907..2cfd0d5bd2d 100644 --- a/cmd/ipfs/util/signal.go +++ b/cmd/ipfs/util/signal.go @@ -1,3 +1,4 @@ +//go:build !wasm // +build !wasm package util diff --git a/cmd/ipfs/util/ui.go b/cmd/ipfs/util/ui.go index d68c9d7a504..cf8ad506744 100644 --- a/cmd/ipfs/util/ui.go +++ b/cmd/ipfs/util/ui.go @@ -1,4 +1,5 @@ -//+build !windows +//go:build !windows +// +build !windows package util diff --git a/cmd/ipfs/util/ulimit_freebsd.go b/cmd/ipfs/util/ulimit_freebsd.go index d4a36de44bf..27b31349b4b 100644 --- a/cmd/ipfs/util/ulimit_freebsd.go +++ b/cmd/ipfs/util/ulimit_freebsd.go @@ -1,3 +1,4 @@ +//go:build freebsd // +build freebsd package util diff --git a/cmd/ipfs/util/ulimit_test.go b/cmd/ipfs/util/ulimit_test.go index 80862ee5852..bef480fffbf 100644 --- a/cmd/ipfs/util/ulimit_test.go +++ b/cmd/ipfs/util/ulimit_test.go @@ -1,3 +1,4 @@ +//go:build !windows && !plan9 // +build !windows,!plan9 package util diff --git a/cmd/ipfs/util/ulimit_unix.go b/cmd/ipfs/util/ulimit_unix.go index ee30dadaf5c..d3b0ec43c89 100644 --- a/cmd/ipfs/util/ulimit_unix.go +++ b/cmd/ipfs/util/ulimit_unix.go @@ -1,3 +1,4 @@ +//go:build darwin || linux || netbsd || openbsd // +build darwin linux netbsd openbsd package util diff --git a/cmd/ipfs/util/ulimit_windows.go b/cmd/ipfs/util/ulimit_windows.go index 3cd9908c327..5dbfd26f7d7 100644 --- a/cmd/ipfs/util/ulimit_windows.go +++ b/cmd/ipfs/util/ulimit_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package util diff --git a/cmd/ipfswatch/ipfswatch_test.go b/cmd/ipfswatch/ipfswatch_test.go index f6a6f7eecb4..b5a41c6bc2a 100644 --- a/cmd/ipfswatch/ipfswatch_test.go +++ b/cmd/ipfswatch/ipfswatch_test.go @@ -1,3 +1,4 @@ +//go:build !plan9 // +build !plan9 package main diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go index e0bd00e17dc..9ffc6f62ea1 100644 --- a/cmd/ipfswatch/main.go +++ b/cmd/ipfswatch/main.go @@ -1,3 +1,4 @@ +//go:build !plan9 // +build !plan9 package main @@ -18,7 +19,6 @@ import ( fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" fsnotify "github.com/fsnotify/fsnotify" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" process "github.com/jbenet/goprocess" homedir "github.com/mitchellh/go-homedir" @@ -216,9 +216,6 @@ func IsHidden(path string) bool { func cmdCtx(node *core.IpfsNode, repoPath string) commands.Context { return commands.Context{ ConfigRoot: repoPath, - LoadConfig: func(path string) (*config.Config, error) { - return node.Repo.Config() - }, ConstructNode: func() (*core.IpfsNode, error) { return node, nil }, diff --git a/commands/context.go b/commands/context.go index e43672eee49..be768f54a12 100644 --- a/commands/context.go +++ b/commands/context.go @@ -11,7 +11,7 @@ import ( loader "github.com/ipfs/go-ipfs/plugin/loader" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" logging "github.com/ipfs/go-log" coreiface "github.com/ipfs/interface-go-ipfs-core" options "github.com/ipfs/interface-go-ipfs-core/options" @@ -26,30 +26,18 @@ type Context struct { Plugins *loader.PluginLoader - config *config.Config - LoadConfig func(path string) (*config.Config, error) - Gateway bool api coreiface.CoreAPI node *core.IpfsNode ConstructNode func() (*core.IpfsNode, error) } -// GetConfig returns the config of the current Command execution -// context. It may load it with the provided function. func (c *Context) GetConfig() (*config.Config, error) { - var err error - if c.config == nil { - if c.LoadConfig == nil { - return nil, errors.New("nil LoadConfig function") - } - c.config, err = c.LoadConfig(c.ConfigRoot) + node, err := c.GetNode() + if err != nil { + return nil, err } - return c.config, err -} - -func (c *Context) GetConfigNoCache() (*config.Config, error) { - return c.LoadConfig(c.ConfigRoot) + return node.Repo.Config() } // GetNode returns the node of the current Command execution @@ -61,12 +49,6 @@ func (c *Context) GetNode() (*core.IpfsNode, error) { return nil, errors.New("nil ConstructNode function") } c.node, err = c.ConstructNode() - if err == nil { - // Pre-load the config from the repo to avoid re-parsing it from disk. - if cfg, err := c.node.Repo.Config(); err != nil { - c.config = cfg - } - } } return c.node, err } diff --git a/commands/reqlog.go b/commands/reqlog.go index cd52d75bf2f..14c10a7c0f8 100644 --- a/commands/reqlog.go +++ b/commands/reqlog.go @@ -42,7 +42,7 @@ func (rl *ReqLog) AddEntry(rle *ReqLogEntry) { rl.nextID++ rl.Requests = append(rl.Requests, rle) - if rle == nil || !rle.Active { + if !rle.Active { rl.maybeCleanup() } } diff --git a/config/addresses.go b/config/addresses.go new file mode 100644 index 00000000000..f16563d6ad6 --- /dev/null +++ b/config/addresses.go @@ -0,0 +1,11 @@ +package config + +// Addresses stores the (string) multiaddr addresses for the node. +type Addresses struct { + Swarm []string // addresses for the swarm to listen on + Announce []string // swarm addresses to announce to the network, if len > 0 replaces auto detected addresses + AppendAnnounce []string // similar to Announce but doesn't overwrite auto detected addresses, they are just appended + NoAnnounce []string // swarm addresses not to announce to the network + API Strings // address for the local API (RPC) + Gateway Strings // address to listen on for IPFS HTTP object gateway +} diff --git a/config/api.go b/config/api.go new file mode 100644 index 00000000000..b36b1080304 --- /dev/null +++ b/config/api.go @@ -0,0 +1,5 @@ +package config + +type API struct { + HTTPHeaders map[string][]string // HTTP headers to return with the API. +} diff --git a/config/autonat.go b/config/autonat.go new file mode 100644 index 00000000000..64856faa680 --- /dev/null +++ b/config/autonat.go @@ -0,0 +1,81 @@ +package config + +import ( + "fmt" +) + +// AutoNATServiceMode configures the ipfs node's AutoNAT service. +type AutoNATServiceMode int + +const ( + // AutoNATServiceUnset indicates that the user has not set the + // AutoNATService mode. + // + // When unset, nodes configured to be public DHT nodes will _also_ + // perform limited AutoNAT dialbacks. + AutoNATServiceUnset AutoNATServiceMode = iota + // AutoNATServiceEnabled indicates that the user has enabled the + // AutoNATService. + AutoNATServiceEnabled + // AutoNATServiceDisabled indicates that the user has disabled the + // AutoNATService. + AutoNATServiceDisabled +) + +func (m *AutoNATServiceMode) UnmarshalText(text []byte) error { + switch string(text) { + case "": + *m = AutoNATServiceUnset + case "enabled": + *m = AutoNATServiceEnabled + case "disabled": + *m = AutoNATServiceDisabled + default: + return fmt.Errorf("unknown autonat mode: %s", string(text)) + } + return nil +} + +func (m AutoNATServiceMode) MarshalText() ([]byte, error) { + switch m { + case AutoNATServiceUnset: + return nil, nil + case AutoNATServiceEnabled: + return []byte("enabled"), nil + case AutoNATServiceDisabled: + return []byte("disabled"), nil + default: + return nil, fmt.Errorf("unknown autonat mode: %d", m) + } +} + +// AutoNATConfig configures the node's AutoNAT subsystem. +type AutoNATConfig struct { + // ServiceMode configures the node's AutoNAT service mode. + ServiceMode AutoNATServiceMode `json:",omitempty"` + + // Throttle configures AutoNAT dialback throttling. + // + // If unset, the conservative libp2p defaults will be unset. To help the + // network, please consider setting this and increasing the limits. + // + // By default, the limits will be a total of 30 dialbacks, with a + // per-peer max of 3 peer, resetting every minute. + Throttle *AutoNATThrottleConfig `json:",omitempty"` +} + +// AutoNATThrottleConfig configures the throttle limites +type AutoNATThrottleConfig struct { + // GlobalLimit and PeerLimit sets the global and per-peer dialback + // limits. The AutoNAT service will only perform the specified number of + // dialbacks per interval. + // + // Setting either to 0 will disable the appropriate limit. + GlobalLimit, PeerLimit int + + // Interval specifies how frequently this node should reset the + // global/peer dialback limits. + // + // When unset, this defaults to 1 minute. + Interval OptionalDuration `json:",omitempty"` +} diff --git a/config/bootstrap_peers.go b/config/bootstrap_peers.go new file mode 100644 index 00000000000..e22c55fb8a7 --- /dev/null +++ b/config/bootstrap_peers.go @@ -0,0 +1,77 @@ +package config + +import ( + "errors" + "fmt" + + peer "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" +) + +// DefaultBootstrapAddresses are the hardcoded bootstrap addresses +// for IPFS. they are nodes run by the IPFS team. docs on these later. +// As with all p2p networks, bootstrap is an important security concern. +// +// NOTE: This is here -- and not inside cmd/ipfs/init.go -- because of an +// import dependency issue. TODO: move this into a config/default/ package. +var DefaultBootstrapAddresses = []string{ + "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", + "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", + "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", + "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", + "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io + "/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io +} + +// ErrInvalidPeerAddr signals an address is not a valid peer address. +var ErrInvalidPeerAddr = errors.New("invalid peer address") + +func (c *Config) BootstrapPeers() ([]peer.AddrInfo, error) { + return ParseBootstrapPeers(c.Bootstrap) +} + +// DefaultBootstrapPeers returns the (parsed) set of default bootstrap peers. +// if it fails, it returns a meaningful error for the user. +// This is here (and not inside cmd/ipfs/init) because of module dependency problems. +func DefaultBootstrapPeers() ([]peer.AddrInfo, error) { + ps, err := ParseBootstrapPeers(DefaultBootstrapAddresses) + if err != nil { + return nil, fmt.Errorf(`failed to parse hardcoded bootstrap peers: %s +This is a problem with the ipfs codebase. Please report it to the dev team`, err) + } + return ps, nil +} + +func (c *Config) SetBootstrapPeers(bps []peer.AddrInfo) { + c.Bootstrap = BootstrapPeerStrings(bps) +} + +// ParseBootstrapPeer parses a bootstrap list into a list of AddrInfos. +func ParseBootstrapPeers(addrs []string) ([]peer.AddrInfo, error) { + maddrs := make([]ma.Multiaddr, len(addrs)) + for i, addr := range addrs { + var err error + maddrs[i], err = ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + } + return peer.AddrInfosFromP2pAddrs(maddrs...) +} + +// BootstrapPeerStrings formats a list of AddrInfos as a bootstrap peer list +// suitable for serialization. +func BootstrapPeerStrings(bps []peer.AddrInfo) []string { + bpss := make([]string, 0, len(bps)) + for _, pi := range bps { + addrs, err := peer.AddrInfoToP2pAddrs(&pi) + if err != nil { + // programmer error. + panic(err) + } + for _, addr := range addrs { + bpss = append(bpss, addr.String()) + } + } + return bpss +} diff --git a/config/bootstrap_peers_test.go b/config/bootstrap_peers_test.go new file mode 100644 index 00000000000..eeea9b5fdc0 --- /dev/null +++ b/config/bootstrap_peers_test.go @@ -0,0 +1,24 @@ +package config + +import ( + "sort" + "testing" +) + +func TestBoostrapPeerStrings(t *testing.T) { + parsed, err := ParseBootstrapPeers(DefaultBootstrapAddresses) + if err != nil { + t.Fatal(err) + } + + formatted := BootstrapPeerStrings(parsed) + sort.Strings(formatted) + expected := append([]string{}, DefaultBootstrapAddresses...) + sort.Strings(expected) + + for i, s := range formatted { + if expected[i] != s { + t.Fatalf("expected %s, %s", expected[i], s) + } + } +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 00000000000..1f4d9e83c87 --- /dev/null +++ b/config/config.go @@ -0,0 +1,151 @@ +// package config implements the ipfs config file datastructures and utilities. +package config + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/mitchellh/go-homedir" +) + +// Config is used to load ipfs config files. +type Config struct { + Identity Identity // local node's peer identity + Datastore Datastore // local node's storage + Addresses Addresses // local node's addresses + Mounts Mounts // local node's mount points + Discovery Discovery // local node's discovery mechanisms + Routing Routing // local node's routing settings + Ipns Ipns // Ipns settings + Bootstrap []string // local nodes's bootstrap peer addresses + Gateway Gateway // local node's gateway server options + API API // local node's API settings + Swarm SwarmConfig + AutoNAT AutoNATConfig + Pubsub PubsubConfig + Peering Peering + DNS DNS + Migration Migration + + Provider Provider + Reprovider Reprovider + Experimental Experiments + Plugins Plugins + Pinning Pinning + + Internal Internal // experimental/unstable options +} + +const ( + // DefaultPathName is the default config dir name + DefaultPathName = ".ipfs" + // DefaultPathRoot is the path to the default config dir location. + DefaultPathRoot = "~/" + DefaultPathName + // DefaultConfigFile is the filename of the configuration file + DefaultConfigFile = "config" + // EnvDir is the environment variable used to change the path root. + EnvDir = "IPFS_PATH" +) + +// PathRoot returns the default configuration root directory +func PathRoot() (string, error) { + dir := os.Getenv(EnvDir) + var err error + if len(dir) == 0 { + dir, err = homedir.Expand(DefaultPathRoot) + } + return dir, err +} + +// Path returns the path `extension` relative to the configuration root. If an +// empty string is provided for `configroot`, the default root is used. +func Path(configroot, extension string) (string, error) { + if len(configroot) == 0 { + dir, err := PathRoot() + if err != nil { + return "", err + } + return filepath.Join(dir, extension), nil + + } + return filepath.Join(configroot, extension), nil +} + +// Filename returns the configuration file path given a configuration root +// directory and a user-provided configuration file path argument with the +// following rules: +// * If the user-provided configuration file path is empty, use the default one. +// * If the configuration root directory is empty, use the default one. +// * If the user-provided configuration file path is only a file name, use the +// configuration root directory, otherwise use only the user-provided path +// and ignore the configuration root. +func Filename(configroot string, userConfigFile string) (string, error) { + if userConfigFile == "" { + return Path(configroot, DefaultConfigFile) + } + + if filepath.Dir(userConfigFile) == "." { + return Path(configroot, userConfigFile) + } + + return userConfigFile, nil +} + +// HumanOutput gets a config value ready for printing +func HumanOutput(value interface{}) ([]byte, error) { + s, ok := value.(string) + if ok { + return []byte(strings.Trim(s, "\n")), nil + } + return Marshal(value) +} + +// Marshal configuration with JSON +func Marshal(value interface{}) ([]byte, error) { + // need to prettyprint, hence MarshalIndent, instead of Encoder + return json.MarshalIndent(value, "", " ") +} + +func FromMap(v map[string]interface{}) (*Config, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(v); err != nil { + return nil, err + } + var conf Config + if err := json.NewDecoder(buf).Decode(&conf); err != nil { + return nil, fmt.Errorf("failure to decode config: %s", err) + } + return &conf, nil +} + +func ToMap(conf *Config) (map[string]interface{}, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(conf); err != nil { + return nil, err + } + var m map[string]interface{} + if err := json.NewDecoder(buf).Decode(&m); err != nil { + return nil, fmt.Errorf("failure to decode config: %s", err) + } + return m, nil +} + +// Clone copies the config. Use when updating. +func (c *Config) Clone() (*Config, error) { + var newConfig Config + var buf bytes.Buffer + + if err := json.NewEncoder(&buf).Encode(c); err != nil { + return nil, fmt.Errorf("failure to encode config: %s", err) + } + + if err := json.NewDecoder(&buf).Decode(&newConfig); err != nil { + return nil, fmt.Errorf("failure to decode config: %s", err) + } + + return &newConfig, nil +} diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 00000000000..dead06f8a23 --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,29 @@ +package config + +import ( + "testing" +) + +func TestClone(t *testing.T) { + c := new(Config) + c.Identity.PeerID = "faketest" + c.API.HTTPHeaders = map[string][]string{"foo": {"bar"}} + + newCfg, err := c.Clone() + if err != nil { + t.Fatal(err) + } + if newCfg.Identity.PeerID != c.Identity.PeerID { + t.Fatal("peer ID not preserved") + } + + c.API.HTTPHeaders["foo"] = []string{"baz"} + if newCfg.API.HTTPHeaders["foo"][0] != "bar" { + t.Fatal("HTTP headers not preserved") + } + + delete(c.API.HTTPHeaders, "foo") + if newCfg.API.HTTPHeaders["foo"][0] != "bar" { + t.Fatal("HTTP headers not preserved") + } +} diff --git a/config/datastore.go b/config/datastore.go new file mode 100644 index 00000000000..2b2bcb51828 --- /dev/null +++ b/config/datastore.go @@ -0,0 +1,32 @@ +package config + +import ( + "encoding/json" +) + +// DefaultDataStoreDirectory is the directory to store all the local IPFS data. +const DefaultDataStoreDirectory = "datastore" + +// Datastore tracks the configuration of the datastore. +type Datastore struct { + StorageMax string // in B, kB, kiB, MB, ... + StorageGCWatermark int64 // in percentage to multiply on StorageMax + GCPeriod string // in ns, us, ms, s, m, h + + // deprecated fields, use Spec + Type string `json:",omitempty"` + Path string `json:",omitempty"` + NoSync bool `json:",omitempty"` + Params *json.RawMessage `json:",omitempty"` + + Spec map[string]interface{} + + HashOnRead bool + BloomFilterSize int +} + +// DataStorePath returns the default data store path given a configuration root +// (set an empty string to have the default configuration root) +func DataStorePath(configroot string) (string, error) { + return Path(configroot, DefaultDataStoreDirectory) +} diff --git a/config/discovery.go b/config/discovery.go new file mode 100644 index 00000000000..4fb8508f00a --- /dev/null +++ b/config/discovery.go @@ -0,0 +1,12 @@ +package config + +type Discovery struct { + MDNS MDNS +} + +type MDNS struct { + Enabled bool + + // Time in seconds between discovery rounds + Interval int +} diff --git a/config/dns.go b/config/dns.go new file mode 100644 index 00000000000..b0f7b2710b6 --- /dev/null +++ b/config/dns.go @@ -0,0 +1,17 @@ +package config + +// DNS specifies DNS resolution rules using custom resolvers +type DNS struct { + // Resolvers is a map of FQDNs to URLs for custom DNS resolution. + // URLs starting with `https://` indicate DoH endpoints. + // Support for other resolver types can be added in the future. + // https://en.wikipedia.org/wiki/Fully_qualified_domain_name + // https://en.wikipedia.org/wiki/DNS_over_HTTPS + // + // Example: + // - Custom resolver for ENS: `eth.` โ†’ `https://eth.link/dns-query` + // - Override the default OS resolver: `.` โ†’ `https://doh.applied-privacy.net/query` + Resolvers map[string]string + // MaxCacheTTL is the maximum duration DNS entries are valid in the cache. + MaxCacheTTL *OptionalDuration `json:",omitempty"` +} diff --git a/config/experiments.go b/config/experiments.go new file mode 100644 index 00000000000..dba0ea7139b --- /dev/null +++ b/config/experiments.go @@ -0,0 +1,12 @@ +package config + +type Experiments struct { + FilestoreEnabled bool + UrlstoreEnabled bool + ShardingEnabled bool `json:",omitempty"` // deprecated by autosharding: https://github.com/ipfs/go-ipfs/pull/8527 + GraphsyncEnabled bool + Libp2pStreamMounting bool + P2pHttpProxy bool + StrategicProviding bool + AcceleratedDHTClient bool +} diff --git a/config/gateway.go b/config/gateway.go new file mode 100644 index 00000000000..486089b7123 --- /dev/null +++ b/config/gateway.go @@ -0,0 +1,79 @@ +package config + +type GatewaySpec struct { + // Paths is explicit list of path prefixes that should be handled by + // this gateway. Example: `["/ipfs", "/ipns", "/api"]` + Paths []string + + // UseSubdomains indicates whether or not this gateway uses subdomains + // for IPFS resources instead of paths. That is: http://CID.ipfs.GATEWAY/... + // + // If this flag is set, any /ipns/$id and/or /ipfs/$id paths in PathPrefixes + // will be permanently redirected to http://$id.[ipns|ipfs].$gateway/. + // + // We do not support using both paths and subdomains for a single domain + // for security reasons (Origin isolation). + UseSubdomains bool + + // NoDNSLink configures this gateway to _not_ resolve DNSLink for the FQDN + // provided in `Host` HTTP header. + NoDNSLink bool +} + +// Gateway contains options for the HTTP gateway server. +type Gateway struct { + + // HTTPHeaders configures the headers that should be returned by this + // gateway. + HTTPHeaders map[string][]string // HTTP headers to return with the gateway + + // RootRedirect is the path to which requests to `/` on this gateway + // should be redirected. + RootRedirect string + + // Writable enables PUT/POST request handling by this gateway. Usually, + // writing is done through the API, not the gateway. + Writable bool + + // PathPrefixes is an array of acceptable url paths that a client can + // specify in X-Ipfs-Path-Prefix header. + // + // The X-Ipfs-Path-Prefix header is used to specify a base path to prepend + // to links in directory listings and for trailing-slash redirects. It is + // intended to be set by a frontend http proxy like nginx. + // + // Example: To mount blog.ipfs.io (a DNSLink site) at ipfs.io/blog + // set PathPrefixes to ["/blog"] and nginx config to translate paths + // and pass Host header (for DNSLink): + // location /blog/ { + // rewrite "^/blog(/.*)$" $1 break; + // proxy_set_header Host blog.ipfs.io; + // proxy_set_header X-Ipfs-Gateway-Prefix /blog; + // proxy_pass http://127.0.0.1:8080; + // } + PathPrefixes []string + + // FastDirIndexThreshold is the maximum number of items in a directory + // before the Gateway switches to a shallow, faster listing which only + // requires the root node. This allows for listing big directories fast, + // without the linear slowdown caused by reading size metadata from child + // nodes. + // Setting to 0 will enable fast listings for all directories. + FastDirIndexThreshold *OptionalInteger `json:",omitempty"` + + // FIXME: Not yet implemented: https://github.com/ipfs/go-ipfs/issues/8059 + APICommands []string + + // NoFetch configures the gateway to _not_ fetch blocks in response to + // requests. + NoFetch bool + + // NoDNSLink configures the gateway to _not_ perform DNS TXT record + // lookups in response to requests with values in `Host` HTTP header. + // This flag can be overridden per FQDN in PublicGateways. + NoDNSLink bool + + // PublicGateways configures behavior of known public gateways. + // Each key is a fully qualified domain name (FQDN). + PublicGateways map[string]*GatewaySpec +} diff --git a/config/identity.go b/config/identity.go new file mode 100644 index 00000000000..f4e7c87200d --- /dev/null +++ b/config/identity.go @@ -0,0 +1,29 @@ +package config + +import ( + "encoding/base64" + + ic "github.com/libp2p/go-libp2p-core/crypto" +) + +const IdentityTag = "Identity" +const PrivKeyTag = "PrivKey" +const PrivKeySelector = IdentityTag + "." + PrivKeyTag + +// Identity tracks the configuration of the local node's identity. +type Identity struct { + PeerID string + PrivKey string `json:",omitempty"` +} + +// DecodePrivateKey is a helper to decode the users PrivateKey +func (i *Identity) DecodePrivateKey(passphrase string) (ic.PrivKey, error) { + pkb, err := base64.StdEncoding.DecodeString(i.PrivKey) + if err != nil { + return nil, err + } + + // currently storing key unencrypted. in the future we need to encrypt it. + // TODO(security) + return ic.UnmarshalPrivateKey(pkb) +} diff --git a/config/init.go b/config/init.go new file mode 100644 index 00000000000..8e54eaa5866 --- /dev/null +++ b/config/init.go @@ -0,0 +1,245 @@ +package config + +import ( + "crypto/rand" + "encoding/base64" + "fmt" + "io" + "time" + + "github.com/ipfs/interface-go-ipfs-core/options" + "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" +) + +func Init(out io.Writer, nBitsForKeypair int) (*Config, error) { + identity, err := CreateIdentity(out, []options.KeyGenerateOption{options.Key.Size(nBitsForKeypair)}) + if err != nil { + return nil, err + } + + return InitWithIdentity(identity) +} + +func InitWithIdentity(identity Identity) (*Config, error) { + bootstrapPeers, err := DefaultBootstrapPeers() + if err != nil { + return nil, err + } + + datastore := DefaultDatastoreConfig() + + conf := &Config{ + API: API{ + HTTPHeaders: map[string][]string{}, + }, + + // setup the node's default addresses. + // NOTE: two swarm listen addrs, one tcp, one utp. + Addresses: addressesConfig(), + + Datastore: datastore, + Bootstrap: BootstrapPeerStrings(bootstrapPeers), + Identity: identity, + Discovery: Discovery{ + MDNS: MDNS{ + Enabled: true, + Interval: 10, + }, + }, + + Routing: Routing{ + Type: "dht", + }, + + // setup the node mount points. + Mounts: Mounts{ + IPFS: "/ipfs", + IPNS: "/ipns", + }, + + Ipns: Ipns{ + ResolveCacheSize: 128, + }, + + Gateway: Gateway{ + RootRedirect: "", + Writable: false, + NoFetch: false, + PathPrefixes: []string{}, + HTTPHeaders: map[string][]string{ + "Access-Control-Allow-Origin": {"*"}, + "Access-Control-Allow-Methods": {"GET"}, + "Access-Control-Allow-Headers": {"X-Requested-With", "Range", "User-Agent"}, + }, + APICommands: []string{}, + }, + Reprovider: Reprovider{ + Interval: "12h", + Strategy: "all", + }, + Swarm: SwarmConfig{ + ConnMgr: ConnMgr{ + LowWater: DefaultConnMgrLowWater, + HighWater: DefaultConnMgrHighWater, + GracePeriod: DefaultConnMgrGracePeriod.String(), + Type: "basic", + }, + }, + Pinning: Pinning{ + RemoteServices: map[string]RemotePinningService{}, + }, + DNS: DNS{ + Resolvers: map[string]string{}, + }, + Migration: Migration{ + DownloadSources: []string{}, + Keep: "", + }, + } + + return conf, nil +} + +// DefaultConnMgrHighWater is the default value for the connection managers +// 'high water' mark +const DefaultConnMgrHighWater = 900 + +// DefaultConnMgrLowWater is the default value for the connection managers 'low +// water' mark +const DefaultConnMgrLowWater = 600 + +// DefaultConnMgrGracePeriod is the default value for the connection managers +// grace period +const DefaultConnMgrGracePeriod = time.Second * 20 + +func addressesConfig() Addresses { + return Addresses{ + Swarm: []string{ + "/ip4/0.0.0.0/tcp/4001", + "/ip6/::/tcp/4001", + "/ip4/0.0.0.0/udp/4001/quic", + "/ip6/::/udp/4001/quic", + }, + Announce: []string{}, + AppendAnnounce: []string{}, + NoAnnounce: []string{}, + API: Strings{"/ip4/127.0.0.1/tcp/5001"}, + Gateway: Strings{"/ip4/127.0.0.1/tcp/8080"}, + } +} + +// DefaultDatastoreConfig is an internal function exported to aid in testing. +func DefaultDatastoreConfig() Datastore { + return Datastore{ + StorageMax: "10GB", + StorageGCWatermark: 90, // 90% + GCPeriod: "1h", + BloomFilterSize: 0, + Spec: flatfsSpec(), + } +} + +func badgerSpec() map[string]interface{} { + return map[string]interface{}{ + "type": "measure", + "prefix": "badger.datastore", + "child": map[string]interface{}{ + "type": "badgerds", + "path": "badgerds", + "syncWrites": false, + "truncate": true, + }, + } +} + +func flatfsSpec() map[string]interface{} { + return map[string]interface{}{ + "type": "mount", + "mounts": []interface{}{ + map[string]interface{}{ + "mountpoint": "/blocks", + "type": "measure", + "prefix": "flatfs.datastore", + "child": map[string]interface{}{ + "type": "flatfs", + "path": "blocks", + "sync": true, + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", + }, + }, + map[string]interface{}{ + "mountpoint": "/", + "type": "measure", + "prefix": "leveldb.datastore", + "child": map[string]interface{}{ + "type": "levelds", + "path": "datastore", + "compression": "none", + }, + }, + }, + } +} + +// CreateIdentity initializes a new identity. +func CreateIdentity(out io.Writer, opts []options.KeyGenerateOption) (Identity, error) { + // TODO guard higher up + ident := Identity{} + + settings, err := options.KeyGenerateOptions(opts...) + if err != nil { + return ident, err + } + + var sk crypto.PrivKey + var pk crypto.PubKey + + switch settings.Algorithm { + case "rsa": + if settings.Size == -1 { + settings.Size = options.DefaultRSALen + } + + fmt.Fprintf(out, "generating %d-bit RSA keypair...", settings.Size) + + priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, settings.Size) + if err != nil { + return ident, err + } + + sk = priv + pk = pub + case "ed25519": + if settings.Size != -1 { + return ident, fmt.Errorf("number of key bits does not apply when using ed25519 keys") + } + fmt.Fprintf(out, "generating ED25519 keypair...") + priv, pub, err := crypto.GenerateEd25519Key(rand.Reader) + if err != nil { + return ident, err + } + + sk = priv + pk = pub + default: + return ident, fmt.Errorf("unrecognized key type: %s", settings.Algorithm) + } + fmt.Fprintf(out, "done\n") + + // currently storing key unencrypted. in the future we need to encrypt it. + // TODO(security) + skbytes, err := crypto.MarshalPrivateKey(sk) + if err != nil { + return ident, err + } + ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes) + + id, err := peer.IDFromPublicKey(pk) + if err != nil { + return ident, err + } + ident.PeerID = id.Pretty() + fmt.Fprintf(out, "peer identity: %s\n", ident.PeerID) + return ident, nil +} diff --git a/config/init_test.go b/config/init_test.go new file mode 100644 index 00000000000..3e66e60cd2c --- /dev/null +++ b/config/init_test.go @@ -0,0 +1,49 @@ +package config + +import ( + "bytes" + "testing" + + "github.com/ipfs/interface-go-ipfs-core/options" + crypto_pb "github.com/libp2p/go-libp2p-core/crypto/pb" +) + +func TestCreateIdentity(t *testing.T) { + writer := bytes.NewBuffer(nil) + id, err := CreateIdentity(writer, []options.KeyGenerateOption{options.Key.Type(options.Ed25519Key)}) + if err != nil { + t.Fatal(err) + } + pk, err := id.DecodePrivateKey("") + if err != nil { + t.Fatal(err) + } + if pk.Type() != crypto_pb.KeyType_Ed25519 { + t.Fatal("unexpected type:", pk.Type()) + } + + id, err = CreateIdentity(writer, []options.KeyGenerateOption{options.Key.Type(options.RSAKey)}) + if err != nil { + t.Fatal(err) + } + pk, err = id.DecodePrivateKey("") + if err != nil { + t.Fatal(err) + } + if pk.Type() != crypto_pb.KeyType_RSA { + t.Fatal("unexpected type:", pk.Type()) + } +} + +func TestCreateIdentityOptions(t *testing.T) { + var w bytes.Buffer + + // ed25519 keys with bit size must fail. + _, err := CreateIdentity(&w, []options.KeyGenerateOption{ + options.Key.Type(options.Ed25519Key), + options.Key.Size(2048), + }) + if err == nil { + t.Errorf("ed25519 keys cannot have a custom bit size") + } +} diff --git a/config/internal.go b/config/internal.go new file mode 100644 index 00000000000..dcd834e701c --- /dev/null +++ b/config/internal.go @@ -0,0 +1,15 @@ +package config + +type Internal struct { + // All marked as omitempty since we are expecting to make changes to all subcomponents of Internal + Bitswap *InternalBitswap `json:",omitempty"` + UnixFSShardingSizeThreshold *OptionalString `json:",omitempty"` + Libp2pForceReachability *OptionalString `json:",omitempty"` +} + +type InternalBitswap struct { + TaskWorkerCount OptionalInteger + EngineBlockstoreWorkerCount OptionalInteger + EngineTaskWorkerCount OptionalInteger + MaxOutstandingBytesPerPeer OptionalInteger +} diff --git a/config/ipns.go b/config/ipns.go new file mode 100644 index 00000000000..d5191088409 --- /dev/null +++ b/config/ipns.go @@ -0,0 +1,11 @@ +package config + +type Ipns struct { + RepublishPeriod string + RecordLifetime string + + ResolveCacheSize int + + // Enable namesys pubsub (--enable-namesys-pubsub) + UsePubsub Flag `json:",omitempty"` +} diff --git a/config/migration.go b/config/migration.go new file mode 100644 index 00000000000..27d4b3c7025 --- /dev/null +++ b/config/migration.go @@ -0,0 +1,17 @@ +package config + +const DefaultMigrationKeep = "cache" + +var DefaultMigrationDownloadSources = []string{"HTTPS", "IPFS"} + +// Migration configures how migrations are downloaded and if the downloads are +// added to IPFS locally +type Migration struct { + // Sources in order of preference, where "IPFS" means use IPFS and "HTTPS" + // means use default gateways. Any other values are interpreted as + // hostnames for custom gateways. Empty list means "use default sources". + DownloadSources []string + // Whether or not to keep the migration after downloading it. + // Options are "discard", "cache", "pin". Empty string for default. + Keep string +} diff --git a/config/migration_test.go b/config/migration_test.go new file mode 100644 index 00000000000..a6cbd4438e7 --- /dev/null +++ b/config/migration_test.go @@ -0,0 +1,34 @@ +package config + +import ( + "encoding/json" + "testing" +) + +func TestMigrationDecode(t *testing.T) { + str := ` + { + "DownloadSources": ["IPFS", "HTTP", "127.0.0.1"], + "Keep": "cache" + } + ` + + var cfg Migration + if err := json.Unmarshal([]byte(str), &cfg); err != nil { + t.Errorf("failed while unmarshalling migration struct: %s", err) + } + + if len(cfg.DownloadSources) != 3 { + t.Fatal("wrong number of DownloadSources") + } + expect := []string{"IPFS", "HTTP", "127.0.0.1"} + for i := range expect { + if cfg.DownloadSources[i] != expect[i] { + t.Errorf("wrong DownloadSource at %d", i) + } + } + + if cfg.Keep != "cache" { + t.Error("wrong value for Keep") + } +} diff --git a/config/mounts.go b/config/mounts.go new file mode 100644 index 00000000000..b23d30b2ef3 --- /dev/null +++ b/config/mounts.go @@ -0,0 +1,8 @@ +package config + +// Mounts stores the (string) mount points +type Mounts struct { + IPFS string + IPNS string + FuseAllowOther bool +} diff --git a/config/peering.go b/config/peering.go new file mode 100644 index 00000000000..242ce2d9898 --- /dev/null +++ b/config/peering.go @@ -0,0 +1,9 @@ +package config + +import "github.com/libp2p/go-libp2p-core/peer" + +// Peering configures the peering service. +type Peering struct { + // Peers lists the nodes to attempt to stay connected with. + Peers []peer.AddrInfo +} diff --git a/config/plugins.go b/config/plugins.go new file mode 100644 index 00000000000..08a1acb34f5 --- /dev/null +++ b/config/plugins.go @@ -0,0 +1,11 @@ +package config + +type Plugins struct { + Plugins map[string]Plugin + // TODO: Loader Path? Leaving that out for now due to security concerns. +} + +type Plugin struct { + Disabled bool + Config interface{} +} diff --git a/config/profile.go b/config/profile.go new file mode 100644 index 00000000000..cbc7c976453 --- /dev/null +++ b/config/profile.go @@ -0,0 +1,249 @@ +package config + +import ( + "fmt" + "net" + "time" +) + +// Transformer is a function which takes configuration and applies some filter to it +type Transformer func(c *Config) error + +// Profile contains the profile transformer the description of the profile +type Profile struct { + // Description briefly describes the functionality of the profile. + Description string + + // Transform takes ipfs configuration and applies the profile to it. + Transform Transformer + + // InitOnly specifies that this profile can only be applied on init. + InitOnly bool +} + +// defaultServerFilters has is a list of IPv4 and IPv6 prefixes that are private, local only, or unrouteable. +// according to https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +// and https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml +var defaultServerFilters = []string{ + "/ip4/10.0.0.0/ipcidr/8", + "/ip4/100.64.0.0/ipcidr/10", + "/ip4/169.254.0.0/ipcidr/16", + "/ip4/172.16.0.0/ipcidr/12", + "/ip4/192.0.0.0/ipcidr/24", + "/ip4/192.0.2.0/ipcidr/24", + "/ip4/192.168.0.0/ipcidr/16", + "/ip4/198.18.0.0/ipcidr/15", + "/ip4/198.51.100.0/ipcidr/24", + "/ip4/203.0.113.0/ipcidr/24", + "/ip4/240.0.0.0/ipcidr/4", + "/ip6/100::/ipcidr/64", + "/ip6/2001:2::/ipcidr/48", + "/ip6/2001:db8::/ipcidr/32", + "/ip6/fc00::/ipcidr/7", + "/ip6/fe80::/ipcidr/10", +} + +// Profiles is a map holding configuration transformers. Docs are in docs/config.md +var Profiles = map[string]Profile{ + "server": { + Description: `Disables local host discovery, recommended when +running IPFS on machines with public IPv4 addresses.`, + + Transform: func(c *Config) error { + c.Addresses.NoAnnounce = appendSingle(c.Addresses.NoAnnounce, defaultServerFilters) + c.Swarm.AddrFilters = appendSingle(c.Swarm.AddrFilters, defaultServerFilters) + c.Discovery.MDNS.Enabled = false + c.Swarm.DisableNatPortMap = true + return nil + }, + }, + + "local-discovery": { + Description: `Sets default values to fields affected by the server +profile, enables discovery in local networks.`, + + Transform: func(c *Config) error { + c.Addresses.NoAnnounce = deleteEntries(c.Addresses.NoAnnounce, defaultServerFilters) + c.Swarm.AddrFilters = deleteEntries(c.Swarm.AddrFilters, defaultServerFilters) + c.Discovery.MDNS.Enabled = true + c.Swarm.DisableNatPortMap = false + return nil + }, + }, + "test": { + Description: `Reduces external interference of IPFS daemon, this +is useful when using the daemon in test environments.`, + + Transform: func(c *Config) error { + c.Addresses.API = Strings{"/ip4/127.0.0.1/tcp/0"} + c.Addresses.Gateway = Strings{"/ip4/127.0.0.1/tcp/0"} + c.Addresses.Swarm = []string{ + "/ip4/127.0.0.1/tcp/0", + } + + c.Swarm.DisableNatPortMap = true + + c.Bootstrap = []string{} + c.Discovery.MDNS.Enabled = false + return nil + }, + }, + "default-networking": { + Description: `Restores default network settings. +Inverse profile of the test profile.`, + + Transform: func(c *Config) error { + c.Addresses = addressesConfig() + + bootstrapPeers, err := DefaultBootstrapPeers() + if err != nil { + return err + } + c.Bootstrap = appendSingle(c.Bootstrap, BootstrapPeerStrings(bootstrapPeers)) + + c.Swarm.DisableNatPortMap = false + c.Discovery.MDNS.Enabled = true + return nil + }, + }, + "default-datastore": { + Description: `Configures the node to use the default datastore (flatfs). + +Read the "flatfs" profile description for more information on this datastore. + +This profile may only be applied when first initializing the node. +`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = flatfsSpec() + return nil + }, + }, + "flatfs": { + Description: `Configures the node to use the flatfs datastore. + +This is the most battle-tested and reliable datastore. +You should use this datastore if: + +* You need a very simple and very reliable datastore, and you trust your + filesystem. This datastore stores each block as a separate file in the + underlying filesystem so it's unlikely to loose data unless there's an issue + with the underlying file system. +* You need to run garbage collection in a way that reclaims free space as soon as possible. +* You want to minimize memory usage. +* You are ok with the default speed of data import, or prefer to use --nocopy. + +This profile may only be applied when first initializing the node. +`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = flatfsSpec() + return nil + }, + }, + "badgerds": { + Description: `Configures the node to use the experimental badger datastore. + +Use this datastore if some aspects of performance, +especially the speed of adding many gigabytes of files, are critical. +However, be aware that: + +* This datastore will not properly reclaim space when your datastore is + smaller than several gigabytes. If you run IPFS with --enable-gc, you plan + on storing very little data in your IPFS node, and disk usage is more + critical than performance, consider using flatfs. +* This datastore uses up to several gigabytes of memory. +* Good for medium-size datastores, but may run into performance issues + if your dataset is bigger than a terabyte. +* The current implementation is based on old badger 1.x + which is no longer supported by the upstream team. + +This profile may only be applied when first initializing the node.`, + + InitOnly: true, + Transform: func(c *Config) error { + c.Datastore.Spec = badgerSpec() + return nil + }, + }, + "lowpower": { + Description: `Reduces daemon overhead on the system. May affect node +functionality - performance of content discovery and data +fetching may be degraded. +`, + Transform: func(c *Config) error { + c.Routing.Type = "dhtclient" + c.AutoNAT.ServiceMode = AutoNATServiceDisabled + c.Reprovider.Interval = "0" + + c.Swarm.ConnMgr.LowWater = 20 + c.Swarm.ConnMgr.HighWater = 40 + c.Swarm.ConnMgr.GracePeriod = time.Minute.String() + return nil + }, + }, + "randomports": { + Description: `Use a random port number for swarm.`, + + Transform: func(c *Config) error { + port, err := getAvailablePort() + if err != nil { + return err + } + c.Addresses.Swarm = []string{ + fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", port), + fmt.Sprintf("/ip6/::/tcp/%d", port), + } + return nil + }, + }, +} + +func getAvailablePort() (port int, err error) { + ln, err := net.Listen("tcp", "[::]:0") + if err != nil { + return 0, err + } + defer ln.Close() + port = ln.Addr().(*net.TCPAddr).Port + return port, nil +} + +func appendSingle(a []string, b []string) []string { + out := make([]string, 0, len(a)+len(b)) + m := map[string]bool{} + for _, f := range a { + if !m[f] { + out = append(out, f) + } + m[f] = true + } + for _, f := range b { + if !m[f] { + out = append(out, f) + } + m[f] = true + } + return out +} + +func deleteEntries(arr []string, del []string) []string { + m := map[string]struct{}{} + for _, f := range arr { + m[f] = struct{}{} + } + for _, f := range del { + delete(m, f) + } + return mapKeys(m) +} + +func mapKeys(m map[string]struct{}) []string { + out := make([]string, 0, len(m)) + for f := range m { + out = append(out, f) + } + return out +} diff --git a/config/provider.go b/config/provider.go new file mode 100644 index 00000000000..f2b5afe05b4 --- /dev/null +++ b/config/provider.go @@ -0,0 +1,5 @@ +package config + +type Provider struct { + Strategy string // Which keys to announce +} diff --git a/config/pubsub.go b/config/pubsub.go new file mode 100644 index 00000000000..aabc35a0e0f --- /dev/null +++ b/config/pubsub.go @@ -0,0 +1,14 @@ +package config + +type PubsubConfig struct { + // Router can be either floodsub (legacy) or gossipsub (new and + // backwards compatible). + Router string + + // DisableSigning disables message signing. Message signing is *enabled* + // by default. + DisableSigning bool + + // Enable pubsub (--enable-pubsub-experiment) + Enabled Flag `json:",omitempty"` +} diff --git a/config/remotepin.go b/config/remotepin.go new file mode 100644 index 00000000000..135aa664d17 --- /dev/null +++ b/config/remotepin.go @@ -0,0 +1,33 @@ +package config + +var ( + RemoteServicesPath = "Pinning.RemoteServices" + PinningConcealSelector = []string{"Pinning", "RemoteServices", "*", "API", "Key"} +) + +type Pinning struct { + RemoteServices map[string]RemotePinningService +} + +type RemotePinningService struct { + API RemotePinningServiceAPI + Policies RemotePinningServicePolicies +} + +type RemotePinningServiceAPI struct { + Endpoint string + Key string +} + +type RemotePinningServicePolicies struct { + MFS RemotePinningServiceMFSPolicy +} + +type RemotePinningServiceMFSPolicy struct { + // Enable enables watching for changes in MFS and re-pinning the MFS root cid whenever a change occurs. + Enable bool + // Name is the pin name for MFS. + PinName string + // RepinInterval determines the repin interval when the policy is enabled. In ns, us, ms, s, m, h. + RepinInterval string +} diff --git a/config/reprovider.go b/config/reprovider.go new file mode 100644 index 00000000000..fa029c2fc21 --- /dev/null +++ b/config/reprovider.go @@ -0,0 +1,6 @@ +package config + +type Reprovider struct { + Interval string // Time period to reprovide locally stored objects to the network + Strategy string // Which keys to announce +} diff --git a/config/routing.go b/config/routing.go new file mode 100644 index 00000000000..c6157ec9637 --- /dev/null +++ b/config/routing.go @@ -0,0 +1,9 @@ +package config + +// Routing defines configuration options for libp2p routing +type Routing struct { + // Type sets default daemon routing mode. + // + // Can be one of "dht", "dhtclient", "dhtserver", "none", or unset. + Type string +} diff --git a/config/serialize/serialize.go b/config/serialize/serialize.go new file mode 100644 index 00000000000..e51e9211575 --- /dev/null +++ b/config/serialize/serialize.go @@ -0,0 +1,72 @@ +package fsrepo + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/ipfs/go-ipfs/config" + + "github.com/facebookgo/atomicfile" +) + +// ErrNotInitialized is returned when we fail to read the config because the +// repo doesn't exist. +var ErrNotInitialized = errors.New("ipfs not initialized, please run 'ipfs init'") + +// ReadConfigFile reads the config from `filename` into `cfg`. +func ReadConfigFile(filename string, cfg interface{}) error { + f, err := os.Open(filename) + if err != nil { + if os.IsNotExist(err) { + err = ErrNotInitialized + } + return err + } + defer f.Close() + if err := json.NewDecoder(f).Decode(cfg); err != nil { + return fmt.Errorf("failure to decode config: %s", err) + } + return nil +} + +// WriteConfigFile writes the config from `cfg` into `filename`. +func WriteConfigFile(filename string, cfg interface{}) error { + err := os.MkdirAll(filepath.Dir(filename), 0755) + if err != nil { + return err + } + + f, err := atomicfile.New(filename, 0600) + if err != nil { + return err + } + defer f.Close() + + return encode(f, cfg) +} + +// encode configuration with JSON +func encode(w io.Writer, value interface{}) error { + // need to prettyprint, hence MarshalIndent, instead of Encoder + buf, err := config.Marshal(value) + if err != nil { + return err + } + _, err = w.Write(buf) + return err +} + +// Load reads given file and returns the read config, or error. +func Load(filename string) (*config.Config, error) { + var cfg config.Config + err := ReadConfigFile(filename, &cfg) + if err != nil { + return nil, err + } + + return &cfg, err +} diff --git a/config/serialize/serialize_test.go b/config/serialize/serialize_test.go new file mode 100644 index 00000000000..0c8e12f40c0 --- /dev/null +++ b/config/serialize/serialize_test.go @@ -0,0 +1,37 @@ +package fsrepo + +import ( + "os" + "runtime" + "testing" + + config "github.com/ipfs/go-ipfs/config" +) + +func TestConfig(t *testing.T) { + const filename = ".ipfsconfig" + cfgWritten := new(config.Config) + cfgWritten.Identity.PeerID = "faketest" + + err := WriteConfigFile(filename, cfgWritten) + if err != nil { + t.Fatal(err) + } + cfgRead, err := Load(filename) + if err != nil { + t.Fatal(err) + } + if cfgWritten.Identity.PeerID != cfgRead.Identity.PeerID { + t.Fatal() + } + st, err := os.Stat(filename) + if err != nil { + t.Fatalf("cannot stat config file: %v", err) + } + + if runtime.GOOS != "windows" { // see https://golang.org/src/os/types_windows.go + if g := st.Mode().Perm(); g&0117 != 0 { + t.Fatalf("config file should not be executable or accessible to world: %v", g) + } + } +} diff --git a/config/swarm.go b/config/swarm.go new file mode 100644 index 00000000000..2cd4e7194cc --- /dev/null +++ b/config/swarm.go @@ -0,0 +1,152 @@ +package config + +import rcmgr "github.com/libp2p/go-libp2p-resource-manager" + +type SwarmConfig struct { + // AddrFilters specifies a set libp2p addresses that we should never + // dial or receive connections from. + AddrFilters []string + + // DisableBandwidthMetrics disables recording of bandwidth metrics for a + // slight reduction in memory usage. You probably don't need to set this + // flag. + DisableBandwidthMetrics bool + + // DisableNatPortMap turns off NAT port mapping (UPnP, etc.). + DisableNatPortMap bool + + // DisableRelay explicitly disables the relay transport. + // + // Deprecated: This flag is deprecated and is overridden by + // `Swarm.Transports.Relay` if specified. + DisableRelay bool `json:",omitempty"` + + // EnableRelayHop makes this node act as a public relay v1 + // + // Deprecated: The circuit v1 protocol is deprecated. + // Use `Swarm.RelayService` to configure the circuit v2 relay. + EnableRelayHop bool `json:",omitempty"` + + // EnableAutoRelay enables the "auto relay user" feature. + // Node will find and use advertised public relays when it determines that + // it's not reachable from the public internet. + // + // Deprecated: This flag is deprecated and is overridden by + // `Swarm.RelayClient.Enabled` if specified. + EnableAutoRelay bool `json:",omitempty"` + + // RelayClient controls the client side of "auto relay" feature. + // When enabled, the node will use relays if it is not publicly reachable. + RelayClient RelayClient + + // RelayService.* controls the "relay service". + // When enabled, node will provide a limited relay service to other peers. + RelayService RelayService + + // EnableHolePunching enables the hole punching service. + EnableHolePunching Flag `json:",omitempty"` + + // Transports contains flags to enable/disable libp2p transports. + Transports Transports + + // ConnMgr configures the connection manager. + ConnMgr ConnMgr + + // ResourceMgr configures the libp2p Network Resource Manager + ResourceMgr ResourceMgr +} + +type RelayClient struct { + // Enables the auto relay feature: will use relays if it is not publicly reachable. + Enabled Flag `json:",omitempty"` + + // StaticRelays configures static relays to use when this node is not + // publicly reachable. If set, auto relay will not try to find any + // other relay servers. + StaticRelays []string `json:",omitempty"` +} + +// RelayService configures the resources of the circuit v2 relay. +// For every field a reasonable default will be defined in go-ipfs. +type RelayService struct { + // Enables the limited relay service for other peers (circuit v2 relay). + Enabled Flag `json:",omitempty"` + + // ConnectionDurationLimit is the time limit before resetting a relayed connection. + ConnectionDurationLimit *OptionalDuration `json:",omitempty"` + // ConnectionDataLimit is the limit of data relayed (on each direction) before resetting the connection. + ConnectionDataLimit *OptionalInteger `json:",omitempty"` + + // ReservationTTL is the duration of a new (or refreshed reservation). + ReservationTTL *OptionalDuration `json:",omitempty"` + + // MaxReservations is the maximum number of active relay slots. + MaxReservations *OptionalInteger `json:",omitempty"` + // MaxCircuits is the maximum number of open relay connections for each peer; defaults to 16. + MaxCircuits *OptionalInteger `json:",omitempty"` + // BufferSize is the size of the relayed connection buffers. + BufferSize *OptionalInteger `json:",omitempty"` + + // MaxReservationsPerPeer is the maximum number of reservations originating from the same peer. + MaxReservationsPerPeer *OptionalInteger `json:",omitempty"` + // MaxReservationsPerIP is the maximum number of reservations originating from the same IP address. + MaxReservationsPerIP *OptionalInteger `json:",omitempty"` + // MaxReservationsPerASN is the maximum number of reservations origination from the same ASN. + MaxReservationsPerASN *OptionalInteger `json:",omitempty"` +} + +type Transports struct { + // Network specifies the base transports we'll use for dialing. To + // listen on a transport, add the transport to your Addresses.Swarm. + Network struct { + // All default to on. + QUIC Flag `json:",omitempty"` + TCP Flag `json:",omitempty"` + Websocket Flag `json:",omitempty"` + Relay Flag `json:",omitempty"` + } + + // Security specifies the transports used to encrypt insecure network + // transports. + Security struct { + // Defaults to 100. + TLS Priority `json:",omitempty"` + // Defaults to 200. + SECIO Priority `json:",omitempty"` + // Defaults to 300. + Noise Priority `json:",omitempty"` + } + + // Multiplexers specifies the transports used to multiplex multiple + // connections over a single duplex connection. + Multiplexers struct { + // Defaults to 100. + Yamux Priority `json:",omitempty"` + // Defaults to 200. + Mplex Priority `json:",omitempty"` + } +} + +// ConnMgr defines configuration options for the libp2p connection manager +type ConnMgr struct { + Type string + LowWater int + HighWater int + GracePeriod string +} + +// ResourceMgr defines configuration options for the libp2p Network Resource Manager +// +type ResourceMgr struct { + // Enables the Network Resource Manager feature, default to on. + Enabled Flag `json:",omitempty"` + Limits *rcmgr.BasicLimiterConfig `json:",omitempty"` +} + +const ( + ResourceMgrSystemScope = "system" + ResourceMgrTransientScope = "transient" + ResourceMgrServiceScopePrefix = "svc:" + ResourceMgrProtocolScopePrefix = "proto:" + ResourceMgrPeerScopePrefix = "peer:" +) diff --git a/config/types.go b/config/types.go new file mode 100644 index 00000000000..c33689c5b2a --- /dev/null +++ b/config/types.go @@ -0,0 +1,367 @@ +package config + +import ( + "encoding/json" + "fmt" + "strings" + "time" +) + +// Strings is a helper type that (un)marshals a single string to/from a single +// JSON string and a slice of strings to/from a JSON array of strings. +type Strings []string + +// UnmarshalJSON conforms to the json.Unmarshaler interface. +func (o *Strings) UnmarshalJSON(data []byte) error { + if data[0] == '[' { + return json.Unmarshal(data, (*[]string)(o)) + } + var value string + if err := json.Unmarshal(data, &value); err != nil { + return err + } + if len(value) == 0 { + *o = []string{} + } else { + *o = []string{value} + } + return nil +} + +// MarshalJSON conforms to the json.Marshaler interface. +func (o Strings) MarshalJSON() ([]byte, error) { + switch len(o) { + case 0: + return json.Marshal(nil) + case 1: + return json.Marshal(o[0]) + default: + return json.Marshal([]string(o)) + } +} + +var _ json.Unmarshaler = (*Strings)(nil) +var _ json.Marshaler = (*Strings)(nil) + +// Flag represents a ternary value: false (-1), default (0), or true (+1). +// +// When encoded in json, False is "false", Default is "null" (or empty), and True +// is "true". +type Flag int8 + +const ( + False Flag = -1 + Default Flag = 0 + True Flag = 1 +) + +// WithDefault resolves the value of the flag given the provided default value. +// +// Panics if Flag is an invalid value. +func (f Flag) WithDefault(defaultValue bool) bool { + switch f { + case False: + return false + case Default: + return defaultValue + case True: + return true + default: + panic(fmt.Sprintf("invalid flag value %d", f)) + } +} + +func (f Flag) MarshalJSON() ([]byte, error) { + switch f { + case Default: + return json.Marshal(nil) + case True: + return json.Marshal(true) + case False: + return json.Marshal(false) + default: + return nil, fmt.Errorf("invalid flag value: %d", f) + } +} + +func (f *Flag) UnmarshalJSON(input []byte) error { + switch string(input) { + case "null": + *f = Default + case "false": + *f = False + case "true": + *f = True + default: + return fmt.Errorf("failed to unmarshal %q into a flag: must be null/undefined, true, or false", string(input)) + } + return nil +} + +func (f Flag) String() string { + switch f { + case Default: + return "default" + case True: + return "true" + case False: + return "false" + default: + return fmt.Sprintf("", f) + } +} + +var _ json.Unmarshaler = (*Flag)(nil) +var _ json.Marshaler = (*Flag)(nil) + +// Priority represents a value with a priority where 0 means "default" and -1 +// means "disabled". +// +// When encoded in json, Default is encoded as "null" and Disabled is encoded as +// "false". +type Priority int64 + +const ( + DefaultPriority Priority = 0 + Disabled Priority = -1 +) + +// WithDefault resolves the priority with the given default. +// +// If defaultPriority is Default/0, this function will return 0. +// +// Panics if the priority has an invalid value (e.g., not DefaultPriority, +// Disabled, or > 0). +func (p Priority) WithDefault(defaultPriority Priority) (priority int64, enabled bool) { + switch p { + case Disabled: + return 0, false + case DefaultPriority: + switch defaultPriority { + case Disabled: + return 0, false + case DefaultPriority: + return 0, true + default: + if defaultPriority <= 0 { + panic(fmt.Sprintf("invalid priority %d < 0", int64(defaultPriority))) + } + return int64(defaultPriority), true + } + default: + if p <= 0 { + panic(fmt.Sprintf("invalid priority %d < 0", int64(p))) + } + return int64(p), true + } +} + +func (p Priority) MarshalJSON() ([]byte, error) { + // > 0 == Priority + if p > 0 { + return json.Marshal(int64(p)) + } + // <= 0 == special + switch p { + case DefaultPriority: + return json.Marshal(nil) + case Disabled: + return json.Marshal(false) + default: + return nil, fmt.Errorf("invalid priority value: %d", p) + } +} + +func (p *Priority) UnmarshalJSON(input []byte) error { + switch string(input) { + case "null", "undefined": + *p = DefaultPriority + case "false": + *p = Disabled + case "true": + return fmt.Errorf("'true' is not a valid priority") + default: + var priority int64 + err := json.Unmarshal(input, &priority) + if err != nil { + return err + } + if priority <= 0 { + return fmt.Errorf("priority must be positive: %d <= 0", priority) + } + *p = Priority(priority) + } + return nil +} + +func (p Priority) String() string { + if p > 0 { + return fmt.Sprintf("%d", p) + } + switch p { + case DefaultPriority: + return "default" + case Disabled: + return "false" + default: + return fmt.Sprintf("", p) + } +} + +var _ json.Unmarshaler = (*Priority)(nil) +var _ json.Marshaler = (*Priority)(nil) + +// OptionalDuration wraps time.Duration to provide json serialization and deserialization. +// +// NOTE: the zero value encodes to JSON nill +type OptionalDuration struct { + value *time.Duration +} + +func (d *OptionalDuration) UnmarshalJSON(input []byte) error { + switch string(input) { + case "null", "undefined", "\"null\"", "", "default", "\"\"", "\"default\"": + *d = OptionalDuration{} + return nil + default: + text := strings.Trim(string(input), "\"") + value, err := time.ParseDuration(text) + if err != nil { + return err + } + *d = OptionalDuration{value: &value} + return nil + } +} + +func (d *OptionalDuration) IsDefault() bool { + return d == nil || d.value == nil +} + +func (d *OptionalDuration) WithDefault(defaultValue time.Duration) time.Duration { + if d == nil || d.value == nil { + return defaultValue + } + return *d.value +} + +func (d OptionalDuration) MarshalJSON() ([]byte, error) { + if d.value == nil { + return json.Marshal(nil) + } + return json.Marshal(d.value.String()) +} + +func (d OptionalDuration) String() string { + if d.value == nil { + return "default" + } + return d.value.String() +} + +var _ json.Unmarshaler = (*OptionalDuration)(nil) +var _ json.Marshaler = (*OptionalDuration)(nil) + +// OptionalInteger represents an integer that has a default value +// +// When encoded in json, Default is encoded as "null" +type OptionalInteger struct { + value *int64 +} + +// WithDefault resolves the integer with the given default. +func (p *OptionalInteger) WithDefault(defaultValue int64) (value int64) { + if p == nil || p.value == nil { + return defaultValue + } + return *p.value +} + +// IsDefault returns if this is a default optional integer +func (p *OptionalInteger) IsDefault() bool { + return p == nil || p.value == nil +} + +func (p OptionalInteger) MarshalJSON() ([]byte, error) { + if p.value != nil { + return json.Marshal(p.value) + } + return json.Marshal(nil) +} + +func (p *OptionalInteger) UnmarshalJSON(input []byte) error { + switch string(input) { + case "null", "undefined": + *p = OptionalInteger{} + default: + var value int64 + err := json.Unmarshal(input, &value) + if err != nil { + return err + } + *p = OptionalInteger{value: &value} + } + return nil +} + +func (p OptionalInteger) String() string { + if p.value == nil { + return "default" + } + return fmt.Sprintf("%d", p.value) +} + +var _ json.Unmarshaler = (*OptionalInteger)(nil) +var _ json.Marshaler = (*OptionalInteger)(nil) + +// OptionalString represents a string that has a default value +// +// When encoded in json, Default is encoded as "null" +type OptionalString struct { + value *string +} + +// WithDefault resolves the integer with the given default. +func (p *OptionalString) WithDefault(defaultValue string) (value string) { + if p == nil || p.value == nil { + return defaultValue + } + return *p.value +} + +// IsDefault returns if this is a default optional integer +func (p *OptionalString) IsDefault() bool { + return p == nil || p.value == nil +} + +func (p OptionalString) MarshalJSON() ([]byte, error) { + if p.value != nil { + return json.Marshal(p.value) + } + return json.Marshal(nil) +} + +func (p *OptionalString) UnmarshalJSON(input []byte) error { + switch string(input) { + case "null", "undefined": + *p = OptionalString{} + default: + var value string + err := json.Unmarshal(input, &value) + if err != nil { + return err + } + *p = OptionalString{value: &value} + } + return nil +} + +func (p OptionalString) String() string { + if p.value == nil { + return "default" + } + return *p.value +} + +var _ json.Unmarshaler = (*OptionalInteger)(nil) +var _ json.Marshaler = (*OptionalInteger)(nil) diff --git a/config/types_test.go b/config/types_test.go new file mode 100644 index 00000000000..caef2b112c0 --- /dev/null +++ b/config/types_test.go @@ -0,0 +1,514 @@ +package config + +import ( + "bytes" + "encoding/json" + "testing" + "time" +) + +func TestOptionalDuration(t *testing.T) { + makeDurationPointer := func(d time.Duration) *time.Duration { return &d } + + t.Run("marshalling and unmarshalling", func(t *testing.T) { + out, err := json.Marshal(OptionalDuration{value: makeDurationPointer(time.Second)}) + if err != nil { + t.Fatal(err) + } + expected := "\"1s\"" + if string(out) != expected { + t.Fatalf("expected %s, got %s", expected, string(out)) + } + var d OptionalDuration + + if err := json.Unmarshal(out, &d); err != nil { + t.Fatal(err) + } + if *d.value != time.Second { + t.Fatal("expected a second") + } + }) + + t.Run("default value", func(t *testing.T) { + for _, jsonStr := range []string{"null", "\"null\"", "\"\"", "\"default\""} { + var d OptionalDuration + if !d.IsDefault() { + t.Fatal("expected value to be the default initially") + } + if err := json.Unmarshal([]byte(jsonStr), &d); err != nil { + t.Fatalf("%s failed to unmarshall with %s", jsonStr, err) + } + if dur := d.WithDefault(time.Hour); dur != time.Hour { + t.Fatalf("expected default value to be used, got %s", dur) + } + if !d.IsDefault() { + t.Fatal("expected value to be the default") + } + } + }) + + t.Run("omitempty with default value", func(t *testing.T) { + type Foo struct { + D *OptionalDuration `json:",omitempty"` + } + // marshall to JSON without empty field + out, err := json.Marshal(new(Foo)) + if err != nil { + t.Fatal(err) + } + if string(out) != "{}" { + t.Fatalf("expected omitempty to omit the duration, got %s", out) + } + // unmarshall missing value and get the default + var foo2 Foo + if err := json.Unmarshal(out, &foo2); err != nil { + t.Fatalf("%s failed to unmarshall with %s", string(out), err) + } + if dur := foo2.D.WithDefault(time.Hour); dur != time.Hour { + t.Fatalf("expected default value to be used, got %s", dur) + } + if !foo2.D.IsDefault() { + t.Fatal("expected value to be the default") + } + }) + + t.Run("roundtrip including the default values", func(t *testing.T) { + for jsonStr, goValue := range map[string]OptionalDuration{ + // there are various footguns user can hit, normalize them to the canonical default + "null": {}, // JSON null โ†’ default value + "\"null\"": {}, // JSON string "null" sent/set by "ipfs config" cli โ†’ default value + "\"default\"": {}, // explicit "default" as string + "\"\"": {}, // user removed custom value, empty string should also parse as default + "\"1s\"": {value: makeDurationPointer(time.Second)}, + "\"42h1m3s\"": {value: makeDurationPointer(42*time.Hour + 1*time.Minute + 3*time.Second)}, + } { + var d OptionalDuration + err := json.Unmarshal([]byte(jsonStr), &d) + if err != nil { + t.Fatal(err) + } + + if goValue.value == nil && d.value == nil { + } else if goValue.value == nil && d.value != nil { + t.Errorf("expected nil for %s, got %s", jsonStr, d) + } else if *d.value != *goValue.value { + t.Fatalf("expected %s for %s, got %s", goValue, jsonStr, d) + } + + // Test Reverse + out, err := json.Marshal(goValue) + if err != nil { + t.Fatal(err) + } + if goValue.value == nil { + if !bytes.Equal(out, []byte("null")) { + t.Fatalf("expected JSON null for %s, got %s", jsonStr, string(out)) + } + continue + } + if string(out) != jsonStr { + t.Fatalf("expected %s, got %s", jsonStr, string(out)) + } + } + }) + + t.Run("invalid duration values", func(t *testing.T) { + for _, invalid := range []string{ + "\"s\"", "\"1ฤ™\"", "\"-1\"", "\"1H\"", "\"day\"", + } { + var d OptionalDuration + err := json.Unmarshal([]byte(invalid), &d) + if err == nil { + t.Errorf("expected to fail to decode %s as an OptionalDuration, got %s instead", invalid, d) + } + } + }) +} + +func TestOneStrings(t *testing.T) { + out, err := json.Marshal(Strings{"one"}) + if err != nil { + t.Fatal(err) + + } + expected := "\"one\"" + if string(out) != expected { + t.Fatalf("expected %s, got %s", expected, string(out)) + } +} + +func TestNoStrings(t *testing.T) { + out, err := json.Marshal(Strings{}) + if err != nil { + t.Fatal(err) + + } + expected := "null" + if string(out) != expected { + t.Fatalf("expected %s, got %s", expected, string(out)) + } +} + +func TestManyStrings(t *testing.T) { + out, err := json.Marshal(Strings{"one", "two"}) + if err != nil { + t.Fatal(err) + + } + expected := "[\"one\",\"two\"]" + if string(out) != expected { + t.Fatalf("expected %s, got %s", expected, string(out)) + } +} + +func TestFunkyStrings(t *testing.T) { + toParse := " [ \"one\", \"two\" ] " + var s Strings + if err := json.Unmarshal([]byte(toParse), &s); err != nil { + t.Fatal(err) + } + if len(s) != 2 || s[0] != "one" && s[1] != "two" { + t.Fatalf("unexpected result: %v", s) + } +} + +func TestFlag(t *testing.T) { + // make sure we have the right zero value. + var defaultFlag Flag + if defaultFlag != Default { + t.Errorf("expected default flag to be %q, got %q", Default, defaultFlag) + } + + if defaultFlag.WithDefault(true) != true { + t.Error("expected default & true to be true") + } + + if defaultFlag.WithDefault(false) != false { + t.Error("expected default & false to be false") + } + + if True.WithDefault(false) != true { + t.Error("default should only apply to default") + } + + if False.WithDefault(true) != false { + t.Error("default should only apply to default") + } + + if True.WithDefault(true) != true { + t.Error("true & true is true") + } + + if False.WithDefault(true) != false { + t.Error("false & false is false") + } + + for jsonStr, goValue := range map[string]Flag{ + "null": Default, + "true": True, + "false": False, + } { + var d Flag + err := json.Unmarshal([]byte(jsonStr), &d) + if err != nil { + t.Fatal(err) + } + if d != goValue { + t.Fatalf("expected %s, got %s", goValue, d) + } + + // Reverse + out, err := json.Marshal(goValue) + if err != nil { + t.Fatal(err) + } + if string(out) != jsonStr { + t.Fatalf("expected %s, got %s", jsonStr, string(out)) + } + } + + type Foo struct { + F Flag `json:",omitempty"` + } + out, err := json.Marshal(new(Foo)) + if err != nil { + t.Fatal(err) + } + expected := "{}" + if string(out) != expected { + t.Fatal("expected omitempty to omit the flag") + } +} + +func TestPriority(t *testing.T) { + // make sure we have the right zero value. + var defaultPriority Priority + if defaultPriority != DefaultPriority { + t.Errorf("expected default priority to be %q, got %q", DefaultPriority, defaultPriority) + } + + if _, ok := defaultPriority.WithDefault(Disabled); ok { + t.Error("should have been disabled") + } + + if p, ok := defaultPriority.WithDefault(1); !ok || p != 1 { + t.Errorf("priority should have been 1, got %d", p) + } + + if p, ok := defaultPriority.WithDefault(DefaultPriority); !ok || p != 0 { + t.Errorf("priority should have been 0, got %d", p) + } + + for jsonStr, goValue := range map[string]Priority{ + "null": DefaultPriority, + "false": Disabled, + "1": 1, + "2": 2, + "100": 100, + } { + var d Priority + err := json.Unmarshal([]byte(jsonStr), &d) + if err != nil { + t.Fatal(err) + } + if d != goValue { + t.Fatalf("expected %s, got %s", goValue, d) + } + + // Reverse + out, err := json.Marshal(goValue) + if err != nil { + t.Fatal(err) + } + if string(out) != jsonStr { + t.Fatalf("expected %s, got %s", jsonStr, string(out)) + } + } + + type Foo struct { + P Priority `json:",omitempty"` + } + out, err := json.Marshal(new(Foo)) + if err != nil { + t.Fatal(err) + } + expected := "{}" + if string(out) != expected { + t.Fatal("expected omitempty to omit the flag") + } + for _, invalid := range []string{ + "0", "-1", "-2", "1.1", "0.0", + } { + var p Priority + err := json.Unmarshal([]byte(invalid), &p) + if err == nil { + t.Errorf("expected to fail to decode %s as a priority", invalid) + } + } +} + +func TestOptionalInteger(t *testing.T) { + makeInt64Pointer := func(v int64) *int64 { + return &v + } + + var defaultOptionalInt OptionalInteger + if !defaultOptionalInt.IsDefault() { + t.Fatal("should be the default") + } + if val := defaultOptionalInt.WithDefault(0); val != 0 { + t.Errorf("optional integer should have been 0, got %d", val) + } + + if val := defaultOptionalInt.WithDefault(1); val != 1 { + t.Errorf("optional integer should have been 1, got %d", val) + } + + if val := defaultOptionalInt.WithDefault(-1); val != -1 { + t.Errorf("optional integer should have been -1, got %d", val) + } + + var filledInt OptionalInteger + filledInt = OptionalInteger{value: makeInt64Pointer(1)} + if filledInt.IsDefault() { + t.Fatal("should not be the default") + } + if val := filledInt.WithDefault(0); val != 1 { + t.Errorf("optional integer should have been 1, got %d", val) + } + + if val := filledInt.WithDefault(-1); val != 1 { + t.Errorf("optional integer should have been 1, got %d", val) + } + + filledInt = OptionalInteger{value: makeInt64Pointer(0)} + if val := filledInt.WithDefault(1); val != 0 { + t.Errorf("optional integer should have been 0, got %d", val) + } + + for jsonStr, goValue := range map[string]OptionalInteger{ + "null": {}, + "0": {value: makeInt64Pointer(0)}, + "1": {value: makeInt64Pointer(1)}, + "-1": {value: makeInt64Pointer(-1)}, + } { + var d OptionalInteger + err := json.Unmarshal([]byte(jsonStr), &d) + if err != nil { + t.Fatal(err) + } + + if goValue.value == nil && d.value == nil { + } else if goValue.value == nil && d.value != nil { + t.Errorf("expected default, got %s", d) + } else if *d.value != *goValue.value { + t.Fatalf("expected %s, got %s", goValue, d) + } + + // Reverse + out, err := json.Marshal(goValue) + if err != nil { + t.Fatal(err) + } + if string(out) != jsonStr { + t.Fatalf("expected %s, got %s", jsonStr, string(out)) + } + } + + // marshal with omitempty + type Foo struct { + I *OptionalInteger `json:",omitempty"` + } + out, err := json.Marshal(new(Foo)) + if err != nil { + t.Fatal(err) + } + expected := "{}" + if string(out) != expected { + t.Fatal("expected omitempty to omit the optional integer") + } + + // unmarshal from omitempty output and get default value + var foo2 Foo + if err := json.Unmarshal(out, &foo2); err != nil { + t.Fatalf("%s failed to unmarshall with %s", string(out), err) + } + if i := foo2.I.WithDefault(42); i != 42 { + t.Fatalf("expected default value to be used, got %d", i) + } + if !foo2.I.IsDefault() { + t.Fatal("expected value to be the default") + } + + // test invalid values + for _, invalid := range []string{ + "foo", "-1.1", "1.1", "0.0", "[]", + } { + var p OptionalInteger + err := json.Unmarshal([]byte(invalid), &p) + if err == nil { + t.Errorf("expected to fail to decode %s as a priority", invalid) + } + } +} + +func TestOptionalString(t *testing.T) { + makeStringPointer := func(v string) *string { + return &v + } + + var defaultOptionalString OptionalString + if !defaultOptionalString.IsDefault() { + t.Fatal("should be the default") + } + if val := defaultOptionalString.WithDefault(""); val != "" { + t.Errorf("optional string should have been empty, got %s", val) + } + if val := defaultOptionalString.String(); val != "default" { + t.Fatalf("default optional string should be the 'default' string, got %s", val) + } + if val := defaultOptionalString.WithDefault("foo"); val != "foo" { + t.Errorf("optional string should have been foo, got %s", val) + } + + var filledStr OptionalString + filledStr = OptionalString{value: makeStringPointer("foo")} + if filledStr.IsDefault() { + t.Fatal("should not be the default") + } + if val := filledStr.WithDefault("bar"); val != "foo" { + t.Errorf("optional string should have been foo, got %s", val) + } + if val := filledStr.String(); val != "foo" { + t.Fatalf("optional string should have been foo, got %s", val) + } + filledStr = OptionalString{value: makeStringPointer("")} + if val := filledStr.WithDefault("foo"); val != "" { + t.Errorf("optional string should have been 0, got %s", val) + } + + for jsonStr, goValue := range map[string]OptionalString{ + "null": {}, + "\"0\"": {value: makeStringPointer("0")}, + "\"\"": {value: makeStringPointer("")}, + `"1"`: {value: makeStringPointer("1")}, + `"-1"`: {value: makeStringPointer("-1")}, + `"qwerty"`: {value: makeStringPointer("qwerty")}, + } { + var d OptionalString + err := json.Unmarshal([]byte(jsonStr), &d) + if err != nil { + t.Fatal(err) + } + + if goValue.value == nil && d.value == nil { + } else if goValue.value == nil && d.value != nil { + t.Errorf("expected default, got %s", d) + } else if *d.value != *goValue.value { + t.Fatalf("expected %s, got %s", goValue, d) + } + + // Reverse + out, err := json.Marshal(goValue) + if err != nil { + t.Fatal(err) + } + if string(out) != jsonStr { + t.Fatalf("expected %s, got %s", jsonStr, string(out)) + } + } + + // marshal with omitempty + type Foo struct { + S *OptionalString `json:",omitempty"` + } + out, err := json.Marshal(new(Foo)) + if err != nil { + t.Fatal(err) + } + expected := "{}" + if string(out) != expected { + t.Fatal("expected omitempty to omit the optional integer") + } + // unmarshal from omitempty output and get default value + var foo2 Foo + if err := json.Unmarshal(out, &foo2); err != nil { + t.Fatalf("%s failed to unmarshall with %s", string(out), err) + } + if s := foo2.S.WithDefault("foo"); s != "foo" { + t.Fatalf("expected default value to be used, got %s", s) + } + if !foo2.S.IsDefault() { + t.Fatal("expected value to be the default") + } + + for _, invalid := range []string{ + "[]", "{}", "0", "a", "'b'", + } { + var p OptionalString + err := json.Unmarshal([]byte(invalid), &p) + if err == nil { + t.Errorf("expected to fail to decode %s as an optional string", invalid) + } + } +} diff --git a/core/builder.go b/core/builder.go index e93ceddb2e3..c6bb9919206 100644 --- a/core/builder.go +++ b/core/builder.go @@ -2,6 +2,8 @@ package core import ( "context" + "fmt" + "reflect" "sync" "time" @@ -9,6 +11,7 @@ import ( "github.com/ipfs/go-ipfs/core/node" "github.com/ipfs/go-metrics-interface" + "go.uber.org/dig" "go.uber.org/fx" ) @@ -75,11 +78,11 @@ func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) { }() if app.Err() != nil { - return nil, app.Err() + return nil, logAndUnwrapFxError(app.Err()) } if err := app.Start(ctx); err != nil { - return nil, err + return nil, logAndUnwrapFxError(err) } // TODO: How soon will bootstrap move to libp2p? @@ -89,3 +92,46 @@ func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) { return n, n.Bootstrap(bootstrap.DefaultBootstrapConfig) } + +// Log the entire `app.Err()` but return only the innermost one to the user +// given the full error can be very long (as it can expose the entire build +// graph in a single string). +// +// The fx.App error exposed through `app.Err()` normally contains un-exported +// errors from its low-level `dig` package: +// * https://github.com/uber-go/dig/blob/5e5a20d/error.go#L82 +// These usually wrap themselves in many layers to expose where in the build +// chain did the error happen. Although useful for a developer that needs to +// debug it, it can be very confusing for a user that just wants the IPFS error +// that he can probably fix without being aware of the entire chain. +// Unwrapping everything is not the best solution as there can be useful +// information in the intermediate errors, mainly in the next to last error +// that locates which component is the build error coming from, but it's the +// best we can do at the moment given all errors in dig are private and we +// just have the generic `RootCause` API. +func logAndUnwrapFxError(fxAppErr error) error { + if fxAppErr == nil { + return nil + } + + log.Error("constructing the node: ", fxAppErr) + + err := fxAppErr + for { + extractedErr := dig.RootCause(err) + // Note that the `RootCause` name is misleading as it just unwraps only + // *one* error layer at a time, so we need to continuously call it. + if !reflect.TypeOf(extractedErr).Comparable() { + // Some internal errors are not comparable (e.g., `dig.errMissingTypes` + // which is a slice) and we can't go further. + break + } + if extractedErr == err { + // We didn't unwrap any new error in the last call, reached the innermost one. + break + } + err = extractedErr + } + + return fmt.Errorf("constructing the node (see log for full detail): %w", err) +} diff --git a/core/commands/block.go b/core/commands/block.go index a06bfe0683e..92e5f9cb3c9 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -8,8 +8,8 @@ import ( files "github.com/ipfs/go-ipfs-files" - util "github.com/ipfs/go-ipfs/blocks/blockstoreutil" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/commands/cmdutils" cmds "github.com/ipfs/go-ipfs-cmds" options "github.com/ipfs/interface-go-ipfs-core/options" @@ -31,8 +31,8 @@ var BlockCmd = &cmds.Command{ Tagline: "Interact with raw IPFS blocks.", ShortDescription: ` 'ipfs block' is a plumbing command used to manipulate raw IPFS blocks. -Reads from stdin or writes to stdout, and is a base58 encoded -multihash. +Reads from stdin or writes to stdout. A block is identified by a Multihash +passed with a valid CID. `, }, @@ -51,14 +51,14 @@ var blockStatCmd = &cmds.Command{ 'ipfs block stat' is a plumbing command for retrieving information on raw IPFS blocks. It outputs the following to stdout: - Key - the base58 encoded multihash + Key - the CID of the block Size - the size of the block in bytes `, }, Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "The base58 multihash of an existing block to stat.").EnableStdin(), + cmds.StringArg("cid", true, false, "The CID of an existing block to stat.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) @@ -90,12 +90,12 @@ var blockGetCmd = &cmds.Command{ Tagline: "Get a raw IPFS block.", ShortDescription: ` 'ipfs block get' is a plumbing command for retrieving raw IPFS blocks. -It outputs to stdout, and is a base58 encoded multihash. +It takes a , and outputs the block to stdout. `, }, Arguments: []cmds.Argument{ - cmds.StringArg("key", true, false, "The base58 multihash of an existing block to get.").EnableStdin(), + cmds.StringArg("cid", true, false, "The CID of an existing block to get.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) @@ -113,9 +113,10 @@ It outputs to stdout, and is a base58 encoded multihash. } const ( - blockFormatOptionName = "format" - mhtypeOptionName = "mhtype" - mhlenOptionName = "mhlen" + blockFormatOptionName = "format" + blockCidCodecOptionName = "cid-codec" + mhtypeOptionName = "mhtype" + mhlenOptionName = "mhlen" ) var blockPutCmd = &cmds.Command{ @@ -123,10 +124,17 @@ var blockPutCmd = &cmds.Command{ Tagline: "Store input as an IPFS block.", ShortDescription: ` 'ipfs block put' is a plumbing command for storing raw IPFS blocks. -It reads from stdin, and outputs the block's CID to stdout. +It reads data from stdin, and outputs the block's CID to stdout. -Unless specified, this command returns dag-pb CIDv0 CIDs. Setting 'mhtype' to anything -other than 'sha2-256' or format to anything other than 'v0' will result in CIDv1. +Unless cid-codec is specified, this command returns raw (0x55) CIDv1 CIDs. + +Passing alternative --cid-codec does not modify imported data, nor run any +validation. It is provided solely for convenience for users who create blocks +in userland. + +NOTE: +Do not use --format for any new code. It got superseded by --cid-codec and left +only for backward compatibility when a legacy CIDv0 is required (--format=v0). `, }, @@ -134,10 +142,12 @@ other than 'sha2-256' or format to anything other than 'v0' will result in CIDv1 cmds.FileArg("data", true, true, "The data to be stored as an IPFS block.").EnableStdin(), }, Options: []cmds.Option{ - cmds.StringOption(blockFormatOptionName, "f", "cid format for blocks to be created with."), - cmds.StringOption(mhtypeOptionName, "multihash hash function").WithDefault("sha2-256"), - cmds.IntOption(mhlenOptionName, "multihash hash length").WithDefault(-1), - cmds.BoolOption(pinOptionName, "pin added blocks recursively").WithDefault(false), + cmds.StringOption(blockCidCodecOptionName, "Multicodec to use in returned CID").WithDefault("raw"), + cmds.StringOption(mhtypeOptionName, "Multihash hash function").WithDefault("sha2-256"), + cmds.IntOption(mhlenOptionName, "Multihash hash length").WithDefault(-1), + cmds.BoolOption(pinOptionName, "Pin added blocks recursively").WithDefault(false), + cmdutils.AllowBigBlockOption, + cmds.StringOption(blockFormatOptionName, "f", "Use legacy format for returned CID (DEPRECATED)"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) @@ -156,13 +166,15 @@ other than 'sha2-256' or format to anything other than 'v0' will result in CIDv1 return errors.New("missing option \"mhlen\"") } - format, formatSet := req.Options[blockFormatOptionName].(string) - if !formatSet { - if mhtval != mh.SHA2_256 || (mhlen != -1 && mhlen != 32) { - format = "protobuf" - } else { - format = "v0" + cidCodec, _ := req.Options[blockCidCodecOptionName].(string) + format, _ := req.Options[blockFormatOptionName].(string) // deprecated + + // use of legacy 'format' needs to supress 'cid-codec' + if format != "" { + if cidCodec != "" && cidCodec != "raw" { + return fmt.Errorf("unable to use %q (deprecated) and a custom %q at the same time", blockFormatOptionName, blockCidCodecOptionName) } + cidCodec = "" // makes it no-op } pin, _ := req.Options[pinOptionName].(bool) @@ -176,12 +188,17 @@ other than 'sha2-256' or format to anything other than 'v0' will result in CIDv1 p, err := api.Block().Put(req.Context, file, options.Block.Hash(mhtval, mhlen), + options.Block.CidCodec(cidCodec), options.Block.Format(format), options.Block.Pin(pin)) if err != nil { return err } + if err := cmdutils.CheckBlockSize(req, uint64(p.Size())); err != nil { + return err + } + err = res.Emit(&BlockStat{ Key: p.Path().Cid().String(), Size: p.Size(), @@ -207,16 +224,21 @@ const ( blockQuietOptionName = "quiet" ) +type removedBlock struct { + Hash string `json:",omitempty"` + Error string `json:",omitempty"` +} + var blockRmCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "Remove IPFS block(s).", + Tagline: "Remove IPFS block(s) from the local datastore.", ShortDescription: ` 'ipfs block rm' is a plumbing command for removing raw ipfs blocks. -It takes a list of base58 encoded multihashes to remove. +It takes a list of CIDs to remove from the local datastore.. `, }, Arguments: []cmds.Argument{ - cmds.StringArg("hash", true, true, "Bash58 encoded multihash of block(s) to remove."), + cmds.StringArg("cid", true, true, "CIDs of block(s) to remove."), }, Options: []cmds.Option{ cmds.BoolOption(forceOptionName, "f", "Ignore nonexistent blocks."), @@ -240,7 +262,7 @@ It takes a list of base58 encoded multihashes to remove. err = api.Block().Rm(req.Context, rp, options.Block.Force(force)) if err != nil { - if err := res.Emit(&util.RemovedBlock{ + if err := res.Emit(&removedBlock{ Hash: rp.Cid().String(), Error: err.Error(), }); err != nil { @@ -250,7 +272,7 @@ It takes a list of base58 encoded multihashes to remove. } if !quiet { - err := res.Emit(&util.RemovedBlock{ + err := res.Emit(&removedBlock{ Hash: rp.Cid().String(), }) if err != nil { @@ -263,8 +285,29 @@ It takes a list of base58 encoded multihashes to remove. }, PostRun: cmds.PostRunMap{ cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error { - return util.ProcRmOutput(res.Next, os.Stdout, os.Stderr) + someFailed := false + for { + res, err := res.Next() + if err == io.EOF { + break + } else if err != nil { + return err + } + r := res.(*removedBlock) + if r.Hash == "" && r.Error != "" { + return fmt.Errorf("aborted: %s", r.Error) + } else if r.Error != "" { + someFailed = true + fmt.Fprintf(os.Stderr, "cannot remove %s: %s\n", r.Hash, r.Error) + } else { + fmt.Fprintf(os.Stdout, "removed %s\n", r.Hash) + } + } + if someFailed { + return fmt.Errorf("some blocks not removed") + } + return nil }, }, - Type: util.RemovedBlock{}, + Type: removedBlock{}, } diff --git a/core/commands/bootstrap.go b/core/commands/bootstrap.go index 1aaa6456501..d572e8c079b 100644 --- a/core/commands/bootstrap.go +++ b/core/commands/bootstrap.go @@ -11,7 +11,7 @@ import ( fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" peer "github.com/libp2p/go-libp2p-core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/core/commands/cat.go b/core/commands/cat.go index 8aff890284a..98a0e41bd2c 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -8,6 +8,7 @@ import ( "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/cheggaaa/pb" "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs-files" "github.com/ipfs/interface-go-ipfs-core" @@ -32,6 +33,7 @@ var CatCmd = &cmds.Command{ Options: []cmds.Option{ cmds.Int64Option(offsetOptionName, "o", "Byte offset to begin reading from."), cmds.Int64Option(lengthOptionName, "l", "Maximum number of bytes to read."), + cmds.BoolOption(progressOptionName, "p", "Stream progress data.").WithDefault(true), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { api, err := cmdenv.GetApi(env, req) @@ -96,8 +98,16 @@ var CatCmd = &cmds.Command{ switch val := v.(type) { case io.Reader: - bar, reader := progressBarForReader(os.Stderr, val, int64(res.Length())) - bar.Start() + reader := val + + req := res.Request() + progress, _ := req.Options[progressOptionName].(bool) + if progress { + var bar *pb.ProgressBar + bar, reader = progressBarForReader(os.Stderr, val, int64(res.Length())) + bar.Start() + defer bar.Finish() + } err = re.Emit(reader) if err != nil { diff --git a/core/commands/cid.go b/core/commands/cid.go index 13c3e83a918..f988d1c8c47 100644 --- a/core/commands/cid.go +++ b/core/commands/cid.go @@ -11,7 +11,10 @@ import ( cidutil "github.com/ipfs/go-cidutil" cmds "github.com/ipfs/go-ipfs-cmds" verifcid "github.com/ipfs/go-verifcid" + ipldmulticodec "github.com/ipld/go-ipld-prime/multicodec" mbase "github.com/multiformats/go-multibase" + "github.com/multiformats/go-multicodec" + mc "github.com/multiformats/go-multicodec" mhash "github.com/multiformats/go-multihash" ) @@ -32,7 +35,7 @@ var CidCmd = &cmds.Command{ const ( cidFormatOptionName = "f" cidVerisonOptionName = "v" - cidCodecOptionName = "codec" + cidCodecOptionName = "mc" cidMultibaseOptionName = "b" ) @@ -46,12 +49,12 @@ The optional format string is a printf style format string: ` + cidutil.FormatRef, }, Arguments: []cmds.Argument{ - cmds.StringArg("cid", true, true, "Cids to format.").EnableStdin(), + cmds.StringArg("cid", true, true, "CIDs to format.").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption(cidFormatOptionName, "Printf style format string.").WithDefault("%s"), cmds.StringOption(cidVerisonOptionName, "CID version to convert to."), - cmds.StringOption(cidCodecOptionName, "CID codec to convert to."), + cmds.StringOption(cidCodecOptionName, "CID multicodec to convert to."), cmds.StringOption(cidMultibaseOptionName, "Multibase to display CID in."), }, Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error { @@ -63,16 +66,17 @@ The optional format string is a printf style format string: opts := cidFormatOpts{} if strings.IndexByte(fmtStr, '%') == -1 { - return fmt.Errorf("invalid format string: %s", fmtStr) + return fmt.Errorf("invalid format string: %q", fmtStr) } opts.fmtStr = fmtStr if codecStr != "" { - codec, ok := cid.Codecs[codecStr] - if !ok { - return fmt.Errorf("unknown IPLD codec: %s", codecStr) + var codec multicodec.Code + err := codec.Set(codecStr) + if err != nil { + return err } - opts.newCodec = codec + opts.newCodec = uint64(codec) } // otherwise, leave it as 0 (not a valid IPLD codec) switch verStr { @@ -80,13 +84,13 @@ The optional format string is a printf style format string: // noop case "0": if opts.newCodec != 0 && opts.newCodec != cid.DagProtobuf { - return fmt.Errorf("cannot convert to CIDv0 with any codec other than DagPB") + return fmt.Errorf("cannot convert to CIDv0 with any codec other than dag-pb") } opts.verConv = toCidV0 case "1": opts.verConv = toCidV1 default: - return fmt.Errorf("invalid cid version: %s", verStr) + return fmt.Errorf("invalid cid version: %q", verStr) } if baseStr != "" { @@ -123,9 +127,13 @@ type CidFormatRes struct { var base32Cmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Convert CIDs to Base32 CID version 1.", + ShortDescription: ` +'ipfs cid base32' normalizes passes CIDs to their canonical case-insensitive encoding. +Useful when processing third-party CIDs which could come with arbitrary formats. +`, }, Arguments: []cmds.Argument{ - cmds.StringArg("cid", true, true, "Cids to convert.").EnableStdin(), + cmds.StringArg("cid", true, true, "CIDs to convert.").EnableStdin(), }, Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error { opts := cidFormatOpts{ @@ -232,7 +240,7 @@ func emitCids(req *cmds.Request, resp cmds.ResponseEmitter, opts cidFormatOpts) func toCidV0(c cid.Cid) (cid.Cid, error) { if c.Type() != cid.DagProtobuf { - return cid.Cid{}, fmt.Errorf("can't convert non-protobuf nodes to cidv0") + return cid.Cid{}, fmt.Errorf("can't convert non-dag-pb nodes to cidv0") } return cid.NewCidV0(c.Hash()), nil } @@ -254,6 +262,9 @@ const ( var basesCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List available multibase encodings.", + ShortDescription: ` +'ipfs cid bases' relies on https://github.com/multiformats/go-multibase +`, }, Options: []cmds.Option{ cmds.BoolOption(prefixOptionName, "also include the single letter prefixes in addition to the code"), @@ -296,21 +307,45 @@ var basesCmd = &cmds.Command{ } const ( - codecsNumericOptionName = "numeric" + codecsNumericOptionName = "numeric" + codecsSupportedOptionName = "supported" ) var codecsCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "List available CID codecs.", + Tagline: "List available CID multicodecs.", + ShortDescription: ` +'ipfs cid codecs' relies on https://github.com/multiformats/go-multicodec +`, }, Options: []cmds.Option{ - cmds.BoolOption(codecsNumericOptionName, "also include numeric codes"), + cmds.BoolOption(codecsNumericOptionName, "n", "also include numeric codes"), + cmds.BoolOption(codecsSupportedOptionName, "s", "list only codecs supported by go-ipfs commands"), }, Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error { + listSupported, _ := req.Options[codecsSupportedOptionName].(bool) + supportedCodecs := make(map[uint64]struct{}) + if listSupported { + for _, code := range ipldmulticodec.ListEncoders() { + supportedCodecs[code] = struct{}{} + } + for _, code := range ipldmulticodec.ListDecoders() { + supportedCodecs[code] = struct{}{} + } + // add libp2p-key + supportedCodecs[uint64(mc.Libp2pKey)] = struct{}{} + } + var res []CodeAndName - // use CodecToStr as there are multiple names for a given code - for code, name := range cid.CodecToStr { - res = append(res, CodeAndName{int(code), name}) + for _, code := range mc.KnownCodes() { + if code.Tag() == "ipld" { + if listSupported { + if _, ok := supportedCodecs[uint64(code)]; !ok { + continue + } + } + res = append(res, CodeAndName{int(code), mc.Code(code).String()}) + } } return cmds.EmitOnce(resp, res) }, @@ -334,6 +369,9 @@ var codecsCmd = &cmds.Command{ var hashesCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List available multihashes.", + ShortDescription: ` +'ipfs cid hashes' relies on https://github.com/multiformats/go-multihash +`, }, Options: codecsCmd.Options, Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error { diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index c21612c3305..ecce8327857 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -9,7 +9,6 @@ import ( "github.com/ipfs/go-ipfs/core" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" logging "github.com/ipfs/go-log" coreiface "github.com/ipfs/interface-go-ipfs-core" options "github.com/ipfs/interface-go-ipfs-core/options" @@ -52,16 +51,6 @@ func GetApi(env cmds.Environment, req *cmds.Request) (coreiface.CoreAPI, error) return api, nil } -// GetConfig extracts the config from the environment. -func GetConfig(env cmds.Environment) (*config.Config, error) { - ctx, ok := env.(*commands.Context) - if !ok { - return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env) - } - - return ctx.GetConfig() -} - // GetConfigRoot extracts the config root from the environment func GetConfigRoot(env cmds.Environment) (string, error) { ctx, ok := env.(*commands.Context) diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go new file mode 100644 index 00000000000..ebbbca64e46 --- /dev/null +++ b/core/commands/cmdutils/utils.go @@ -0,0 +1,51 @@ +package cmdutils + +import ( + "fmt" + + cmds "github.com/ipfs/go-ipfs-cmds" + + "github.com/ipfs/go-cid" + coreiface "github.com/ipfs/interface-go-ipfs-core" +) + +const ( + AllowBigBlockOptionName = "allow-big-block" + SoftBlockLimit = 1024 * 1024 // https://github.com/ipfs/go-ipfs/issues/7421#issuecomment-910833499 +) + +var AllowBigBlockOption cmds.Option + +func init() { + AllowBigBlockOption = cmds.BoolOption(AllowBigBlockOptionName, "Disable block size check and allow creation of blocks bigger than 1MiB. WARNING: such blocks won't be transferable over the standard bitswap.").WithDefault(false) +} + +func CheckCIDSize(req *cmds.Request, c cid.Cid, dagAPI coreiface.APIDagService) error { + n, err := dagAPI.Get(req.Context, c) + if err != nil { + return fmt.Errorf("CheckCIDSize: getting dag: %w", err) + } + + nodeSize, err := n.Size() + if err != nil { + return fmt.Errorf("CheckCIDSize: getting node size: %w", err) + } + + return CheckBlockSize(req, nodeSize) +} + +func CheckBlockSize(req *cmds.Request, size uint64) error { + allowAnyBlockSize, _ := req.Options[AllowBigBlockOptionName].(bool) + if allowAnyBlockSize { + return nil + } + + // We do not allow producing blocks bigger than 1 MiB to avoid errors + // when transmitting them over BitSwap. The 1 MiB constant is an + // unenforced and undeclared rule of thumb hard-coded here. + if size > SoftBlockLimit { + return fmt.Errorf("produced block is over 1MiB: big blocks can't be exchanged with other peers. consider using UnixFS for automatic chunking of bigger files, or pass --allow-big-block to override") + } + return nil + +} diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index 964baad9299..b0980f13126 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -237,11 +237,13 @@ func TestCommands(t *testing.T) { "/swarm/filters", "/swarm/filters/add", "/swarm/filters/rm", + "/swarm/limit", "/swarm/peers", "/swarm/peering", "/swarm/peering/add", "/swarm/peering/ls", "/swarm/peering/rm", + "/swarm/stats", "/tar", "/tar/add", "/tar/cat", diff --git a/core/commands/config.go b/core/commands/config.go index 86037ceb4f9..38e14c31da9 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -16,7 +16,7 @@ import ( "github.com/elgris/jsondiff" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ) // ConfigUpdateOutput is config profile apply command's output @@ -186,7 +186,8 @@ NOTE: For security reasons, this command will omit your private key and remote s return err } - fname, err := config.Filename(cfgRoot) + configFileOpt, _ := req.Options[ConfigFileOption].(string) + fname, err := config.Filename(cfgRoot, configFileOpt) if err != nil { return err } @@ -215,18 +216,20 @@ NOTE: For security reasons, this command will omit your private key and remote s return cmds.EmitOnce(res, &cfg) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *map[string]interface{}) error { - buf, err := config.HumanOutput(out) - if err != nil { - return err - } - buf = append(buf, byte('\n')) - _, err = w.Write(buf) - return err - }), + cmds.Text: HumanJSONEncoder, }, } +var HumanJSONEncoder = cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *map[string]interface{}) error { + buf, err := config.HumanOutput(out) + if err != nil { + return err + } + buf = append(buf, byte('\n')) + _, err = w.Write(buf) + return err +}) + // Scrubs value and returns error if missing func scrubValue(m map[string]interface{}, key []string) (map[string]interface{}, error) { return scrubMapInternal(m, key, false) @@ -289,7 +292,8 @@ variable set to your preferred text editor. return err } - filename, err := config.Filename(cfgRoot) + configFileOpt, _ := req.Options[ConfigFileOption].(string) + filename, err := config.Filename(cfgRoot, configFileOpt) if err != nil { return err } diff --git a/core/commands/dag/dag.go b/core/commands/dag/dag.go index cbaf7f93fe1..d5d7479f268 100644 --- a/core/commands/dag/dag.go +++ b/core/commands/dag/dag.go @@ -5,6 +5,7 @@ import ( "io" "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/commands/cmdutils" cid "github.com/ipfs/go-cid" cidenc "github.com/ipfs/go-cidutil/cidenc" @@ -29,9 +30,9 @@ var DagCmd = &cmds.Command{ ShortDescription: ` 'ipfs dag' is used for creating and manipulating DAG objects/hierarchies. -This subcommand is currently an experimental feature, but it is intended -to deprecate and replace the existing 'ipfs object' command moving forward. - `, +This subcommand is intended to deprecate and replace +the existing 'ipfs object' command moving forward. +`, }, Subcommands: map[string]*cmds.Command{ "put": DagPutCmd, @@ -88,6 +89,7 @@ into an object of the specified format. cmds.StringOption("input-codec", "Codec that the input object is encoded in").WithDefault("dag-json"), cmds.BoolOption("pin", "Pin this object when adding."), cmds.StringOption("hash", "Hash function to use").WithDefault("sha2-256"), + cmdutils.AllowBigBlockOption, }, Run: dagPut, Type: OutputObject{}, @@ -205,6 +207,7 @@ Maximum supported CAR version: 1 cmds.BoolOption(pinRootsOptionName, "Pin optional roots listed in the .car headers after importing.").WithDefault(true), cmds.BoolOption(silentOptionName, "No output."), cmds.BoolOption(statsOptionName, "Output stats."), + cmdutils.AllowBigBlockOption, }, Type: CarImportOutput{}, Run: dagImport, diff --git a/core/commands/dag/export.go b/core/commands/dag/export.go index 7290002e7f0..530bf4d5788 100644 --- a/core/commands/dag/export.go +++ b/core/commands/dag/export.go @@ -63,8 +63,7 @@ func dagExport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment err = <-errCh // minimal user friendliness - if err != nil && - err == ipld.ErrNotFound { + if ipld.IsNotFound(err) { explicitOffline, _ := req.Options["offline"].(bool) if explicitOffline { err = fmt.Errorf("%s (currently offline, perhaps retry without the offline flag)", err) diff --git a/core/commands/dag/import.go b/core/commands/dag/import.go index e206652ce36..77d688ca9ea 100644 --- a/core/commands/dag/import.go +++ b/core/commands/dag/import.go @@ -8,12 +8,13 @@ import ( cid "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/commands/cmdutils" ipld "github.com/ipfs/go-ipld-format" iface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/options" cmds "github.com/ipfs/go-ipfs-cmds" - gocar "github.com/ipld/go-car" + gocarv2 "github.com/ipld/go-car/v2" ) func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -159,17 +160,12 @@ func importWorker(req *cmds.Request, re cmds.ResponseEmitter, api iface.CoreAPI, err := func() error { defer file.Close() - car, err := gocar.NewCarReader(file) + car, err := gocarv2.NewBlockReader(file) if err != nil { return err } - // Be explicit here, until the spec is finished - if car.Header.Version != 1 { - return errors.New("only car files version 1 supported at present") - } - - for _, c := range car.Header.Roots { + for _, c := range car.Roots { roots[c] = struct{}{} } @@ -180,6 +176,9 @@ func importWorker(req *cmds.Request, re cmds.ResponseEmitter, api iface.CoreAPI, } else if block == nil { break } + if err := cmdutils.CheckBlockSize(req, uint64(len(block.RawData()))); err != nil { + return err + } // the double-decode is suboptimal, but we need it for batching nd, err := ipld.Decode(block) diff --git a/core/commands/dag/put.go b/core/commands/dag/put.go index 0bb7fd2ae50..e741f11124d 100644 --- a/core/commands/dag/put.go +++ b/core/commands/dag/put.go @@ -7,6 +7,7 @@ import ( blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/commands/cmdutils" ipldlegacy "github.com/ipfs/go-ipld-legacy" "github.com/ipld/go-ipld-prime/multicodec" basicnode "github.com/ipld/go-ipld-prime/node/basic" @@ -102,6 +103,10 @@ func dagPut(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) e Node: n, } + if err := cmdutils.CheckBlockSize(req, uint64(bd.Len())); err != nil { + return err + } + if err := b.Add(req.Context, &ln); err != nil { return err } diff --git a/core/commands/dns.go b/core/commands/dns.go index 42a7c98c1a2..8fccadf6774 100644 --- a/core/commands/dns.go +++ b/core/commands/dns.go @@ -17,40 +17,17 @@ const ( ) var DNSCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/8607 Helptext: cmds.HelpText{ - Tagline: "Resolve DNS links.", + Tagline: "Resolve DNSLink records.", ShortDescription: ` -Multihashes are hard to remember, but domain names are usually easy to -remember. To create memorable aliases for multihashes, DNS TXT -records can point to other DNS links, IPFS objects, IPNS keys, etc. -This command resolves those links to the referenced object. -`, - LongDescription: ` -Multihashes are hard to remember, but domain names are usually easy to -remember. To create memorable aliases for multihashes, DNS TXT -records can point to other DNS links, IPFS objects, IPNS keys, etc. -This command resolves those links to the referenced object. - -Note: This command can only recursively resolve DNS links, -it will fail to recursively resolve through IPNS keys etc. -For general-purpose recursive resolution, use ipfs name resolve -r. - -For example, with this DNS TXT record: - - > dig +short TXT _dnslink.ipfs.io - dnslink=/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy - -The resolver will give: - - > ipfs dns ipfs.io - /ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy +This command can only recursively resolve DNSLink TXT records. +It will fail to recursively resolve through IPNS keys etc. -The resolver can recursively resolve: +DEPRECATED: superseded by 'ipfs resolve' - > dig +short TXT recursive.ipfs.io - dnslink=/ipns/ipfs.io - > ipfs dns -r recursive.ipfs.io - /ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy +For general-purpose recursive resolution, use 'ipfs resolve -r'. +It will work across multiple DNSLinks and IPNS keys. `, }, diff --git a/core/commands/files.go b/core/commands/files.go index 3f7e3e6b9a9..4c403f7688a 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -297,7 +297,7 @@ func walkBlock(ctx context.Context, dagserv ipld.DAGService, nd ipld.Node) (bool for _, link := range nd.Links() { child, err := dagserv.Get(ctx, link.Cid) - if err == ipld.ErrNotFound { + if ipld.IsNotFound(err) { local = false continue } @@ -348,8 +348,8 @@ $ ipfs pin add The lazy-copy feature can also be used to protect partial DAG contents from garbage collection. i.e. adding the Wikipedia root to MFS would not download -all the Wikipedia, but will any downloaded Wikipedia-DAG content from being -GC'ed. +all the Wikipedia, but will prevent any downloaded Wikipedia-DAG content from +being GC'ed. `, }, Arguments: []cmds.Argument{ @@ -1052,74 +1052,13 @@ Remove files or directories. for _, arg := range req.Arguments { path, err := checkPath(arg) if err != nil { - errs = append(errs, fmt.Errorf("%s: %w", arg, err)) + errs = append(errs, fmt.Errorf("%s is not a valid path: %w", arg, err)) continue } - if path == "/" { - errs = append(errs, fmt.Errorf("%s: cannot delete root", path)) - continue - } - - // 'rm a/b/c/' will fail unless we trim the slash at the end - if path[len(path)-1] == '/' { - path = path[:len(path)-1] - } - - dir, name := gopath.Split(path) - - pdir, err := getParentDir(nd.FilesRoot, dir) - if err != nil { - if force && err == os.ErrNotExist { - continue - } - errs = append(errs, fmt.Errorf("%s: parent lookup: %w", path, err)) - continue - } - - if force { - err := pdir.Unlink(name) - if err != nil { - if err == os.ErrNotExist { - continue - } - errs = append(errs, fmt.Errorf("%s: %w", path, err)) - continue - } - err = pdir.Flush() - if err != nil { - errs = append(errs, fmt.Errorf("%s: %w", path, err)) - } - continue - } - - // get child node by name, when the node is corrupted and nonexistent, - // it will return specific error. - child, err := pdir.Child(name) - if err != nil { - errs = append(errs, fmt.Errorf("%s: %w", path, err)) - continue - } - - switch child.(type) { - case *mfs.Directory: - if !dashr { - errs = append(errs, fmt.Errorf("%s is a directory, use -r to remove directories", path)) - continue - } - } - - err = pdir.Unlink(name) - if err != nil { - errs = append(errs, fmt.Errorf("%s: %w", path, err)) - continue - } - - err = pdir.Flush() - if err != nil { + if err := removePath(nd.FilesRoot, path, force, dashr); err != nil { errs = append(errs, fmt.Errorf("%s: %w", path, err)) } - continue } if len(errs) > 0 { for _, err = range errs { @@ -1134,6 +1073,59 @@ Remove files or directories. }, } +func removePath(filesRoot *mfs.Root, path string, force bool, dashr bool) error { + if path == "/" { + return fmt.Errorf("cannot delete root") + } + + // 'rm a/b/c/' will fail unless we trim the slash at the end + if path[len(path)-1] == '/' { + path = path[:len(path)-1] + } + + dir, name := gopath.Split(path) + + pdir, err := getParentDir(filesRoot, dir) + if err != nil { + if force && err == os.ErrNotExist { + return nil + } + return err + } + + if force { + err := pdir.Unlink(name) + if err != nil { + if err == os.ErrNotExist { + return nil + } + return err + } + return pdir.Flush() + } + + // get child node by name, when the node is corrupted and nonexistent, + // it will return specific error. + child, err := pdir.Child(name) + if err != nil { + return err + } + + switch child.(type) { + case *mfs.Directory: + if !dashr { + return fmt.Errorf("path is a directory, use -r to remove directories") + } + } + + err = pdir.Unlink(name) + if err != nil { + return err + } + + return pdir.Flush() +} + func getPrefixNew(req *cmds.Request) (cid.Builder, error) { cidVer, cidVerSet := req.Options[filesCidVersionOptionName].(int) hashFunStr, hashFunSet := req.Options[filesHashOptionName].(string) diff --git a/core/commands/get.go b/core/commands/get.go index 7fb53467f5d..7f687ed228b 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -54,12 +54,14 @@ may also specify the level of compression by specifying '-l=<1-9>'. cmds.BoolOption(archiveOptionName, "a", "Output a TAR archive."), cmds.BoolOption(compressOptionName, "C", "Compress the output with GZIP compression."), cmds.IntOption(compressionLevelOptionName, "l", "The level of compression (1-9)."), + cmds.BoolOption(progressOptionName, "p", "Stream progress data.").WithDefault(true), }, PreRun: func(req *cmds.Request, env cmds.Environment) error { _, err := getCompressOptions(req) return err }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + ctx := req.Context cmplvl, err := getCompressOptions(req) if err != nil { return err @@ -72,7 +74,7 @@ may also specify the level of compression by specifying '-l=<1-9>'. p := path.New(req.Arguments[0]) - file, err := api.Unixfs().Get(req.Context, p) + file, err := api.Unixfs().Get(ctx, p) if err != nil { return err } @@ -89,6 +91,13 @@ may also specify the level of compression by specifying '-l=<1-9>'. if err != nil { return err } + go func() { + // We cannot defer a close in the response writer (like we should) + // Because the cmd framework outsmart us and doesn't call response + // if the context is over. + <-ctx.Done() + reader.Close() + }() return res.Emit(reader) }, @@ -114,6 +123,7 @@ may also specify the level of compression by specifying '-l=<1-9>'. } archive, _ := req.Options[archiveOptionName].(bool) + progress, _ := req.Options[progressOptionName].(bool) gw := getWriter{ Out: os.Stdout, @@ -121,6 +131,7 @@ may also specify the level of compression by specifying '-l=<1-9>'. Archive: archive, Compression: cmplvl, Size: int64(res.Length()), + Progress: progress, } return gw.Write(outReader, outPath) @@ -181,6 +192,7 @@ type getWriter struct { Archive bool Compression int Size int64 + Progress bool } func (gw *getWriter) Write(r io.Reader, fpath string) error { @@ -213,22 +225,29 @@ func (gw *getWriter) writeArchive(r io.Reader, fpath string) error { defer file.Close() fmt.Fprintf(gw.Out, "Saving archive to %s\n", fpath) - bar, barR := progressBarForReader(gw.Err, r, gw.Size) - bar.Start() - defer bar.Finish() + if gw.Progress { + var bar *pb.ProgressBar + bar, r = progressBarForReader(gw.Err, r, gw.Size) + bar.Start() + defer bar.Finish() + } - _, err = io.Copy(file, barR) + _, err = io.Copy(file, r) return err } func (gw *getWriter) writeExtracted(r io.Reader, fpath string) error { fmt.Fprintf(gw.Out, "Saving file(s) to %s\n", fpath) - bar := makeProgressBar(gw.Err, gw.Size) - bar.Start() - defer bar.Finish() - defer bar.Set64(gw.Size) + var progressCb func(int64) int64 + if gw.Progress { + bar := makeProgressBar(gw.Err, gw.Size) + bar.Start() + defer bar.Finish() + defer bar.Set64(gw.Size) + progressCb = bar.Add64 + } - extractor := &tar.Extractor{Path: fpath, Progress: bar.Add64} + extractor := &tar.Extractor{Path: fpath, Progress: progressCb} return extractor.Extract(r) } @@ -246,7 +265,7 @@ func getCompressOptions(req *cmds.Request) (int, error) { return cmplvl, nil } -// DefaultBufSize is the buffer size for gets. for now, 1MB, which is ~4 blocks. +// DefaultBufSize is the buffer size for gets. for now, 1MiB, which is ~4 blocks. // TODO: does this need to be configurable? var DefaultBufSize = 1048576 @@ -262,7 +281,7 @@ func (i *identityWriteCloser) Close() error { return nil } -func fileArchive(f files.Node, name string, archive bool, compression int) (io.Reader, error) { +func fileArchive(f files.Node, name string, archive bool, compression int) (io.ReadCloser, error) { cleaned := gopath.Clean(name) _, filename := gopath.Split(cleaned) diff --git a/core/commands/id.go b/core/commands/id.go index 06a70bf35b5..8920c90921f 100644 --- a/core/commands/id.go +++ b/core/commands/id.go @@ -23,14 +23,7 @@ import ( identify "github.com/libp2p/go-libp2p/p2p/protocol/identify" ) -const offlineIdErrorMessage = `'ipfs id' currently cannot query information on remote -peers without a running daemon; we are working to fix this. -In the meantime, if you want to query remote peers using 'ipfs id', -please run the daemon: - - ipfs daemon & - ipfs id QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ -` +const offlineIdErrorMessage = "'ipfs id' cannot query information on remote peers without a running daemon; if you only want to convert --peerid-base, pass --offline option." type IdOutput struct { ID string @@ -102,19 +95,21 @@ EXAMPLE: return cmds.EmitOnce(res, output) } - // TODO handle offline mode with polymorphism instead of conditionals - if !n.IsOnline { + offline, _ := req.Options[OfflineOption].(bool) + if !offline && !n.IsOnline { return errors.New(offlineIdErrorMessage) } - // We need to actually connect to run identify. - err = n.PeerHost.Connect(req.Context, peer.AddrInfo{ID: id}) - switch err { - case nil: - case kb.ErrLookupFailure: - return errors.New(offlineIdErrorMessage) - default: - return err + if !offline { + // We need to actually connect to run identify. + err = n.PeerHost.Connect(req.Context, peer.AddrInfo{ID: id}) + switch err { + case nil: + case kb.ErrLookupFailure: + return errors.New(offlineIdErrorMessage) + default: + return err + } } output, err := printPeer(keyEnc, n.Peerstore, id) diff --git a/core/commands/keystore.go b/core/commands/keystore.go index bd3146ca57c..4f7ca4af80f 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -2,6 +2,9 @@ package commands import ( "bytes" + "crypto/ed25519" + "crypto/x509" + "encoding/pem" "fmt" "io" "io/ioutil" @@ -11,9 +14,9 @@ import ( "text/tabwriter" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" keystore "github.com/ipfs/go-ipfs-keystore" oldcmds "github.com/ipfs/go-ipfs/commands" + config "github.com/ipfs/go-ipfs/config" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" "github.com/ipfs/go-ipfs/core/commands/e" ke "github.com/ipfs/go-ipfs/core/commands/keyencode" @@ -135,6 +138,14 @@ var keyGenCmd = &cmds.Command{ Type: KeyOutput{}, } +const ( + // Key format options used both for importing and exporting. + keyFormatOptionName = "format" + keyFormatPemCleartextOption = "pem-pkcs8-cleartext" + keyFormatLibp2pCleartextOption = "libp2p-protobuf-cleartext" + keyAllowAnyTypeOptionName = "allow-any-key-type" +) + var keyExportCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Export a keypair", @@ -143,6 +154,13 @@ Exports a named libp2p key to disk. By default, the output will be stored at './.key', but an alternate path can be specified with '--output=' or '-o='. + +It is possible to export a private key to interoperable PEM PKCS8 format by explicitly +passing '--format=pem-pkcs8-cleartext'. The resulting PEM file can then be consumed +elsewhere. For example, using openssl to get a PEM with public key: + + $ ipfs key export testkey --format=pem-pkcs8-cleartext -o privkey.pem + $ openssl pkey -in privkey.pem -pubout > pubkey.pem `, }, Arguments: []cmds.Argument{ @@ -150,6 +168,7 @@ path can be specified with '--output=' or '-o='. }, Options: []cmds.Option{ cmds.StringOption(outputOptionName, "o", "The path where the output should be stored."), + cmds.StringOption(keyFormatOptionName, "f", "The format of the exported private key, libp2p-protobuf-cleartext or pem-pkcs8-cleartext.").WithDefault(keyFormatLibp2pCleartextOption), }, NoRemote: true, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -186,12 +205,38 @@ path can be specified with '--output=' or '-o='. return fmt.Errorf("key with name '%s' doesn't exist", name) } - encoded, err := crypto.MarshalPrivateKey(sk) - if err != nil { - return err + exportFormat, _ := req.Options[keyFormatOptionName].(string) + var formattedKey []byte + switch exportFormat { + case keyFormatPemCleartextOption: + stdKey, err := crypto.PrivKeyToStdKey(sk) + if err != nil { + return fmt.Errorf("converting libp2p private key to std Go key: %w", err) + + } + // For some reason the ed25519.PrivateKey does not use pointer + // receivers, so we need to convert it for MarshalPKCS8PrivateKey. + // (We should probably change this upstream in PrivKeyToStdKey). + if ed25519KeyPointer, ok := stdKey.(*ed25519.PrivateKey); ok { + stdKey = *ed25519KeyPointer + } + // This function supports a restricted list of public key algorithms, + // but we generate and use only the RSA and ed25519 types that are on that list. + formattedKey, err = x509.MarshalPKCS8PrivateKey(stdKey) + if err != nil { + return fmt.Errorf("marshalling key to PKCS8 format: %w", err) + } + + case keyFormatLibp2pCleartextOption: + formattedKey, err = crypto.MarshalPrivateKey(sk) + if err != nil { + return err + } + default: + return fmt.Errorf("unrecognized export format: %s", exportFormat) } - return res.Emit(bytes.NewReader(encoded)) + return res.Emit(bytes.NewReader(formattedKey)) }, PostRun: cmds.PostRunMap{ cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error { @@ -208,8 +253,16 @@ path can be specified with '--output=' or '-o='. } outPath, _ := req.Options[outputOptionName].(string) + exportFormat, _ := req.Options[keyFormatOptionName].(string) if outPath == "" { - trimmed := strings.TrimRight(fmt.Sprintf("%s.key", req.Arguments[0]), "/") + var fileExtension string + switch exportFormat { + case keyFormatPemCleartextOption: + fileExtension = "pem" + case keyFormatLibp2pCleartextOption: + fileExtension = "key" + } + trimmed := strings.TrimRight(fmt.Sprintf("%s.%s", req.Arguments[0], fileExtension), "/") _, outPath = filepath.Split(trimmed) outPath = filepath.Clean(outPath) } @@ -221,9 +274,26 @@ path can be specified with '--output=' or '-o='. } defer file.Close() - _, err = io.Copy(file, outReader) - if err != nil { - return err + switch exportFormat { + case keyFormatPemCleartextOption: + privKeyBytes, err := ioutil.ReadAll(outReader) + if err != nil { + return err + } + + err = pem.Encode(file, &pem.Block{ + Type: "PRIVATE KEY", + Bytes: privKeyBytes, + }) + if err != nil { + return fmt.Errorf("encoding PEM block: %w", err) + } + + case keyFormatLibp2pCleartextOption: + _, err = io.Copy(file, outReader) + if err != nil { + return err + } } return nil @@ -234,9 +304,23 @@ path can be specified with '--output=' or '-o='. var keyImportCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Import a key and prints imported key id", + ShortDescription: ` +Imports a key and stores it under the provided name. + +By default, the key is assumed to be in 'libp2p-protobuf-cleartext' format, +however it is possible to import private keys wrapped in interoperable PEM PKCS8 +by passing '--format=pem-pkcs8-cleartext'. + +The PEM format allows for key generation outside of the IPFS node: + + $ openssl genpkey -algorithm ED25519 > ed25519.pem + $ ipfs key import test-openssl -f pem-pkcs8-cleartext ed25519.pem +`, }, Options: []cmds.Option{ ke.OptionIPNSBase, + cmds.StringOption(keyFormatOptionName, "f", "The format of the private key to import, libp2p-protobuf-cleartext or pem-pkcs8-cleartext.").WithDefault(keyFormatLibp2pCleartextOption), + cmds.BoolOption(keyAllowAnyTypeOptionName, "Allow importing any key type.").WithDefault(false), }, Arguments: []cmds.Argument{ cmds.StringArg("name", true, false, "name to associate with key in keychain"), @@ -265,9 +349,62 @@ var keyImportCmd = &cmds.Command{ return err } - sk, err := crypto.UnmarshalPrivateKey(data) - if err != nil { - return err + importFormat, _ := req.Options[keyFormatOptionName].(string) + var sk crypto.PrivKey + switch importFormat { + case keyFormatPemCleartextOption: + pemBlock, rest := pem.Decode(data) + if pemBlock == nil { + return fmt.Errorf("PEM block not found in input data:\n%s", rest) + } + + if pemBlock.Type != "PRIVATE KEY" { + return fmt.Errorf("expected PRIVATE KEY type in PEM block but got: %s", pemBlock.Type) + } + + stdKey, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes) + if err != nil { + return fmt.Errorf("parsing PKCS8 format: %w", err) + } + + // In case ed25519.PrivateKey is returned we need the pointer for + // conversion to libp2p (see export command for more details). + if ed25519KeyPointer, ok := stdKey.(ed25519.PrivateKey); ok { + stdKey = &ed25519KeyPointer + } + + sk, _, err = crypto.KeyPairFromStdKey(stdKey) + if err != nil { + return fmt.Errorf("converting std Go key to libp2p key: %w", err) + + } + case keyFormatLibp2pCleartextOption: + sk, err = crypto.UnmarshalPrivateKey(data) + if err != nil { + // check if data is PEM, if so, provide user with hint + pemBlock, _ := pem.Decode(data) + if pemBlock != nil { + return fmt.Errorf("unexpected PEM block for format=%s: try again with format=%s", keyFormatLibp2pCleartextOption, keyFormatPemCleartextOption) + } + return fmt.Errorf("unable to unmarshall format=%s: %w", keyFormatLibp2pCleartextOption, err) + } + + default: + return fmt.Errorf("unrecognized import format: %s", importFormat) + } + + // We only allow importing keys of the same type we generate (see list in + // https://github.com/ipfs/interface-go-ipfs-core/blob/1c3d8fc/options/key.go#L58-L60), + // unless explicitly stated by the user. + allowAnyKeyType, _ := req.Options[keyAllowAnyTypeOptionName].(bool) + if !allowAnyKeyType { + switch t := sk.(type) { + case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey: + default: + return fmt.Errorf("key type %T is not allowed to be imported, only RSA or Ed25519;"+ + " use flag --%s if you are sure of what you're doing", + t, keyAllowAnyTypeOptionName) + } } cfgRoot, err := cmdenv.GetConfigRoot(env) diff --git a/core/commands/log.go b/core/commands/log.go index 78ff8a6b50f..96366d4c4ee 100644 --- a/core/commands/log.go +++ b/core/commands/log.go @@ -105,6 +105,7 @@ subsystems of a running daemon. } var logTailCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Read the event log.", ShortDescription: ` diff --git a/core/commands/mount_nofuse.go b/core/commands/mount_nofuse.go index ea535068808..c425aff0fcf 100644 --- a/core/commands/mount_nofuse.go +++ b/core/commands/mount_nofuse.go @@ -1,3 +1,4 @@ +//go:build !windows && nofuse // +build !windows,nofuse package commands @@ -7,6 +8,7 @@ import ( ) var MountCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Mounts ipfs to the filesystem (disabled).", ShortDescription: ` diff --git a/core/commands/mount_unix.go b/core/commands/mount_unix.go index c6678d17585..fd1c486ee3f 100644 --- a/core/commands/mount_unix.go +++ b/core/commands/mount_unix.go @@ -1,3 +1,4 @@ +//go:build !windows && !nofuse // +build !windows,!nofuse package commands @@ -6,11 +7,12 @@ import ( "fmt" "io" + oldcmds "github.com/ipfs/go-ipfs/commands" cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" nodeMount "github.com/ipfs/go-ipfs/fuse/node" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ) const ( @@ -19,6 +21,7 @@ const ( ) var MountCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Mounts IPFS to the filesystem (read-only).", ShortDescription: ` @@ -80,7 +83,7 @@ baz cmds.StringOption(mountIPNSPathOptionName, "n", "The path where IPNS should be mounted."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - cfg, err := cmdenv.GetConfig(env) + cfg, err := env.(*oldcmds.Context).GetConfig() if err != nil { return err } diff --git a/core/commands/name/ipnsps.go b/core/commands/name/ipnsps.go index 31791570970..949ea43d5e8 100644 --- a/core/commands/name/ipnsps.go +++ b/core/commands/name/ipnsps.go @@ -26,6 +26,7 @@ type stringList struct { // IpnsPubsubCmd is the subcommand that allows us to manage the IPNS pubsub system var IpnsPubsubCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "IPNS pubsub management", ShortDescription: ` @@ -42,6 +43,7 @@ Note: this command is experimental and subject to change as the system is refine } var ipnspsStateCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Query the state of IPNS pubsub.", }, @@ -70,6 +72,7 @@ var ipnspsStateCmd = &cmds.Command{ } var ipnspsSubsCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Show current name subscriptions.", }, @@ -114,6 +117,7 @@ var ipnspsSubsCmd = &cmds.Command{ } var ipnspsCancelCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Cancel a name subscription.", }, diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index d83da7cec5d..54727cd287f 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -20,6 +20,7 @@ type Changes struct { } var ObjectDiffCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Display the diff between two IPFS objects.", ShortDescription: ` diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 1e145208a59..00f2f44ce3d 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -47,6 +47,7 @@ const ( ) var ObjectCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated commands to interact with dag-pb objects. Use 'dag' or 'files' instead.", ShortDescription: ` @@ -68,6 +69,7 @@ directly. Deprecated, use more modern 'ipfs dag' and 'ipfs files' instead.`, // ObjectDataCmd object data command var ObjectDataCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to read the raw bytes of a dag-pb object: use 'dag get' instead.", ShortDescription: ` @@ -107,6 +109,7 @@ is the raw data of the object. // ObjectLinksCmd object links command var ObjectLinksCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to output links in the specified dag-pb object: use 'dag get' instead.", ShortDescription: ` @@ -181,6 +184,7 @@ multihash. Provided for legacy reasons. Use 'ipfs dag get' instead. // ObjectGetCmd object get command var ObjectGetCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to get and serialize the dag-pb node. Use 'dag get' instead", ShortDescription: ` @@ -272,6 +276,7 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag get' instead. // ObjectStatCmd object stat command var ObjectStatCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to read stats for the dag-pb node. Use 'files stat' instead.", ShortDescription: ` @@ -371,6 +376,7 @@ DEPRECATED: Provided for legacy reasons. Modern replacements: // ObjectPutCmd object put command var ObjectPutCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to store input as a DAG object. Use 'dag put' instead.", ShortDescription: ` @@ -450,6 +456,7 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs dag put' instead. // ObjectNewCmd object new command var ObjectNewCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to create a new dag-pb object from a template.", ShortDescription: ` diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index 78f92703254..6843b226765 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -4,21 +4,16 @@ import ( "fmt" "io" - "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs/core/commands/cmdenv" - coreiface "github.com/ipfs/interface-go-ipfs-core" + "github.com/ipfs/go-ipfs/core/commands/cmdutils" "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" ) -const ( - softBlockLimit = 1024 * 1024 // https://github.com/ipfs/go-ipfs/issues/7421#issuecomment-910833499 - allowBigBlock = "allow-big-block" -) - var ObjectPatchCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to create a new merkledag object based on an existing one. Use MFS with 'files cp|rm' instead.", ShortDescription: ` @@ -49,11 +44,12 @@ For modern use cases, use MFS with 'files' commands: 'ipfs files --help'. "set-data": patchSetDataCmd, }, Options: []cmds.Option{ - cmds.BoolOption(allowBigBlock, "Disable block size check and allow creation of blocks bigger than 1MB. WARNING: such blocks won't be transferable over the standard bitswap.").WithDefault(false), + cmdutils.AllowBigBlockOption, }, } var patchAppendDataCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to append data to the data segment of a DAG node.", ShortDescription: ` @@ -64,7 +60,7 @@ Example: $ echo "hello" | ipfs object patch $HASH append-data NOTE: This does not append data to a file - it modifies the actual raw -data within a dag-pb object. Blocks have a max size of 1MB and objects larger than +data within a dag-pb object. Blocks have a max size of 1MiB and objects larger than the limit will not be respected by the network. DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' instead. @@ -92,7 +88,7 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste return err } - if err := checkBlockSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { return err } @@ -108,6 +104,7 @@ DEPRECATED and provided for legacy reasons. Use 'ipfs add' or 'ipfs files' inste } var patchSetDataCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to set the data field of dag-pb object.", ShortDescription: ` @@ -142,7 +139,7 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead return err } - if err := checkBlockSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { return err } @@ -158,6 +155,7 @@ DEPRECATED and provided for legacy reasons. Use 'files cp' and 'dag put' instead } var patchRmLinkCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to remove a link from dag-pb object.", ShortDescription: ` @@ -184,7 +182,7 @@ DEPRECATED and provided for legacy reasons. Use 'files rm' instead. return err } - if err := checkBlockSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { return err } @@ -204,6 +202,7 @@ const ( ) var patchAddLinkCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7936 Helptext: cmds.HelpText{ Tagline: "Deprecated way to add a link to a given dag-pb.", ShortDescription: ` @@ -254,7 +253,7 @@ Use MFS and 'files' commands instead: return err } - if err := checkBlockSize(req, p.Cid(), api.Dag()); err != nil { + if err := cmdutils.CheckCIDSize(req, p.Cid(), api.Dag()); err != nil { return err } @@ -268,26 +267,3 @@ Use MFS and 'files' commands instead: }), }, } - -func checkBlockSize(req *cmds.Request, c cid.Cid, dagAPI coreiface.APIDagService) error { - allowAnyBlockSize, _ := req.Options[allowBigBlock].(bool) - if allowAnyBlockSize { - return nil - } - - // We do not allow producing blocks bigger than 1 MiB to avoid errors - // when transmitting them over BitSwap. The 1 MiB constant is an - // unenforced and undeclared rule of thumb hard-coded here. - modifiedNode, err := dagAPI.Get(req.Context, c) - if err != nil { - return err - } - modifiedNodeSize, err := modifiedNode.Size() - if err != nil { - return err - } - if modifiedNodeSize > softBlockLimit { - return fmt.Errorf("produced block is over 1MB, object API is deprecated and does not support HAMT-sharding: to create big directories, please use the files API (MFS)") - } - return nil -} diff --git a/core/commands/p2p.go b/core/commands/p2p.go index 77e7ca2b4f8..e9c32626bc4 100644 --- a/core/commands/p2p.go +++ b/core/commands/p2p.go @@ -59,6 +59,7 @@ var resolveTimeout = 10 * time.Second // P2PCmd is the 'ipfs p2p' command var P2PCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Libp2p stream mounting.", ShortDescription: ` @@ -78,6 +79,7 @@ are refined`, } var p2pForwardCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Forward connections to libp2p service.", ShortDescription: ` @@ -179,6 +181,7 @@ func parseIpfsAddr(addr string) (*peer.AddrInfo, error) { } var p2pListenCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Create libp2p service.", ShortDescription: ` @@ -280,6 +283,7 @@ const ( ) var p2pLsCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "List active p2p listeners.", }, @@ -343,6 +347,7 @@ const ( ) var p2pCloseCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Stop listening for new connections to forward.", }, @@ -427,6 +432,7 @@ var p2pCloseCmd = &cmds.Command{ // p2pStreamCmd is the 'ipfs p2p stream' command var p2pStreamCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "P2P stream management.", ShortDescription: "Create and manage p2p streams", @@ -439,6 +445,7 @@ var p2pStreamCmd = &cmds.Command{ } var p2pStreamLsCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "List active p2p streams.", }, @@ -488,6 +495,7 @@ var p2pStreamLsCmd = &cmds.Command{ } var p2pStreamCloseCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Close active p2p stream.", }, diff --git a/core/commands/pin/pin.go b/core/commands/pin/pin.go index 3a9caa03143..0344932f652 100644 --- a/core/commands/pin/pin.go +++ b/core/commands/pin/pin.go @@ -200,7 +200,7 @@ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, var rmPinCmd = &cmds.Command{ Helptext: cmds.HelpText{ - Tagline: "Remove pinned objects from local storage.", + Tagline: "Remove object from pin-list.", ShortDescription: ` Removes the pin from the given object allowing it to be garbage collected if needed. (By default, recursively. Use -r=false for direct pins.) diff --git a/core/commands/pin/remotepin.go b/core/commands/pin/remotepin.go index 3ca0d353278..495a1400367 100644 --- a/core/commands/pin/remotepin.go +++ b/core/commands/pin/remotepin.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "os" "sort" "strings" "text/tabwriter" @@ -16,7 +17,7 @@ import ( cid "github.com/ipfs/go-cid" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/core/commands/cmdenv" fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" logging "github.com/ipfs/go-log" @@ -185,6 +186,8 @@ NOTE: a comma-separated notation is supported in CLI for convenience: return err } opts = append(opts, pinclient.PinOpts.WithOrigins(addrs...)) + } else if isInBlockstore && !node.IsOnline && cmds.GetEncoding(req, cmds.Text) == cmds.Text { + fmt.Fprintf(os.Stdout, "WARNING: the local node is offline and remote pinning may fail if there is no other provider for this CID\n") } // Execute remote pin request diff --git a/core/commands/profile.go b/core/commands/profile.go index 46c3ee19b8c..a5567fc814b 100644 --- a/core/commands/profile.go +++ b/core/commands/profile.go @@ -2,18 +2,15 @@ package commands import ( "archive/zip" - "context" - "encoding/json" "fmt" "io" "os" - "runtime" - "runtime/pprof" "strings" "time" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/go-ipfs/core/commands/e" + "github.com/ipfs/go-ipfs/profile" ) // time format that works in filenames on windows. @@ -23,22 +20,27 @@ type profileResult struct { File string } -const cpuProfileTimeOption = "cpu-profile-time" +const ( + collectorsOptionName = "collectors" + profileTimeOption = "profile-time" + mutexProfileFractionOption = "mutex-profile-fraction" + blockProfileRateOption = "block-profile-rate" +) var sysProfileCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Collect a performance profile for debugging.", ShortDescription: ` -Collects cpu, heap, and goroutine profiles from a running go-ipfs daemon -into a single zip file. To aid in debugging, this command also attempts to -include a copy of the running go-ipfs binary. +Collects profiles from a running go-ipfs daemon into a single zip file. +To aid in debugging, this command also attempts to include a copy of +the running go-ipfs binary. `, LongDescription: ` -Collects cpu, heap, and goroutine profiles from a running go-ipfs daemon -into a single zipfile. To aid in debugging, this command also attempts to -include a copy of the running go-ipfs binary. +Collects profiles from a running go-ipfs daemon into a single zipfile. +To aid in debugging, this command also attempts to include a copy of +the running go-ipfs binary. -Profile's can be examined using 'go tool pprof', some tips can be found at +Profiles can be examined using 'go tool pprof', some tips can be found at https://github.com/ipfs/go-ipfs/blob/master/docs/debug-guide.md. Privacy Notice: @@ -48,6 +50,8 @@ The output file includes: - A list of running goroutines. - A CPU profile. - A heap profile. +- A mutex profile. +- A block profile. - Your copy of go-ipfs. - The output of 'ipfs version --all'. @@ -68,19 +72,51 @@ However, it could reveal: }, NoLocal: true, Options: []cmds.Option{ - cmds.StringOption(outputOptionName, "o", "The path where the output should be stored."), - cmds.StringOption(cpuProfileTimeOption, "The amount of time spent profiling CPU usage.").WithDefault("30s"), + cmds.StringOption(outputOptionName, "o", "The path where the output .zip should be stored. Default: ./ipfs-profile-[timestamp].zip"), + cmds.DelimitedStringsOption(",", collectorsOptionName, "The list of collectors to use for collecting diagnostic data."). + WithDefault([]string{ + profile.CollectorGoroutinesStack, + profile.CollectorGoroutinesPprof, + profile.CollectorVersion, + profile.CollectorHeap, + profile.CollectorBin, + profile.CollectorCPU, + profile.CollectorMutex, + profile.CollectorBlock, + }), + cmds.StringOption(profileTimeOption, "The amount of time spent profiling. If this is set to 0, then sampling profiles are skipped.").WithDefault("30s"), + cmds.IntOption(mutexProfileFractionOption, "The fraction 1/n of mutex contention events that are reported in the mutex profile.").WithDefault(4), + cmds.StringOption(blockProfileRateOption, "The duration to wait between sampling goroutine-blocking events for the blocking profile.").WithDefault("1ms"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - cpuProfileTimeStr, _ := req.Options[cpuProfileTimeOption].(string) - cpuProfileTime, err := time.ParseDuration(cpuProfileTimeStr) + collectors := req.Options[collectorsOptionName].([]string) + + profileTimeStr, _ := req.Options[profileTimeOption].(string) + profileTime, err := time.ParseDuration(profileTimeStr) + if err != nil { + return fmt.Errorf("failed to parse profile duration %q: %w", profileTimeStr, err) + } + + blockProfileRateStr, _ := req.Options[blockProfileRateOption].(string) + blockProfileRate, err := time.ParseDuration(blockProfileRateStr) if err != nil { - return fmt.Errorf("failed to parse CPU profile duration %q: %w", cpuProfileTimeStr, err) + return fmt.Errorf("failed to parse block profile rate %q: %w", blockProfileRateStr, err) } + mutexProfileFraction, _ := req.Options[mutexProfileFractionOption].(int) + r, w := io.Pipe() + go func() { - _ = w.CloseWithError(writeProfiles(req.Context, cpuProfileTime, w)) + archive := zip.NewWriter(w) + err = profile.WriteProfiles(req.Context, archive, profile.Options{ + Collectors: collectors, + ProfileDuration: profileTime, + MutexProfileFraction: mutexProfileFraction, + BlockProfileRate: blockProfileRate, + }) + archive.Close() + _ = w.CloseWithError(err) }() return res.Emit(r) }, @@ -120,118 +156,3 @@ However, it could reveal: }), }, } - -func writeProfiles(ctx context.Context, cpuProfileTime time.Duration, w io.Writer) error { - archive := zip.NewWriter(w) - - // Take some profiles. - type profile struct { - name string - file string - debug int - } - - profiles := []profile{{ - name: "goroutine", - file: "goroutines.stacks", - debug: 2, - }, { - name: "goroutine", - file: "goroutines.pprof", - }, { - name: "heap", - file: "heap.pprof", - }} - - for _, profile := range profiles { - prof := pprof.Lookup(profile.name) - out, err := archive.Create(profile.file) - if err != nil { - return err - } - err = prof.WriteTo(out, profile.debug) - if err != nil { - return err - } - } - - // Take a CPU profile. - if cpuProfileTime != 0 { - out, err := archive.Create("cpu.pprof") - if err != nil { - return err - } - - err = writeCPUProfile(ctx, cpuProfileTime, out) - if err != nil { - return err - } - } - - // Collect version info - // I'd use diag sysinfo, but that includes some more sensitive information - // (GOPATH, etc.). - { - out, err := archive.Create("version.json") - if err != nil { - return err - } - - err = json.NewEncoder(out).Encode(getVersionInfo()) - if err != nil { - return err - } - } - - // Collect binary - if fi, err := openIPFSBinary(); err == nil { - fname := "ipfs" - if runtime.GOOS == "windows" { - fname += ".exe" - } - - out, err := archive.Create(fname) - if err != nil { - return err - } - - _, err = io.Copy(out, fi) - _ = fi.Close() - if err != nil { - return err - } - } - return archive.Close() -} - -func writeCPUProfile(ctx context.Context, d time.Duration, w io.Writer) error { - if err := pprof.StartCPUProfile(w); err != nil { - return err - } - defer pprof.StopCPUProfile() - - timer := time.NewTimer(d) - defer timer.Stop() - - select { - case <-timer.C: - case <-ctx.Done(): - return ctx.Err() - } - return nil -} - -func openIPFSBinary() (*os.File, error) { - if runtime.GOOS == "linux" { - pid := os.Getpid() - fi, err := os.Open(fmt.Sprintf("/proc/%d/exe", pid)) - if err == nil { - return fi, nil - } - } - path, err := os.Executable() - if err != nil { - return nil, err - } - return os.Open(path) -} diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index 47d893852af..e36b3b185b4 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -17,6 +17,7 @@ import ( ) var PubsubCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "An experimental publish-subscribe system on ipfs.", ShortDescription: ` @@ -46,6 +47,7 @@ type pubsubMessage struct { } var PubsubSubCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Subscribe to messages on a given topic.", ShortDescription: ` @@ -73,7 +75,7 @@ TOPIC AND DATA ENCODING `, }, Arguments: []cmds.Argument{ - cmds.StringArg("topic", true, false, "Name of topic to subscribe to."), + cmds.StringArg("topic", true, false, "Name of topic to subscribe to (multibase encoded when sent over HTTP RPC)."), }, PreRun: urlArgsEncoder, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { @@ -144,6 +146,7 @@ TOPIC AND DATA ENCODING } var PubsubPubCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "Publish data to a given pubsub topic.", ShortDescription: ` @@ -167,7 +170,7 @@ HTTP RPC ENCODING `, }, Arguments: []cmds.Argument{ - cmds.StringArg("topic", true, false, "Topic to publish to."), + cmds.StringArg("topic", true, false, "Topic to publish to (multibase encoded when sent over HTTP RPC)."), cmds.FileArg("data", true, false, "The data to be published.").EnableStdin(), }, PreRun: urlArgsEncoder, @@ -199,6 +202,7 @@ HTTP RPC ENCODING } var PubsubLsCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "List subscribed topics by name.", ShortDescription: ` @@ -270,6 +274,7 @@ func safeTextListEncoder(req *cmds.Request, w io.Writer, list *stringList) error } var PubsubPeersCmd = &cmds.Command{ + Status: cmds.Experimental, Helptext: cmds.HelpText{ Tagline: "List peers we are currently pubsubbing with.", ShortDescription: ` diff --git a/core/commands/repo.go b/core/commands/repo.go index 20cc41fcd91..367a6d901da 100644 --- a/core/commands/repo.go +++ b/core/commands/repo.go @@ -51,6 +51,7 @@ type GcResult struct { const ( repoStreamErrorsOptionName = "stream-errors" repoQuietOptionName = "quiet" + repoSilentOptionName = "silent" ) var repoGcCmd = &cmds.Command{ @@ -65,6 +66,7 @@ order to reclaim hard disk space. Options: []cmds.Option{ cmds.BoolOption(repoStreamErrorsOptionName, "Stream errors."), cmds.BoolOption(repoQuietOptionName, "q", "Write minimal output."), + cmds.BoolOption(repoSilentOptionName, "Write no output."), }, Run: func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error { n, err := cmdenv.GetNode(env) @@ -72,6 +74,7 @@ order to reclaim hard disk space. return err } + silent, _ := req.Options[repoSilentOptionName].(bool) streamErrors, _ := req.Options[repoStreamErrorsOptionName].(bool) gcOutChan := corerepo.GarbageCollectAsync(n, req.Context) @@ -95,6 +98,9 @@ order to reclaim hard disk space. } } else { err := corerepo.CollectResult(req.Context, gcOutChan, func(k cid.Cid) { + if silent { + return + } // Nothing to do with this error, really. This // most likely means that the client is gone but // we still need to let the GC finish. @@ -111,6 +117,11 @@ order to reclaim hard disk space. Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, gcr *GcResult) error { quiet, _ := req.Options[repoQuietOptionName].(bool) + silent, _ := req.Options[repoSilentOptionName].(bool) + + if silent { + return nil + } if gcr.Error != "" { _, err := fmt.Fprintf(w, "Error: %s\n", gcr.Error) @@ -211,6 +222,7 @@ Version string The repo version. } var repoFsckCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/6435 Helptext: cmds.HelpText{ Tagline: "Remove repo lockfiles.", ShortDescription: ` diff --git a/core/commands/root.go b/core/commands/root.go index 64b9b42fbf0..71ec35e372c 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -19,11 +19,13 @@ var log = logging.Logger("core/commands") var ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first") const ( - ConfigOption = "config" - DebugOption = "debug" - LocalOption = "local" // DEPRECATED: use OfflineOption - OfflineOption = "offline" - ApiOption = "api" + RepoDirOption = "repo-dir" + ConfigFileOption = "config-file" + ConfigOption = "config" + DebugOption = "debug" + LocalOption = "local" // DEPRECATED: use OfflineOption + OfflineOption = "offline" + ApiOption = "api" ) var Root = &cmds.Command{ @@ -50,16 +52,15 @@ TEXT ENCODING COMMANDS ADVANCED COMMANDS daemon Start a long-running daemon process - mount Mount an IPFS read-only mount point - resolve Resolve any type of name + resolve Resolve any type of content path name Publish and resolve IPNS names key Create and list IPNS name keypairs - dns Resolve DNS links pin Pin objects to local storage repo Manipulate the IPFS repository stats Various operational stats - p2p Libp2p stream mounting + p2p Libp2p stream mounting (experimental) filestore Manage the filestore (experimental) + mount Mount an IPFS read-only mount point (experimental) NETWORK COMMANDS id Show info about IPFS peers @@ -67,13 +68,13 @@ NETWORK COMMANDS swarm Manage connections to the p2p network dht Query the DHT for values or peers ping Measure the latency of a connection - diag Print diagnostics bitswap Inspect bitswap state pubsub Send and receive messages via pubsub TOOL COMMANDS config Manage configuration version Show IPFS version information + diag Generate diagnostic reports update Download and apply go-ipfs updates commands List all available commands log Manage and show logs of running daemon @@ -95,7 +96,9 @@ The CLI will exit with one of the following values: `, }, Options: []cmds.Option{ - cmds.StringOption(ConfigOption, "c", "Path to the configuration file to use."), + cmds.StringOption(RepoDirOption, "Path to the repository directory to use."), + cmds.StringOption(ConfigFileOption, "Path to the configuration file to use."), + cmds.StringOption(ConfigOption, "c", "[DEPRECATED] Path to the configuration file to use."), cmds.BoolOption(DebugOption, "D", "Operate in debug mode."), cmds.BoolOption(cmds.OptLongHelp, "Show the full command help text."), cmds.BoolOption(cmds.OptShortHelp, "Show a short version of the command help text."), @@ -149,7 +152,7 @@ var rootSubcommands = map[string]*cmds.Command{ "swarm": SwarmCmd, "tar": TarCmd, "file": unixfs.UnixFSCmd, - "update": ExternalBinary("Please see https://git.io/fjylH for installation instructions."), + "update": ExternalBinary("Please see https://github.com/ipfs/ipfs-update/blob/master/README.md#install for installation instructions."), "urlstore": urlStoreCmd, "version": VersionCmd, "shutdown": daemonShutdownCmd, diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 7c7ee3e814f..fcf2a50340e 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -1,7 +1,9 @@ package commands import ( + "bytes" "context" + "encoding/json" "errors" "fmt" "io" @@ -10,15 +12,18 @@ import ( "sync" "time" - commands "github.com/ipfs/go-ipfs/commands" - cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv" - repo "github.com/ipfs/go-ipfs/repo" - fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" + files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-ipfs/commands" + "github.com/ipfs/go-ipfs/config" + "github.com/ipfs/go-ipfs/core/commands/cmdenv" + "github.com/ipfs/go-ipfs/core/node/libp2p" + "github.com/ipfs/go-ipfs/repo" + "github.com/ipfs/go-ipfs/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" - config "github.com/ipfs/go-ipfs-config" inet "github.com/libp2p/go-libp2p-core/network" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" mamask "github.com/whyrusleeping/multiaddr-filter" @@ -52,6 +57,8 @@ ipfs peers in the internet. "filters": swarmFiltersCmd, "peers": swarmPeersCmd, "peering": swarmPeeringCmd, + "stats": swarmStatsCmd, // libp2p Network Resource Manager + "limit": swarmLimitCmd, // libp2p Network Resource Manager }, } @@ -72,7 +79,7 @@ var swarmPeeringCmd = &cmds.Command{ Tagline: "Modify the peering subsystem.", ShortDescription: ` 'ipfs swarm peering' manages the peering subsystem. -Peers in the peering subsystem is maintained to be connected, reconnected +Peers in the peering subsystem are maintained to be connected, reconnected on disconnect with a back-off. The changes are not saved to the config. `, @@ -304,6 +311,132 @@ var swarmPeersCmd = &cmds.Command{ Type: connInfos{}, } +var swarmStatsCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Report resource usage for a scope.", + LongDescription: `Report resource usage for a scope. +The scope can be one of the following: +- system -- reports the system aggregate resource usage. +- transient -- reports the transient resource usage. +- svc: -- reports the resource usage of a specific service. +- proto: -- reports the resource usage of a specific protocol. +- peer: -- reports the resource usage of a specific peer. +- all -- reports the resource usage for all currently active scopes. + +The output of this command is JSON. +`}, + Arguments: []cmds.Argument{ + cmds.StringArg("scope", true, false, "scope of the stat report"), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + node, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + if node.ResourceManager == nil { + return libp2p.NoResourceMgrError + } + + if len(req.Arguments) != 1 { + return fmt.Errorf("must specify exactly one scope") + } + scope := req.Arguments[0] + result, err := libp2p.NetStat(node.ResourceManager, scope) + if err != nil { + return err + } + + b := new(bytes.Buffer) + enc := json.NewEncoder(b) + err = enc.Encode(result) + if err != nil { + return err + } + return cmds.EmitOnce(res, b) + }, + Encoders: cmds.EncoderMap{ + cmds.Text: HumanJSONEncoder, + }, +} + +var swarmLimitCmd = &cmds.Command{ + Status: cmds.Experimental, + Helptext: cmds.HelpText{ + Tagline: "Get or set resource limits for a scope.", + LongDescription: `Get or set resource limits for a scope. +The scope can be one of the following: +- system -- limits for the system aggregate resource usage. +- transient -- limits for the transient resource usage. +- svc: -- limits for the resource usage of a specific service. +- proto: -- limits for the resource usage of a specific protocol. +- peer: -- limits for the resource usage of a specific peer. + +The output of this command is JSON. + +It is possible to use this command to inspect and tweak limits at runtime: + + $ ipfs swarm limit system > limit.json + $ vi limit.json + $ ipfs swarm limit system limit.json + +Changes made via command line are persisted in the Swarm.ResourceMgr.Limits field of the $IPFS_PATH/config file. +`}, + Arguments: []cmds.Argument{ + cmds.StringArg("scope", true, false, "scope of the limit"), + cmds.FileArg("limit.json", false, false, "limits to be set").EnableStdin(), + }, + Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { + node, err := cmdenv.GetNode(env) + if err != nil { + return err + } + + if node.ResourceManager == nil { + return libp2p.NoResourceMgrError + } + + scope := req.Arguments[0] + + // set scope limit to new values (when limit.json is passed as a second arg) + if req.Files != nil { + var newLimit rcmgr.BasicLimitConfig + it := req.Files.Entries() + if it.Next() { + file := files.FileFromEntry(it) + if file == nil { + return errors.New("expected a JSON file") + } + if err := json.NewDecoder(file).Decode(&newLimit); err != nil { + return fmt.Errorf("decoding JSON as ResourceMgrScopeConfig: %w", err) + } + return libp2p.NetSetLimit(node.ResourceManager, node.Repo, scope, newLimit) + } + if err := it.Err(); err != nil { + return fmt.Errorf("error opening limit JSON file: %w", err) + } + } + + // get scope limit + result, err := libp2p.NetLimit(node.ResourceManager, scope) + if err != nil { + return err + } + + b := new(bytes.Buffer) + enc := json.NewEncoder(b) + err = enc.Encode(result) + if err != nil { + return err + } + return cmds.EmitOnce(res, b) + }, + Encoders: cmds.EncoderMap{ + cmds.Text: HumanJSONEncoder, + }, +} + type streamInfo struct { Protocol string } diff --git a/core/commands/tar.go b/core/commands/tar.go index efc1503cdb8..4dcb22be8b2 100644 --- a/core/commands/tar.go +++ b/core/commands/tar.go @@ -13,6 +13,7 @@ import ( ) var TarCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7951 Helptext: cmds.HelpText{ Tagline: "Utility functions for tar files in ipfs.", }, @@ -24,6 +25,7 @@ var TarCmd = &cmds.Command{ } var tarAddCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7951 Helptext: cmds.HelpText{ Tagline: "Import a tar file into IPFS.", ShortDescription: ` @@ -74,6 +76,7 @@ represent it. } var tarCatCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/issues/7951 Helptext: cmds.HelpText{ Tagline: "Export a tar file from IPFS.", ShortDescription: ` diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index e5fd4e0c260..ac012b04fe4 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -33,8 +33,9 @@ type LsOutput struct { } var LsCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/pull/7755 Helptext: cmds.HelpText{ - Tagline: "List directory contents for Unix filesystem objects. Deprecated: Use 'ipfs ls' instead.", + Tagline: "List directory contents for Unix filesystem objects. Deprecated: Use 'ipfs ls' and 'ipfs files ls' instead.", ShortDescription: ` Displays the contents of an IPFS or IPNS object(s) at the given path. diff --git a/core/commands/unixfs/unixfs.go b/core/commands/unixfs/unixfs.go index f1dfabc91e0..cb5c8ddaf32 100644 --- a/core/commands/unixfs/unixfs.go +++ b/core/commands/unixfs/unixfs.go @@ -5,17 +5,12 @@ import ( ) var UnixFSCmd = &cmds.Command{ + Status: cmds.Deprecated, // https://github.com/ipfs/go-ipfs/pull/7755 Helptext: cmds.HelpText{ Tagline: "Interact with IPFS objects representing Unix filesystems.", ShortDescription: ` -'ipfs file' provides a familiar interface to file systems represented -by IPFS objects, which hides ipfs implementation details like layout -objects (e.g. fanout and chunking). -`, - LongDescription: ` -'ipfs file' provides a familiar interface to file systems represented -by IPFS objects, which hides ipfs implementation details like layout -objects (e.g. fanout and chunking). +Old interface to file systems represented by UnixFS. +Superseded by modern alternatives: 'ipfs ls' and 'ipfs files' `, }, diff --git a/core/commands/urlstore.go b/core/commands/urlstore.go index c71229b5a6e..0b7dcbc5f50 100644 --- a/core/commands/urlstore.go +++ b/core/commands/urlstore.go @@ -23,6 +23,7 @@ var urlStoreCmd = &cmds.Command{ } var urlAdd = &cmds.Command{ + Status: cmds.Deprecated, Helptext: cmds.HelpText{ Tagline: "Add URL via urlstore.", LongDescription: ` diff --git a/core/commands/version.go b/core/commands/version.go index ecdda594b2d..93ec5dd87a8 100644 --- a/core/commands/version.go +++ b/core/commands/version.go @@ -4,23 +4,13 @@ import ( "errors" "fmt" "io" - "runtime" "runtime/debug" version "github.com/ipfs/go-ipfs" - fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo" cmds "github.com/ipfs/go-ipfs-cmds" ) -type VersionOutput struct { - Version string - Commit string - Repo string - System string - Golang string -} - const ( versionNumberOptionName = "number" versionCommitOptionName = "commit" @@ -28,16 +18,6 @@ const ( versionAllOptionName = "all" ) -func getVersionInfo() *VersionOutput { - return &VersionOutput{ - Version: version.CurrentVersionNumber, - Commit: version.CurrentCommit, - Repo: fmt.Sprint(fsrepo.RepoVersion), - System: runtime.GOARCH + "/" + runtime.GOOS, //TODO: Precise version here - Golang: runtime.Version(), - } -} - var VersionCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Show IPFS version information.", @@ -56,10 +36,10 @@ var VersionCmd = &cmds.Command{ // must be permitted to run before init Extra: CreateCmdExtras(SetDoesNotUseRepo(true), SetDoesNotUseConfigAsInput(true)), Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - return cmds.EmitOnce(res, getVersionInfo()) + return cmds.EmitOnce(res, version.GetVersionInfo()) }, Encoders: cmds.EncoderMap{ - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, version *VersionOutput) error { + cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, version *version.VersionInfo) error { all, _ := req.Options[versionAllOptionName].(bool) if all { ver := version.Version @@ -91,11 +71,11 @@ var VersionCmd = &cmds.Command{ return nil } - fmt.Fprint(w, fmt.Sprintf("ipfs version %s%s\n", version.Version, commitTxt)) + fmt.Fprintf(w, "ipfs version %s%s\n", version.Version, commitTxt) return nil }), }, - Type: VersionOutput{}, + Type: version.VersionInfo{}, } type Dependency struct { diff --git a/core/core.go b/core/core.go index 888d3d78013..1a09b85e83f 100644 --- a/core/core.go +++ b/core/core.go @@ -30,6 +30,7 @@ import ( ic "github.com/libp2p/go-libp2p-core/crypto" p2phost "github.com/libp2p/go-libp2p-core/host" metrics "github.com/libp2p/go-libp2p-core/metrics" + "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-core/peer" pstore "github.com/libp2p/go-libp2p-core/peerstore" routing "github.com/libp2p/go-libp2p-core/routing" @@ -85,17 +86,18 @@ type IpfsNode struct { RecordValidator record.Validator // Online - PeerHost p2phost.Host `optional:"true"` // the network host (server+client) - Peering *peering.PeeringService `optional:"true"` - Filters *ma.Filters `optional:"true"` - Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper - Routing routing.Routing `optional:"true"` // the routing system. recommend ipfs-dht - DNSResolver *madns.Resolver // the DNS resolver - Exchange exchange.Interface // the block exchange + strategy (bitswap) - Namesys namesys.NameSystem // the name system, resolves paths to hashes - Provider provider.System // the value provider system - IpnsRepub *ipnsrp.Republisher `optional:"true"` - GraphExchange graphsync.GraphExchange `optional:"true"` + PeerHost p2phost.Host `optional:"true"` // the network host (server+client) + Peering *peering.PeeringService `optional:"true"` + Filters *ma.Filters `optional:"true"` + Bootstrapper io.Closer `optional:"true"` // the periodic bootstrapper + Routing routing.Routing `optional:"true"` // the routing system. recommend ipfs-dht + DNSResolver *madns.Resolver // the DNS resolver + Exchange exchange.Interface // the block exchange + strategy (bitswap) + Namesys namesys.NameSystem // the name system, resolves paths to hashes + Provider provider.System // the value provider system + IpnsRepub *ipnsrp.Republisher `optional:"true"` + GraphExchange graphsync.GraphExchange `optional:"true"` + ResourceManager network.ResourceManager `optional:"true"` PubSub *pubsub.PubSub `optional:"true"` PSRouter *psrouter.PubsubValueStore `optional:"true"` diff --git a/core/core_test.go b/core/core_test.go index 051b812c11a..e1563789e73 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -9,7 +9,7 @@ import ( datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ) func TestInitialization(t *testing.T) { diff --git a/core/coreapi/block.go b/core/coreapi/block.go index e1ad9badc05..56520690833 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -13,8 +13,11 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" path "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" util "github.com/ipfs/go-ipfs/blocks/blockstoreutil" + "github.com/ipfs/go-ipfs/tracing" ) type BlockAPI CoreAPI @@ -25,7 +28,10 @@ type BlockStat struct { } func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.BlockStat, error) { - settings, pref, err := caopts.BlockPutOptions(opts...) + ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Put") + defer span.End() + + settings, err := caopts.BlockPutOptions(opts...) if err != nil { return nil, err } @@ -35,7 +41,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc return nil, err } - bcid, err := pref.Sum(data) + bcid, err := settings.CidPrefix.Sum(data) if err != nil { return nil, err } @@ -65,6 +71,8 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc } func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Get", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() rp, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err @@ -79,6 +87,9 @@ func (api *BlockAPI) Get(ctx context.Context, p path.Path) (io.Reader, error) { } func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRmOption) error { + ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Rm", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + rp, err := api.core().ResolvePath(ctx, p) if err != nil { return err @@ -107,8 +118,8 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm return errors.New("got unexpected output from util.RmBlocks") } - if remBlock.Error != "" { - return errors.New(remBlock.Error) + if remBlock.Error != nil { + return remBlock.Error } return nil case <-ctx.Done(): @@ -117,6 +128,9 @@ func (api *BlockAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.BlockRm } func (api *BlockAPI) Stat(ctx context.Context, p path.Path) (coreiface.BlockStat, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.BlockAPI", "Stat", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + rp, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index d056e8e6e0a..696c5bab76c 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -5,8 +5,11 @@ import ( cid "github.com/ipfs/go-cid" pin "github.com/ipfs/go-ipfs-pinner" + "github.com/ipfs/go-ipfs/tracing" ipld "github.com/ipfs/go-ipld-format" dag "github.com/ipfs/go-merkledag" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type dagAPI struct { @@ -18,6 +21,8 @@ type dagAPI struct { type pinningAdder CoreAPI func (adder *pinningAdder) Add(ctx context.Context, nd ipld.Node) error { + ctx, span := tracing.Span(ctx, "CoreAPI.PinningAdder", "Add", trace.WithAttributes(attribute.String("node", nd.String()))) + defer span.End() defer adder.blockstore.PinLock(ctx).Unlock(ctx) if err := adder.dag.Add(ctx, nd); err != nil { @@ -30,6 +35,8 @@ func (adder *pinningAdder) Add(ctx context.Context, nd ipld.Node) error { } func (adder *pinningAdder) AddMany(ctx context.Context, nds []ipld.Node) error { + ctx, span := tracing.Span(ctx, "CoreAPI.PinningAdder", "AddMany", trace.WithAttributes(attribute.Int("nodes.count", len(nds)))) + defer span.End() defer adder.blockstore.PinLock(ctx).Unlock(ctx) if err := adder.dag.AddMany(ctx, nds); err != nil { diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 3f10a0ffcf8..c196aba9bd8 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -9,17 +9,22 @@ import ( cidutil "github.com/ipfs/go-cidutil" blockstore "github.com/ipfs/go-ipfs-blockstore" offline "github.com/ipfs/go-ipfs-exchange-offline" + "github.com/ipfs/go-ipfs/tracing" dag "github.com/ipfs/go-merkledag" coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" path "github.com/ipfs/interface-go-ipfs-core/path" peer "github.com/libp2p/go-libp2p-core/peer" routing "github.com/libp2p/go-libp2p-core/routing" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type DhtAPI CoreAPI func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "FindPeer", trace.WithAttributes(attribute.String("peer", p.String()))) + defer span.End() err := api.checkOnline(false) if err != nil { return peer.AddrInfo{}, err @@ -34,10 +39,14 @@ func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, erro } func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "FindProviders", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + settings, err := caopts.DhtFindProvidersOptions(opts...) if err != nil { return nil, err } + span.SetAttributes(attribute.Int("numproviders", settings.NumProviders)) err = api.checkOnline(false) if err != nil { @@ -59,10 +68,14 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p path.Path, opts ...caopt } func (api *DhtAPI) Provide(ctx context.Context, path path.Path, opts ...caopts.DhtProvideOption) error { + ctx, span := tracing.Span(ctx, "CoreAPI.DhtAPI", "Provide", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + settings, err := caopts.DhtProvideOptions(opts...) if err != nil { return err } + span.SetAttributes(attribute.Bool("recursive", settings.Recursive)) err = api.checkOnline(false) if err != nil { diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 9b4045ed04a..1468e6c0c5a 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -7,12 +7,15 @@ import ( "fmt" "sort" + "github.com/ipfs/go-ipfs/tracing" ipfspath "github.com/ipfs/go-path" coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" path "github.com/ipfs/interface-go-ipfs-core/path" crypto "github.com/libp2p/go-libp2p-core/crypto" peer "github.com/libp2p/go-libp2p-core/peer" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type KeyAPI CoreAPI @@ -40,6 +43,9 @@ func (k *key) ID() peer.ID { // Generate generates new key, stores it in the keystore under the specified // name and returns a base58 encoded multihash of its public key. func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (coreiface.Key, error) { + _, span := tracing.Span(ctx, "CoreAPI.KeyAPI", "Generate", trace.WithAttributes(attribute.String("name", name))) + defer span.End() + options, err := caopts.KeyGenerateOptions(opts...) if err != nil { return nil, err @@ -97,6 +103,9 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key // List returns a list keys stored in keystore. func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { + _, span := tracing.Span(ctx, "CoreAPI.KeyAPI", "List") + defer span.End() + keys, err := api.repo.Keystore().List() if err != nil { return nil, err @@ -128,10 +137,14 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { // Rename renames `oldName` to `newName`. Returns the key and whether another // key was overwritten, or an error. func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (coreiface.Key, bool, error) { + _, span := tracing.Span(ctx, "CoreAPI.KeyAPI", "Rename", trace.WithAttributes(attribute.String("oldname", oldName), attribute.String("newname", newName))) + defer span.End() + options, err := caopts.KeyRenameOptions(opts...) if err != nil { return nil, false, err } + span.SetAttributes(attribute.Bool("force", options.Force)) ks := api.repo.Keystore() @@ -187,6 +200,9 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o // Remove removes keys from keystore. Returns ipns path of the removed key. func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, error) { + _, span := tracing.Span(ctx, "CoreAPI.KeyAPI", "Remove", trace.WithAttributes(attribute.String("name", name))) + defer span.End() + ks := api.repo.Keystore() if name == "self" { diff --git a/core/coreapi/name.go b/core/coreapi/name.go index b007ccd7d5c..e39c05d0f5f 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -6,8 +6,11 @@ import ( "strings" "time" - "github.com/ipfs/go-ipfs-keystore" + keystore "github.com/ipfs/go-ipfs-keystore" + "github.com/ipfs/go-ipfs/tracing" "github.com/ipfs/go-namesys" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ipath "github.com/ipfs/go-path" coreiface "github.com/ipfs/interface-go-ipfs-core" @@ -36,6 +39,9 @@ func (e *ipnsEntry) Value() path.Path { // Publish announces new IPNS name and returns the new IPNS entry. func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.NameAPI", "Publish", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + if err := api.checkPublishAllowed(); err != nil { return nil, err } @@ -44,6 +50,14 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam if err != nil { return nil, err } + span.SetAttributes( + attribute.Bool("allowoffline", options.AllowOffline), + attribute.String("key", options.Key), + attribute.Float64("validtime", options.ValidTime.Seconds()), + ) + if options.TTL != nil { + span.SetAttributes(attribute.Float64("ttl", options.TTL.Seconds())) + } err = api.checkOnline(options.AllowOffline) if err != nil { @@ -61,6 +75,7 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam } if options.TTL != nil { + // nolint: staticcheck // non-backward compatible change ctx = context.WithValue(ctx, "ipns-publish-ttl", *options.TTL) } @@ -82,11 +97,16 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam } func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.NameResolveOption) (<-chan coreiface.IpnsResult, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.NameAPI", "Search", trace.WithAttributes(attribute.String("name", name))) + defer span.End() + options, err := caopts.NameResolveOptions(opts...) if err != nil { return nil, err } + span.SetAttributes(attribute.Bool("cache", options.Cache)) + err = api.checkOnline(true) if err != nil { return nil, err @@ -124,6 +144,9 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name // Resolve attempts to resolve the newest version of the specified name and // returns its path. func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (path.Path, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.NameAPI", "Resolve", trace.WithAttributes(attribute.String("name", name))) + defer span.End() + ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 62d31daede1..8c3a2e0aa0c 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -13,6 +13,7 @@ import ( cid "github.com/ipfs/go-cid" pin "github.com/ipfs/go-ipfs-pinner" + "github.com/ipfs/go-ipfs/tracing" ipld "github.com/ipfs/go-ipld-format" dag "github.com/ipfs/go-merkledag" "github.com/ipfs/go-merkledag/dagutils" @@ -20,6 +21,8 @@ import ( coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" ipath "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) const inputLimit = 2 << 20 @@ -37,6 +40,9 @@ type Node struct { } func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (ipld.Node, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "New") + defer span.End() + options, err := caopts.ObjectNewOptions(opts...) if err != nil { return nil, err @@ -60,10 +66,18 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) ( } func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.ObjectPutOption) (ipath.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Put") + defer span.End() + options, err := caopts.ObjectPutOptions(opts...) if err != nil { return nil, err } + span.SetAttributes( + attribute.Bool("pin", options.Pin), + attribute.String("datatype", options.DataType), + attribute.String("inputenc", options.InputEnc), + ) data, err := ioutil.ReadAll(io.LimitReader(src, inputLimit+10)) if err != nil { @@ -130,10 +144,15 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } func (api *ObjectAPI) Get(ctx context.Context, path ipath.Path) (ipld.Node, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Get", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() return api.core().ResolveNode(ctx, path) } func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Data", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + nd, err := api.core().ResolveNode(ctx, path) if err != nil { return nil, err @@ -148,6 +167,9 @@ func (api *ObjectAPI) Data(ctx context.Context, path ipath.Path) (io.Reader, err } func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Links", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + nd, err := api.core().ResolveNode(ctx, path) if err != nil { return nil, err @@ -163,6 +185,9 @@ func (api *ObjectAPI) Links(ctx context.Context, path ipath.Path) ([]*ipld.Link, } func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.ObjectStat, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Stat", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + nd, err := api.core().ResolveNode(ctx, path) if err != nil { return nil, err @@ -186,10 +211,18 @@ func (api *ObjectAPI) Stat(ctx context.Context, path ipath.Path) (*coreiface.Obj } func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, child ipath.Path, opts ...caopts.ObjectAddLinkOption) (ipath.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AddLink", trace.WithAttributes( + attribute.String("base", base.String()), + attribute.String("name", name), + attribute.String("child", child.String()), + )) + defer span.End() + options, err := caopts.ObjectAddLinkOptions(opts...) if err != nil { return nil, err } + span.SetAttributes(attribute.Bool("create", options.Create)) baseNd, err := api.core().ResolveNode(ctx, base) if err != nil { @@ -227,6 +260,12 @@ func (api *ObjectAPI) AddLink(ctx context.Context, base ipath.Path, name string, } func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) (ipath.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "RmLink", trace.WithAttributes( + attribute.String("base", base.String()), + attribute.String("link", link)), + ) + defer span.End() + baseNd, err := api.core().ResolveNode(ctx, base) if err != nil { return nil, err @@ -253,10 +292,16 @@ func (api *ObjectAPI) RmLink(ctx context.Context, base ipath.Path, link string) } func (api *ObjectAPI) AppendData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "AppendData", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + return api.patchData(ctx, path, r, true) } func (api *ObjectAPI) SetData(ctx context.Context, path ipath.Path, r io.Reader) (ipath.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "SetData", trace.WithAttributes(attribute.String("path", path.String()))) + defer span.End() + return api.patchData(ctx, path, r, false) } @@ -290,6 +335,12 @@ func (api *ObjectAPI) patchData(ctx context.Context, path ipath.Path, r io.Reade } func (api *ObjectAPI) Diff(ctx context.Context, before ipath.Path, after ipath.Path) ([]coreiface.ObjectChange, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.ObjectAPI", "Diff", trace.WithAttributes( + attribute.String("before", before.String()), + attribute.String("after", after.String()), + )) + defer span.End() + beforeNd, err := api.core().ResolveNode(ctx, before) if err != nil { return nil, err diff --git a/core/coreapi/path.go b/core/coreapi/path.go index b9bf83e0df6..5f2b4100789 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -5,8 +5,12 @@ import ( "fmt" gopath "path" + "github.com/ipfs/go-ipfs/tracing" "github.com/ipfs/go-namesys/resolve" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + "github.com/ipfs/go-cid" "github.com/ipfs/go-fetcher" ipld "github.com/ipfs/go-ipld-format" @@ -19,6 +23,9 @@ import ( // ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the // resolved Node. func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) { + ctx, span := tracing.Span(ctx, "CoreAPI", "ResolveNode", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + rp, err := api.ResolvePath(ctx, p) if err != nil { return nil, err @@ -34,6 +41,9 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, er // ResolvePath resolves the path `p` using Unixfs resolver, returns the // resolved path. func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + if _, ok := p.(path.Resolved); ok { return p.(path.Resolved), nil } diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index 52ea6a6a453..51667c4b71f 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -8,15 +8,21 @@ import ( "github.com/ipfs/go-cid" offline "github.com/ipfs/go-ipfs-exchange-offline" pin "github.com/ipfs/go-ipfs-pinner" + "github.com/ipfs/go-ipfs/tracing" "github.com/ipfs/go-merkledag" coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type PinAPI CoreAPI func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOption) error { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Add", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + dagNode, err := api.core().ResolveNode(ctx, p) if err != nil { return fmt.Errorf("pin: %s", err) @@ -27,6 +33,8 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp return err } + span.SetAttributes(attribute.Bool("recursive", settings.Recursive)) + defer api.blockstore.PinLock(ctx).Unlock(ctx) err = api.pinning.Pin(ctx, dagNode, settings.Recursive) @@ -42,11 +50,16 @@ func (api *PinAPI) Add(ctx context.Context, p path.Path, opts ...caopts.PinAddOp } func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan coreiface.Pin, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Ls") + defer span.End() + settings, err := caopts.PinLsOptions(opts...) if err != nil { return nil, err } + span.SetAttributes(attribute.String("type", settings.Type)) + switch settings.Type { case "all", "direct", "indirect", "recursive": default: @@ -57,6 +70,9 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan c } func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "IsPinned", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + resolved, err := api.core().ResolvePath(ctx, p) if err != nil { return "", false, fmt.Errorf("error resolving path: %s", err) @@ -67,6 +83,8 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin return "", false, err } + span.SetAttributes(attribute.String("withtype", settings.WithType)) + mode, ok := pin.StringToMode(settings.WithType) if !ok { return "", false, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.WithType) @@ -77,6 +95,9 @@ func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.Pin // Rm pin rm api func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOption) error { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Rm", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + rp, err := api.core().ResolvePath(ctx, p) if err != nil { return err @@ -87,6 +108,8 @@ func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOpti return err } + span.SetAttributes(attribute.Bool("recursive", settings.Recursive)) + // Note: after unpin the pin sets are flushed to the blockstore, so we need // to take a lock to prevent a concurrent garbage collection defer api.blockstore.PinLock(ctx).Unlock(ctx) @@ -99,11 +122,19 @@ func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOpti } func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opts ...caopts.PinUpdateOption) error { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Update", trace.WithAttributes( + attribute.String("from", from.String()), + attribute.String("to", to.String()), + )) + defer span.End() + settings, err := caopts.PinUpdateOptions(opts...) if err != nil { return err } + span.SetAttributes(attribute.Bool("unpin", settings.Unpin)) + fp, err := api.core().ResolvePath(ctx, from) if err != nil { return err @@ -153,6 +184,9 @@ func (n *badNode) Err() error { } func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Verify") + defer span.End() + visited := make(map[cid.Cid]*pinStatus) bs := api.blockstore DAG := merkledag.NewDAGService(bserv.New(bs, offline.Exchange(bs))) @@ -164,6 +198,9 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro var checkPin func(root cid.Cid) *pinStatus checkPin = func(root cid.Cid) *pinStatus { + ctx, span := tracing.Span(ctx, "CoreAPI.PinAPI", "Verify.CheckPin", trace.WithAttributes(attribute.String("cid", root.String()))) + defer span.End() + if status, ok := visited[root]; ok { return status } diff --git a/core/coreapi/provider.go b/core/coreapi/provider.go deleted file mode 100644 index 8148c87892e..00000000000 --- a/core/coreapi/provider.go +++ /dev/null @@ -1,13 +0,0 @@ -package coreapi - -import ( - cid "github.com/ipfs/go-cid" -) - -// ProviderAPI brings Provider behavior to CoreAPI -type ProviderAPI CoreAPI - -// Provide the given cid using the current provider -func (api *ProviderAPI) Provide(cid cid.Cid) error { - return api.provider.Provide(cid) -} diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index a75db36296b..99658b59952 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -4,11 +4,14 @@ import ( "context" "errors" + "github.com/ipfs/go-ipfs/tracing" coreiface "github.com/ipfs/interface-go-ipfs-core" caopts "github.com/ipfs/interface-go-ipfs-core/options" peer "github.com/libp2p/go-libp2p-core/peer" routing "github.com/libp2p/go-libp2p-core/routing" pubsub "github.com/libp2p/go-libp2p-pubsub" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type PubSubAPI CoreAPI @@ -22,6 +25,9 @@ type pubSubMessage struct { } func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) { + _, span := tracing.Span(ctx, "CoreAPI.PubSubAPI", "Ls") + defer span.End() + _, err := api.checkNode() if err != nil { return nil, err @@ -31,6 +37,9 @@ func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) { } func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) { + _, span := tracing.Span(ctx, "CoreAPI.PubSubAPI", "Peers") + defer span.End() + _, err := api.checkNode() if err != nil { return nil, err @@ -41,10 +50,15 @@ func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio return nil, err } + span.SetAttributes(attribute.String("topic", settings.Topic)) + return api.pubSub.ListPeers(settings.Topic), nil } func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) error { + _, span := tracing.Span(ctx, "CoreAPI.PubSubAPI", "Publish", trace.WithAttributes(attribute.String("topic", topic))) + defer span.End() + _, err := api.checkNode() if err != nil { return err @@ -55,6 +69,9 @@ func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) er } func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (coreiface.PubSubSubscription, error) { + _, span := tracing.Span(ctx, "CoreAPI.PubSubAPI", "Subscribe", trace.WithAttributes(attribute.String("topic", topic))) + defer span.End() + // Parse the options to avoid introducing silent failures for invalid // options. However, we don't currently have any use for them. The only // subscription option, discovery, is now a no-op as it's handled by @@ -97,6 +114,9 @@ func (sub *pubSubSubscription) Close() error { } func (sub *pubSubSubscription) Next(ctx context.Context) (coreiface.PubSubMessage, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.PubSubSubscription", "Next") + defer span.End() + msg, err := sub.subscription.Next(ctx) if err != nil { return nil, err diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index 3c3c40ddbdc..2aea3152ca1 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -5,6 +5,7 @@ import ( "sort" "time" + "github.com/ipfs/go-ipfs/tracing" coreiface "github.com/ipfs/interface-go-ipfs-core" inet "github.com/libp2p/go-libp2p-core/network" peer "github.com/libp2p/go-libp2p-core/peer" @@ -12,6 +13,8 @@ import ( protocol "github.com/libp2p/go-libp2p-core/protocol" swarm "github.com/libp2p/go-libp2p-swarm" ma "github.com/multiformats/go-multiaddr" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type SwarmAPI CoreAPI @@ -30,6 +33,9 @@ const connectionManagerTag = "user-connect" const connectionManagerWeight = 100 func (api *SwarmAPI) Connect(ctx context.Context, pi peer.AddrInfo) error { + ctx, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "Connect", trace.WithAttributes(attribute.String("peerid", pi.ID.String()))) + defer span.End() + if api.peerHost == nil { return coreiface.ErrOffline } @@ -47,6 +53,9 @@ func (api *SwarmAPI) Connect(ctx context.Context, pi peer.AddrInfo) error { } func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { + _, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "Disconnect", trace.WithAttributes(attribute.String("addr", addr.String()))) + defer span.End() + if api.peerHost == nil { return coreiface.ErrOffline } @@ -56,6 +65,8 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { return peer.ErrInvalidAddr } + span.SetAttributes(attribute.String("peerid", id.String())) + net := api.peerHost.Network() if taddr == nil { if net.Connectedness(id) != inet.Connected { @@ -76,7 +87,10 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { return coreiface.ErrConnNotFound } -func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) { +func (api *SwarmAPI) KnownAddrs(ctx context.Context) (map[peer.ID][]ma.Multiaddr, error) { + _, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "KnownAddrs") + defer span.End() + if api.peerHost == nil { return nil, coreiface.ErrOffline } @@ -93,7 +107,10 @@ func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, er return addrs, nil } -func (api *SwarmAPI) LocalAddrs(context.Context) ([]ma.Multiaddr, error) { +func (api *SwarmAPI) LocalAddrs(ctx context.Context) ([]ma.Multiaddr, error) { + _, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "LocalAddrs") + defer span.End() + if api.peerHost == nil { return nil, coreiface.ErrOffline } @@ -101,7 +118,10 @@ func (api *SwarmAPI) LocalAddrs(context.Context) ([]ma.Multiaddr, error) { return api.peerHost.Addrs(), nil } -func (api *SwarmAPI) ListenAddrs(context.Context) ([]ma.Multiaddr, error) { +func (api *SwarmAPI) ListenAddrs(ctx context.Context) ([]ma.Multiaddr, error) { + _, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "ListenAddrs") + defer span.End() + if api.peerHost == nil { return nil, coreiface.ErrOffline } @@ -109,7 +129,10 @@ func (api *SwarmAPI) ListenAddrs(context.Context) ([]ma.Multiaddr, error) { return api.peerHost.Network().InterfaceListenAddresses() } -func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) { +func (api *SwarmAPI) Peers(ctx context.Context) ([]coreiface.ConnectionInfo, error) { + _, span := tracing.Span(ctx, "CoreAPI.SwarmAPI", "Peers") + defer span.End() + if api.peerHost == nil { return nil, coreiface.ErrOffline } diff --git a/core/coreapi/test/api_test.go b/core/coreapi/test/api_test.go index 54f3b48ca43..b8eed6102d9 100644 --- a/core/coreapi/test/api_test.go +++ b/core/coreapi/test/api_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/ipfs/go-filestore" - "github.com/ipfs/go-ipfs-keystore" + keystore "github.com/ipfs/go-ipfs-keystore" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/bootstrap" "github.com/ipfs/go-ipfs/core/coreapi" @@ -19,12 +19,12 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - "github.com/ipfs/go-ipfs-config" + "github.com/ipfs/go-ipfs/config" coreiface "github.com/ipfs/interface-go-ipfs-core" "github.com/ipfs/interface-go-ipfs-core/tests" "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p/p2p/net/mock" + "github.com/libp2p/go-libp2p-core/peer" + mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" @@ -32,7 +32,7 @@ const testPeerID = "QmTFauExutTsy4XP6JbMFcw2Wa9645HJt2bTqL6qYDCKfe" type NodeProvider struct{} func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) { - mn := mocknet.New(ctx) + mn := mocknet.New() nodes := make([]*core.IpfsNode, n) apis := make([]coreiface.CoreAPI, n) diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 55410dcb098..b4e1bbc3ee5 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -6,6 +6,9 @@ import ( "sync" "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/tracing" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" "github.com/ipfs/go-ipfs/core/coreunix" @@ -55,11 +58,30 @@ func getOrCreateNilNode() (*core.IpfsNode, error) { // Add builds a merkledag node from a reader, adds it to the blockstore, // and returns the key representing that node. func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options.UnixfsAddOption) (path.Resolved, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "Add") + defer span.End() + settings, prefix, err := options.UnixfsAddOptions(opts...) if err != nil { return nil, err } + span.SetAttributes( + attribute.String("chunker", settings.Chunker), + attribute.Int("cidversion", settings.CidVersion), + attribute.Bool("inline", settings.Inline), + attribute.Int("inlinelimit", settings.InlineLimit), + attribute.Bool("rawleaves", settings.RawLeaves), + attribute.Bool("rawleavesset", settings.RawLeavesSet), + attribute.Int("layout", int(settings.Layout)), + attribute.Bool("pin", settings.Pin), + attribute.Bool("onlyhash", settings.OnlyHash), + attribute.Bool("fscache", settings.FsCache), + attribute.Bool("nocopy", settings.NoCopy), + attribute.Bool("silent", settings.Silent), + attribute.Bool("progress", settings.Progress), + ) + cfg, err := api.repo.Config() if err != nil { return nil, err @@ -74,7 +96,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options //} if settings.NoCopy && !(cfg.Experimental.FilestoreEnabled || cfg.Experimental.UrlstoreEnabled) { - return nil, fmt.Errorf("either the filestore or the urlstore must be enabled to use nocopy, see: https://git.io/vNItf") + return nil, fmt.Errorf("either the filestore or the urlstore must be enabled to use nocopy, see: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-filestore") } addblockstore := api.blockstore @@ -179,6 +201,9 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options } func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "Get", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + ses := api.core().getSession(ctx) nd, err := ses.ResolveNode(ctx, p) @@ -192,11 +217,16 @@ func (api *UnixfsAPI) Get(ctx context.Context, p path.Path) (files.Node, error) // Ls returns the contents of an IPFS or IPNS object(s) at path p, with the format: // ` ` func (api *UnixfsAPI) Ls(ctx context.Context, p path.Path, opts ...options.UnixfsLsOption) (<-chan coreiface.DirEntry, error) { + ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "Ls", trace.WithAttributes(attribute.String("path", p.String()))) + defer span.End() + settings, err := options.UnixfsLsOptions(opts...) if err != nil { return nil, err } + span.SetAttributes(attribute.Bool("resolvechildren", settings.ResolveChildren)) + ses := api.core().getSession(ctx) uses := (*UnixfsAPI)(ses) @@ -217,6 +247,13 @@ func (api *UnixfsAPI) Ls(ctx context.Context, p path.Path, opts ...options.Unixf } func (api *UnixfsAPI) processLink(ctx context.Context, linkres ft.LinkResult, settings *options.UnixfsLsSettings) coreiface.DirEntry { + ctx, span := tracing.Span(ctx, "CoreAPI.UnixfsAPI", "ProcessLink") + defer span.End() + if linkres.Link != nil { + span.SetAttributes(attribute.String("linkname", linkres.Link.Name), attribute.String("cid", linkres.Link.Cid.String())) + + } + if linkres.Err != nil { return coreiface.DirEntry{Err: linkres.Err} } @@ -265,7 +302,7 @@ func (api *UnixfsAPI) processLink(ctx context.Context, linkres ft.LinkResult, se } func (api *UnixfsAPI) lsFromLinksAsync(ctx context.Context, dir uio.Directory, settings *options.UnixfsLsSettings) (<-chan coreiface.DirEntry, error) { - out := make(chan coreiface.DirEntry) + out := make(chan coreiface.DirEntry, uio.DefaultShardWidth) go func() { defer close(out) diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index c5443f6eb3f..14b503ff528 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -16,7 +16,7 @@ import ( cmds "github.com/ipfs/go-ipfs-cmds" cmdsHttp "github.com/ipfs/go-ipfs-cmds/http" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" path "github.com/ipfs/go-path" ) @@ -46,6 +46,11 @@ var defaultLocalhostOrigins = []string{ "https://localhost:", } +var companionBrowserExtensionOrigins = []string{ + "chrome-extension://nibjojkomfdiaoajekhjakgkdhaomnch", // ipfs-companion + "chrome-extension://hjoieblefckbooibpepigmacodalfndh", // ipfs-companion-beta +} + func addCORSFromEnv(c *cmdsHttp.ServerConfig) { origin := os.Getenv(originEnvKey) if origin != "" { @@ -84,10 +89,9 @@ func addHeadersFromConfig(c *cmdsHttp.ServerConfig, nc *config.Config) { } func addCORSDefaults(c *cmdsHttp.ServerConfig) { - // by default use localhost origins - if len(c.AllowedOrigins()) == 0 { - c.SetAllowedOrigins(defaultLocalhostOrigins...) - } + // always safelist certain origins + c.AppendAllowedOrigins(defaultLocalhostOrigins...) + c.AppendAllowedOrigins(companionBrowserExtensionOrigins...) // by default, use GET, PUT, POST if len(c.AllowedMethods()) == 0 { diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index fb1524da529..84ad13897c8 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -9,15 +9,17 @@ import ( version "github.com/ipfs/go-ipfs" core "github.com/ipfs/go-ipfs/core" coreapi "github.com/ipfs/go-ipfs/core/coreapi" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" options "github.com/ipfs/interface-go-ipfs-core/options" id "github.com/libp2p/go-libp2p/p2p/protocol/identify" ) type GatewayConfig struct { - Headers map[string][]string - Writable bool - PathPrefixes []string + Headers map[string][]string + Writable bool + PathPrefixes []string + FastDirIndexThreshold int } // A helper function to clean up a set of headers: @@ -82,17 +84,23 @@ func GatewayOption(writable bool, paths ...string) ServeOption { headers[ACEHeadersName] = cleanHeaderSet( append([]string{ + "Content-Length", "Content-Range", "X-Chunked-Output", "X-Stream-Output", + "X-Ipfs-Path", + "X-Ipfs-Roots", }, headers[ACEHeadersName]...)) - gateway := newGatewayHandler(GatewayConfig{ - Headers: headers, - Writable: writable, - PathPrefixes: cfg.Gateway.PathPrefixes, + var gateway http.Handler = newGatewayHandler(GatewayConfig{ + Headers: headers, + Writable: writable, + PathPrefixes: cfg.Gateway.PathPrefixes, + FastDirIndexThreshold: int(cfg.Gateway.FastDirIndexThreshold.WithDefault(100)), }, api) + gateway = otelhttp.NewHandler(gateway, "Gateway.Request") + for _, p := range paths { mux.Handle(p+"/", gateway) } diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index f5ee54d8cfd..f32fac54ecd 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -7,6 +7,7 @@ import ( "io" "mime" "net/http" + "net/textproto" "net/url" "os" gopath "path" @@ -16,11 +17,8 @@ import ( "strings" "time" - humanize "github.com/dustin/go-humanize" - "github.com/gabriel-vasile/mimetype" - "github.com/ipfs/go-cid" + cid "github.com/ipfs/go-cid" files "github.com/ipfs/go-ipfs-files" - assets "github.com/ipfs/go-ipfs/assets" dag "github.com/ipfs/go-merkledag" mfs "github.com/ipfs/go-mfs" path "github.com/ipfs/go-path" @@ -29,14 +27,21 @@ import ( ipath "github.com/ipfs/interface-go-ipfs-core/path" routing "github.com/libp2p/go-libp2p-core/routing" prometheus "github.com/prometheus/client_golang/prometheus" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + "go.uber.org/zap" ) const ( - ipfsPathPrefix = "/ipfs/" - ipnsPathPrefix = "/ipns/" + ipfsPathPrefix = "/ipfs/" + ipnsPathPrefix = "/ipns/" + immutableCacheControl = "public, max-age=29030400, immutable" ) -var onlyAscii = regexp.MustCompile("[[:^ascii:]]") +var ( + onlyAscii = regexp.MustCompile("[[:^ascii:]]") + noModtime = time.Unix(0, 0) // disables Last-Modified header if passed as modtime +) // HTML-based redirect for errors which can be recovered from, but we want // to provide hint to people that they should fix things on their end. @@ -64,7 +69,15 @@ type gatewayHandler struct { config GatewayConfig api coreiface.CoreAPI - unixfsGetMetric *prometheus.SummaryVec + // generic metrics + firstContentBlockGetMetric *prometheus.HistogramVec + unixfsGetMetric *prometheus.SummaryVec // deprecated, use firstContentBlockGetMetric + + // response type metrics + unixfsFileGetMetric *prometheus.HistogramVec + unixfsGenDirGetMetric *prometheus.HistogramVec + carStreamGetMetric *prometheus.HistogramVec + rawBlockGetMetric *prometheus.HistogramVec } // StatusResponseWriter enables us to override HTTP Status Code passed to @@ -74,6 +87,25 @@ type statusResponseWriter struct { http.ResponseWriter } +// Custom type for collecting error details to be handled by `webRequestError` +type requestError struct { + Message string + StatusCode int + Err error +} + +func (r *requestError) Error() string { + return r.Err.Error() +} + +func newRequestError(message string, err error, statusCode int) *requestError { + return &requestError{ + Message: message, + Err: err, + StatusCode: statusCode, + } +} + func (sw *statusResponseWriter) WriteHeader(code int) { // Check if we need to adjust Status Code to account for scheduled redirect // This enables us to return payload along with HTTP 301 @@ -82,32 +114,146 @@ func (sw *statusResponseWriter) WriteHeader(code int) { redirect := sw.ResponseWriter.Header().Get("Location") if redirect != "" && code == http.StatusOK { code = http.StatusMovedPermanently + log.Debugw("subdomain redirect", "location", redirect, "status", code) } sw.ResponseWriter.WriteHeader(code) } -func newGatewayHandler(c GatewayConfig, api coreiface.CoreAPI) *gatewayHandler { - unixfsGetMetric := prometheus.NewSummaryVec( +// ServeContent replies to the request using the content in the provided ReadSeeker +// and returns the status code written and any error encountered during a write. +// It wraps http.ServeContent which takes care of If-None-Match+Etag, +// Content-Length and range requests. +func ServeContent(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) (int, bool, error) { + ew := &errRecordingResponseWriter{ResponseWriter: w} + http.ServeContent(ew, req, name, modtime, content) + + // When we calculate some metrics we want a flag that lets us to ignore + // errors and 304 Not Modified, and only care when requested data + // was sent in full. + dataSent := ew.code/100 == 2 && ew.err == nil + + return ew.code, dataSent, ew.err +} + +// errRecordingResponseWriter wraps a ResponseWriter to record the status code and any write error. +type errRecordingResponseWriter struct { + http.ResponseWriter + code int + err error +} + +func (w *errRecordingResponseWriter) WriteHeader(code int) { + if w.code == 0 { + w.code = code + } + w.ResponseWriter.WriteHeader(code) +} + +func (w *errRecordingResponseWriter) Write(p []byte) (int, error) { + n, err := w.ResponseWriter.Write(p) + if err != nil && w.err == nil { + w.err = err + } + return n, err +} + +// ReadFrom exposes errRecordingResponseWriter's underlying ResponseWriter to io.Copy +// to allow optimized methods to be taken advantage of. +func (w *errRecordingResponseWriter) ReadFrom(r io.Reader) (n int64, err error) { + n, err = io.Copy(w.ResponseWriter, r) + if err != nil && w.err == nil { + w.err = err + } + return n, err +} + +func newGatewaySummaryMetric(name string, help string) *prometheus.SummaryVec { + summaryMetric := prometheus.NewSummaryVec( prometheus.SummaryOpts{ Namespace: "ipfs", Subsystem: "http", - Name: "unixfs_get_latency_seconds", - Help: "The time till the first block is received when 'getting' a file from the gateway.", + Name: name, + Help: help, }, []string{"gateway"}, ) - if err := prometheus.Register(unixfsGetMetric); err != nil { + if err := prometheus.Register(summaryMetric); err != nil { if are, ok := err.(prometheus.AlreadyRegisteredError); ok { - unixfsGetMetric = are.ExistingCollector.(*prometheus.SummaryVec) + summaryMetric = are.ExistingCollector.(*prometheus.SummaryVec) } else { - log.Errorf("failed to register unixfsGetMetric: %v", err) + log.Errorf("failed to register ipfs_http_%s: %v", name, err) } } + return summaryMetric +} +func newGatewayHistogramMetric(name string, help string) *prometheus.HistogramVec { + // We can add buckets as a parameter in the future, but for now using static defaults + // suggested in https://github.com/ipfs/go-ipfs/issues/8441 + defaultBuckets := []float64{0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30, 60} + histogramMetric := prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: "ipfs", + Subsystem: "http", + Name: name, + Help: help, + Buckets: defaultBuckets, + }, + []string{"gateway"}, + ) + if err := prometheus.Register(histogramMetric); err != nil { + if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + histogramMetric = are.ExistingCollector.(*prometheus.HistogramVec) + } else { + log.Errorf("failed to register ipfs_http_%s: %v", name, err) + } + } + return histogramMetric +} + +func newGatewayHandler(c GatewayConfig, api coreiface.CoreAPI) *gatewayHandler { i := &gatewayHandler{ - config: c, - api: api, - unixfsGetMetric: unixfsGetMetric, + config: c, + api: api, + // Improved Metrics + // ---------------------------- + // Time till the first content block (bar in /ipfs/cid/foo/bar) + // (format-agnostic, across all response types) + firstContentBlockGetMetric: newGatewayHistogramMetric( + "gw_first_content_block_get_latency_seconds", + "The time till the first content block is received on GET from the gateway.", + ), + + // Response-type specific metrics + // ---------------------------- + // UnixFS: time it takes to return a file + unixfsFileGetMetric: newGatewayHistogramMetric( + "gw_unixfs_file_get_duration_seconds", + "The time to serve an entire UnixFS file from the gateway.", + ), + // UnixFS: time it takes to generate static HTML with directory listing + unixfsGenDirGetMetric: newGatewayHistogramMetric( + "gw_unixfs_gen_dir_listing_get_duration_seconds", + "The time to serve a generated UnixFS HTML directory listing from the gateway.", + ), + // CAR: time it takes to return requested CAR stream + carStreamGetMetric: newGatewayHistogramMetric( + "gw_car_stream_get_duration_seconds", + "The time to GET an entire CAR stream from the gateway.", + ), + // Block: time it takes to return requested Block + rawBlockGetMetric: newGatewayHistogramMetric( + "gw_raw_block_get_duration_seconds", + "The time to GET an entire raw Block from the gateway.", + ), + + // Legacy Metrics + // ---------------------------- + unixfsGetMetric: newGatewaySummaryMetric( // TODO: remove? + // (deprecated, use firstContentBlockGetMetric instead) + "unixfs_get_latency_seconds", + "The time to receive the first UnixFS node on a GET from the gateway.", + ), } return i } @@ -195,359 +341,104 @@ func (i *gatewayHandler) optionsHandler(w http.ResponseWriter, r *http.Request) func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request) { begin := time.Now() - urlPath := r.URL.Path - escapedURLPath := r.URL.EscapedPath() - - // If the gateway is behind a reverse proxy and mounted at a sub-path, - // the prefix header can be set to signal this sub-path. - // It will be prepended to links in directory listings and the index.html redirect. - // TODO: this feature is deprecated and will be removed (https://github.com/ipfs/go-ipfs/issues/7702) - prefix := "" - if prfx := r.Header.Get("X-Ipfs-Gateway-Prefix"); len(prfx) > 0 { - for _, p := range i.config.PathPrefixes { - if prfx == p || strings.HasPrefix(prfx, p+"/") { - prefix = prfx - break - } - } - } - // HostnameOption might have constructed an IPNS/IPFS path using the Host header. - // In this case, we need the original path for constructing redirects - // and links that match the requested URL. - // For example, http://example.net would become /ipns/example.net, and - // the redirects and links would end up as http://example.net/ipns/example.net - requestURI, err := url.ParseRequestURI(r.RequestURI) - if err != nil { - webError(w, "failed to parse request path", err, http.StatusInternalServerError) + logger := log.With("from", r.RequestURI) + logger.Debug("http request received") + + if err := handleUnsupportedHeaders(r); err != nil { + webRequestError(w, err) return } - originalUrlPath := prefix + requestURI.Path - // ?uri query param support for requests produced by web browsers - // via navigator.registerProtocolHandler Web API - // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler - // TLDR: redirect /ipfs/?uri=ipfs%3A%2F%2Fcid%3Fquery%3Dval to /ipfs/cid?query=val - if uriParam := r.URL.Query().Get("uri"); uriParam != "" { - u, err := url.Parse(uriParam) - if err != nil { - webError(w, "failed to parse uri query parameter", err, http.StatusBadRequest) - return - } - if u.Scheme != "ipfs" && u.Scheme != "ipns" { - webError(w, "uri query parameter scheme must be ipfs or ipns", err, http.StatusBadRequest) - return - } - path := u.Path - if u.RawQuery != "" { // preserve query if present - path = path + "?" + u.RawQuery - } - http.Redirect(w, r, gopath.Join("/", prefix, u.Scheme, u.Host, path), http.StatusMovedPermanently) + if requestHandled := handleProtocolHandlerRedirect(w, r, logger); requestHandled { return } - // Service Worker registration request - if r.Header.Get("Service-Worker") == "script" { - // Disallow Service Worker registration on namespace roots - // https://github.com/ipfs/go-ipfs/issues/4025 - matched, _ := regexp.MatchString(`^/ip[fn]s/[^/]+$`, r.URL.Path) - if matched { - err := fmt.Errorf("registration is not allowed for this scope") - webError(w, "navigator.serviceWorker", err, http.StatusBadRequest) - return - } + if err := handleServiceWorkerRegistration(r); err != nil { + webRequestError(w, err) + return } - parsedPath := ipath.New(urlPath) - if pathErr := parsedPath.IsValid(); pathErr != nil { - if prefix == "" && fixupSuperfluousNamespace(w, urlPath, r.URL.RawQuery) { - // the error was due to redundant namespace, which we were able to fix - // by returning error/redirect page, nothing left to do here - return - } - // unable to fix path, returning error - webError(w, "invalid ipfs path", pathErr, http.StatusBadRequest) + contentPath := ipath.New(r.URL.Path) + if requestHandled := handleSuperfluousNamespace(w, r, contentPath); requestHandled { return } // Resolve path to the final DAG node for the ETag - resolvedPath, err := i.api.ResolvePath(r.Context(), parsedPath) + resolvedPath, err := i.api.ResolvePath(r.Context(), contentPath) switch err { case nil: case coreiface.ErrOffline: - webError(w, "ipfs resolve -r "+escapedURLPath, err, http.StatusServiceUnavailable) + webError(w, "ipfs resolve -r "+debugStr(contentPath.String()), err, http.StatusServiceUnavailable) return default: - if i.servePretty404IfPresent(w, r, parsedPath) { + // if Accept is text/html, see if ipfs-404.html is present + if i.servePretty404IfPresent(w, r, contentPath) { + logger.Debugw("serve pretty 404 if present") return } - webError(w, "ipfs resolve -r "+escapedURLPath, err, http.StatusNotFound) + webError(w, "ipfs resolve -r "+debugStr(contentPath.String()), err, http.StatusNotFound) return } - dr, err := i.api.Unixfs().Get(r.Context(), resolvedPath) + // Detect when explicit Accept header or ?format parameter are present + responseFormat, formatParams, err := customResponseFormat(r) if err != nil { - webError(w, "ipfs cat "+escapedURLPath, err, http.StatusNotFound) + webError(w, "error while processing the Accept header", err, http.StatusBadRequest) return } - - i.unixfsGetMetric.WithLabelValues(parsedPath.Namespace()).Observe(time.Since(begin).Seconds()) - - defer dr.Close() - - var responseEtag string - - // we need to figure out whether this is a directory before doing most of the heavy lifting below - _, ok := dr.(files.Directory) - - if ok && assets.BindataVersionHash != "" { - responseEtag = `"DirIndex-` + assets.BindataVersionHash + `_CID-` + resolvedPath.Cid().String() + `"` - } else { - responseEtag = `"` + resolvedPath.Cid().String() + `"` - } - - // Check etag sent back to us - if r.Header.Get("If-None-Match") == responseEtag || r.Header.Get("If-None-Match") == `W/`+responseEtag { - w.WriteHeader(http.StatusNotModified) - return - } - - i.addUserHeaders(w) // ok, _now_ write user's headers. - w.Header().Set("X-IPFS-Path", urlPath) - w.Header().Set("Etag", responseEtag) - - // set these headers _after_ the error, for we may just not have it - // and don't want the client to cache a 500 response... - // and only if it's /ipfs! - // TODO: break this out when we split /ipfs /ipns routes. - modtime := time.Now() - - if f, ok := dr.(files.File); ok { - if strings.HasPrefix(urlPath, ipfsPathPrefix) { - w.Header().Set("Cache-Control", "public, max-age=29030400, immutable") - - // set modtime to a really long time ago, since files are immutable and should stay cached - modtime = time.Unix(1, 0) - } - - urlFilename := r.URL.Query().Get("filename") - var name string - if urlFilename != "" { - disposition := "inline" - if r.URL.Query().Get("download") == "true" { - disposition = "attachment" - } - utf8Name := url.PathEscape(urlFilename) - asciiName := url.PathEscape(onlyAscii.ReplaceAllLiteralString(urlFilename, "_")) - w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"; filename*=UTF-8''%s", disposition, asciiName, utf8Name)) - name = urlFilename - } else { - name = getFilename(urlPath) - } - i.serveFile(w, r, name, modtime, f) - return - } - dir, ok := dr.(files.Directory) - if !ok { - internalWebError(w, fmt.Errorf("unsupported file type")) - return - } - - idx, err := i.api.Unixfs().Get(r.Context(), ipath.Join(resolvedPath, "index.html")) - switch err.(type) { - case nil: - dirwithoutslash := urlPath[len(urlPath)-1] != '/' - goget := r.URL.Query().Get("go-get") == "1" - if dirwithoutslash && !goget { - // See comment above where originalUrlPath is declared. - suffix := "/" - if r.URL.RawQuery != "" { - // preserve query parameters - suffix = suffix + "?" + r.URL.RawQuery - } - http.Redirect(w, r, originalUrlPath+suffix, 302) + trace.SpanFromContext(r.Context()).SetAttributes(attribute.String("ResponseFormat", responseFormat)) + trace.SpanFromContext(r.Context()).SetAttributes(attribute.String("ResolvedPath", resolvedPath.String())) + + // Detect when If-None-Match HTTP header allows returning HTTP 304 Not Modified + if inm := r.Header.Get("If-None-Match"); inm != "" { + pathCid := resolvedPath.Cid() + // need to check against both File and Dir Etag variants + // because this inexpensive check happens before we do any I/O + cidEtag := getEtag(r, pathCid) + dirEtag := getDirListingEtag(pathCid) + if etagMatch(inm, cidEtag, dirEtag) { + // Finish early if client already has a matching Etag + w.WriteHeader(http.StatusNotModified) return } - - f, ok := idx.(files.File) - if !ok { - internalWebError(w, files.ErrNotReader) - return - } - - // write to request - i.serveFile(w, r, "index.html", modtime, f) - return - case resolver.ErrNoLink: - // no index.html; noop - default: - internalWebError(w, err) - return } - // See statusResponseWriter.WriteHeader - // and https://github.com/ipfs/go-ipfs/issues/7164 - // Note: this needs to occur before listingTemplate.Execute otherwise we get - // superfluous response.WriteHeader call from prometheus/client_golang - if w.Header().Get("Location") != "" { - w.WriteHeader(http.StatusMovedPermanently) + if err := i.handleGettingFirstBlock(r, begin, contentPath, resolvedPath); err != nil { + webRequestError(w, err) return } - // A HTML directory index will be presented, be sure to set the correct - // type instead of relying on autodetection (which may fail). - w.Header().Set("Content-Type", "text/html") - if r.Method == http.MethodHead { + if err := i.setCommonHeaders(w, r, contentPath); err != nil { + webRequestError(w, err) return } - // storage for directory listing - var dirListing []directoryItem - dirit := dir.Entries() - for dirit.Next() { - size := "?" - if s, err := dirit.Node().Size(); err == nil { - // Size may not be defined/supported. Continue anyways. - size = humanize.Bytes(uint64(s)) - } - - resolved, err := i.api.ResolvePath(r.Context(), ipath.Join(resolvedPath, dirit.Name())) - if err != nil { - internalWebError(w, err) - return - } - hash := resolved.Cid().String() - - // See comment above where originalUrlPath is declared. - di := directoryItem{ - Size: size, - Name: dirit.Name(), - Path: gopath.Join(originalUrlPath, dirit.Name()), - Hash: hash, - ShortHash: shortHash(hash), - } - dirListing = append(dirListing, di) - } - if dirit.Err() != nil { - internalWebError(w, dirit.Err()) + // Support custom response formats passed via ?format or Accept HTTP header + switch responseFormat { + case "": // The implicit response format is UnixFS + logger.Debugw("serving unixfs", "path", contentPath) + i.serveUnixFS(r.Context(), w, r, resolvedPath, contentPath, begin, logger) return - } - - // construct the correct back link - // https://github.com/ipfs/go-ipfs/issues/1365 - var backLink string = originalUrlPath - - // don't go further up than /ipfs/$hash/ - pathSplit := path.SplitList(urlPath) - switch { - // keep backlink - case len(pathSplit) == 3: // url: /ipfs/$hash - - // keep backlink - case len(pathSplit) == 4 && pathSplit[3] == "": // url: /ipfs/$hash/ - - // add the correct link depending on whether the path ends with a slash - default: - if strings.HasSuffix(backLink, "/") { - backLink += "./.." - } else { - backLink += "/.." - } - } - - size := "?" - if s, err := dir.Size(); err == nil { - // Size may not be defined/supported. Continue anyways. - size = humanize.Bytes(uint64(s)) - } - - hash := resolvedPath.Cid().String() - - // Gateway root URL to be used when linking to other rootIDs. - // This will be blank unless subdomain or DNSLink resolution is being used - // for this request. - var gwURL string - - // Get gateway hostname and build gateway URL. - if h, ok := r.Context().Value("gw-hostname").(string); ok { - gwURL = "//" + h - } else { - gwURL = "" - } - - dnslink := hasDNSLinkOrigin(gwURL, urlPath) - - // See comment above where originalUrlPath is declared. - tplData := listingTemplateData{ - GatewayURL: gwURL, - DNSLink: dnslink, - Listing: dirListing, - Size: size, - Path: urlPath, - Breadcrumbs: breadcrumbs(urlPath, dnslink), - BackLink: backLink, - Hash: hash, - } - - err = listingTemplate.Execute(w, tplData) - if err != nil { - internalWebError(w, err) + case "application/vnd.ipld.raw": + logger.Debugw("serving raw block", "path", contentPath) + i.serveRawBlock(r.Context(), w, r, resolvedPath, contentPath, begin) return - } -} - -func (i *gatewayHandler) serveFile(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, file files.File) { - size, err := file.Size() - if err != nil { - http.Error(w, "cannot serve files with unknown sizes", http.StatusBadGateway) + case "application/vnd.ipld.car": + logger.Debugw("serving car stream", "path", contentPath) + carVersion := formatParams["version"] + i.serveCAR(r.Context(), w, r, resolvedPath, contentPath, carVersion, begin) + return + default: // catch-all for unsuported application/vnd.* + err := fmt.Errorf("unsupported format %q", responseFormat) + webError(w, "failed respond with requested content type", err, http.StatusBadRequest) return } - - content := &lazySeeker{ - size: size, - reader: file, - } - - var ctype string - if _, isSymlink := file.(*files.Symlink); isSymlink { - // We should be smarter about resolving symlinks but this is the - // "most correct" we can be without doing that. - ctype = "inode/symlink" - } else { - ctype = mime.TypeByExtension(gopath.Ext(name)) - if ctype == "" { - // uses https://github.com/gabriel-vasile/mimetype library to determine the content type. - // Fixes https://github.com/ipfs/go-ipfs/issues/7252 - mimeType, err := mimetype.DetectReader(content) - if err != nil { - http.Error(w, fmt.Sprintf("cannot detect content-type: %s", err.Error()), http.StatusInternalServerError) - return - } - - ctype = mimeType.String() - _, err = content.Seek(0, io.SeekStart) - if err != nil { - http.Error(w, "seeker can't seek", http.StatusInternalServerError) - return - } - } - // Strip the encoding from the HTML Content-Type header and let the - // browser figure it out. - // - // Fixes https://github.com/ipfs/go-ipfs/issues/2203 - if strings.HasPrefix(ctype, "text/html;") { - ctype = "text/html" - } - } - w.Header().Set("Content-Type", ctype) - - w = &statusResponseWriter{w} - http.ServeContent(w, req, name, modtime, content) } -func (i *gatewayHandler) servePretty404IfPresent(w http.ResponseWriter, r *http.Request, parsedPath ipath.Path) bool { - resolved404Path, ctype, err := i.searchUpTreeFor404(r, parsedPath) +func (i *gatewayHandler) servePretty404IfPresent(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) bool { + resolved404Path, ctype, err := i.searchUpTreeFor404(r, contentPath) if err != nil { return false } @@ -568,7 +459,7 @@ func (i *gatewayHandler) servePretty404IfPresent(w http.ResponseWriter, r *http. return false } - log.Debugf("using pretty 404 file for %s", parsedPath.String()) + log.Debugw("using pretty 404 file", "path", contentPath) w.Header().Set("Content-Type", ctype) w.Header().Set("Content-Length", strconv.FormatInt(size, 10)) w.WriteHeader(http.StatusNotFound) @@ -585,6 +476,7 @@ func (i *gatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) { i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("IPFS-Hash", p.Cid().String()) + log.Debugw("CID created, http redirect", "from", r.URL, "to", p, "status", http.StatusCreated) http.Redirect(w, r, p.String(), http.StatusCreated) } @@ -677,7 +569,10 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("IPFS-Hash", newcid.String()) - http.Redirect(w, r, gopath.Join(ipfsPathPrefix, newcid.String(), newPath), http.StatusCreated) + + redirectURL := gopath.Join(ipfsPathPrefix, newcid.String(), newPath) + log.Debugw("CID replaced, redirect", "from", r.URL, "to", redirectURL, "status", http.StatusCreated) + http.Redirect(w, r, redirectURL, http.StatusCreated) } func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { @@ -743,13 +638,17 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { nnode, err := root.GetDirectory().GetNode() if err != nil { webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError) + return } ncid := nnode.Cid() i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("IPFS-Hash", ncid.String()) + + redirectURL := gopath.Join(ipfsPathPrefix+ncid.String(), directory) // note: StatusCreated is technically correct here as we created a new resource. - http.Redirect(w, r, gopath.Join(ipfsPathPrefix+ncid.String(), directory), http.StatusCreated) + log.Debugw("CID deleted, redirect", "from", r.RequestURI, "to", redirectURL, "status", http.StatusCreated) + http.Redirect(w, r, redirectURL, http.StatusCreated) } func (i *gatewayHandler) addUserHeaders(w http.ResponseWriter) { @@ -758,6 +657,114 @@ func (i *gatewayHandler) addUserHeaders(w http.ResponseWriter) { } } +func addCacheControlHeaders(w http.ResponseWriter, r *http.Request, contentPath ipath.Path, fileCid cid.Cid) (modtime time.Time) { + // Set Etag to based on CID (override whatever was set before) + w.Header().Set("Etag", getEtag(r, fileCid)) + + // Set Cache-Control and Last-Modified based on contentPath properties + if contentPath.Mutable() { + // mutable namespaces such as /ipns/ can't be cached forever + + /* For now we set Last-Modified to Now() to leverage caching heuristics built into modern browsers: + * https://github.com/ipfs/go-ipfs/pull/8074#pullrequestreview-645196768 + * but we should not set it to fake values and use Cache-Control based on TTL instead */ + modtime = time.Now() + + // TODO: set Cache-Control based on TTL of IPNS/DNSLink: https://github.com/ipfs/go-ipfs/issues/1818#issuecomment-1015849462 + // TODO: set Last-Modified based on /ipns/ publishing timestamp? + } else { + // immutable! CACHE ALL THE THINGS, FOREVER! wolololol + w.Header().Set("Cache-Control", immutableCacheControl) + + // Set modtime to 'zero time' to disable Last-Modified header (superseded by Cache-Control) + modtime = noModtime + + // TODO: set Last-Modified? - TBD - /ipfs/ modification metadata is present in unixfs 1.5 https://github.com/ipfs/go-ipfs/issues/6920? + } + + return modtime +} + +// Set Content-Disposition if filename URL query param is present, return preferred filename +func addContentDispositionHeader(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) string { + /* This logic enables: + * - creation of HTML links that trigger "Save As.." dialog instead of being rendered by the browser + * - overriding the filename used when saving subresource assets on HTML page + * - providing a default filename for HTTP clients when downloading direct /ipfs/CID without any subpath + */ + + // URL param ?filename=cat.jpg triggers Content-Disposition: [..] filename + // which impacts default name used in "Save As.." dialog + name := getFilename(contentPath) + urlFilename := r.URL.Query().Get("filename") + if urlFilename != "" { + disposition := "inline" + // URL param ?download=true triggers Content-Disposition: [..] attachment + // which skips rendering and forces "Save As.." dialog in browsers + if r.URL.Query().Get("download") == "true" { + disposition = "attachment" + } + setContentDispositionHeader(w, urlFilename, disposition) + name = urlFilename + } + return name +} + +// Set Content-Disposition to arbitrary filename and disposition +func setContentDispositionHeader(w http.ResponseWriter, filename string, disposition string) { + utf8Name := url.PathEscape(filename) + asciiName := url.PathEscape(onlyAscii.ReplaceAllLiteralString(filename, "_")) + w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"; filename*=UTF-8''%s", disposition, asciiName, utf8Name)) +} + +// Set X-Ipfs-Roots with logical CID array for efficient HTTP cache invalidation. +func (i *gatewayHandler) buildIpfsRootsHeader(contentPath string, r *http.Request) (string, error) { + /* + These are logical roots where each CID represent one path segment + and resolves to either a directory or the root block of a file. + The main purpose of this header is allow HTTP caches to do smarter decisions + around cache invalidation (eg. keep specific subdirectory/file if it did not change) + + A good example is Wikipedia, which is HAMT-sharded, but we only care about + logical roots that represent each segment of the human-readable content + path: + + Given contentPath = /ipns/en.wikipedia-on-ipfs.org/wiki/Block_of_Wikipedia_in_Turkey + rootCidList is a generated by doing `ipfs resolve -r` on each sub path: + /ipns/en.wikipedia-on-ipfs.org โ†’ bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze + /ipns/en.wikipedia-on-ipfs.org/wiki/ โ†’ bafybeihn2f7lhumh4grizksi2fl233cyszqadkn424ptjajfenykpsaiw4 + /ipns/en.wikipedia-on-ipfs.org/wiki/Block_of_Wikipedia_in_Turkey โ†’ bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma + + The result is an ordered array of values: + X-Ipfs-Roots: bafybeiaysi4s6lnjev27ln5icwm6tueaw2vdykrtjkwiphwekaywqhcjze,bafybeihn2f7lhumh4grizksi2fl233cyszqadkn424ptjajfenykpsaiw4,bafkreibn6euazfvoghepcm4efzqx5l3hieof2frhp254hio5y7n3hv5rma + + Note that while the top one will change every time any article is changed, + the last root (responsible for specific article) may not change at all. + */ + var sp strings.Builder + var pathRoots []string + pathSegments := strings.Split(contentPath[6:], "/") + sp.WriteString(contentPath[:5]) // /ipfs or /ipns + for _, root := range pathSegments { + if root == "" { + continue + } + sp.WriteString("/") + sp.WriteString(root) + resolvedSubPath, err := i.api.ResolvePath(r.Context(), ipath.New(sp.String())) + if err != nil { + return "", err + } + pathRoots = append(pathRoots, resolvedSubPath.Cid().String()) + } + rootCidList := strings.Join(pathRoots, ",") // convention from rfc2616#sec4.2 + return rootCidList, nil +} + +func webRequestError(w http.ResponseWriter, err *requestError) { + webError(w, err.Message, err.Err, err.StatusCode) +} + func webError(w http.ResponseWriter, message string, err error, defaultCode int) { if _, ok := err.(resolver.ErrNoLink); ok { webErrorWithCode(w, message, err, http.StatusNotFound) @@ -773,7 +780,7 @@ func webError(w http.ResponseWriter, message string, err error, defaultCode int) func webErrorWithCode(w http.ResponseWriter, message string, err error, code int) { http.Error(w, fmt.Sprintf("%s: %s", message, err), code) if code >= 500 { - log.Warnf("server error: %s: %s", err) + log.Warnf("server error: %s: %s", message, err) } } @@ -782,7 +789,8 @@ func internalWebError(w http.ResponseWriter, err error) { webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError) } -func getFilename(s string) string { +func getFilename(contentPath ipath.Path) string { + s := contentPath.String() if (strings.HasPrefix(s, ipfsPathPrefix) || strings.HasPrefix(s, ipnsPathPrefix)) && strings.Count(gopath.Clean(s), "/") <= 2 { // Don't want to treat ipfs.io in /ipns/ipfs.io as a filename. return "" @@ -790,13 +798,120 @@ func getFilename(s string) string { return gopath.Base(s) } -func (i *gatewayHandler) searchUpTreeFor404(r *http.Request, parsedPath ipath.Path) (ipath.Resolved, string, error) { +// etagMatch evaluates if we can respond with HTTP 304 Not Modified +// It supports multiple weak and strong etags passed in If-None-Matc stringh +// including the wildcard one. +func etagMatch(ifNoneMatchHeader string, cidEtag string, dirEtag string) bool { + buf := ifNoneMatchHeader + for { + buf = textproto.TrimString(buf) + if len(buf) == 0 { + break + } + if buf[0] == ',' { + buf = buf[1:] + continue + } + // If-None-Match: * should match against any etag + if buf[0] == '*' { + return true + } + etag, remain := scanETag(buf) + if etag == "" { + break + } + // Check for match both strong and weak etags + if etagWeakMatch(etag, cidEtag) || etagWeakMatch(etag, dirEtag) { + return true + } + buf = remain + } + return false +} + +// scanETag determines if a syntactically valid ETag is present at s. If so, +// the ETag and remaining text after consuming ETag is returned. Otherwise, +// it returns "", "". +// (This is the same logic as one executed inside of http.ServeContent) +func scanETag(s string) (etag string, remain string) { + s = textproto.TrimString(s) + start := 0 + if strings.HasPrefix(s, "W/") { + start = 2 + } + if len(s[start:]) < 2 || s[start] != '"' { + return "", "" + } + // ETag is either W/"text" or "text". + // See RFC 7232 2.3. + for i := start + 1; i < len(s); i++ { + c := s[i] + switch { + // Character values allowed in ETags. + case c == 0x21 || c >= 0x23 && c <= 0x7E || c >= 0x80: + case c == '"': + return s[:i+1], s[i+1:] + default: + return "", "" + } + } + return "", "" +} + +// etagWeakMatch reports whether a and b match using weak ETag comparison. +func etagWeakMatch(a, b string) bool { + return strings.TrimPrefix(a, "W/") == strings.TrimPrefix(b, "W/") +} + +// generate Etag value based on HTTP request and CID +func getEtag(r *http.Request, cid cid.Cid) string { + prefix := `"` + suffix := `"` + responseFormat, _, err := customResponseFormat(r) + if err == nil && responseFormat != "" { + // application/vnd.ipld.foo โ†’ foo + f := responseFormat[strings.LastIndex(responseFormat, ".")+1:] + // Etag: "cid.foo" (gives us nice compression together with Content-Disposition in block (raw) and car responses) + suffix = `.` + f + suffix + } + // TODO: include selector suffix when https://github.com/ipfs/go-ipfs/issues/8769 lands + return prefix + cid.String() + suffix +} + +// return explicit response format if specified in request as query parameter or via Accept HTTP header +func customResponseFormat(r *http.Request) (mediaType string, params map[string]string, err error) { + if formatParam := r.URL.Query().Get("format"); formatParam != "" { + // translate query param to a content type + switch formatParam { + case "raw": + return "application/vnd.ipld.raw", nil, nil + case "car": + return "application/vnd.ipld.car", nil, nil + } + } + // Browsers and other user agents will send Accept header with generic types like: + // Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 + // We only care about explciit, vendor-specific content-types. + for _, accept := range r.Header.Values("Accept") { + // respond to the very first ipld content type + if strings.HasPrefix(accept, "application/vnd.ipld") { + mediatype, params, err := mime.ParseMediaType(accept) + if err != nil { + return "", nil, err + } + return mediatype, params, nil + } + } + return "", nil, nil +} + +func (i *gatewayHandler) searchUpTreeFor404(r *http.Request, contentPath ipath.Path) (ipath.Resolved, string, error) { filename404, ctype, err := preferred404Filename(r.Header.Values("Accept")) if err != nil { return nil, "", err } - pathComponents := strings.Split(parsedPath.String(), "/") + pathComponents := strings.Split(contentPath.String(), "/") for idx := len(pathComponents); idx >= 3; idx-- { pretty404 := gopath.Join(append(pathComponents[0:idx], filename404)...) @@ -832,32 +947,135 @@ func preferred404Filename(acceptHeaders []string) (string, string, error) { return "", "", fmt.Errorf("there is no 404 file for the requested content types") } +// returns unquoted path with all special characters revealed as \u codes +func debugStr(path string) string { + q := fmt.Sprintf("%+q", path) + if len(q) >= 3 { + q = q[1 : len(q)-1] + } + return q +} + +func handleUnsupportedHeaders(r *http.Request) (err *requestError) { + // X-Ipfs-Gateway-Prefix was removed (https://github.com/ipfs/go-ipfs/issues/7702) + // TODO: remove this after go-ipfs 0.13 ships + if prfx := r.Header.Get("X-Ipfs-Gateway-Prefix"); prfx != "" { + err := fmt.Errorf("X-Ipfs-Gateway-Prefix support was removed: https://github.com/ipfs/go-ipfs/issues/7702") + return newRequestError("unsupported HTTP header", err, http.StatusBadRequest) + } + return nil +} + +// ?uri query param support for requests produced by web browsers +// via navigator.registerProtocolHandler Web API +// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler +// TLDR: redirect /ipfs/?uri=ipfs%3A%2F%2Fcid%3Fquery%3Dval to /ipfs/cid?query=val +func handleProtocolHandlerRedirect(w http.ResponseWriter, r *http.Request, logger *zap.SugaredLogger) (requestHandled bool) { + if uriParam := r.URL.Query().Get("uri"); uriParam != "" { + u, err := url.Parse(uriParam) + if err != nil { + webError(w, "failed to parse uri query parameter", err, http.StatusBadRequest) + return true + } + if u.Scheme != "ipfs" && u.Scheme != "ipns" { + webError(w, "uri query parameter scheme must be ipfs or ipns", err, http.StatusBadRequest) + return true + } + path := u.Path + if u.RawQuery != "" { // preserve query if present + path = path + "?" + u.RawQuery + } + + redirectURL := gopath.Join("/", u.Scheme, u.Host, path) + logger.Debugw("uri param, redirect", "to", redirectURL, "status", http.StatusMovedPermanently) + http.Redirect(w, r, redirectURL, http.StatusMovedPermanently) + return true + } + + return false +} + +// Disallow Service Worker registration on namespace roots +// https://github.com/ipfs/go-ipfs/issues/4025 +func handleServiceWorkerRegistration(r *http.Request) (err *requestError) { + if r.Header.Get("Service-Worker") == "script" { + matched, _ := regexp.MatchString(`^/ip[fn]s/[^/]+$`, r.URL.Path) + if matched { + err := fmt.Errorf("registration is not allowed for this scope") + return newRequestError("navigator.serviceWorker", err, http.StatusBadRequest) + } + } + + return nil +} + // Attempt to fix redundant /ipfs/ namespace as long as resulting // 'intended' path is valid. This is in case gremlins were tickled // wrong way and user ended up at /ipfs/ipfs/{cid} or /ipfs/ipns/{id} // like in bafybeien3m7mdn6imm425vc2s22erzyhbvk5n3ofzgikkhmdkh5cuqbpbq :^)) -func fixupSuperfluousNamespace(w http.ResponseWriter, urlPath string, urlQuery string) bool { - if !(strings.HasPrefix(urlPath, "/ipfs/ipfs/") || strings.HasPrefix(urlPath, "/ipfs/ipns/")) { - return false // not a superfluous namespace +func handleSuperfluousNamespace(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) (requestHandled bool) { + // If the path is valid, there's nothing to do + if pathErr := contentPath.IsValid(); pathErr == nil { + return false + } + + // If there's no superflous namespace, there's nothing to do + if !(strings.HasPrefix(r.URL.Path, "/ipfs/ipfs/") || strings.HasPrefix(r.URL.Path, "/ipfs/ipns/")) { + return false } - intendedPath := ipath.New(strings.TrimPrefix(urlPath, "/ipfs")) + + // Attempt to fix the superflous namespace + intendedPath := ipath.New(strings.TrimPrefix(r.URL.Path, "/ipfs")) if err := intendedPath.IsValid(); err != nil { - return false // not a valid path + webError(w, "invalid ipfs path", err, http.StatusBadRequest) + return true } intendedURL := intendedPath.String() - if urlQuery != "" { + if r.URL.RawQuery != "" { // we render HTML, so ensure query entries are properly escaped - q, _ := url.ParseQuery(urlQuery) + q, _ := url.ParseQuery(r.URL.RawQuery) intendedURL = intendedURL + "?" + q.Encode() } // return HTTP 400 (Bad Request) with HTML error page that: // - points at correct canonical path via header // - displays human-readable error // - redirects to intendedURL after a short delay + w.WriteHeader(http.StatusBadRequest) - return redirectTemplate.Execute(w, redirectTemplateData{ + if err := redirectTemplate.Execute(w, redirectTemplateData{ RedirectURL: intendedURL, SuggestedPath: intendedPath.String(), - ErrorMsg: fmt.Sprintf("invalid path: %q should be %q", urlPath, intendedPath.String()), - }) == nil + ErrorMsg: fmt.Sprintf("invalid path: %q should be %q", r.URL.Path, intendedPath.String()), + }); err != nil { + webError(w, "failed to redirect when fixing superfluous namespace", err, http.StatusBadRequest) + } + + return true +} + +func (i *gatewayHandler) handleGettingFirstBlock(r *http.Request, begin time.Time, contentPath ipath.Path, resolvedPath ipath.Resolved) *requestError { + // Update the global metric of the time it takes to read the final root block of the requested resource + // NOTE: for legacy reasons this happens before we go into content-type specific code paths + _, err := i.api.Block().Get(r.Context(), resolvedPath) + if err != nil { + return newRequestError("ipfs block get "+resolvedPath.Cid().String(), err, http.StatusInternalServerError) + } + ns := contentPath.Namespace() + timeToGetFirstContentBlock := time.Since(begin).Seconds() + i.unixfsGetMetric.WithLabelValues(ns).Observe(timeToGetFirstContentBlock) // deprecated, use firstContentBlockGetMetric instead + i.firstContentBlockGetMetric.WithLabelValues(ns).Observe(timeToGetFirstContentBlock) + return nil +} + +func (i *gatewayHandler) setCommonHeaders(w http.ResponseWriter, r *http.Request, contentPath ipath.Path) *requestError { + i.addUserHeaders(w) // ok, _now_ write user's headers. + w.Header().Set("X-Ipfs-Path", contentPath.String()) + + if rootCids, err := i.buildIpfsRootsHeader(contentPath.String(), r); err == nil { + w.Header().Set("X-Ipfs-Roots", rootCids) + } else { // this should never happen, as we resolved the contentPath already + return newRequestError("error while resolving X-Ipfs-Roots", err, http.StatusInternalServerError) + } + + return nil } diff --git a/core/corehttp/gateway_handler_block.go b/core/corehttp/gateway_handler_block.go new file mode 100644 index 00000000000..8d6ce0f3686 --- /dev/null +++ b/core/corehttp/gateway_handler_block.go @@ -0,0 +1,50 @@ +package corehttp + +import ( + "bytes" + "context" + "io/ioutil" + "net/http" + "time" + + "github.com/ipfs/go-ipfs/tracing" + ipath "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +// serveRawBlock returns bytes behind a raw block +func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time) { + ctx, span := tracing.Span(ctx, "Gateway", "ServeRawBlock", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) + defer span.End() + blockCid := resolvedPath.Cid() + blockReader, err := i.api.Block().Get(ctx, resolvedPath) + if err != nil { + webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) + return + } + block, err := ioutil.ReadAll(blockReader) + if err != nil { + webError(w, "ipfs block get "+blockCid.String(), err, http.StatusInternalServerError) + return + } + content := bytes.NewReader(block) + + // Set Content-Disposition + name := blockCid.String() + ".bin" + setContentDispositionHeader(w, name, "attachment") + + // Set remaining headers + modtime := addCacheControlHeaders(w, r, contentPath, blockCid) + w.Header().Set("Content-Type", "application/vnd.ipld.raw") + w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) + + // ServeContent will take care of + // If-None-Match+Etag, Content-Length and range requests + _, dataSent, _ := ServeContent(w, r, name, modtime, content) + + if dataSent { + // Update metrics + i.rawBlockGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) + } +} diff --git a/core/corehttp/gateway_handler_car.go b/core/corehttp/gateway_handler_car.go new file mode 100644 index 00000000000..1958088706e --- /dev/null +++ b/core/corehttp/gateway_handler_car.go @@ -0,0 +1,92 @@ +package corehttp + +import ( + "context" + "fmt" + "net/http" + "time" + + blocks "github.com/ipfs/go-block-format" + cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-ipfs/tracing" + coreiface "github.com/ipfs/interface-go-ipfs-core" + ipath "github.com/ipfs/interface-go-ipfs-core/path" + gocar "github.com/ipld/go-car" + selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +// serveCAR returns a CAR stream for specific DAG+selector +func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, carVersion string, begin time.Time) { + ctx, span := tracing.Span(ctx, "Gateway", "ServeCAR", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) + defer span.End() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + switch carVersion { + case "": // noop, client does not care about version + case "1": // noop, we support this + default: + err := fmt.Errorf("only version=1 is supported") + webError(w, "unsupported CAR version", err, http.StatusBadRequest) + return + } + rootCid := resolvedPath.Cid() + + // Set Content-Disposition + name := rootCid.String() + ".car" + setContentDispositionHeader(w, name, "attachment") + + // Weak Etag W/ because we can't guarantee byte-for-byte identical responses + // (CAR is streamed, and in theory, blocks may arrive from datastore in non-deterministic order) + etag := `W/` + getEtag(r, rootCid) + w.Header().Set("Etag", etag) + + // Finish early if Etag match + if r.Header.Get("If-None-Match") == etag { + w.WriteHeader(http.StatusNotModified) + return + } + + // Make it clear we don't support range-requests over a car stream + // Partial downloads and resumes should be handled using + // IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 + w.Header().Set("Accept-Ranges", "none") + + // Explicit Cache-Control to ensure fresh stream on retry. + // CAR stream could be interrupted, and client should be able to resume and get full response, not the truncated one + w.Header().Set("Cache-Control", "no-cache, no-transform") + + w.Header().Set("Content-Type", "application/vnd.ipld.car; version=1") + w.Header().Set("X-Content-Type-Options", "nosniff") // no funny business in the browsers :^) + + // Same go-car settings as dag.export command + store := dagStore{dag: i.api.Dag(), ctx: ctx} + + // TODO: support selectors passed as request param: https://github.com/ipfs/go-ipfs/issues/8769 + dag := gocar.Dag{Root: rootCid, Selector: selectorparse.CommonSelector_ExploreAllRecursively} + car := gocar.NewSelectiveCar(ctx, store, []gocar.Dag{dag}, gocar.TraverseLinksOnlyOnce()) + + if err := car.Write(w); err != nil { + // We return error as a trailer, however it is not something browsers can access + // (https://github.com/mdn/browser-compat-data/issues/14703) + // Due to this, we suggest client always verify that + // the received CAR stream response is matching requested DAG selector + w.Header().Set("X-Stream-Error", err.Error()) + return + } + + // Update metrics + i.carStreamGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) +} + +type dagStore struct { + dag coreiface.APIDagService + ctx context.Context +} + +func (ds dagStore) Get(c cid.Cid) (blocks.Block, error) { + obj, err := ds.dag.Get(ds.ctx, c) + return obj, err +} diff --git a/core/corehttp/gateway_handler_unixfs.go b/core/corehttp/gateway_handler_unixfs.go new file mode 100644 index 00000000000..b318a641a09 --- /dev/null +++ b/core/corehttp/gateway_handler_unixfs.go @@ -0,0 +1,46 @@ +package corehttp + +import ( + "context" + "fmt" + "html" + "net/http" + "time" + + files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-ipfs/tracing" + ipath "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + "go.uber.org/zap" +) + +func (i *gatewayHandler) serveUnixFS(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) { + ctx, span := tracing.Span(ctx, "Gateway", "ServeUnixFS", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) + defer span.End() + + // Handling UnixFS + dr, err := i.api.Unixfs().Get(ctx, resolvedPath) + if err != nil { + webError(w, "ipfs cat "+html.EscapeString(contentPath.String()), err, http.StatusNotFound) + return + } + defer dr.Close() + + // Handling Unixfs file + if f, ok := dr.(files.File); ok { + logger.Debugw("serving unixfs file", "path", contentPath) + i.serveFile(ctx, w, r, resolvedPath, contentPath, f, begin) + return + } + + // Handling Unixfs directory + dir, ok := dr.(files.Directory) + if !ok { + internalWebError(w, fmt.Errorf("unsupported UnixFS type")) + return + } + + logger.Debugw("serving unixfs directory", "path", contentPath) + i.serveDirectory(ctx, w, r, resolvedPath, contentPath, dir, begin, logger) +} diff --git a/core/corehttp/gateway_handler_unixfs_dir.go b/core/corehttp/gateway_handler_unixfs_dir.go new file mode 100644 index 00000000000..1e059200a3b --- /dev/null +++ b/core/corehttp/gateway_handler_unixfs_dir.go @@ -0,0 +1,218 @@ +package corehttp + +import ( + "context" + "net/http" + "net/url" + gopath "path" + "strings" + "time" + + "github.com/dustin/go-humanize" + cid "github.com/ipfs/go-cid" + files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-ipfs/assets" + "github.com/ipfs/go-ipfs/tracing" + path "github.com/ipfs/go-path" + "github.com/ipfs/go-path/resolver" + options "github.com/ipfs/interface-go-ipfs-core/options" + ipath "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + "go.uber.org/zap" +) + +// serveDirectory returns the best representation of UnixFS directory +// +// It will return index.html if present, or generate directory listing otherwise. +func (i *gatewayHandler) serveDirectory(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, dir files.Directory, begin time.Time, logger *zap.SugaredLogger) { + ctx, span := tracing.Span(ctx, "Gateway", "ServeDirectory", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) + defer span.End() + + // HostnameOption might have constructed an IPNS/IPFS path using the Host header. + // In this case, we need the original path for constructing redirects + // and links that match the requested URL. + // For example, http://example.net would become /ipns/example.net, and + // the redirects and links would end up as http://example.net/ipns/example.net + requestURI, err := url.ParseRequestURI(r.RequestURI) + if err != nil { + webError(w, "failed to parse request path", err, http.StatusInternalServerError) + return + } + originalUrlPath := requestURI.Path + + // Check if directory has index.html, if so, serveFile + idxPath := ipath.Join(resolvedPath, "index.html") + idx, err := i.api.Unixfs().Get(ctx, idxPath) + switch err.(type) { + case nil: + cpath := contentPath.String() + dirwithoutslash := cpath[len(cpath)-1] != '/' + goget := r.URL.Query().Get("go-get") == "1" + if dirwithoutslash && !goget { + // See comment above where originalUrlPath is declared. + suffix := "/" + if r.URL.RawQuery != "" { + // preserve query parameters + suffix = suffix + "?" + r.URL.RawQuery + } + + redirectURL := originalUrlPath + suffix + logger.Debugw("serving index.html file", "to", redirectURL, "status", http.StatusFound, "path", idxPath) + http.Redirect(w, r, redirectURL, http.StatusFound) + return + } + + f, ok := idx.(files.File) + if !ok { + internalWebError(w, files.ErrNotReader) + return + } + + logger.Debugw("serving index.html file", "path", idxPath) + // write to request + i.serveFile(ctx, w, r, resolvedPath, idxPath, f, begin) + return + case resolver.ErrNoLink: + logger.Debugw("no index.html; noop", "path", idxPath) + default: + internalWebError(w, err) + return + } + + // See statusResponseWriter.WriteHeader + // and https://github.com/ipfs/go-ipfs/issues/7164 + // Note: this needs to occur before listingTemplate.Execute otherwise we get + // superfluous response.WriteHeader call from prometheus/client_golang + if w.Header().Get("Location") != "" { + logger.Debugw("location moved permanently", "status", http.StatusMovedPermanently) + w.WriteHeader(http.StatusMovedPermanently) + return + } + + // A HTML directory index will be presented, be sure to set the correct + // type instead of relying on autodetection (which may fail). + w.Header().Set("Content-Type", "text/html") + + // Generated dir index requires custom Etag (output may change between go-ipfs versions) + dirEtag := getDirListingEtag(resolvedPath.Cid()) + w.Header().Set("Etag", dirEtag) + + if r.Method == http.MethodHead { + logger.Debug("return as request's HTTP method is HEAD") + return + } + + // Optimization 1: + // List children without fetching their root blocks (fast, but no size info) + results, err := i.api.Unixfs().Ls(ctx, resolvedPath, options.Unixfs.ResolveChildren(false)) + if err != nil { + internalWebError(w, err) + return + } + + // storage for directory listing + dirListing := make([]directoryItem, 0, len(results)) + + for link := range results { + if link.Err != nil { + internalWebError(w, err) + return + } + hash := link.Cid.String() + di := directoryItem{ + Size: "", // no size because we did not fetch child nodes + Name: link.Name, + Path: gopath.Join(originalUrlPath, link.Name), + Hash: hash, + ShortHash: shortHash(hash), + } + dirListing = append(dirListing, di) + } + + // Optimization 2: fetch sizes only for dirs below FastDirIndexThreshold + if len(dirListing) < i.config.FastDirIndexThreshold { + dirit := dir.Entries() + linkNo := 0 + for dirit.Next() { + size := "?" + if s, err := dirit.Node().Size(); err == nil { + // Size may not be defined/supported. Continue anyways. + size = humanize.Bytes(uint64(s)) + } + dirListing[linkNo].Size = size + linkNo++ + } + } + + // construct the correct back link + // https://github.com/ipfs/go-ipfs/issues/1365 + var backLink string = originalUrlPath + + // don't go further up than /ipfs/$hash/ + pathSplit := path.SplitList(contentPath.String()) + switch { + // keep backlink + case len(pathSplit) == 3: // url: /ipfs/$hash + + // keep backlink + case len(pathSplit) == 4 && pathSplit[3] == "": // url: /ipfs/$hash/ + + // add the correct link depending on whether the path ends with a slash + default: + if strings.HasSuffix(backLink, "/") { + backLink += "./.." + } else { + backLink += "/.." + } + } + + size := "?" + if s, err := dir.Size(); err == nil { + // Size may not be defined/supported. Continue anyways. + size = humanize.Bytes(uint64(s)) + } + + hash := resolvedPath.Cid().String() + + // Gateway root URL to be used when linking to other rootIDs. + // This will be blank unless subdomain or DNSLink resolution is being used + // for this request. + var gwURL string + + // Get gateway hostname and build gateway URL. + if h, ok := r.Context().Value("gw-hostname").(string); ok { + gwURL = "//" + h + } else { + gwURL = "" + } + + dnslink := hasDNSLinkOrigin(gwURL, contentPath.String()) + + // See comment above where originalUrlPath is declared. + tplData := listingTemplateData{ + GatewayURL: gwURL, + DNSLink: dnslink, + Listing: dirListing, + Size: size, + Path: contentPath.String(), + Breadcrumbs: breadcrumbs(contentPath.String(), dnslink), + BackLink: backLink, + Hash: hash, + FastDirIndexThreshold: i.config.FastDirIndexThreshold, + } + + logger.Debugw("request processed", "tplDataDNSLink", dnslink, "tplDataSize", size, "tplDataBackLink", backLink, "tplDataHash", hash) + + if err := listingTemplate.Execute(w, tplData); err != nil { + internalWebError(w, err) + return + } + + // Update metrics + i.unixfsGenDirGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) +} + +func getDirListingEtag(dirCid cid.Cid) string { + return `"DirIndex-` + assets.AssetHash + `_CID-` + dirCid.String() + `"` +} diff --git a/core/corehttp/gateway_handler_unixfs_file.go b/core/corehttp/gateway_handler_unixfs_file.go new file mode 100644 index 00000000000..1852705fd08 --- /dev/null +++ b/core/corehttp/gateway_handler_unixfs_file.go @@ -0,0 +1,95 @@ +package corehttp + +import ( + "context" + "fmt" + "io" + "mime" + "net/http" + gopath "path" + "strings" + "time" + + "github.com/gabriel-vasile/mimetype" + files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-ipfs/tracing" + ipath "github.com/ipfs/interface-go-ipfs-core/path" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +// serveFile returns data behind a file along with HTTP headers based on +// the file itself, its CID and the contentPath used for accessing it. +func (i *gatewayHandler) serveFile(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, file files.File, begin time.Time) { + _, span := tracing.Span(ctx, "Gateway", "ServeFile", trace.WithAttributes(attribute.String("path", resolvedPath.String()))) + defer span.End() + + // Set Cache-Control and read optional Last-Modified time + modtime := addCacheControlHeaders(w, r, contentPath, resolvedPath.Cid()) + + // Set Content-Disposition + name := addContentDispositionHeader(w, r, contentPath) + + // Prepare size value for Content-Length HTTP header (set inside of http.ServeContent) + size, err := file.Size() + if err != nil { + http.Error(w, "cannot serve files with unknown sizes", http.StatusBadGateway) + return + } + + // Lazy seeker enables efficient range-requests and HTTP HEAD responses + content := &lazySeeker{ + size: size, + reader: file, + } + + // Calculate deterministic value for Content-Type HTTP header + // (we prefer to do it here, rather than using implicit sniffing in http.ServeContent) + var ctype string + if _, isSymlink := file.(*files.Symlink); isSymlink { + // We should be smarter about resolving symlinks but this is the + // "most correct" we can be without doing that. + ctype = "inode/symlink" + } else { + ctype = mime.TypeByExtension(gopath.Ext(name)) + if ctype == "" { + // uses https://github.com/gabriel-vasile/mimetype library to determine the content type. + // Fixes https://github.com/ipfs/go-ipfs/issues/7252 + mimeType, err := mimetype.DetectReader(content) + if err != nil { + http.Error(w, fmt.Sprintf("cannot detect content-type: %s", err.Error()), http.StatusInternalServerError) + return + } + + ctype = mimeType.String() + _, err = content.Seek(0, io.SeekStart) + if err != nil { + http.Error(w, "seeker can't seek", http.StatusInternalServerError) + return + } + } + // Strip the encoding from the HTML Content-Type header and let the + // browser figure it out. + // + // Fixes https://github.com/ipfs/go-ipfs/issues/2203 + if strings.HasPrefix(ctype, "text/html;") { + ctype = "text/html" + } + } + // Setting explicit Content-Type to avoid mime-type sniffing on the client + // (unifies behavior across gateways and web browsers) + w.Header().Set("Content-Type", ctype) + + // special fixup around redirects + w = &statusResponseWriter{w} + + // ServeContent will take care of + // If-None-Match+Etag, Content-Length and range requests + _, dataSent, _ := ServeContent(w, r, name, modtime, content) + + // Was response successful? + if dataSent { + // Update metrics + i.unixfsFileGetMetric.WithLabelValues(contentPath.Namespace()).Observe(time.Since(begin).Seconds()) + } +} diff --git a/core/corehttp/gateway_indexPage.go b/core/corehttp/gateway_indexPage.go index 3bee4822bb4..6cc548cdc4d 100644 --- a/core/corehttp/gateway_indexPage.go +++ b/core/corehttp/gateway_indexPage.go @@ -12,14 +12,15 @@ import ( // structs for directory listing type listingTemplateData struct { - GatewayURL string - DNSLink bool - Listing []directoryItem - Size string - Path string - Breadcrumbs []breadcrumb - BackLink string - Hash string + GatewayURL string + DNSLink bool + Listing []directoryItem + Size string + Path string + Breadcrumbs []breadcrumb + BackLink string + Hash string + FastDirIndexThreshold int } type directoryItem struct { @@ -94,7 +95,7 @@ func hasDNSLinkOrigin(gwURL string, path string) bool { var listingTemplate *template.Template func init() { - knownIconsBytes, err := assets.Asset("dir-index-html/knownIcons.txt") + knownIconsBytes, err := assets.Asset.ReadFile("dir-index-html/knownIcons.txt") if err != nil { panic(err) } @@ -121,7 +122,7 @@ func init() { } // Directory listing template - dirIndexBytes, err := assets.Asset("dir-index-html/dir-index.html") + dirIndexBytes, err := assets.Asset.ReadFile("dir-index-html/dir-index.html") if err != nil { panic(err) } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 8cccde0e22a..303e4a1ac11 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -19,8 +19,8 @@ import ( datastore "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" + config "github.com/ipfs/go-ipfs/config" path "github.com/ipfs/go-path" iface "github.com/ipfs/interface-go-ipfs-core" nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" @@ -126,12 +126,6 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface t.Fatal(err) } - cfg, err := n.Repo.Config() - if err != nil { - t.Fatal(err) - } - cfg.Gateway.PathPrefixes = []string{"/good-prefix"} - // need this variable here since we need to construct handler with // listener, and server with handler. yay cycles. dh := &delegatedHandler{} @@ -242,7 +236,7 @@ func TestGatewayGet(t *testing.T) { {"127.0.0.1:8080", "/" + k.Cid().String(), http.StatusNotFound, "404 page not found\n"}, {"127.0.0.1:8080", k.String(), http.StatusOK, "fnord"}, {"127.0.0.1:8080", "/ipns/nxdomain.example.com", http.StatusNotFound, "ipfs resolve -r /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"}, - {"127.0.0.1:8080", "/ipns/%0D%0A%0D%0Ahello", http.StatusNotFound, "ipfs resolve -r /ipns/%0D%0A%0D%0Ahello: " + namesys.ErrResolveFailed.Error() + "\n"}, + {"127.0.0.1:8080", "/ipns/%0D%0A%0D%0Ahello", http.StatusNotFound, "ipfs resolve -r /ipns/\\r\\n\\r\\nhello: " + namesys.ErrResolveFailed.Error() + "\n"}, {"127.0.0.1:8080", "/ipns/example.com", http.StatusOK, "fnord"}, {"example.com", "/", http.StatusOK, "fnord"}, @@ -403,7 +397,6 @@ func TestIPNSHostnameRedirect(t *testing.T) { t.Fatal(err) } req.Host = "example.net" - req.Header.Set("X-Ipfs-Gateway-Prefix", "/good-prefix") res, err = doWithoutRedirect(req) if err != nil { @@ -417,8 +410,8 @@ func TestIPNSHostnameRedirect(t *testing.T) { hdr = res.Header["Location"] if len(hdr) < 1 { t.Errorf("location header not present") - } else if hdr[0] != "/good-prefix/foo/" { - t.Errorf("location header is %v, expected /good-prefix/foo/", hdr[0]) + } else if hdr[0] != "/foo/" { + t.Errorf("location header is %v, expected /foo/", hdr[0]) } // make sure /version isn't exposed @@ -427,7 +420,6 @@ func TestIPNSHostnameRedirect(t *testing.T) { t.Fatal(err) } req.Host = "example.net" - req.Header.Set("X-Ipfs-Gateway-Prefix", "/good-prefix") res, err = doWithoutRedirect(req) if err != nil { @@ -583,82 +575,6 @@ func TestIPNSHostnameBacklinks(t *testing.T) { if !strings.Contains(s, k3.Cid().String()) { t.Fatalf("expected hash in directory listing") } - - // make request to directory listing with prefix - req, err = http.NewRequest(http.MethodGet, ts.URL, nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - req.Header.Set("X-Ipfs-Gateway-Prefix", "/good-prefix") - - res, err = doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - // expect correct backlinks with prefix - body, err = ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("error reading response: %s", err) - } - s = string(body) - t.Logf("body: %s\n", string(body)) - - if !matchPathOrBreadcrumbs(s, "/ipns/example.net") { - t.Fatalf("expected a path in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected backlink in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected file in directory listing") - } - if !strings.Contains(s, k.Cid().String()) { - t.Fatalf("expected hash in directory listing") - } - - // make request to directory listing with illegal prefix - req, err = http.NewRequest(http.MethodGet, ts.URL, nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - req.Header.Set("X-Ipfs-Gateway-Prefix", "/bad-prefix") - - // make request to directory listing with evil prefix - req, err = http.NewRequest(http.MethodGet, ts.URL, nil) - if err != nil { - t.Fatal(err) - } - req.Host = "example.net" - req.Header.Set("X-Ipfs-Gateway-Prefix", "//good-prefix/foo") - - res, err = doWithoutRedirect(req) - if err != nil { - t.Fatal(err) - } - - // expect correct backlinks without illegal prefix - body, err = ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("error reading response: %s", err) - } - s = string(body) - t.Logf("body: %s\n", string(body)) - - if !matchPathOrBreadcrumbs(s, "/") { - t.Fatalf("expected a path in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected backlink in directory listing") - } - if !strings.Contains(s, "") { - t.Fatalf("expected file in directory listing") - } - if !strings.Contains(s, k.Cid().String()) { - t.Fatalf("expected hash in directory listing") - } } func TestCacheControlImmutable(t *testing.T) { @@ -740,3 +656,28 @@ func TestVersion(t *testing.T) { t.Fatalf("response doesn't contain protocol version:\n%s", s) } } + +func TestEtagMatch(t *testing.T) { + for _, test := range []struct { + header string // value in If-None-Match HTTP header + cidEtag string + dirEtag string + expected bool // expected result of etagMatch(header, cidEtag, dirEtag) + }{ + {"", `"etag"`, "", false}, // no If-None-Match + {"", "", `"etag"`, false}, // no If-None-Match + {`"etag"`, `"etag"`, "", true}, // file etag match + {`W/"etag"`, `"etag"`, "", true}, // file etag match + {`"foo", W/"bar", W/"etag"`, `"etag"`, "", true}, // file etag match (array) + {`"foo",W/"bar",W/"etag"`, `"etag"`, "", true}, // file etag match (compact array) + {`"etag"`, "", `W/"etag"`, true}, // dir etag match + {`"etag"`, "", `W/"etag"`, true}, // dir etag match + {`W/"etag"`, "", `W/"etag"`, true}, // dir etag match + {`*`, `"etag"`, "", true}, // wildcard etag match + } { + result := etagMatch(test.header, test.cidEtag, test.dirEtag) + if result != test.expected { + t.Fatalf("unexpected result of etagMatch(%q, %q, %q), got %t, expected %t", test.header, test.cidEtag, test.dirEtag, result, test.expected) + } + } +} diff --git a/core/corehttp/hostname.go b/core/corehttp/hostname.go index 57c2c2191a6..93dde67ab28 100644 --- a/core/corehttp/hostname.go +++ b/core/corehttp/hostname.go @@ -18,7 +18,7 @@ import ( mbase "github.com/multiformats/go-multibase" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" iface "github.com/ipfs/interface-go-ipfs-core" options "github.com/ipfs/interface-go-ipfs-core/options" nsopts "github.com/ipfs/interface-go-ipfs-core/options/namesys" @@ -249,6 +249,7 @@ func withHostnameContext(r *http.Request, hostname string) *http.Request { // on subdomain and dnslink gateways. While DNSlink could read value from // Host header, subdomain gateways have more comples rules (knownSubdomainDetails) // More: https://github.com/ipfs/dir-index-html/issues/42 + // nolint: staticcheck // non-backward compatible change ctx := context.WithValue(r.Context(), "gw-hostname", hostname) return r.WithContext(ctx) } diff --git a/core/corehttp/hostname_test.go b/core/corehttp/hostname_test.go index f7ba89a8c9b..df0f4f22971 100644 --- a/core/corehttp/hostname_test.go +++ b/core/corehttp/hostname_test.go @@ -7,8 +7,8 @@ import ( "testing" cid "github.com/ipfs/go-cid" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" + config "github.com/ipfs/go-ipfs/config" coreapi "github.com/ipfs/go-ipfs/core/coreapi" path "github.com/ipfs/go-path" ) diff --git a/core/corehttp/mutex_profile.go b/core/corehttp/mutex_profile.go index fbb23340d00..a8265326c5e 100644 --- a/core/corehttp/mutex_profile.go +++ b/core/corehttp/mutex_profile.go @@ -41,3 +41,38 @@ func MutexFractionOption(path string) ServeOption { return mux, nil } } + +// BlockProfileRateOption allows to set runtime.SetBlockProfileRate via HTTP +// using POST request with parameter 'rate'. +// The profiler tries to sample 1 event every nanoseconds. +// If rate == 1, then the profiler samples every blocking event. +// To disable, set rate = 0. +func BlockProfileRateOption(path string) ServeOption { + return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) + return + } + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + rateStr := r.Form.Get("rate") + if len(rateStr) == 0 { + http.Error(w, "parameter 'rate' must be set", http.StatusBadRequest) + return + } + + rate, err := strconv.Atoi(rateStr) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + log.Infof("Setting BlockProfileRate to %d", rate) + runtime.SetBlockProfileRate(rate) + }) + return mux, nil + } +} diff --git a/core/corehttp/webui.go b/core/corehttp/webui.go index 72656751a95..0ed60f760db 100644 --- a/core/corehttp/webui.go +++ b/core/corehttp/webui.go @@ -1,11 +1,12 @@ package corehttp // TODO: move to IPNS -const WebUIPath = "/ipfs/bafybeihcyruaeza7uyjd6ugicbcrqumejf6uf353e5etdkhotqffwtguva" // v2.13.0 +const WebUIPath = "/ipfs/bafybeiednzu62vskme5wpoj4bjjikeg3xovfpp4t7vxk5ty2jxdi4mv4bu" // v2.15.0 // this is a list of all past webUI paths. var WebUIPaths = []string{ WebUIPath, + "/ipfs/bafybeihcyruaeza7uyjd6ugicbcrqumejf6uf353e5etdkhotqffwtguva", "/ipfs/bafybeiflkjt66aetfgcrgvv75izymd5kc47g6luepqmfq6zsf5w6ueth6y", "/ipfs/bafybeid26vjplsejg7t3nrh7mxmiaaxriebbm4xxrxxdunlk7o337m5sqq", "/ipfs/bafybeif4zkmu7qdhkpf3pnhwxipylqleof7rl6ojbe7mq3fzogz6m4xk3i", diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 387a977784d..a0079b9eb07 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -14,6 +14,7 @@ import ( files "github.com/ipfs/go-ipfs-files" pin "github.com/ipfs/go-ipfs-pinner" posinfo "github.com/ipfs/go-ipfs-posinfo" + "github.com/ipfs/go-ipfs/tracing" ipld "github.com/ipfs/go-ipld-format" logging "github.com/ipfs/go-log" dag "github.com/ipfs/go-merkledag" @@ -158,20 +159,23 @@ func (adder *Adder) curRootNode() (ipld.Node, error) { // Recursively pins the root node of Adder and // writes the pin state to the backing datastore. -func (adder *Adder) PinRoot(root ipld.Node) error { +func (adder *Adder) PinRoot(ctx context.Context, root ipld.Node) error { + ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "PinRoot") + defer span.End() + if !adder.Pin { return nil } rnk := root.Cid() - err := adder.dagService.Add(adder.ctx, root) + err := adder.dagService.Add(ctx, root) if err != nil { return err } if adder.tempRoot.Defined() { - err := adder.pinning.Unpin(adder.ctx, adder.tempRoot, true) + err := adder.pinning.Unpin(ctx, adder.tempRoot, true) if err != nil { return err } @@ -179,7 +183,7 @@ func (adder *Adder) PinRoot(root ipld.Node) error { } adder.pinning.PinWithMode(rnk, pin.Recursive) - return adder.pinning.Flush(adder.ctx) + return adder.pinning.Flush(ctx) } func (adder *Adder) outputDirs(path string, fsn mfs.FSNode) error { @@ -255,6 +259,9 @@ func (adder *Adder) addNode(node ipld.Node, path string) error { // AddAllAndPin adds the given request's files and pin them. func (adder *Adder) AddAllAndPin(ctx context.Context, file files.Node) (ipld.Node, error) { + ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "AddAllAndPin") + defer span.End() + if adder.Pin { adder.unlocker = adder.gcLocker.PinLock(ctx) } @@ -330,10 +337,13 @@ func (adder *Adder) AddAllAndPin(ctx context.Context, file files.Node) (ipld.Nod if !adder.Pin { return nd, nil } - return nd, adder.PinRoot(nd) + return nd, adder.PinRoot(ctx, nd) } func (adder *Adder) addFileNode(ctx context.Context, path string, file files.Node, toplevel bool) error { + ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "AddFileNode") + defer span.End() + defer file.Close() err := adder.maybePauseForGC(ctx) @@ -436,13 +446,16 @@ func (adder *Adder) addDir(ctx context.Context, path string, dir files.Directory } func (adder *Adder) maybePauseForGC(ctx context.Context) error { + ctx, span := tracing.Span(ctx, "CoreUnix.Adder", "MaybePauseForGC") + defer span.End() + if adder.unlocker != nil && adder.gcLocker.GCRequested(ctx) { rn, err := adder.curRootNode() if err != nil { return err } - err = adder.PinRoot(rn) + err = adder.PinRoot(ctx, rn) if err != nil { return err } diff --git a/core/coreunix/add_test.go b/core/coreunix/add_test.go index 7dd2b0cec65..de326559c3f 100644 --- a/core/coreunix/add_test.go +++ b/core/coreunix/add_test.go @@ -21,9 +21,9 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" blockstore "github.com/ipfs/go-ipfs-blockstore" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" pi "github.com/ipfs/go-ipfs-posinfo" + config "github.com/ipfs/go-ipfs/config" dag "github.com/ipfs/go-merkledag" coreiface "github.com/ipfs/interface-go-ipfs-core" ) diff --git a/core/mock/mock.go b/core/mock/mock.go index d0a5cd7f65c..0b34857f2b6 100644 --- a/core/mock/mock.go +++ b/core/mock/mock.go @@ -13,7 +13,7 @@ import ( "github.com/ipfs/go-datastore" syncds "github.com/ipfs/go-datastore/sync" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p-core/host" @@ -26,12 +26,10 @@ import ( // NewMockNode constructs an IpfsNode for use in tests. func NewMockNode() (*core.IpfsNode, error) { - ctx := context.Background() - // effectively offline, only peer in its network - return core.NewNode(ctx, &core.BuildCfg{ + return core.NewNode(context.Background(), &core.BuildCfg{ Online: true, - Host: MockHostOption(mocknet.New(ctx)), + Host: MockHostOption(mocknet.New()), }) } @@ -69,9 +67,6 @@ func MockCmdsCtx() (commands.Context, error) { return commands.Context{ ConfigRoot: "/tmp/.mockipfsconfig", - LoadConfig: func(path string) (*config.Config, error) { - return &conf, nil - }, ConstructNode: func() (*core.IpfsNode, error) { return node, nil }, diff --git a/core/node/bitswap.go b/core/node/bitswap.go index a2548ab3ce6..44698f92123 100644 --- a/core/node/bitswap.go +++ b/core/node/bitswap.go @@ -6,8 +6,8 @@ import ( "github.com/ipfs/go-bitswap" "github.com/ipfs/go-bitswap/network" blockstore "github.com/ipfs/go-ipfs-blockstore" - config "github.com/ipfs/go-ipfs-config" exchange "github.com/ipfs/go-ipfs-exchange-interface" + config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/routing" "go.uber.org/fx" diff --git a/core/node/builder.go b/core/node/builder.go index 803caf51885..689f151b17a 100644 --- a/core/node/builder.go +++ b/core/node/builder.go @@ -14,7 +14,7 @@ import ( ds "github.com/ipfs/go-datastore" dsync "github.com/ipfs/go-datastore/sync" - cfg "github.com/ipfs/go-ipfs-config" + cfg "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p-core/crypto" peer "github.com/libp2p/go-libp2p-core/peer" ) diff --git a/core/node/dns.go b/core/node/dns.go index e49a93ac157..2fc6327635c 100644 --- a/core/node/dns.go +++ b/core/node/dns.go @@ -2,9 +2,11 @@ package node import ( "fmt" + "math" "strings" + "time" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" doh "github.com/libp2p/go-doh-resolver" madns "github.com/multiformats/go-multiaddr-dns" @@ -16,18 +18,23 @@ var defaultResolvers = map[string]string{ "crypto.": "https://resolver.cloudflare-eth.com/dns-query", } -func newResolver(url string) (madns.BasicResolver, error) { +func newResolver(url string, opts ...doh.Option) (madns.BasicResolver, error) { if !strings.HasPrefix(url, "https://") { return nil, fmt.Errorf("invalid resolver url: %s", url) } - return doh.NewResolver(url), nil + return doh.NewResolver(url, opts...) } func DNSResolver(cfg *config.Config) (*madns.Resolver, error) { var opts []madns.Option var err error + var dohOpts []doh.Option + if !cfg.DNS.MaxCacheTTL.IsDefault() { + dohOpts = append(dohOpts, doh.WithMaxCacheTTL(cfg.DNS.MaxCacheTTL.WithDefault(time.Duration(math.MaxUint32)*time.Second))) + } + domains := make(map[string]struct{}) // to track overridden default resolvers rslvrs := make(map[string]madns.BasicResolver) // to reuse resolvers for the same URL @@ -44,7 +51,7 @@ func DNSResolver(cfg *config.Config) (*madns.Resolver, error) { rslv, ok := rslvrs[url] if !ok { - rslv, err = newResolver(url) + rslv, err = newResolver(url, dohOpts...) if err != nil { return nil, fmt.Errorf("bad resolver for %s: %w", domain, err) } diff --git a/core/node/groups.go b/core/node/groups.go index 80367156e55..007d2a76eb2 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -7,8 +7,8 @@ import ( "time" blockstore "github.com/ipfs/go-ipfs-blockstore" - config "github.com/ipfs/go-ipfs-config" util "github.com/ipfs/go-ipfs-util" + "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p-core/peer" pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -111,50 +111,57 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { autonat = fx.Provide(libp2p.AutoNATService(cfg.AutoNAT.Throttle)) } - // If `cfg.Swarm.DisableRelay` is set and `Network.RelayTransport` isn't, use the former. - enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(!cfg.Swarm.DisableRelay) //nolint + enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(true) // nolint + enableRelayService := cfg.Swarm.RelayService.Enabled.WithDefault(enableRelayTransport) + enableRelayClient := cfg.Swarm.RelayClient.Enabled.WithDefault(enableRelayTransport) - // Warn about a deprecated option. - //nolint - if cfg.Swarm.DisableRelay { - logger.Error("The 'Swarm.DisableRelay' config field is deprecated.") - if enableRelayTransport { - logger.Error("'Swarm.DisableRelay' has been overridden by 'Swarm.Transports.Network.Relay'") - } else { - logger.Error("Use the 'Swarm.Transports.Network.Relay' config field instead") + // Log error when relay subsystem could not be initialized due to missing dependency + if !enableRelayTransport { + if enableRelayService { + logger.Fatal("Failed to enable `Swarm.RelayService`, it requires `Swarm.Transports.Network.Relay` to be true.") + } + if enableRelayClient { + logger.Fatal("Failed to enable `Swarm.RelayClient`, it requires `Swarm.Transports.Network.Relay` to be true.") } } - //nolint + + // Force users to migrate old config. + // nolint + if cfg.Swarm.DisableRelay { + logger.Fatal("The 'Swarm.DisableRelay' config field was removed." + + "Use the 'Swarm.Transports.Network.Relay' instead.") + } + // nolint if cfg.Swarm.EnableAutoRelay { - logger.Error("The 'Swarm.EnableAutoRelay' config field is deprecated.") - if cfg.Swarm.RelayClient.Enabled == config.Default { - logger.Error("Use the 'Swarm.AutoRelay.Enabled' config field instead") - } else { - logger.Error("'Swarm.EnableAutoRelay' has been overridden by 'Swarm.AutoRelay.Enabled'") - } + logger.Fatal("The 'Swarm.EnableAutoRelay' config field was removed." + + "Use the 'Swarm.RelayClient.Enabled' instead.") } - //nolint + // nolint if cfg.Swarm.EnableRelayHop { - logger.Fatal("The `Swarm.EnableRelayHop` config field is ignored.\n" + + logger.Fatal("The `Swarm.EnableRelayHop` config field was removed.\n" + "Use `Swarm.RelayService` to configure the circuit v2 relay.\n" + - "If you want to continue running a circuit v1 relay, please use the standalone relay daemon: https://github.com/libp2p/go-libp2p-relay-daemon (with RelayV1.Enabled: true)") + "If you want to continue running a circuit v1 relay, please use the standalone relay daemon: https://dist.ipfs.io/#libp2p-relay-daemon (with RelayV1.Enabled: true)") } + peerChan := make(libp2p.AddrInfoChan) // Gather all the options opts := fx.Options( BaseLibP2P, + fx.Supply(peerChan), + + // Services (resource management) + fx.Provide(libp2p.ResourceManager(cfg.Swarm)), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)), fx.Provide(libp2p.RelayTransport(enableRelayTransport)), - fx.Provide(libp2p.RelayService(cfg.Swarm.RelayService.Enabled.WithDefault(true), cfg.Swarm.RelayService)), + fx.Provide(libp2p.RelayService(enableRelayService, cfg.Swarm.RelayService)), fx.Provide(libp2p.Transports(cfg.Swarm.Transports)), fx.Invoke(libp2p.StartListening(cfg.Addresses.Swarm)), fx.Invoke(libp2p.SetupDiscovery(cfg.Discovery.MDNS.Enabled, cfg.Discovery.MDNS.Interval)), fx.Provide(libp2p.ForceReachability(cfg.Internal.Libp2pForceReachability)), - fx.Provide(libp2p.StaticRelays(cfg.Swarm.RelayClient.StaticRelays)), - fx.Provide(libp2p.HolePunching(cfg.Swarm.EnableHolePunching, cfg.Swarm.RelayClient.Enabled.WithDefault(false))), + fx.Provide(libp2p.HolePunching(cfg.Swarm.EnableHolePunching, enableRelayClient)), fx.Provide(libp2p.Security(!bcfg.DisableEncryptedConnections, cfg.Swarm.Transports)), @@ -164,7 +171,8 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { maybeProvide(libp2p.BandwidthCounter, !cfg.Swarm.DisableBandwidthMetrics), maybeProvide(libp2p.NatPortMap, !cfg.Swarm.DisableNatPortMap), - maybeProvide(libp2p.AutoRelay(len(cfg.Swarm.RelayClient.StaticRelays) == 0), cfg.Swarm.RelayClient.Enabled.WithDefault(false)), + maybeProvide(libp2p.AutoRelay(cfg.Swarm.RelayClient.StaticRelays, peerChan), enableRelayClient), + maybeInvoke(libp2p.AutoRelayFeeder(cfg.Peering), enableRelayClient), autonat, connmgr, ps, diff --git a/core/node/libp2p/discovery.go b/core/node/libp2p/discovery.go index 64860ce5c66..dbc2b0beaad 100644 --- a/core/node/libp2p/discovery.go +++ b/core/node/libp2p/discovery.go @@ -42,7 +42,8 @@ func SetupDiscovery(useMdns bool, mdnsInterval int) func(helpers.MetricsCtx, fx. if useMdns { service := mdns.NewMdnsService(host, mdns.ServiceName, handler) if err := service.Start(); err != nil { - return err + log.Error("error starting mdns service: ", err) + return nil } if mdnsInterval == 0 { diff --git a/core/node/libp2p/libp2p.go b/core/node/libp2p/libp2p.go index 3659b3c6179..59e9a37d4df 100644 --- a/core/node/libp2p/libp2p.go +++ b/core/node/libp2p/libp2p.go @@ -6,14 +6,14 @@ import ( "time" version "github.com/ipfs/go-ipfs" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" logging "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p" - connmgr "github.com/libp2p/go-libp2p-connmgr" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/p2p/net/connmgr" "go.uber.org/fx" ) @@ -30,7 +30,10 @@ var UserAgent = simpleOpt(libp2p.UserAgent(version.GetUserAgentVersion())) func ConnectionManager(low, high int, grace time.Duration) func() (opts Libp2pOpts, err error) { return func() (opts Libp2pOpts, err error) { - cm := connmgr.NewConnManager(low, high, grace) + cm, err := connmgr.NewConnManager(low, high, connmgr.WithGracePeriod(grace)) + if err != nil { + return opts, err + } opts.Opts = append(opts.Opts, libp2p.ConnectionManager(cm)) return } @@ -58,7 +61,7 @@ type priorityOption struct { func prioritizeOptions(opts []priorityOption) libp2p.Option { type popt struct { - priority int64 + priority int64 // lower priority values mean higher priority opt libp2p.Option } enabledOptions := make([]popt, 0, len(opts)) @@ -71,7 +74,7 @@ func prioritizeOptions(opts []priorityOption) libp2p.Option { } } sort.Slice(enabledOptions, func(i, j int) bool { - return enabledOptions[i].priority > enabledOptions[j].priority + return enabledOptions[i].priority < enabledOptions[j].priority }) p2pOpts := make([]libp2p.Option, len(enabledOptions)) for i, opt := range enabledOptions { diff --git a/core/node/libp2p/libp2p_test.go b/core/node/libp2p/libp2p_test.go new file mode 100644 index 00000000000..fa949130384 --- /dev/null +++ b/core/node/libp2p/libp2p_test.go @@ -0,0 +1,58 @@ +package libp2p + +import ( + "fmt" + "strconv" + "testing" + + "github.com/libp2p/go-libp2p" + ma "github.com/multiformats/go-multiaddr" + + "github.com/stretchr/testify/require" +) + +func TestPrioritize(t *testing.T) { + // The option is encoded into the port number of a TCP multiaddr. + // By extracting the port numbers obtained from the applied option, we can make sure that + // prioritization sorted the options correctly. + newOption := func(num int) libp2p.Option { + return func(cfg *libp2p.Config) error { + cfg.ListenAddrs = append(cfg.ListenAddrs, ma.StringCast(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", num))) + return nil + } + } + + extractNums := func(cfg *libp2p.Config) []int { + addrs := cfg.ListenAddrs + nums := make([]int, 0, len(addrs)) + for _, addr := range addrs { + _, comp := ma.SplitLast(addr) + num, err := strconv.Atoi(comp.Value()) + require.NoError(t, err) + nums = append(nums, num) + } + return nums + } + + t.Run("using default priorities", func(t *testing.T) { + opts := []priorityOption{ + {defaultPriority: 200, opt: newOption(200)}, + {defaultPriority: 1, opt: newOption(1)}, + {defaultPriority: 300, opt: newOption(300)}, + } + var cfg libp2p.Config + require.NoError(t, prioritizeOptions(opts)(&cfg)) + require.Equal(t, extractNums(&cfg), []int{1, 200, 300}) + }) + + t.Run("using custom priorities", func(t *testing.T) { + opts := []priorityOption{ + {defaultPriority: 200, priority: 1, opt: newOption(1)}, + {defaultPriority: 1, priority: 300, opt: newOption(300)}, + {defaultPriority: 300, priority: 20, opt: newOption(20)}, + } + var cfg libp2p.Config + require.NoError(t, prioritizeOptions(opts)(&cfg)) + require.Equal(t, extractNums(&cfg), []int{1, 20, 300}) + }) +} diff --git a/core/node/libp2p/nat.go b/core/node/libp2p/nat.go index ce0ca345f70..28560662d2c 100644 --- a/core/node/libp2p/nat.go +++ b/core/node/libp2p/nat.go @@ -3,7 +3,7 @@ package libp2p import ( "time" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p" ) diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go new file mode 100644 index 00000000000..c6a4a5f4866 --- /dev/null +++ b/core/node/libp2p/rcmgr.go @@ -0,0 +1,408 @@ +package libp2p + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/benbjohnson/clock" + config "github.com/ipfs/go-ipfs/config" + "github.com/ipfs/go-ipfs/core/node/helpers" + "github.com/ipfs/go-ipfs/repo" + logging "github.com/ipfs/go-log/v2" + "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + + "go.uber.org/fx" +) + +const NetLimitDefaultFilename = "limit.json" +const NetLimitTraceFilename = "rcmgr.json.gz" + +var NoResourceMgrError = fmt.Errorf("missing ResourceMgr: make sure the daemon is running with Swarm.ResourceMgr.Enabled") + +func ResourceManager(cfg config.SwarmConfig) interface{} { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, repo repo.Repo) (network.ResourceManager, Libp2pOpts, error) { + var manager network.ResourceManager + var opts Libp2pOpts + + enabled := cfg.ResourceMgr.Enabled.WithDefault(false) + + /// ENV overrides Config (if present) + switch os.Getenv("LIBP2P_RCMGR") { + case "0", "false": + enabled = false + case "1", "true": + enabled = true + } + + if enabled { + log.Debug("libp2p resource manager is enabled") + + repoPath, err := config.PathRoot() + if err != nil { + return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err) + } + + defaultLimits := adjustedDefaultLimits(cfg) + + var limits rcmgr.BasicLimiterConfig + if cfg.ResourceMgr.Limits != nil { + limits = *cfg.ResourceMgr.Limits + } + + limiter, err := rcmgr.NewLimiter(limits, defaultLimits) + if err != nil { + return nil, opts, err + } + + libp2p.SetDefaultServiceLimits(limiter) + + ropts := []rcmgr.Option{rcmgr.WithMetrics(createRcmgrMetrics())} + + if os.Getenv("LIBP2P_DEBUG_RCMGR") != "" { + traceFilePath := filepath.Join(repoPath, NetLimitTraceFilename) + ropts = append(ropts, rcmgr.WithTrace(traceFilePath)) + } + + manager, err = rcmgr.NewResourceManager(limiter, ropts...) + if err != nil { + return nil, opts, fmt.Errorf("creating libp2p resource manager: %w", err) + } + lrm := &loggingResourceManager{ + clock: clock.New(), + logger: &logging.Logger("resourcemanager").SugaredLogger, + delegate: manager, + } + lrm.start(helpers.LifecycleCtx(mctx, lc)) + manager = lrm + } else { + log.Debug("libp2p resource manager is disabled") + manager = network.NullResourceManager + } + + opts.Opts = append(opts.Opts, libp2p.ResourceManager(manager)) + + lc.Append(fx.Hook{ + OnStop: func(_ context.Context) error { + return manager.Close() + }}) + + return manager, opts, nil + } +} + +type NetStatOut struct { + System *network.ScopeStat `json:",omitempty"` + Transient *network.ScopeStat `json:",omitempty"` + Services map[string]network.ScopeStat `json:",omitempty"` + Protocols map[string]network.ScopeStat `json:",omitempty"` + Peers map[string]network.ScopeStat `json:",omitempty"` +} + +func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) { + var err error + var result NetStatOut + switch { + case scope == "all": + rapi, ok := mgr.(rcmgr.ResourceManagerState) + if !ok { // NullResourceManager + return result, NoResourceMgrError + } + + stat := rapi.Stat() + result.System = &stat.System + result.Transient = &stat.Transient + if len(stat.Services) > 0 { + result.Services = stat.Services + } + if len(stat.Protocols) > 0 { + result.Protocols = make(map[string]network.ScopeStat, len(stat.Protocols)) + for proto, stat := range stat.Protocols { + result.Protocols[string(proto)] = stat + } + } + if len(stat.Peers) > 0 { + result.Peers = make(map[string]network.ScopeStat, len(stat.Peers)) + for p, stat := range stat.Peers { + result.Peers[p.Pretty()] = stat + } + } + + return result, nil + + case scope == config.ResourceMgrSystemScope: + err = mgr.ViewSystem(func(s network.ResourceScope) error { + stat := s.Stat() + result.System = &stat + return nil + }) + return result, err + + case scope == config.ResourceMgrTransientScope: + err = mgr.ViewTransient(func(s network.ResourceScope) error { + stat := s.Stat() + result.Transient = &stat + return nil + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): + svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) + err = mgr.ViewService(svc, func(s network.ServiceScope) error { + stat := s.Stat() + result.Services = map[string]network.ScopeStat{ + svc: stat, + } + return nil + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): + proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + stat := s.Stat() + result.Protocols = map[string]network.ScopeStat{ + proto: stat, + } + return nil + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): + p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) + pid, err := peer.Decode(p) + if err != nil { + return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + stat := s.Stat() + result.Peers = map[string]network.ScopeStat{ + p: stat, + } + return nil + }) + return result, err + + default: + return result, fmt.Errorf("invalid scope %q", scope) + } +} + +func NetLimit(mgr network.ResourceManager, scope string) (rcmgr.BasicLimitConfig, error) { + var result rcmgr.BasicLimitConfig + getLimit := func(s network.ResourceScope) error { + limiter, ok := s.(rcmgr.ResourceScopeLimiter) + if !ok { // NullResourceManager + return NoResourceMgrError + } + limit := limiter.Limit() + switch l := limit.(type) { + case *rcmgr.StaticLimit: + result.Dynamic = false + result.Memory = l.Memory + result.Streams = l.BaseLimit.Streams + result.StreamsInbound = l.BaseLimit.StreamsInbound + result.StreamsOutbound = l.BaseLimit.StreamsOutbound + result.Conns = l.BaseLimit.Conns + result.ConnsInbound = l.BaseLimit.ConnsInbound + result.ConnsOutbound = l.BaseLimit.ConnsOutbound + result.FD = l.BaseLimit.FD + + case *rcmgr.DynamicLimit: + result.Dynamic = true + result.MemoryFraction = l.MemoryLimit.MemoryFraction + result.MinMemory = l.MemoryLimit.MinMemory + result.MaxMemory = l.MemoryLimit.MaxMemory + result.Streams = l.BaseLimit.Streams + result.StreamsInbound = l.BaseLimit.StreamsInbound + result.StreamsOutbound = l.BaseLimit.StreamsOutbound + result.Conns = l.BaseLimit.Conns + result.ConnsInbound = l.BaseLimit.ConnsInbound + result.ConnsOutbound = l.BaseLimit.ConnsOutbound + result.FD = l.BaseLimit.FD + + default: + return fmt.Errorf("unknown limit type %T", limit) + } + + return nil + } + + switch { + case scope == config.ResourceMgrSystemScope: + err := mgr.ViewSystem(func(s network.ResourceScope) error { + return getLimit(s) + }) + return result, err + + case scope == config.ResourceMgrTransientScope: + err := mgr.ViewTransient(func(s network.ResourceScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): + svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) + err := mgr.ViewService(svc, func(s network.ServiceScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): + proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) + err := mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return getLimit(s) + }) + return result, err + + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): + p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) + pid, err := peer.Decode(p) + if err != nil { + return result, fmt.Errorf("invalid peer ID: %q: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + return getLimit(s) + }) + return result, err + + default: + return result, fmt.Errorf("invalid scope %q", scope) + } +} + +// NetSetLimit sets new ResourceManager limits for the given scope. The limits take effect immediately, and are also persisted to the repo config. +func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limit rcmgr.BasicLimitConfig) error { + setLimit := func(s network.ResourceScope) error { + limiter, ok := s.(rcmgr.ResourceScopeLimiter) + if !ok { // NullResourceManager + return NoResourceMgrError + } + + var newLimit rcmgr.Limit + if limit.Dynamic { + newLimit = &rcmgr.DynamicLimit{ + MemoryLimit: rcmgr.MemoryLimit{ + MemoryFraction: limit.MemoryFraction, + MinMemory: limit.MinMemory, + MaxMemory: limit.MaxMemory, + }, + BaseLimit: rcmgr.BaseLimit{ + Streams: limit.Streams, + StreamsInbound: limit.StreamsInbound, + StreamsOutbound: limit.StreamsOutbound, + Conns: limit.Conns, + ConnsInbound: limit.ConnsInbound, + ConnsOutbound: limit.ConnsOutbound, + FD: limit.FD, + }, + } + } else { + newLimit = &rcmgr.StaticLimit{ + Memory: limit.Memory, + BaseLimit: rcmgr.BaseLimit{ + Streams: limit.Streams, + StreamsInbound: limit.StreamsInbound, + StreamsOutbound: limit.StreamsOutbound, + Conns: limit.Conns, + ConnsInbound: limit.ConnsInbound, + ConnsOutbound: limit.ConnsOutbound, + FD: limit.FD, + }, + } + } + + limiter.SetLimit(newLimit) + return nil + } + + cfg, err := repo.Config() + if err != nil { + return fmt.Errorf("reading config to set limit: %w", err) + } + + if cfg.Swarm.ResourceMgr.Limits == nil { + cfg.Swarm.ResourceMgr.Limits = &rcmgr.BasicLimiterConfig{} + } + configLimits := cfg.Swarm.ResourceMgr.Limits + + var setConfigFunc func() + switch { + case scope == config.ResourceMgrSystemScope: + err = mgr.ViewSystem(func(s network.ResourceScope) error { + return setLimit(s) + }) + setConfigFunc = func() { configLimits.System = &limit } + + case scope == config.ResourceMgrTransientScope: + err = mgr.ViewTransient(func(s network.ResourceScope) error { + return setLimit(s) + }) + setConfigFunc = func() { configLimits.Transient = &limit } + + case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix): + svc := strings.TrimPrefix(scope, config.ResourceMgrServiceScopePrefix) + err = mgr.ViewService(svc, func(s network.ServiceScope) error { + return setLimit(s) + }) + setConfigFunc = func() { + if configLimits.Service == nil { + configLimits.Service = map[string]rcmgr.BasicLimitConfig{} + } + configLimits.Service[svc] = limit + } + + case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix): + proto := strings.TrimPrefix(scope, config.ResourceMgrProtocolScopePrefix) + err = mgr.ViewProtocol(protocol.ID(proto), func(s network.ProtocolScope) error { + return setLimit(s) + }) + setConfigFunc = func() { + if configLimits.Protocol == nil { + configLimits.Protocol = map[string]rcmgr.BasicLimitConfig{} + } + configLimits.Protocol[proto] = limit + } + + case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix): + p := strings.TrimPrefix(scope, config.ResourceMgrPeerScopePrefix) + var pid peer.ID + pid, err = peer.Decode(p) + if err != nil { + return fmt.Errorf("invalid peer ID: %q: %w", p, err) + } + err = mgr.ViewPeer(pid, func(s network.PeerScope) error { + return setLimit(s) + }) + setConfigFunc = func() { + if configLimits.Peer == nil { + configLimits.Peer = map[string]rcmgr.BasicLimitConfig{} + } + configLimits.Peer[p] = limit + } + + default: + return fmt.Errorf("invalid scope %q", scope) + } + + if err != nil { + return fmt.Errorf("setting new limits on resource manager: %w", err) + } + + if cfg.Swarm.ResourceMgr.Limits == nil { + cfg.Swarm.ResourceMgr.Limits = &rcmgr.BasicLimiterConfig{} + } + setConfigFunc() + + if err := repo.SetConfig(cfg); err != nil { + return fmt.Errorf("writing new limits to repo config: %w", err) + } + + return nil +} diff --git a/core/node/libp2p/rcmgr_defaults.go b/core/node/libp2p/rcmgr_defaults.go new file mode 100644 index 00000000000..3f754fce433 --- /dev/null +++ b/core/node/libp2p/rcmgr_defaults.go @@ -0,0 +1,673 @@ +package libp2p + +import ( + "encoding/json" + "fmt" + "math/bits" + "os" + "strings" + + config "github.com/ipfs/go-ipfs/config" + "github.com/libp2p/go-libp2p" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + + "github.com/wI2L/jsondiff" +) + +// This file defines implicit limit defaults used when Swarm.ResourceMgr.Enabled + +// adjustedDefaultLimits allows for tweaking defaults based on external factors, +// such as values in Swarm.ConnMgr.HiWater config. +func adjustedDefaultLimits(cfg config.SwarmConfig) rcmgr.DefaultLimitConfig { + // Run checks to avoid introducing regressions + if os.Getenv("IPFS_CHECK_RCMGR_DEFAULTS") != "" { + // FIXME: Broken. Being tracked in https://github.com/ipfs/go-ipfs/issues/8949. + checkImplicitDefaults() + } + + // Adjust limits + // (based on https://github.com/filecoin-project/lotus/pull/8318/files) + // - give it more memory, up to 4G, min of 1G + // - if Swarm.ConnMgr.HighWater is too high, adjust Conn/FD/Stream limits + defaultLimits := rcmgr.DefaultLimits.WithSystemMemory(.125, 1<<30, 4<<30) + + // Outbound conns and FDs are set very high to allow for the accelerated DHT client to (re)load its routing table. + // Currently it doesn't gracefully handle RM throttling--once it does we can lower these. + // High outbound conn limits are considered less of a DoS risk than high inbound conn limits. + // Also note that, due to the behavior of the accelerated DHT client, we don't need many streams, just conns. + if minOutbound := 65536; defaultLimits.SystemBaseLimit.ConnsOutbound < minOutbound { + defaultLimits.SystemBaseLimit.ConnsOutbound = minOutbound + } + if minFD := 4096; defaultLimits.SystemBaseLimit.FD < minFD { + defaultLimits.SystemBaseLimit.FD = minFD + } + + // Do we need to adjust due to Swarm.ConnMgr.HighWater? + if cfg.ConnMgr.Type == "basic" { + maxconns := cfg.ConnMgr.HighWater + if 2*maxconns > defaultLimits.SystemBaseLimit.ConnsInbound { + // Conns should be at least 2x larger than the high water to allow for two conns per peer (TCP+QUIC). + defaultLimits.SystemBaseLimit.ConnsInbound = logScale(2 * maxconns) + + // We want the floor of minOutbound conns to be no less than what was set above. + if minOutbound := logScale(2 * maxconns); minOutbound > defaultLimits.SystemBaseLimit.ConnsOutbound { + defaultLimits.SystemBaseLimit.ConnsOutbound = minOutbound + } + + if 2*maxconns > defaultLimits.SystemBaseLimit.FD { + defaultLimits.SystemBaseLimit.FD = logScale(2 * maxconns) + } + + defaultLimits.SystemBaseLimit.StreamsInbound = logScale(16 * maxconns) + defaultLimits.SystemBaseLimit.StreamsOutbound = logScale(64 * maxconns) + defaultLimits.SystemBaseLimit.Streams = logScale(64 * maxconns) + + defaultLimits.ServiceBaseLimit.StreamsInbound = logScale(8 * maxconns) + defaultLimits.ServiceBaseLimit.StreamsOutbound = logScale(32 * maxconns) + defaultLimits.ServiceBaseLimit.Streams = logScale(32 * maxconns) + + defaultLimits.ProtocolBaseLimit.StreamsInbound = logScale(8 * maxconns) + defaultLimits.ProtocolBaseLimit.StreamsOutbound = logScale(32 * maxconns) + defaultLimits.ProtocolBaseLimit.Streams = logScale(32 * maxconns) + } + } + + defaultLimits.SystemBaseLimit.Conns = defaultLimits.SystemBaseLimit.ConnsOutbound + defaultLimits.SystemBaseLimit.ConnsInbound + + return defaultLimits +} + +func logScale(val int) int { + bitlen := bits.Len(uint(val)) + return 1 << bitlen +} + +// checkImplicitDefaults compares libp2p defaults agains expected ones +// and panics when they don't match. This ensures we are not surprised +// by silent default limit changes when we update go-libp2p dependencies. +func checkImplicitDefaults() { + ok := true + + // Check 1: did go-libp2p-resource-manager's DefaultLimits change? + defaults, err := json.Marshal(rcmgr.DefaultLimits) + if err != nil { + log.Fatal(err) + } + changes, err := jsonDiff([]byte(expectedDefaultLimits), defaults) + if err != nil { + log.Fatal(err) + } + if len(changes) > 0 { + ok = false + log.Errorf("===> OOF! go-libp2p-resource-manager changed DefaultLimits\n"+ + "=> changes ('test' represents the old value):\n%s\n"+ + "=> go-libp2p-resource-manager DefaultLimits update needs a review:\n"+ + "Please inspect if changes impact go-ipfs users, and update expectedDefaultLimits in rcmgr_defaults.go to remove this message", + strings.Join(changes, "\n"), + ) + } + + // Check 2: did go-libp2p's SetDefaultServiceLimits change? + testLimiter := rcmgr.NewStaticLimiter(rcmgr.DefaultLimits) + libp2p.SetDefaultServiceLimits(testLimiter) + + serviceDefaults, err := json.Marshal(testLimiter) + if err != nil { + log.Fatal(err) + } + changes, err = jsonDiff([]byte(expectedDefaultServiceLimits), serviceDefaults) + if err != nil { + log.Fatal(err) + } + if len(changes) > 0 { + ok = false + log.Errorf("===> OOF! go-libp2p changed DefaultServiceLimits\n"+ + "=> changes ('test' represents the old value):\n%s\n"+ + "=> go-libp2p SetDefaultServiceLimits update needs a review:\n"+ + "Please inspect if changes impact go-ipfs users, and update expectedDefaultServiceLimits in rcmgr_defaults.go to remove this message", + strings.Join(changes, "\n"), + ) + } + if !ok { + log.Fatal("daemon will refuse to run with the resource manager until this is resolved") + } +} + +// jsonDiff compares two strings and returns diff in JSON Patch format +func jsonDiff(old []byte, updated []byte) ([]string, error) { + // generate 'invertible' patch which includes old values as "test" op + patch, err := jsondiff.CompareJSONOpts(old, updated, jsondiff.Invertible()) + changes := make([]string, len(patch)) + if err != nil { + return changes, err + } + for i, op := range patch { + changes[i] = fmt.Sprintf(" %s", op) + } + return changes, nil +} + +// https://github.com/libp2p/go-libp2p-resource-manager/blob/v0.1.5/limit_defaults.go#L49 +const expectedDefaultLimits = `{ + "SystemBaseLimit": { + "Streams": 16384, + "StreamsInbound": 4096, + "StreamsOutbound": 16384, + "Conns": 1024, + "ConnsInbound": 256, + "ConnsOutbound": 1024, + "FD": 512 + }, + "SystemMemory": { + "MemoryFraction": 0.125, + "MinMemory": 134217728, + "MaxMemory": 1073741824 + }, + "TransientBaseLimit": { + "Streams": 512, + "StreamsInbound": 128, + "StreamsOutbound": 512, + "Conns": 128, + "ConnsInbound": 32, + "ConnsOutbound": 128, + "FD": 128 + }, + "TransientMemory": { + "MemoryFraction": 1, + "MinMemory": 67108864, + "MaxMemory": 67108864 + }, + "ServiceBaseLimit": { + "Streams": 8192, + "StreamsInbound": 2048, + "StreamsOutbound": 8192, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0 + }, + "ServiceMemory": { + "MemoryFraction": 0.03125, + "MinMemory": 67108864, + "MaxMemory": 268435456 + }, + "ServicePeerBaseLimit": { + "Streams": 512, + "StreamsInbound": 256, + "StreamsOutbound": 512, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0 + }, + "ServicePeerMemory": { + "MemoryFraction": 0.0078125, + "MinMemory": 16777216, + "MaxMemory": 67108864 + }, + "ProtocolBaseLimit": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0 + }, + "ProtocolMemory": { + "MemoryFraction": 0.015625, + "MinMemory": 67108864, + "MaxMemory": 134217728 + }, + "ProtocolPeerBaseLimit": { + "Streams": 512, + "StreamsInbound": 128, + "StreamsOutbound": 256, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0 + }, + "ProtocolPeerMemory": { + "MemoryFraction": 0.0078125, + "MinMemory": 16777216, + "MaxMemory": 67108864 + }, + "PeerBaseLimit": { + "Streams": 1024, + "StreamsInbound": 512, + "StreamsOutbound": 1024, + "Conns": 16, + "ConnsInbound": 8, + "ConnsOutbound": 16, + "FD": 8 + }, + "PeerMemory": { + "MemoryFraction": 0.0078125, + "MinMemory": 67108864, + "MaxMemory": 134217728 + }, + "ConnBaseLimit": { + "Streams": 0, + "StreamsInbound": 0, + "StreamsOutbound": 0, + "Conns": 1, + "ConnsInbound": 1, + "ConnsOutbound": 1, + "FD": 1 + }, + "ConnMemory": 1048576, + "StreamBaseLimit": { + "Streams": 1, + "StreamsInbound": 1, + "StreamsOutbound": 1, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0 + }, + "StreamMemory": 16777216 +}` + +// https://github.com/libp2p/go-libp2p/blob/v0.18.0/limits.go#L17 +const expectedDefaultServiceLimits = `{ + "SystemLimits": { + "Streams": 16384, + "StreamsInbound": 4096, + "StreamsOutbound": 16384, + "Conns": 1024, + "ConnsInbound": 256, + "ConnsOutbound": 1024, + "FD": 512, + "Memory": 1073741824 + }, + "TransientLimits": { + "Streams": 512, + "StreamsInbound": 128, + "StreamsOutbound": 512, + "Conns": 128, + "ConnsInbound": 32, + "ConnsOutbound": 128, + "FD": 128, + "Memory": 67108864 + }, + "DefaultServiceLimits": { + "Streams": 8192, + "StreamsInbound": 2048, + "StreamsOutbound": 8192, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "DefaultServicePeerLimits": { + "Streams": 512, + "StreamsInbound": 256, + "StreamsOutbound": 512, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 16777216 + }, + "ServiceLimits": { + "libp2p.autonat": { + "Streams": 128, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "libp2p.holepunch": { + "Streams": 256, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "libp2p.identify": { + "Streams": 256, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "libp2p.ping": { + "Streams": 128, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "libp2p.relay/v1": { + "Streams": 1024, + "StreamsInbound": 1024, + "StreamsOutbound": 1024, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "libp2p.relay/v2": { + "Streams": 1024, + "StreamsInbound": 1024, + "StreamsOutbound": 1024, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + } + }, + "ServicePeerLimits": { + "libp2p.autonat": { + "Streams": 2, + "StreamsInbound": 2, + "StreamsOutbound": 2, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 557056 + }, + "libp2p.holepunch": { + "Streams": 2, + "StreamsInbound": 2, + "StreamsOutbound": 2, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 557056 + }, + "libp2p.identify": { + "Streams": 32, + "StreamsInbound": 16, + "StreamsOutbound": 16, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 8912896 + }, + "libp2p.ping": { + "Streams": 4, + "StreamsInbound": 2, + "StreamsOutbound": 3, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 1114112 + }, + "libp2p.relay/v1": { + "Streams": 64, + "StreamsInbound": 64, + "StreamsOutbound": 64, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 17825792 + }, + "libp2p.relay/v2": { + "Streams": 64, + "StreamsInbound": 64, + "StreamsOutbound": 64, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 17825792 + } + }, + "DefaultProtocolLimits": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "DefaultProtocolPeerLimits": { + "Streams": 512, + "StreamsInbound": 128, + "StreamsOutbound": 256, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 16777216 + }, + "ProtocolLimits": { + "/ipfs/id/1.0.0": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 33554432 + }, + "/ipfs/id/push/1.0.0": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 33554432 + }, + "/ipfs/ping/1.0.0": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "/libp2p/autonat/1.0.0": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "/libp2p/circuit/relay/0.1.0": { + "Streams": 1280, + "StreamsInbound": 1280, + "StreamsOutbound": 1280, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "/libp2p/circuit/relay/0.2.0/hop": { + "Streams": 1280, + "StreamsInbound": 1280, + "StreamsOutbound": 1280, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "/libp2p/circuit/relay/0.2.0/stop": { + "Streams": 1280, + "StreamsInbound": 1280, + "StreamsOutbound": 1280, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "/libp2p/dcutr": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 67108864 + }, + "/p2p/id/delta/1.0.0": { + "Streams": 4096, + "StreamsInbound": 1024, + "StreamsOutbound": 4096, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 33554432 + } + }, + "ProtocolPeerLimits": { + "/ipfs/id/1.0.0": { + "Streams": 32, + "StreamsInbound": 16, + "StreamsOutbound": 16, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 8912896 + }, + "/ipfs/id/push/1.0.0": { + "Streams": 32, + "StreamsInbound": 16, + "StreamsOutbound": 16, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 8912896 + }, + "/ipfs/ping/1.0.0": { + "Streams": 4, + "StreamsInbound": 2, + "StreamsOutbound": 3, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 1114112 + }, + "/libp2p/autonat/1.0.0": { + "Streams": 2, + "StreamsInbound": 2, + "StreamsOutbound": 2, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 557056 + }, + "/libp2p/circuit/relay/0.1.0": { + "Streams": 128, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 35651584 + }, + "/libp2p/circuit/relay/0.2.0/hop": { + "Streams": 128, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 35651584 + }, + "/libp2p/circuit/relay/0.2.0/stop": { + "Streams": 128, + "StreamsInbound": 128, + "StreamsOutbound": 128, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 35651584 + }, + "/libp2p/dcutr": { + "Streams": 2, + "StreamsInbound": 2, + "StreamsOutbound": 2, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 557056 + }, + "/p2p/id/delta/1.0.0": { + "Streams": 32, + "StreamsInbound": 16, + "StreamsOutbound": 16, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 8912896 + } + }, + "DefaultPeerLimits": { + "Streams": 1024, + "StreamsInbound": 512, + "StreamsOutbound": 1024, + "Conns": 16, + "ConnsInbound": 8, + "ConnsOutbound": 16, + "FD": 8, + "Memory": 67108864 + }, + "PeerLimits": null, + "ConnLimits": { + "Streams": 0, + "StreamsInbound": 0, + "StreamsOutbound": 0, + "Conns": 1, + "ConnsInbound": 1, + "ConnsOutbound": 1, + "FD": 1, + "Memory": 1048576 + }, + "StreamLimits": { + "Streams": 1, + "StreamsInbound": 1, + "StreamsOutbound": 1, + "Conns": 0, + "ConnsInbound": 0, + "ConnsOutbound": 0, + "FD": 0, + "Memory": 16777216 + } +}` diff --git a/core/node/libp2p/rcmgr_logging.go b/core/node/libp2p/rcmgr_logging.go new file mode 100644 index 00000000000..06d22c71b8c --- /dev/null +++ b/core/node/libp2p/rcmgr_logging.go @@ -0,0 +1,160 @@ +package libp2p + +import ( + "context" + "errors" + "sync" + "time" + + "github.com/benbjohnson/clock" + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + "go.uber.org/zap" +) + +type loggingResourceManager struct { + clock clock.Clock + logger *zap.SugaredLogger + delegate network.ResourceManager + logInterval time.Duration + + mut sync.Mutex + limitExceededErrs uint64 +} + +type loggingScope struct { + logger *zap.SugaredLogger + delegate network.ResourceScope + countErrs func(error) +} + +var _ network.ResourceManager = (*loggingResourceManager)(nil) + +func (n *loggingResourceManager) start(ctx context.Context) { + logInterval := n.logInterval + if logInterval == 0 { + logInterval = 10 * time.Second + } + ticker := n.clock.Ticker(logInterval) + go func() { + defer ticker.Stop() + for { + select { + case <-ticker.C: + n.mut.Lock() + errs := n.limitExceededErrs + n.limitExceededErrs = 0 + n.mut.Unlock() + if errs != 0 { + n.logger.Warnf("Resource limits were exceeded %d times, consider inspecting logs and raising the resource manager limits.", errs) + } + case <-ctx.Done(): + return + } + } + }() +} + +func (n *loggingResourceManager) countErrs(err error) { + if errors.Is(err, network.ErrResourceLimitExceeded) { + n.mut.Lock() + n.limitExceededErrs++ + n.mut.Unlock() + } +} + +func (n *loggingResourceManager) ViewSystem(f func(network.ResourceScope) error) error { + return n.delegate.ViewSystem(f) +} +func (n *loggingResourceManager) ViewTransient(f func(network.ResourceScope) error) error { + return n.delegate.ViewTransient(func(s network.ResourceScope) error { + return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) + }) +} +func (n *loggingResourceManager) ViewService(svc string, f func(network.ServiceScope) error) error { + return n.delegate.ViewService(svc, func(s network.ServiceScope) error { + return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) + }) +} +func (n *loggingResourceManager) ViewProtocol(p protocol.ID, f func(network.ProtocolScope) error) error { + return n.delegate.ViewProtocol(p, func(s network.ProtocolScope) error { + return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) + }) +} +func (n *loggingResourceManager) ViewPeer(p peer.ID, f func(network.PeerScope) error) error { + return n.delegate.ViewPeer(p, func(s network.PeerScope) error { + return f(&loggingScope{logger: n.logger, delegate: s, countErrs: n.countErrs}) + }) +} +func (n *loggingResourceManager) OpenConnection(dir network.Direction, usefd bool) (network.ConnManagementScope, error) { + connMgmtScope, err := n.delegate.OpenConnection(dir, usefd) + n.countErrs(err) + return connMgmtScope, err +} +func (n *loggingResourceManager) OpenStream(p peer.ID, dir network.Direction) (network.StreamManagementScope, error) { + connMgmtScope, err := n.delegate.OpenStream(p, dir) + n.countErrs(err) + return connMgmtScope, err +} +func (n *loggingResourceManager) Close() error { + return n.delegate.Close() +} + +func (s *loggingScope) ReserveMemory(size int, prio uint8) error { + err := s.delegate.ReserveMemory(size, prio) + s.countErrs(err) + return err +} +func (s *loggingScope) ReleaseMemory(size int) { + s.delegate.ReleaseMemory(size) +} +func (s *loggingScope) Stat() network.ScopeStat { + return s.delegate.Stat() +} +func (s *loggingScope) BeginSpan() (network.ResourceScopeSpan, error) { + return s.delegate.BeginSpan() +} +func (s *loggingScope) Done() { + s.delegate.(network.ResourceScopeSpan).Done() +} +func (s *loggingScope) Name() string { + return s.delegate.(network.ServiceScope).Name() +} +func (s *loggingScope) Protocol() protocol.ID { + return s.delegate.(network.ProtocolScope).Protocol() +} +func (s *loggingScope) Peer() peer.ID { + return s.delegate.(network.PeerScope).Peer() +} +func (s *loggingScope) PeerScope() network.PeerScope { + return s.delegate.(network.PeerScope) +} +func (s *loggingScope) SetPeer(p peer.ID) error { + err := s.delegate.(network.ConnManagementScope).SetPeer(p) + s.countErrs(err) + return err +} +func (s *loggingScope) ProtocolScope() network.ProtocolScope { + return s.delegate.(network.ProtocolScope) +} +func (s *loggingScope) SetProtocol(proto protocol.ID) error { + err := s.delegate.(network.StreamManagementScope).SetProtocol(proto) + s.countErrs(err) + return err +} +func (s *loggingScope) ServiceScope() network.ServiceScope { + return s.delegate.(network.ServiceScope) +} +func (s *loggingScope) SetService(srv string) error { + err := s.delegate.(network.StreamManagementScope).SetService(srv) + s.countErrs(err) + return err +} +func (s *loggingScope) Limit() rcmgr.Limit { + return s.delegate.(rcmgr.ResourceScopeLimiter).Limit() +} +func (s *loggingScope) SetLimit(limit rcmgr.Limit) { + s.delegate.(rcmgr.ResourceScopeLimiter).SetLimit(limit) +} diff --git a/core/node/libp2p/rcmgr_logging_test.go b/core/node/libp2p/rcmgr_logging_test.go new file mode 100644 index 00000000000..72f34b80885 --- /dev/null +++ b/core/node/libp2p/rcmgr_logging_test.go @@ -0,0 +1,58 @@ +package libp2p + +import ( + "context" + "testing" + "time" + + "github.com/benbjohnson/clock" + "github.com/libp2p/go-libp2p-core/network" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" +) + +func TestLoggingResourceManager(t *testing.T) { + clock := clock.NewMock() + limiter := rcmgr.NewDefaultLimiter() + limiter.SystemLimits = limiter.SystemLimits.WithConnLimit(1, 1, 1) + rm, err := rcmgr.NewResourceManager(limiter) + if err != nil { + t.Fatal(err) + } + + oCore, oLogs := observer.New(zap.WarnLevel) + oLogger := zap.New(oCore) + lrm := &loggingResourceManager{ + clock: clock, + logger: oLogger.Sugar(), + delegate: rm, + logInterval: 1 * time.Second, + } + + // 2 of these should result in resource limit exceeded errors and subsequent log messages + for i := 0; i < 3; i++ { + _, _ = lrm.OpenConnection(network.DirInbound, false) + } + + // run the logger which will write an entry for those errors + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + lrm.start(ctx) + clock.Add(3 * time.Second) + + timer := time.NewTimer(1 * time.Second) + for { + select { + case <-timer.C: + t.Fatalf("expected logs never arrived") + default: + if oLogs.Len() == 0 { + continue + } + require.Equal(t, "Resource limits were exceeded 2 times, consider inspecting logs and raising the resource manager limits.", oLogs.All()[0].Message) + return + } + } +} diff --git a/core/node/libp2p/rcmgr_metrics.go b/core/node/libp2p/rcmgr_metrics.go new file mode 100644 index 00000000000..48c54426cfe --- /dev/null +++ b/core/node/libp2p/rcmgr_metrics.go @@ -0,0 +1,251 @@ +package libp2p + +import ( + "errors" + "strconv" + + "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/protocol" + rcmgr "github.com/libp2p/go-libp2p-resource-manager" + + "github.com/prometheus/client_golang/prometheus" +) + +func mustRegister(c prometheus.Collector) { + err := prometheus.Register(c) + are := prometheus.AlreadyRegisteredError{} + if errors.As(err, &are) { + return + } + if err != nil { + panic(err) + } +} + +func createRcmgrMetrics() rcmgr.MetricsReporter { + const ( + direction = "direction" + usesFD = "usesFD" + protocol = "protocol" + service = "service" + ) + + connAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_conns_allowed_total", + Help: "allowed connections", + }, + []string{direction, usesFD}, + ) + mustRegister(connAllowed) + + connBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_conns_blocked_total", + Help: "blocked connections", + }, + []string{direction, usesFD}, + ) + mustRegister(connBlocked) + + streamAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_streams_allowed_total", + Help: "allowed streams", + }, + []string{direction}, + ) + mustRegister(streamAllowed) + + streamBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_streams_blocked_total", + Help: "blocked streams", + }, + []string{direction}, + ) + mustRegister(streamBlocked) + + peerAllowed := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_peers_allowed_total", + Help: "allowed peers", + }) + mustRegister(peerAllowed) + + peerBlocked := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_peer_blocked_total", + Help: "blocked peers", + }) + mustRegister(peerBlocked) + + protocolAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_allowed_total", + Help: "allowed streams attached to a protocol", + }, + []string{protocol}, + ) + mustRegister(protocolAllowed) + + protocolBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_blocked_total", + Help: "blocked streams attached to a protocol", + }, + []string{protocol}, + ) + mustRegister(protocolBlocked) + + protocolPeerBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_protocols_for_peer_blocked_total", + Help: "blocked streams attached to a protocol for a specific peer", + }, + []string{protocol}, + ) + mustRegister(protocolPeerBlocked) + + serviceAllowed := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_services_allowed_total", + Help: "allowed streams attached to a service", + }, + []string{service}, + ) + mustRegister(serviceAllowed) + + serviceBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_services_blocked_total", + Help: "blocked streams attached to a service", + }, + []string{service}, + ) + mustRegister(serviceBlocked) + + servicePeerBlocked := prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "libp2p_rcmgr_service_for_peer_blocked_total", + Help: "blocked streams attached to a service for a specific peer", + }, + []string{service}, + ) + mustRegister(servicePeerBlocked) + + memoryAllowed := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_memory_allocations_allowed_total", + Help: "allowed memory allocations", + }) + mustRegister(memoryAllowed) + + memoryBlocked := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "libp2p_rcmgr_memory_allocations_blocked_total", + Help: "blocked memory allocations", + }) + mustRegister(memoryBlocked) + + return rcmgrMetrics{ + connAllowed, + connBlocked, + streamAllowed, + streamBlocked, + peerAllowed, + peerBlocked, + protocolAllowed, + protocolBlocked, + protocolPeerBlocked, + serviceAllowed, + serviceBlocked, + servicePeerBlocked, + memoryAllowed, + memoryBlocked, + } +} + +// Failsafe to ensure interface from go-libp2p-resource-manager is implemented +var _ rcmgr.MetricsReporter = rcmgrMetrics{} + +type rcmgrMetrics struct { + connAllowed *prometheus.CounterVec + connBlocked *prometheus.CounterVec + streamAllowed *prometheus.CounterVec + streamBlocked *prometheus.CounterVec + peerAllowed prometheus.Counter + peerBlocked prometheus.Counter + protocolAllowed *prometheus.CounterVec + protocolBlocked *prometheus.CounterVec + protocolPeerBlocked *prometheus.CounterVec + serviceAllowed *prometheus.CounterVec + serviceBlocked *prometheus.CounterVec + servicePeerBlocked *prometheus.CounterVec + memoryAllowed prometheus.Counter + memoryBlocked prometheus.Counter +} + +func getDirection(d network.Direction) string { + switch d { + default: + return "" + case network.DirInbound: + return "inbound" + case network.DirOutbound: + return "outbound" + } +} + +func (r rcmgrMetrics) AllowConn(dir network.Direction, usefd bool) { + r.connAllowed.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() +} + +func (r rcmgrMetrics) BlockConn(dir network.Direction, usefd bool) { + r.connBlocked.WithLabelValues(getDirection(dir), strconv.FormatBool(usefd)).Inc() +} + +func (r rcmgrMetrics) AllowStream(_ peer.ID, dir network.Direction) { + r.streamAllowed.WithLabelValues(getDirection(dir)).Inc() +} + +func (r rcmgrMetrics) BlockStream(_ peer.ID, dir network.Direction) { + r.streamBlocked.WithLabelValues(getDirection(dir)).Inc() +} + +func (r rcmgrMetrics) AllowPeer(_ peer.ID) { + r.peerAllowed.Inc() +} + +func (r rcmgrMetrics) BlockPeer(_ peer.ID) { + r.peerBlocked.Inc() +} + +func (r rcmgrMetrics) AllowProtocol(proto protocol.ID) { + r.protocolAllowed.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) BlockProtocol(proto protocol.ID) { + r.protocolBlocked.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) BlockProtocolPeer(proto protocol.ID, _ peer.ID) { + r.protocolPeerBlocked.WithLabelValues(string(proto)).Inc() +} + +func (r rcmgrMetrics) AllowService(svc string) { + r.serviceAllowed.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) BlockService(svc string) { + r.serviceBlocked.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) BlockServicePeer(svc string, _ peer.ID) { + r.servicePeerBlocked.WithLabelValues(svc).Inc() +} + +func (r rcmgrMetrics) AllowMemory(_ int) { + r.memoryAllowed.Inc() +} + +func (r rcmgrMetrics) BlockMemory(_ int) { + r.memoryBlocked.Inc() +} diff --git a/core/node/libp2p/relay.go b/core/node/libp2p/relay.go index 33d958d5c9d..5bb8b946e51 100644 --- a/core/node/libp2p/relay.go +++ b/core/node/libp2p/relay.go @@ -1,10 +1,10 @@ package libp2p import ( - config "github.com/ipfs/go-ipfs-config" - "github.com/libp2p/go-libp2p-core/peer" - + "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/p2p/host/autorelay" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" ) @@ -43,39 +43,42 @@ func RelayService(enable bool, relayOpts config.RelayService) func() (opts Libp2 } } -func StaticRelays(relays []string) func() (opts Libp2pOpts, err error) { +func AutoRelay(staticRelays []string, peerChan <-chan peer.AddrInfo) func() (opts Libp2pOpts, err error) { return func() (opts Libp2pOpts, err error) { - staticRelays := make([]peer.AddrInfo, 0, len(relays)) - for _, s := range relays { - var addr *peer.AddrInfo - addr, err = peer.AddrInfoFromString(s) - if err != nil { - return + var autoRelayOpts []autorelay.Option + if len(staticRelays) > 0 { + static := make([]peer.AddrInfo, 0, len(staticRelays)) + for _, s := range staticRelays { + var addr *peer.AddrInfo + addr, err = peer.AddrInfoFromString(s) + if err != nil { + return + } + static = append(static, *addr) } - staticRelays = append(staticRelays, *addr) + autoRelayOpts = append(autoRelayOpts, autorelay.WithStaticRelays(static)) + autoRelayOpts = append(autoRelayOpts, autorelay.WithCircuitV1Support()) } - if len(staticRelays) > 0 { - opts.Opts = append(opts.Opts, libp2p.StaticRelays(staticRelays)) - } - return - } -} - -func AutoRelay(addDefaultRelays bool) func() (opts Libp2pOpts, err error) { - return func() (opts Libp2pOpts, err error) { - opts.Opts = append(opts.Opts, libp2p.EnableAutoRelay()) - if addDefaultRelays { - opts.Opts = append(opts.Opts, libp2p.DefaultStaticRelays()) + if peerChan != nil { + autoRelayOpts = append(autoRelayOpts, autorelay.WithPeerSource(peerChan)) } + opts.Opts = append(opts.Opts, libp2p.EnableAutoRelay(autoRelayOpts...)) return } } func HolePunching(flag config.Flag, hasRelayClient bool) func() (opts Libp2pOpts, err error) { return func() (opts Libp2pOpts, err error) { - if flag.WithDefault(false) { + if flag.WithDefault(true) { if !hasRelayClient { - log.Fatal("To enable `Swarm.EnableHolePunching` requires `Swarm.RelayClient.Enabled` to be enabled.") + // If hole punching is explicitly enabled but the relay client is disabled then panic, + // otherwise just silently disable hole punching + if flag != config.Default { + log.Fatal("Failed to enable `Swarm.EnableHolePunching`, it requires `Swarm.RelayClient.Enabled` to be true.") + } else { + log.Info("HolePunching has been disabled due to the RelayClient being disabled.") + } + return } opts.Opts = append(opts.Opts, libp2p.EnableHolePunching()) } diff --git a/core/node/libp2p/routing.go b/core/node/libp2p/routing.go index b249611cc49..9c7351318d1 100644 --- a/core/node/libp2p/routing.go +++ b/core/node/libp2p/routing.go @@ -2,22 +2,27 @@ package libp2p import ( "context" + "fmt" + "runtime/debug" "sort" "time" "github.com/ipfs/go-ipfs/core/node/helpers" + config "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/repo" - host "github.com/libp2p/go-libp2p-core/host" - routing "github.com/libp2p/go-libp2p-core/routing" + "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/routing" dht "github.com/libp2p/go-libp2p-kad-dht" ddht "github.com/libp2p/go-libp2p-kad-dht/dual" "github.com/libp2p/go-libp2p-kad-dht/fullrt" - "github.com/libp2p/go-libp2p-pubsub" + pubsub "github.com/libp2p/go-libp2p-pubsub" namesys "github.com/libp2p/go-libp2p-pubsub-router" record "github.com/libp2p/go-libp2p-record" routinghelpers "github.com/libp2p/go-libp2p-routing-helpers" + "github.com/cenkalti/backoff/v4" "go.uber.org/fx" ) @@ -55,6 +60,8 @@ type processInitialRoutingOut struct { BaseRT BaseIpfsRouting } +type AddrInfoChan chan peer.AddrInfo + func BaseRouting(experimentalDHTClient bool) interface{} { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle, in processInitialRoutingIn) (out processInitialRoutingOut, err error) { var dr *ddht.DHT @@ -179,3 +186,80 @@ func PubsubRouter(mctx helpers.MetricsCtx, lc fx.Lifecycle, in p2pPSRoutingIn) ( }, }, psRouter, nil } + +func AutoRelayFeeder(cfgPeering config.Peering) func(fx.Lifecycle, host.Host, AddrInfoChan, *ddht.DHT) { + return func(lc fx.Lifecycle, h host.Host, peerChan AddrInfoChan, dht *ddht.DHT) { + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovering from unexpected error in AutoRelayFeeder:", r) + debug.PrintStack() + } + }() + go func() { + defer close(done) + + // Feed peers more often right after the bootstrap, then backoff + bo := backoff.NewExponentialBackOff() + bo.InitialInterval = 15 * time.Second + bo.Multiplier = 3 + bo.MaxInterval = 1 * time.Hour + bo.MaxElapsedTime = 0 // never stop + t := backoff.NewTicker(bo) + defer t.Stop() + for { + select { + case <-t.C: + case <-ctx.Done(): + return + } + + // Always feed trusted IDs (Peering.Peers in the config) + for _, trustedPeer := range cfgPeering.Peers { + if len(trustedPeer.Addrs) == 0 { + continue + } + select { + case peerChan <- trustedPeer: + case <-ctx.Done(): + return + } + } + + // Additionally, feed closest peers discovered via DHT + if dht == nil { + /* noop due to missing dht.WAN. happens in some unit tests, + not worth fixing as we will refactor this after go-libp2p 0.20 */ + continue + } + closestPeers, err := dht.WAN.GetClosestPeers(ctx, h.ID().String()) + if err != nil { + // no-op: usually 'failed to find any peer in table' during startup + continue + } + for _, p := range closestPeers { + addrs := h.Peerstore().Addrs(p) + if len(addrs) == 0 { + continue + } + dhtPeer := peer.AddrInfo{ID: p, Addrs: addrs} + select { + case peerChan <- dhtPeer: + case <-ctx.Done(): + return + } + } + } + }() + + lc.Append(fx.Hook{ + OnStop: func(_ context.Context) error { + cancel() + <-done + return nil + }, + }) + } +} diff --git a/core/node/libp2p/sec.go b/core/node/libp2p/sec.go index 65b440ec4a4..6246d2fe30d 100644 --- a/core/node/libp2p/sec.go +++ b/core/node/libp2p/sec.go @@ -1,7 +1,7 @@ package libp2p import ( - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p" noise "github.com/libp2p/go-libp2p-noise" tls "github.com/libp2p/go-libp2p-tls" @@ -30,11 +30,11 @@ func Security(enabled bool, tptConfig config.Transports) interface{} { return func() (opts Libp2pOpts) { opts.Opts = append(opts.Opts, prioritizeOptions([]priorityOption{{ priority: tptConfig.Security.TLS, - defaultPriority: 100, + defaultPriority: 200, opt: libp2p.Security(tls.ID, tls.New), }, { priority: tptConfig.Security.Noise, - defaultPriority: 300, + defaultPriority: 100, opt: libp2p.Security(noise.ID, noise.New), }})) return opts diff --git a/core/node/libp2p/smux.go b/core/node/libp2p/smux.go index 8ce540109ce..539cad30788 100644 --- a/core/node/libp2p/smux.go +++ b/core/node/libp2p/smux.go @@ -5,14 +5,14 @@ import ( "os" "strings" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "github.com/libp2p/go-libp2p" - smux "github.com/libp2p/go-libp2p-core/mux" + "github.com/libp2p/go-libp2p-core/network" mplex "github.com/libp2p/go-libp2p-mplex" yamux "github.com/libp2p/go-libp2p-yamux" ) -func yamuxTransport() smux.Multiplexer { +func yamuxTransport() network.Multiplexer { tpt := *yamux.DefaultTransport tpt.AcceptBacklog = 512 if os.Getenv("YAMUX_DEBUG") != "" { diff --git a/core/node/libp2p/transport.go b/core/node/libp2p/transport.go index c5112e9c0b8..303a70d8061 100644 --- a/core/node/libp2p/transport.go +++ b/core/node/libp2p/transport.go @@ -3,7 +3,7 @@ package libp2p import ( "fmt" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" libp2p "github.com/libp2p/go-libp2p" metrics "github.com/libp2p/go-libp2p-core/metrics" libp2pquic "github.com/libp2p/go-libp2p-quic-transport" diff --git a/core/node/storage.go b/core/node/storage.go index 3e3e90fa174..6a647ffd7bc 100644 --- a/core/node/storage.go +++ b/core/node/storage.go @@ -3,7 +3,7 @@ package node import ( "github.com/ipfs/go-datastore" blockstore "github.com/ipfs/go-ipfs-blockstore" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" "go.uber.org/fx" "github.com/ipfs/go-filestore" diff --git a/coverage/main/main.go b/coverage/main/main.go index be616e08d72..7efa0f694d4 100644 --- a/coverage/main/main.go +++ b/coverage/main/main.go @@ -1,3 +1,4 @@ +//go:build testrunmain // +build testrunmain package main diff --git a/docs/PATCH_RELEASE_TEMPLATE.md b/docs/PATCH_RELEASE_TEMPLATE.md index cd2a1819dba..1cce02a4f27 100644 --- a/docs/PATCH_RELEASE_TEMPLATE.md +++ b/docs/PATCH_RELEASE_TEMPLATE.md @@ -2,12 +2,15 @@ This process handles patch releases from version `vX.Y.Z` to `vX.Y.Z+1` assuming that `vX.Y.Z` is the latest released version of go-ipfs. +- [ ] Get temporary permissions to force-push to `release-*` branches - [ ] Fork a new branch (`release-vX.Y.Z`) from `release` and cherry-pick the relevant commits from master (or custom fixes) onto this branch -- [ ] Make a minimal changelog update tracking the relevant fixes to CHANGELOG. -- [ ] version string in `version.go` has been updated (in the `release-vX.Y.Z+1` branch). + - [ ] Use `git cherry-pick -x` so that the commit message says `(cherry picked from commit ...)` +- [ ] Make a minimal changelog update tracking the relevant fixes to CHANGELOG, as its own commit e.g. `docs: update changelog vX.Y.Z+1` +- [ ] version string in `version.go` has been updated (in the `release-vX.Y.Z+1` branch), as its own commit. - [ ] Make a PR merging `release-vX.Y.Z+1` into the release branch -- [ ] tag the merge commit in the `release` branch with `vX.Y.Z+1` -- [ ] upload to dist.ipfs.io + - This may be unnecessary, e.g. for backports +- [ ] Tag the merge commit in the `release` branch with `vX.Y.Z+1` (ensure the tag is signed) +- [ ] Upload to dist.ipfs.io 1. Build: https://github.com/ipfs/distributions#usage. 2. Pin the resulting release. 3. Make a PR against ipfs/distributions with the updated versions, including the new hash in the PR comment. diff --git a/docs/RELEASE_ISSUE_TEMPLATE.md b/docs/RELEASE_ISSUE_TEMPLATE.md index c23122bdcd0..3f276f26305 100644 --- a/docs/RELEASE_ISSUE_TEMPLATE.md +++ b/docs/RELEASE_ISSUE_TEMPLATE.md @@ -82,6 +82,7 @@ Checklist: - [ ] to [dist.ipfs.io](https://dist.ipfs.io) - [ ] to [npm-go-ipfs](https://github.com/ipfs/npm-go-ipfs) - [ ] to [chocolatey](https://chocolatey.org/packages/go-ipfs) + - [ ] Manually run [the release workflow](https://github.com/ipfs/choco-go-ipfs/actions/workflows/main.yml) - [ ] to [snap](https://snapcraft.io/ipfs) - [ ] to [github](https://github.com/ipfs/go-ipfs/releases) - [ ] use the artifacts built in CI for dist.ipfs.io: `wget "https://ipfs.io/api/v0/get?arg=/ipns/dist.ipfs.io/go-ipfs/$(curl -s https://dist.ipfs.io/go-ipfs/versions | tail -n 1)"` diff --git a/docs/config.md b/docs/config.md index fed33589712..8f2cee06fec 100644 --- a/docs/config.md +++ b/docs/config.md @@ -16,6 +16,9 @@ config file at runtime. - [`strings`](#strings) - [`duration`](#duration) - [`optionalInteger`](#optionalinteger) + - [`optionalBytes`](#optionalbytes) + - [`optionalString`](#optionalstring) + - [`optionalDuration`](#optionalduration) - [`Addresses`](#addresses) - [`Addresses.API`](#addressesapi) - [`Addresses.Gateway`](#addressesgateway) @@ -48,6 +51,7 @@ config file at runtime. - [`Gateway.NoDNSLink`](#gatewaynodnslink) - [`Gateway.HTTPHeaders`](#gatewayhttpheaders) - [`Gateway.RootRedirect`](#gatewayrootredirect) + - [`Gateway.FastDirIndexThreshold`](#gatewayfastdirindexthreshold) - [`Gateway.Writable`](#gatewaywritable) - [`Gateway.PathPrefixes`](#gatewaypathprefixes) - [`Gateway.PublicGateways`](#gatewaypublicgateways) @@ -65,6 +69,7 @@ config file at runtime. - [`Internal.Bitswap.EngineBlockstoreWorkerCount`](#internalbitswapengineblockstoreworkercount) - [`Internal.Bitswap.EngineTaskWorkerCount`](#internalbitswapenginetaskworkercount) - [`Internal.Bitswap.MaxOutstandingBytesPerPeer`](#internalbitswapmaxoutstandingbytesperpeer) + - [`Internal.UnixFSShardingSizeThreshold`](#internalunixfsshardingsizethreshold) - [`Ipns`](#ipns) - [`Ipns.RepublishPeriod`](#ipnsrepublishperiod) - [`Ipns.RecordLifetime`](#ipnsrecordlifetime) @@ -103,7 +108,6 @@ config file at runtime. - [`Swarm.DisableBandwidthMetrics`](#swarmdisablebandwidthmetrics) - [`Swarm.DisableNatPortMap`](#swarmdisablenatportmap) - [`Swarm.EnableHolePunching`](#swarmenableholepunching) - - [`Swarm.EnableAutoRelay`](#swarmenableautorelay) - [`Swarm.RelayClient`](#swarmrelayclient) - [`Swarm.RelayClient.Enabled`](#swarmrelayclientenabled) - [`Swarm.RelayClient.StaticRelays`](#swarmrelayclientstaticrelays) @@ -118,7 +122,6 @@ config file at runtime. - [`Swarm.RelayService.MaxReservationsPerPeer`](#swarmrelayservicemaxreservationsperpeer) - [`Swarm.RelayService.MaxReservationsPerIP`](#swarmrelayservicemaxreservationsperip) - [`Swarm.RelayService.MaxReservationsPerASN`](#swarmrelayservicemaxreservationsperasn) - - [`Swarm.DisableRelay`](#swarmdisablerelay) - [`Swarm.EnableAutoNATService`](#swarmenableautonatservice) - [`Swarm.ConnMgr`](#swarmconnmgr) - [`Swarm.ConnMgr.Type`](#swarmconnmgrtype) @@ -126,6 +129,9 @@ config file at runtime. - [`Swarm.ConnMgr.LowWater`](#swarmconnmgrlowwater) - [`Swarm.ConnMgr.HighWater`](#swarmconnmgrhighwater) - [`Swarm.ConnMgr.GracePeriod`](#swarmconnmgrgraceperiod) + - [`Swarm.ResourceMgr`](#swarmresourcemgr) + - [`Swarm.ResourceMgr.Enabled`](#swarmresourcemgrenabled) + - [`Swarm.ResourceMgr.Limits`](#swarmresourcemgrlimits) - [`Swarm.Transports`](#swarmtransports) - [`Swarm.Transports.Network`](#swarmtransportsnetwork) - [`Swarm.Transports.Network.TCP`](#swarmtransportsnetworktcp) @@ -140,7 +146,8 @@ config file at runtime. - [`Swarm.Transports.Multiplexers.Yamux`](#swarmtransportsmultiplexersyamux) - [`Swarm.Transports.Multiplexers.Mplex`](#swarmtransportsmultiplexersmplex) - [`DNS`](#dns) - - [`DNS.Resolvers`](#dnsresolvers) + - [`DNS.Resolvers`](#dnsresolvers) + - [`DNS.MaxCacheTTL`](#dnsmaxcachettl) @@ -188,37 +195,36 @@ documented in `ipfs config profile --help`. - `flatfs` - Configures the node to use the flatfs datastore. + Configures the node to use the flatfs datastore. Flatfs is the default datastore. - This is the most battle-tested and reliable datastore, but it's significantly - slower than the badger datastore. You should use this datastore if: + This is the most battle-tested and reliable datastore. + You should use this datastore if: - - You need a very simple and very reliable datastore and you trust your + - You need a very simple and very reliable datastore, and you trust your filesystem. This datastore stores each block as a separate file in the underlying filesystem so it's unlikely to lose data unless there's an issue with the underlying file system. - - You need to run garbage collection on a small (<= 10GiB) datastore. The - default datastore, badger, can leave several gigabytes of data behind when - garbage collecting. - - You're concerned about memory usage. In its default configuration, badger can - use up to several gigabytes of memory. + - You need to run garbage collection in a way that reclaims free space as soon as possible. + - You want to minimize memory usage. + - You are ok with the default speed of data import, or prefer to use `--nocopy`. This profile may only be applied when first initializing the node. - `badgerds` - Configures the node to use the badger datastore. - - This is the fastest datastore. Use this datastore if performance, especially - when adding many gigabytes of files, is critical. However: + Configures the node to use the experimental badger datastore. Keep in mind that this **uses an outdated badger 1.x**. + Use this datastore if some aspects of performance, + especially the speed of adding many gigabytes of files, are critical. However, be aware that: + - This datastore will not properly reclaim space when your datastore is - smaller than several gigabytes. If you run IPFS with '--enable-gc' (you have - enabled block-level garbage collection), you plan on storing very little data in + smaller than several gigabytes. If you run IPFS with `--enable-gc`, you plan on storing very little data in your IPFS node, and disk usage is more critical than performance, consider using - flatfs. - - This datastore uses up to several gigabytes of memory. + `flatfs`. + - This datastore uses up to several gigabytes of memory. + - Good for medium-size datastores, but may run into performance issues if your dataset is bigger than a terabyte. + - The current implementation is based on old badger 1.x which is no longer supported by the upstream team. This profile may only be applied when first initializing the node. @@ -270,12 +276,38 @@ does (e.g, `"1d2h4m40.01s"`). ### `optionalInteger` -Optional Integers allow specifying some numerical value which has -an implicit default when `null` or missing from the config file: +Optional integers allow specifying some numerical value which has +an implicit default when missing from the config file: -- `null`/missing (apply the default value defined in go-ipfs sources) +- `null`/missing will apply the default value defined in go-ipfs sources (`.WithDefault(value)`) - an integer between `-2^63` and `2^63-1` (i.e. `-9223372036854775808` to `9223372036854775807`) +### `optionalBytes` + +Optional Bytes allow specifying some number of bytes which has +an implicit default when missing from the config file: + +- `null`/missing (apply the default value defined in go-ipfs sources) +- a string value indicating the number of bytes, including human readable representations: + - [SI sizes](https://en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes) (metric units, powers of 1000), e.g. `1B`, `2kB`, `3MB`, `4GB`, `5TB`, โ€ฆ) + - [IEC sizes](https://en.wikipedia.org/wiki/Binary_prefix#IEC_prefixes) (binary units, powers of 1024), e.g. `1B`, `2KiB`, `3MiB`, `4GiB`, `5TiB`, โ€ฆ) + +### `optionalString` + +Optional strings allow specifying some string value which has +an implicit default when missing from the config file: + +- `null`/missing will apply the default value defined in go-ipfs sources (`.WithDefault("value")`) +- a string + +### `optionalDuration` + +Optional durations allow specifying some duration value which has +an implicit default when missing from the config file: + +- `null`/missing will apply the default value defined in go-ipfs sources (`.WithDefault("1h2m3s")`) +- a string with a valid [go duration](#duration) (e.g, `"1d2h4m40.01s"`). + ## `Addresses` Contains information about various listener addresses to be used by this node. @@ -616,6 +648,20 @@ Default: `""` Type: `string` (url) +### `Gateway.FastDirIndexThreshold` + +The maximum number of items in a directory before the Gateway switches +to a shallow, faster listing which only requires the root node. + +This allows for fast listings of big directories, without the linear slowdown caused +by reading size metadata from child nodes. + +Setting to 0 will enable fast listings for all directories. + +Default: `100` + +Type: `optionalInteger` + ### `Gateway.Writable` A boolean to configure whether the gateway is writeable or not. @@ -701,7 +747,7 @@ between content roots. - `true` - enables [subdomain gateway](#https://docs.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://*.{hostname}/` - **Requires whitelist:** make sure respective `Paths` are set. - For example, `Paths: ["/ipfs", "/ipns"]` are required for `http://{cid}.ipfs.{hostname}` and `http://{foo}.ipns.{hostname}` to work: + For example, `Paths: ["/ipfs", "/ipns"]` are required for `http://{cid}.ipfs.{hostname}` and `http://{foo}.ipns.{hostname}` to work: ```json "Gateway": { "PublicGateways": { @@ -786,7 +832,7 @@ Below is a list of the most common public gateway setups. `http://dweb.link/ipfs/{cid}` โ†’ `http://{cid}.ipfs.dweb.link` - **X-Forwarded-Proto:** if you run go-ipfs behind a reverse proxy that provides TLS, make it add a `X-Forwarded-Proto: https` HTTP header to ensure users are redirected to `https://`, not `http://`. It will also ensure DNSLink names are inlined to fit in a single DNS label, so they work fine with a wildcart TLS cert ([details](https://github.com/ipfs/in-web-browsers/issues/169)). The NGINX directive is `proxy_set_header X-Forwarded-Proto "https";`.: - + `http://dweb.link/ipfs/{cid}` โ†’ `https://{cid}.ipfs.dweb.link` `http://dweb.link/ipns/your-dnslink.site.example.com` โ†’ `https://your--dnslink-site-example-com.ipfs.dweb.link` @@ -920,6 +966,18 @@ deteriorate the quality provided to less aggressively-wanting peers. Type: `optionalInteger` (byte count, `null` means default which is 1MB) +### `Internal.UnixFSShardingSizeThreshold` + +The sharding threshold used internally to decide whether a UnixFS directory should be sharded or not. +This value is not strictly related to the size of the UnixFS directory block and any increases in +the threshold should come with being careful that block sizes stay under 2MiB in order for them to be +reliably transferable through the networking stack (IPFS peers on the public swarm tend to ignore requests for blocks bigger than 2MiB). + +Decreasing this value to 1B is functionally equivalent to the previous experimental sharding option to +shard all directories. + +Type: `optionalBytes` (`null` means default which is 256KiB) + ## `Ipns` ### `Ipns.RepublishPeriod` @@ -977,6 +1035,8 @@ Default: `cache` ## `Mounts` +**EXPERIMENTAL:** read about current limitations at [fuse.md](./fuse.md). + FUSE mount point configuration options. ### `Mounts.IPFS` @@ -1223,7 +1283,7 @@ Tells reprovider what should be announced. Valid strategies are: Default: all -Type: `string` (or unset for the default) +Type: `string` (or unset for the default, which is "all") ## `Routing` @@ -1326,27 +1386,15 @@ to [upgrade to a direct connection](https://github.com/libp2p/specs/blob/master/ through a NAT/firewall whenever possible. This feature requires `Swarm.RelayClient.Enabled` to be set to `true`. -Default: `false` +Default: `true` Type: `flag` ### `Swarm.EnableAutoRelay` -Deprecated: Set `Swarm.RelayClient.Enabled` to `true`. - -Enables "automatic relay user" mode for this node. - -Your node will automatically _use_ public relays from the network if it detects -that it cannot be reached from the public internet (e.g., it's behind a -firewall) and get a `/p2p-circuit` address from a public relay. - -This is likely the feature you're looking for, but see also: -- [`Swarm.RelayService.Enabled`](#swarmrelayserviceenabled) if your node should act as a limited relay for other peers -- Docs: [Libp2p Circuit Relay](https://docs.libp2p.io/concepts/circuit-relay/) - -Default: `false` +**REMOVED** -Type: `bool` +See `Swarm.RelayClient` instead. ### `Swarm.RelayClient` @@ -1364,14 +1412,14 @@ Your node will automatically _use_ public relays from the network if it detects that it cannot be reached from the public internet (e.g., it's behind a firewall) and get a `/p2p-circuit` address from a public relay. -Default: `false` +Default: `true` -Type: `bool` +Type: `flag` #### `Swarm.RelayClient.StaticRelays` -Your node will use these statically configured relay servers instead of -discovering public relays from the network. +Your node will use these statically configured relay servers (V1 or V2) +instead of discovering public relays V2 from the network. Default: `[]` @@ -1392,9 +1440,9 @@ Enables providing `/p2p-circuit` v2 relay service to other peers on the network. NOTE: This is the service/server part of the relay system. Disabling this will prevent this node from running as a relay server. -Use [`Swarm.EnableAutoRelay`](#swarmenableautorelay) for turning your node into a relay user. +Use [`Swarm.RelayClient.Enabled`](#swarmrelayclientenabled) for turning your node into a relay user. -Default: Enabled +Default: `true` Type: `flag` @@ -1441,7 +1489,7 @@ Default: `128` Type: `optionalInteger` -#### `Swarm.RelayService.MaxReservations` +#### `Swarm.RelayService.MaxCircuits` Maximum number of open relay connections for each peer. @@ -1492,15 +1540,9 @@ Replaced with [`Swarm.RelayService.Enabled`](#swarmrelayserviceenabled). ### `Swarm.DisableRelay` -Deprecated: Set `Swarm.Transports.Network.Relay` to `false`. - -Disables the p2p-circuit relay transport. This will prevent this node from -connecting to nodes behind relays, or accepting connections from nodes behind -relays. +**REMOVED** -Default: `false` - -Type: `bool` +Set `Swarm.Transports.Network.Relay` to `false` instead. ### `Swarm.EnableAutoNATService` @@ -1586,6 +1628,61 @@ Default: `"20s"` Type: `duration` +### `Swarm.ResourceMgr` + +The [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) allows setting limits per a scope, +and tracking recource usage over time. + +#### `Swarm.ResourceMgr.Enabled` +Enables the libp2p Network Resource Manager and auguments the default limits +using user-defined ones in `Swarm.ResourceMgr.Limits` (if present). + +Default: `false` + +Type: `flag` + +#### `Swarm.ResourceMgr.Limits` + +Map of resource limits [per scope](https://github.com/libp2p/go-libp2p-resource-manager#resource-scopes). + +The map supports fields from [`BasicLimiterConfig`](https://github.com/libp2p/go-libp2p-resource-manager/blob/v0.3.0/limit_config.go#L165-L185) +struct from [go-libp2p-resource-manager](https://github.com/libp2p/go-libp2p-resource-manager#readme). + +Example: + +```json +{ + "Swarm": { + "ResourceMgr": { + "Enabled": true, + "Limits": { + "System": { + "Conns": 1024, + "ConnsInbound": 256, + "ConnsOutbound": 1024, + "FD": 512, + "Memory": 1073741824, + "Streams": 16384, + "StreamsInbound": 4096, + "StreamsOutbound": 16384 + } + } + } + } +} +``` + +Current resource usage and a list of services, protocols, and peers can be +obtained via `ipfs swarm stats --help` + +It is also possible to adjust some runtime limits via `ipfs stats limit --help`. +Changes made via `stats limit` are persisted in `Swarm.ResourceMgr.Limits`. + +Default: `{}` (use the safe implicit defaults) + +Type: `object[string->object]` + + ### `Swarm.Transports` Configuration section for libp2p transports. An empty configuration will apply @@ -1659,8 +1756,9 @@ NATs. See also: - Docs: [Libp2p Circuit Relay](https://docs.libp2p.io/concepts/circuit-relay/) -- [`Swarm.EnableAutoRelay`](#swarmenableautorelay) for getting a public - `/p2p-circuit` address when behind a firewall. +- [`Swarm.RelayClient.Enabled`](#swarmrelayclientenabled) for getting a public +- `/p2p-circuit` address when behind a firewall. + - [`Swarm.EnableHolePunching`](#swarmenableholepunching) for direct connection upgrade through relay - [`Swarm.RelayService.Enabled`](#swarmrelayserviceenabled) for becoming a limited relay for other peers @@ -1757,7 +1855,7 @@ Type: `priority` Options for configuring DNS resolution for [DNSLink](https://docs.ipfs.io/concepts/dnslink/) and `/dns*` [Multiaddrs](https://github.com/multiformats/multiaddr/). -## `DNS.Resolvers` +### `DNS.Resolvers` Map of [FQDNs](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) to custom resolver URLs. @@ -1772,7 +1870,7 @@ Example: "eth.": "https://eth.link/dns-query", "crypto.": "https://resolver.unstoppable.io/dns-query", "libre.": "https://ns1.iriseden.fr/dns-query", - ".": "https://doh-ch.blahdns.com:4443/dns-query" + ".": "https://cloudflare-dns.com/dns-query" } } } @@ -1785,7 +1883,7 @@ Be mindful that: ```json { "eth.": "https://resolver.cloudflare-eth.com/dns-query", - "crypto.": "https://resolver.cloudflare-eth.com/dns-query + "crypto.": "https://resolver.cloudflare-eth.com/dns-query" } ``` To get all the benefits of a decentralized naming system we strongly suggest setting DoH endpoint to an empty string and running own decentralized resolver as catch-all one on localhost. @@ -1793,3 +1891,20 @@ Be mindful that: Default: `{}` Type: `object[string -> string]` + +### `DNS.MaxCacheTTL` + +Maximum duration for which entries are valid in the DoH cache. + +This allows you to cap the Time-To-Live suggested by the DNS response ([RFC2181](https://datatracker.ietf.org/doc/html/rfc2181#section-8)). +If present, the upper bound is applied to DoH resolvers in [`DNS.Resolvers`](#dnsresolvers). + +Note: this does NOT work with Go's default DNS resolver. To make this a global setting, add a `.` entry to `DNS.Resolvers` first. + +**Examples:** +* `"5m"` DNS entries are kept for 5 minutes or less. +* `"0s"` DNS entries expire as soon as they are retrieved. + +Default: Respect DNS Response TTL + +Type: `optionalDuration` diff --git a/docs/debug-guide.md b/docs/debug-guide.md index 07439c37cfe..5bb39eee564 100644 --- a/docs/debug-guide.md +++ b/docs/debug-guide.md @@ -7,6 +7,7 @@ This is a document for helping debug go-ipfs. Please add to it if you can! - [Analyzing the stack dump](#analyzing-the-stack-dump) - [Analyzing the CPU Profile](#analyzing-the-cpu-profile) - [Analyzing vars and memory statistics](#analyzing-vars-and-memory-statistics) +- [Tracing](#tracing) - [Other](#other) ### Beginning @@ -95,6 +96,11 @@ the quickest way to easily point out where the hot spots in the code are. The output is JSON formatted and includes badger store statistics, the command line run, and the output from Go's [runtime.ReadMemStats](https://golang.org/pkg/runtime/#ReadMemStats). The [MemStats](https://golang.org/pkg/runtime/#MemStats) has useful information about memory allocation and garbage collection. +### Tracing + +Experimental tracing via OpenTelemetry suite of tools is available. +See `tracing/doc.go` for more details. + ### Other If you have any questions, or want us to analyze some weird go-ipfs behaviour, diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 174e283f9fc..90206664886 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -1,13 +1,5 @@ # go-ipfs environment variables -## `LIBP2P_TCP_REUSEPORT` - -go-ipfs tries to reuse the same source port for all connections to improve NAT -traversal. If this is an issue, you can disable it by setting -`LIBP2P_TCP_REUSEPORT` to false. - -Default: true - ## `IPFS_PATH` Sets the location of the IPFS repo (where the config, blocks, etc. @@ -17,28 +9,55 @@ Default: ~/.ipfs ## `IPFS_LOGGING` -Sets the log level for go-ipfs. It can be set to one of: +Specifies the log level for go-ipfs. -* `CRITICAL` -* `ERROR` -* `WARNING` -* `NOTICE` -* `INFO` -* `DEBUG` +`IPFS_LOGGING` is a deprecated alias for the `GOLOG_LOG_LEVEL` environment variable. See below. -Logging can also be configured (on a subsystem by subsystem basis) at runtime -with the `ipfs log` command. +## `IPFS_LOGGING_FMT` -Default: `ERROR` +Specifies the log message format. -## `IPFS_LOGGING_FMT` +`IPFS_LOGGING_FMT` is a deprecated alias for the `GOLOG_LOG_FMT` environment variable. See below. + +## `GOLOG_LOG_LEVEL` + +Specifies the log-level, both globally and on a per-subsystem basis. Level can be one of: + +* `debug` +* `info` +* `warn` +* `error` +* `dpanic` +* `panic` +* `fatal` + +Per-subsystem levels can be specified with `subsystem=level`. One global level and one or more per-subsystem levels +can be specified by separating them with commas. + +Default: `error` + +Example: + +```console +GOLOG_LOG_LEVEL="error,core/server=debug" ipfs daemon +``` -Sets the log message format. Can be one of: +Logging can also be configured at runtime, both globally and on a per-subsystem basis, with the `ipfs log` command. -* `color` -* `nocolor` +## `GOLOG_LOG_FMT` -Default: `color` +Specifies the log message format. It supports the following values: + +- `color` -- human readable, colorized (ANSI) output +- `nocolor` -- human readable, plain-text output. +- `json` -- structured JSON. + +For example, to log structured JSON (for easier parsing): + +```bash +export GOLOG_LOG_FMT="json" +``` +The logging format defaults to `color` when the output is a terminal, and `nocolor` otherwise. ## `GOLOG_FILE` @@ -95,6 +114,14 @@ $ ipfs resolve -r /ipns/dnslink-test2.example.com /ipfs/bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am ``` +## `LIBP2P_TCP_REUSEPORT` + +go-ipfs tries to reuse the same source port for all connections to improve NAT +traversal. If this is an issue, you can disable it by setting +`LIBP2P_TCP_REUSEPORT` to false. + +Default: true + ## `LIBP2P_MUX_PREFS` Deprecated: Use the `Swarm.Transports.Multiplexers` config field. @@ -102,3 +129,88 @@ Deprecated: Use the `Swarm.Transports.Multiplexers` config field. Tells go-ipfs which multiplexers to use in which order. Default: "/yamux/1.0.0 /mplex/6.7.0" + +## `LIBP2P_RCMGR` + +Forces [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) +to be enabled (`1`) or disabled (`0`). +When set, overrides [`Swarm.ResourceMgr.Enabled`](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#swarmresourcemgrenabled) from the config. + +Default: use config (not set) + +## `LIBP2P_DEBUG_RCMGR` + +Enables tracing of [libp2p Network Resource Manager](https://github.com/libp2p/go-libp2p-resource-manager#readme) +and outputs it to `rcmgr.json.gz` + + +Default: disabled (not set) + +# Tracing +For advanced configuration (e.g. ratio-based sampling), see also: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md + +## `OTEL_TRACES_EXPORTER` +Specifies the exporters to use as a comma-separated string. Each exporter has a set of additional environment variables used to configure it. The following values are supported: + +- `otlp` +- `jaeger` +- `zipkin` +- `file` -- appends traces to a JSON file on the filesystem + +Setting this enables OpenTelemetry tracing. + +**NOTE** Tracing support is experimental: releases may contain tracing-related breaking changes. + +Default: "" (no exporters) + +## `OTLP Exporter` +Unless specified in this section, the OTLP exporter uses the environment variables documented here: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md + +### `OTEL_EXPORTER_OTLP_PROTOCOL` +Specifies the OTLP protocol to use, which is one of: + +- `grpc` +- `http/protobuf` + +Default: "grpc" + +## `Jaeger Exporter` + +See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter + +## `Zipkin Exporter` +See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#zipkin-exporter + +## `File Exporter` +### `OTEL_EXPORTER_FILE_PATH` +Specifies the filesystem path for the JSON file. + +Default: "$PWD/traces.json" + +### How to use Jaeger UI + +One can use the `jaegertracing/all-in-one` Docker image to run a full Jaeger +stack and configure go-ipfs to publish traces to it (here, in an ephemeral +container): + +```console +$ docker run --rm -it --name jaeger \ + -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ + -p 5775:5775/udp \ + -p 6831:6831/udp \ + -p 6832:6832/udp \ + -p 5778:5778 \ + -p 16686:16686 \ + -p 14268:14268 \ + -p 14268:14269 \ + -p 14250:14250 \ + -p 9411:9411 \ + jaegertracing/all-in-one +``` + +Then, in other terminal, start go-ipfs with Jaeger tracing enabled: +``` +$ OTEL_TRACES_EXPORTER=jaeger ipfs daemon +``` + +Finally, the [Jaeger UI](https://github.com/jaegertracing/jaeger-ui#readme) is available at http://localhost:16686 diff --git a/docs/examples/go-ipfs-as-a-library/go.mod b/docs/examples/go-ipfs-as-a-library/go.mod index 00b294b63a6..9d574ed0450 100644 --- a/docs/examples/go-ipfs-as-a-library/go.mod +++ b/docs/examples/go-ipfs-as-a-library/go.mod @@ -1,12 +1,236 @@ module github.com/ipfs/go-ipfs/examples/go-ipfs-as-a-library -go 1.16 +go 1.17 require ( - github.com/ipfs/go-ipfs v0.10.0 - github.com/ipfs/go-ipfs-config v0.16.0 - github.com/ipfs/go-ipfs-files v0.0.8 - github.com/ipfs/interface-go-ipfs-core v0.5.1 - github.com/libp2p/go-libp2p-core v0.11.0 - github.com/multiformats/go-multiaddr v0.4.0 + github.com/ipfs/go-ipfs v0.12.3-0.20220504184349-34aac1ee4316 + github.com/ipfs/go-ipfs-files v0.1.1 + github.com/ipfs/interface-go-ipfs-core v0.7.0 + github.com/libp2p/go-libp2p-core v0.15.1 + github.com/multiformats/go-multiaddr v0.5.0 +) + +require ( + bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect + github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect + github.com/Stebalien/go-bitfield v0.0.1 // indirect + github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/btcsuite/btcd v0.22.0-beta // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cenkalti/backoff/v4 v4.1.2 // indirect + github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cheekybits/genny v1.0.0 // indirect + github.com/containerd/cgroups v1.0.3 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect + github.com/cskr/pubsub v1.0.2 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/dgraph-io/badger v1.6.2 // indirect + github.com/dgraph-io/ristretto v0.0.2 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/elastic/gosigar v0.14.2 // indirect + github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/huin/goupnp v1.0.3 // indirect + github.com/ipfs/bbloom v0.0.4 // indirect + github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-bitswap v0.6.0 // indirect + github.com/ipfs/go-block-format v0.0.3 // indirect + github.com/ipfs/go-blockservice v0.3.0 // indirect + github.com/ipfs/go-cid v0.1.0 // indirect + github.com/ipfs/go-cidutil v0.0.2 // indirect + github.com/ipfs/go-datastore v0.5.1 // indirect + github.com/ipfs/go-ds-badger v0.3.0 // indirect + github.com/ipfs/go-ds-flatfs v0.5.1 // indirect + github.com/ipfs/go-ds-leveldb v0.5.0 // indirect + github.com/ipfs/go-ds-measure v0.2.0 // indirect + github.com/ipfs/go-fetcher v1.6.1 // indirect + github.com/ipfs/go-filestore v1.2.0 // indirect + github.com/ipfs/go-fs-lock v0.0.7 // indirect + github.com/ipfs/go-graphsync v0.13.1 // indirect + github.com/ipfs/go-ipfs-blockstore v1.2.0 // indirect + github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect + github.com/ipfs/go-ipfs-delay v0.0.1 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.1.0 // indirect + github.com/ipfs/go-ipfs-exchange-offline v0.2.0 // indirect + github.com/ipfs/go-ipfs-keystore v0.0.2 // indirect + github.com/ipfs/go-ipfs-pinner v0.2.1 // indirect + github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect + github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipfs-provider v0.7.1 // indirect + github.com/ipfs/go-ipfs-routing v0.2.1 // indirect + github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-format v0.4.0 // indirect + github.com/ipfs/go-ipld-git v0.1.1 // indirect + github.com/ipfs/go-ipld-legacy v0.1.1 // indirect + github.com/ipfs/go-ipns v0.1.2 // indirect + github.com/ipfs/go-log v1.0.5 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/ipfs/go-merkledag v0.6.0 // indirect + github.com/ipfs/go-metrics-interface v0.0.1 // indirect + github.com/ipfs/go-mfs v0.2.1 // indirect + github.com/ipfs/go-namesys v0.5.0 // indirect + github.com/ipfs/go-path v0.3.0 // indirect + github.com/ipfs/go-peertaskqueue v0.7.1 // indirect + github.com/ipfs/go-unixfs v0.3.1 // indirect + github.com/ipfs/go-unixfsnode v1.4.0 // indirect + github.com/ipfs/go-verifcid v0.0.1 // indirect + github.com/ipld/go-codec-dagpb v1.4.0 // indirect + github.com/ipld/go-ipld-prime v0.16.0 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/jbenet/goprocess v0.1.4 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/cpuid/v2 v2.0.12 // indirect + github.com/koron/go-ssdp v0.0.2 // indirect + github.com/libp2p/go-buffer-pool v0.0.2 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-conn-security-multistream v0.3.0 // indirect + github.com/libp2p/go-doh-resolver v0.4.0 // indirect + github.com/libp2p/go-eventbus v0.2.1 // indirect + github.com/libp2p/go-flow-metrics v0.0.3 // indirect + github.com/libp2p/go-libp2p v0.19.1 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-blankhost v0.3.0 // indirect + github.com/libp2p/go-libp2p-discovery v0.6.0 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.15.0 // indirect + github.com/libp2p/go-libp2p-kbucket v0.4.7 // indirect + github.com/libp2p/go-libp2p-loggables v0.1.0 // indirect + github.com/libp2p/go-libp2p-mplex v0.7.0 // indirect + github.com/libp2p/go-libp2p-nat v0.1.0 // indirect + github.com/libp2p/go-libp2p-noise v0.4.0 // indirect + github.com/libp2p/go-libp2p-peerstore v0.6.0 // indirect + github.com/libp2p/go-libp2p-pnet v0.2.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.6.1 // indirect + github.com/libp2p/go-libp2p-pubsub-router v0.5.0 // indirect + github.com/libp2p/go-libp2p-quic-transport v0.17.0 // indirect + github.com/libp2p/go-libp2p-record v0.1.3 // indirect + github.com/libp2p/go-libp2p-resource-manager v0.3.0 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.2.3 // indirect + github.com/libp2p/go-libp2p-swarm v0.10.2 // indirect + github.com/libp2p/go-libp2p-tls v0.4.1 // indirect + github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 // indirect + github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db // indirect + github.com/libp2p/go-libp2p-yamux v0.9.1 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect + github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.0 // indirect + github.com/libp2p/go-openssl v0.0.7 // indirect + github.com/libp2p/go-reuseport v0.1.0 // indirect + github.com/libp2p/go-reuseport-transport v0.1.0 // indirect + github.com/libp2p/go-stream-muxer-multistream v0.4.0 // indirect + github.com/libp2p/go-tcp-transport v0.5.1 // indirect + github.com/libp2p/go-ws-transport v0.6.0 // indirect + github.com/libp2p/go-yamux/v3 v3.1.1 // indirect + github.com/libp2p/zeroconf/v2 v2.1.1 // indirect + github.com/lucas-clemente/quic-go v0.27.0 // indirect + github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect + github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/miekg/dns v1.1.48 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.0.4 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multibase v0.0.3 // indirect + github.com/multiformats/go-multicodec v0.4.1 // indirect + github.com/multiformats/go-multihash v0.1.0 // indirect + github.com/multiformats/go-multistream v0.3.0 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/openzipkin/zipkin-go v0.4.0 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/prometheus/client_golang v1.12.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.33.0 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/raulk/clock v1.1.0 // indirect + github.com/raulk/go-watchdog v1.2.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/syndtr/goleveldb v1.0.0 // indirect + github.com/tidwall/gjson v1.14.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/wI2L/jsondiff v0.2.0 // indirect + github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect + github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect + github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 // indirect + github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect + github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect + go.opencensus.io v0.23.0 // indirect + go.opentelemetry.io/otel v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/jaeger v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.6.3 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.6.3 // indirect + go.opentelemetry.io/otel/sdk v1.6.3 // indirect + go.opentelemetry.io/otel/trace v1.6.3 // indirect + go.opentelemetry.io/proto/otlp v0.15.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/dig v1.14.0 // indirect + go.uber.org/fx v1.16.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.21.0 // indirect + go4.org v0.0.0-20200411211856-f5505b9728dd // indirect + golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect + golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.10 // indirect + golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect + google.golang.org/grpc v1.45.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/docs/examples/go-ipfs-as-a-library/go.sum b/docs/examples/go-ipfs-as-a-library/go.sum index bb26555cc37..6b9a1421255 100644 --- a/docs/examples/go-ipfs-as-a-library/go.sum +++ b/docs/examples/go-ipfs-as-a-library/go.sum @@ -34,9 +34,10 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -contrib.go.opencensus.io/exporter/prometheus v0.3.0/go.mod h1:rpCPVQKhiyH8oomWgm34ZmgIdZa8OVYO5WAIygPbBBE= +contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -52,7 +53,9 @@ github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETF github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -63,6 +66,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= +github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -79,8 +84,9 @@ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -113,24 +119,38 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= +github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -139,14 +159,20 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -169,13 +195,19 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWeVx9BjvqBsnC/8RUlAYpIFmPvgROcw0n1scE= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -183,28 +215,33 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= +github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -214,15 +251,25 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -232,6 +279,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -267,8 +316,9 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -278,15 +328,17 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -310,23 +362,29 @@ github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE0 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1/go.mod h1:jvfsLIxk0fY/2BKSQ1xf2406AKA5dwMmKKv0ADcOfN8= @@ -348,6 +406,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -362,8 +421,9 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI= github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -371,47 +431,49 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= +github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= -github.com/ipfs/go-bitswap v0.1.3/go.mod h1:YEQlFy0kkxops5Vy+OxWdRSEZIoS7I7KDIwoa5Chkps= github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM= github.com/ipfs/go-bitswap v0.3.4/go.mod h1:4T7fvNv/LmOys+21tnLzGKncMeeXUYUd1nUiJ2teMvI= -github.com/ipfs/go-bitswap v0.4.0 h1:bLiqrpef1na4wdqGLqHKv954s1zz6KFghfmQWCPjBik= -github.com/ipfs/go-bitswap v0.4.0/go.mod h1:J2sAsp9UKxLgHDektSy3y3Q9OfQjM9sjhKBR1dlwrMg= +github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= +github.com/ipfs/go-bitswap v0.6.0 h1:f2rc6GZtoSFhEIzQmddgGiel9xntj02Dg0ZNf2hSC+w= +github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= -github.com/ipfs/go-blockservice v0.1.1/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= -github.com/ipfs/go-blockservice v0.1.3/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= github.com/ipfs/go-blockservice v0.1.4/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= -github.com/ipfs/go-blockservice v0.1.7 h1:yVe9te0M7ow8i+PPkx03YFSpxqzXx594d6h+34D6qMg= -github.com/ipfs/go-blockservice v0.1.7/go.mod h1:GmS+BAt4hrwBKkzE11AFDQUrnvqjwFatGS2MY7wOjEM= +github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= +github.com/ipfs/go-blockservice v0.3.0 h1:cDgcZ+0P0Ih3sl8+qjFr2sVaMdysg/YZpLj5WJ8kiiw= +github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= +github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/ipfs/go-cidutil v0.0.2 h1:CNOboQf1t7Qp0nuNh8QMmhJs0+Q//bRL1axtCnIB1Yo= github.com/ipfs/go-cidutil v0.0.2/go.mod h1:ewllrvrxG6AMYStla3GD7Cqn+XYSLqjK0vc+086tB6s= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= -github.com/ipfs/go-datastore v0.3.0/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= -github.com/ipfs/go-datastore v0.4.6 h1:zU2cmweykxJ+ziXnA2cPtsLe8rdR/vrthOipLPuf6kc= -github.com/ipfs/go-datastore v0.4.6/go.mod h1:XSipLSc64rFKSFRFGo1ecQl+WhYce3K7frtpHkyPFUc= +github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= +github.com/ipfs/go-datastore v0.5.1 h1:WkRhLuISI+XPD0uk3OskB0fYFSyqK8Ob5ZYew9Qa1nQ= +github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= @@ -419,67 +481,76 @@ github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaH github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk= github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= -github.com/ipfs/go-ds-badger v0.2.6/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= -github.com/ipfs/go-ds-badger v0.2.7 h1:ju5REfIm+v+wgVnQ19xGLYPHYHbYLR6qJfmMbCDSK1I= github.com/ipfs/go-ds-badger v0.2.7/go.mod h1:02rnztVKA4aZwDuaRPTf8mpqcKmXP7mLl6JPxd14JHA= -github.com/ipfs/go-ds-flatfs v0.4.5 h1:4QceuKEbH+HVZ2ZommstJMi3o3II+dWS3IhLaD7IGHs= -github.com/ipfs/go-ds-flatfs v0.4.5/go.mod h1:e4TesLyZoA8k1gV/yCuBTnt2PJtypn4XUlB5n8KQMZY= +github.com/ipfs/go-ds-badger v0.3.0 h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro= +github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= +github.com/ipfs/go-ds-flatfs v0.5.1 h1:ZCIO/kQOS/PSh3vcF1H6a8fkRGS7pOfwfPdx4n/KJH4= +github.com/ipfs/go-ds-flatfs v0.5.1/go.mod h1:RWTV7oZD/yZYBKdbVIFXTX2fdY2Tbvl94NsWqmoyAX4= github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8= github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ds-leveldb v0.4.2 h1:QmQoAJ9WkPMUfBLnu1sBVy0xWWlJPg0m4kRAiJL9iaw= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-ds-measure v0.1.0 h1:vE4TyY4aeLeVgnnPBC5QzKIjKrqzha0NCujTfgvVbVQ= -github.com/ipfs/go-ds-measure v0.1.0/go.mod h1:1nDiFrhLlwArTME1Ees2XaBOl49OoCgd2A3f8EchMSY= -github.com/ipfs/go-fetcher v1.5.0 h1:oreKTKBzja3S09rSmoZlA3KGVlRiUbJ1pQjtB4K6y3w= +github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUNumo= +github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= +github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= +github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= github.com/ipfs/go-fetcher v1.5.0/go.mod h1:5pDZ0393oRF/fHiLmtFZtpMNBQfHOYNPtryWedVuSWE= -github.com/ipfs/go-filestore v0.0.3 h1:MhZ1jT5K3NewZwim6rS/akcJLm1xM+r6nz6foeB9EwE= -github.com/ipfs/go-filestore v0.0.3/go.mod h1:dvXRykFzyyXN2CdNlRGzDAkXMDPyI+D7JE066SiKLSE= +github.com/ipfs/go-fetcher v1.6.1 h1:UFuRVYX5AIllTiRhi5uK/iZkfhSpBCGX7L70nSZEmK8= +github.com/ipfs/go-fetcher v1.6.1/go.mod h1:27d/xMV8bodjVs9pugh/RCjjK2OZ68UgAMspMdingNo= +github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3yU= +github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.8.0 h1:Zhh6QdTqdipYHD71ncLO8eA6c8EGUTOoJ4Rqybw3K+o= -github.com/ipfs/go-graphsync v0.8.0/go.mod h1:CLxN859dUTcXCav1DvNvmAUWPZfmNLjlGLJYy+c3dlM= -github.com/ipfs/go-ipfs v0.10.0 h1:+b6QNlNvYTTEUPIFab484t1Ubylz+fBczIK+q0UV62Q= -github.com/ipfs/go-ipfs v0.10.0/go.mod h1:HsnRkQdpruG6JMaycJyrlLwJdduw1dJv2rEPgWxdJvA= +github.com/ipfs/go-graphsync v0.13.1 h1:lWiP/WLycoPUYyj3IDEi1GJNP30kFuYOvimcfeuZyQs= +github.com/ipfs/go-graphsync v0.13.1/go.mod h1:y8e8G6CmZeL9Srvx1l15CtGiRdf3h5JdQuqPz/iYL0A= +github.com/ipfs/go-ipfs v0.12.3-0.20220504184349-34aac1ee4316 h1:Q/CuIOQOFkWVhsqmYydZ/C5KN82wCV+JPeK5XR5pNzY= +github.com/ipfs/go-ipfs v0.12.3-0.20220504184349-34aac1ee4316/go.mod h1:ujgVaB9pWbXPYZ7oGGogJOB9sU+fPXqk+7iRaBURojQ= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ= -github.com/ipfs/go-ipfs-blockstore v0.1.6 h1:+RNM/gkTF6lzLPtt/xqjEUXJuG0lFwAiv+MV8MoAhvA= -github.com/ipfs/go-ipfs-blockstore v0.1.6/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ= +github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= +github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= +github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= +github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.6.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= -github.com/ipfs/go-ipfs-config v0.16.0 h1:CBtIYyp/iWIczCv83bmfge8EA2KqxOOfqmETs3tUnnU= -github.com/ipfs/go-ipfs-config v0.16.0/go.mod h1:wz2lKzOjgJeYJa6zx8W9VT7mz+iSd0laBMqS/9wmX6A= +github.com/ipfs/go-ipfs-cmds v0.8.1/go.mod h1:y0bflH6m4g6ary4HniYt98UqbrVnRxmRarzeMdLIUn0= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= -github.com/ipfs/go-ipfs-ds-help v0.1.1 h1:IW/bXGeaAZV2VH0Kuok+Ohva/zHkHmeLFBxC1k7mNPc= github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs= -github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= +github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= -github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-interface v0.1.0 h1:TiMekCrOGQuWYtZO3mf4YJXDIdNgnKWZ9IE3fGlnWfo= +github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-exchange-offline v0.1.1/go.mod h1:vTiBRIbzSwDD0OWm+i3xeT0mO7jG2cbJYatp3HPk5XY= +github.com/ipfs/go-ipfs-exchange-offline v0.2.0 h1:2PF4o4A7W656rC0RxuhUace997FTcDTcIQ6NoEtyjAI= +github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= +github.com/ipfs/go-ipfs-files v0.1.1 h1:/MbEowmpLo9PJTEQk16m9rKzUHjeP4KRU9nWJyJO324= +github.com/ipfs/go-ipfs-files v0.1.1/go.mod h1:8xkIrMWH+Y5P7HvJ4Yc5XWwIW2e52dyXUiC0tZyjDbM= github.com/ipfs/go-ipfs-keystore v0.0.2 h1:Fa9xg9IFD1VbiZtrNLzsD0GuELVHUFXCWF64kCPfEXU= github.com/ipfs/go-ipfs-keystore v0.0.2/go.mod h1:H49tRmibOEs7gLMgbOsjC4dqh1u5e0R/SWuc2ScfgSo= -github.com/ipfs/go-ipfs-pinner v0.1.2 h1:Ve9OBhL6eg5+tVqEnIhPZOCXDtMjB+OhOohVZxPUxms= -github.com/ipfs/go-ipfs-pinner v0.1.2/go.mod h1:/u9kMe+TyQybN21O5OBicdyx3x93lVI77PCtiTnArUk= +github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= +github.com/ipfs/go-ipfs-pinner v0.2.1/go.mod h1:l1AtLL5bovb7opnG77sh4Y10waINz3Y1ni6CvTzx7oo= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-provider v0.6.1 h1:4VenAH1J5XH+/mgM2Y7p+QN3wlk7CInMDG8rsT2CGW4= -github.com/ipfs/go-ipfs-provider v0.6.1/go.mod h1:I4Cig3InhftbRJohph76Qy/P2uKEZILNGiKvDJmmC28= +github.com/ipfs/go-ipfs-provider v0.7.1 h1:eKToBUAb6ZY8iiA6AYVxzW4G1ep67XUaaEBUIYpxhfw= +github.com/ipfs/go-ipfs-provider v0.7.1/go.mod h1:QwdDYRYnC5sYGLlOwVDY/0ZB6T3zcMtu+5+GdGeUuw8= github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= -github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-routing v0.2.1 h1:E+whHWhJkdN9YeoHZNj5itzc+OR292AJ2uE9FFiW0BY= +github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= @@ -490,14 +561,15 @@ github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5 github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= -github.com/ipfs/go-ipld-format v0.2.0 h1:xGlJKkArkmBvowr+GMCX0FEZtkro71K1AwiKnL37mwA= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= +github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= +github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.1.0 h1:wxkkc4k8cnvIGIjPO0waJCe7SHEyFgl+yQdafdjGrpA= github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= -github.com/ipfs/go-ipns v0.0.2/go.mod h1:WChil4e0/m9cIINWLxZe1Jtf77oz5L05rO2ei/uKJ5U= -github.com/ipfs/go-ipns v0.1.0/go.mod h1:3IbsuPkR6eAGcnx+E7j6HpOSbSQJPZ6zlRj+NK3jPxQ= +github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= +github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.1.2 h1:O/s/0ht+4Jl9+VoxoUo0zaHjnZUS+aBQIKTuzdZ/ucI= github.com/ipfs/go-ipns v0.1.2/go.mod h1:ioQ0j02o6jdIVW+bmi18f4k2gRf0AV3kZ9KeHYHICnQ= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= @@ -511,57 +583,67 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.3.0 h1:31Re/cPqFHpsRHgyVwjWADPoF0otB1WrjTy8ZFYwEZU= github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= +github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= -github.com/ipfs/go-merkledag v0.1.0/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= -github.com/ipfs/go-merkledag v0.3.0/go.mod h1:4pymaZLhSLNVuiCITYrpViD6vmfZ/Ws4n/L9tfNv3S4= -github.com/ipfs/go-merkledag v0.3.1/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= -github.com/ipfs/go-merkledag v0.4.0 h1:ixNu/5MJSaT/Qs073T0/HsWKwnOoBgqSq1g+GaJIen0= -github.com/ipfs/go-merkledag v0.4.0/go.mod h1:XshXBkhyeS63YNGisLL1uDSfuTyrQIxVUOg3ojR5MOE= +github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= +github.com/ipfs/go-merkledag v0.6.0 h1:oV5WT2321tS4YQVOPgIrWHvJ0lJobRTerU+i9nmUCuA= +github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= -github.com/ipfs/go-mfs v0.1.2 h1:DlelNSmH+yz/Riy0RjPKlooPg0KML4lXGdLw7uZkfAg= -github.com/ipfs/go-mfs v0.1.2/go.mod h1:T1QBiZPEpkPLzDqEJLNnbK55BVKVlNi2a+gVm4diFo0= -github.com/ipfs/go-namesys v0.3.1 h1:DqmeXlVODejOyECAqoqhSB5JGRv8aRFhtG0oPDmxsMc= -github.com/ipfs/go-namesys v0.3.1/go.mod h1:/BL4xk8LP5Lq82AmaRKyxZv/eYRlumNiU9SZUe1Hlps= +github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= +github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDWP88= +github.com/ipfs/go-namesys v0.5.0 h1:vZEkdqxRiSnxBBJrvYTkwHYBFgibGUSpNtg9BHRyN+o= +github.com/ipfs/go-namesys v0.5.0/go.mod h1:zZOme8KDAUYDl4f5MnWSiTRhoxcM7kLkZIyps/HV/S0= github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= github.com/ipfs/go-path v0.0.9/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8= github.com/ipfs/go-path v0.1.1/go.mod h1:vC8q4AKOtrjJz2NnllIrmr2ZbGlF5fW2OKKyhV9ggb0= -github.com/ipfs/go-path v0.1.2 h1:yQxN9JNhO4KbaaYtVgVpIH0BQDzn5Zpl5A6to93O7Ck= -github.com/ipfs/go-path v0.1.2/go.mod h1:3DdbxZb0PtT0g3UlMqyzms1UBKPc0pQ2NHx5/XScYdY= +github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= +github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= +github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY= -github.com/ipfs/go-peertaskqueue v0.4.0 h1:x1hFgA4JOUJ3ntPfqLRu6v4k6kKL0p07r3RSg9JNyHI= -github.com/ipfs/go-peertaskqueue v0.4.0/go.mod h1:KL9F49hXJMoXCad8e5anivjN+kWdr+CyGcyh4K6doLc= -github.com/ipfs/go-pinning-service-http-client v0.1.0/go.mod h1:tcCKmlkWWH9JUUkKs8CrOZBanacNc1dmKLfjlyXAMu4= -github.com/ipfs/go-unixfs v0.1.0/go.mod h1:lysk5ELhOso8+Fed9U1QTGey2ocsfaZ18h0NCO2Fj9s= +github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= +github.com/ipfs/go-peertaskqueue v0.7.1 h1:7PLjon3RZwRQMgOTvYccZ+mjzkmds/7YzSWKFlBAypE= +github.com/ipfs/go-peertaskqueue v0.7.1/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= +github.com/ipfs/go-pinning-service-http-client v0.1.1/go.mod h1:i6tC2nWOnJbZZUQPgxOlrg4CX8bhQZMh4II09FxvD58= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= -github.com/ipfs/go-unixfs v0.2.5 h1:irj/WzIcgTBay48mSMUYDbKlIzIocXWcuUUsi5qOMOE= -github.com/ipfs/go-unixfs v0.2.5/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= +github.com/ipfs/go-unixfs v0.3.1 h1:LrfED0OGfG98ZEegO4/xiprx2O+yS+krCMQSp7zLVv8= +github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.1.3 h1:IyqJBGIEvcHvll1wDDVIHOEVXnE+IH6tjzTWpZ6kGiI= -github.com/ipfs/go-unixfsnode v1.1.3/go.mod h1:ZZxUM5wXBC+G0Co9FjrYTOm+UlhZTjxLfRYdWY9veZ4= +github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= +github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/interface-go-ipfs-core v0.4.0/go.mod h1:UJBcU6iNennuI05amq3FQ7g0JHUkibHFAfhfUIy927o= -github.com/ipfs/interface-go-ipfs-core v0.5.1 h1:1KMM7RkjUD8W5fSoRsa9xR6ZMzeL8fLHOUM1UEW9Y4M= -github.com/ipfs/interface-go-ipfs-core v0.5.1/go.mod h1:lNBJrdXHtWS46evMPBdWtDQMDsrKcGbxCOGoKLkztOE= -github.com/ipfs/tar-utils v0.0.1/go.mod h1:ACflm9wXvV9w0eMJt6yYXxS2zuIV+yXGNwbuq1bhLeE= -github.com/ipld/go-car v0.3.1/go.mod h1:dPkEWeAK8KaVvH5TahaCs6Mncpd4lDMpkbs0/SPzuVs= +github.com/ipfs/interface-go-ipfs-core v0.7.0 h1:7tb+2upz8oCcjIyjo1atdMk+P+u7wPmI+GksBlLE8js= +github.com/ipfs/interface-go-ipfs-core v0.7.0/go.mod h1:lF27E/nnSPbylPqKVXGZghal2hzifs3MmjyiEjnc9FY= +github.com/ipfs/tar-utils v0.0.2/go.mod h1:4qlnRWgTVljIMhSG2SqRYn66NT+3wrv/kZt9V+eqxDM= +github.com/ipld/go-car v0.3.2 h1:V9wt/80FNfbMRWSD98W5br6fyjUAyVgI2lDOTZX16Lg= +github.com/ipld/go-car v0.3.2/go.mod h1:WEjynkVt04dr0GwJhry0KlaTeSDEiEYyMPOxDBQ17KE= +github.com/ipld/go-car/v2 v2.1.1 h1:saaKz4nC0AdfCGHLYKeXLGn8ivoPC54fyS55uyOLKwA= +github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= github.com/ipld/go-codec-dagpb v1.2.0/go.mod h1:6nBN7X7h8EOsEejZGqC7tej5drsdBAXbMHyBT+Fne5s= -github.com/ipld/go-codec-dagpb v1.3.0 h1:czTcaoAuNNyIYWs6Qe01DJ+sEX7B+1Z0LcXjSatMGe8= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= +github.com/ipld/go-codec-dagpb v1.3.1/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= +github.com/ipld/go-codec-dagpb v1.4.0 h1:VqADPIFng8G4vz5EQytmmcx/2gEgOHfBuw/kIuCgDAY= +github.com/ipld/go-codec-dagpb v1.4.0/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= -github.com/ipld/go-ipld-prime v0.12.2 h1:StIquYvKIRuSEAtjJDr39fyzBtziioHPwVC75tBiXzo= -github.com/ipld/go-ipld-prime v0.12.2/go.mod h1:PaeLYq8k6dJLmDUSLrzkEpoGV4PEfe/1OtFN/eALOc8= +github.com/ipld/go-ipld-prime v0.12.3/go.mod h1:PaeLYq8k6dJLmDUSLrzkEpoGV4PEfe/1OtFN/eALOc8= +github.com/ipld/go-ipld-prime v0.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= +github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= +github.com/ipld/go-ipld-prime v0.16.0 h1:RS5hhjB/mcpeEPJvfyj0qbOj/QL+/j05heZ0qa97dVo= +github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -578,6 +660,12 @@ github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsj github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -588,9 +676,9 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -604,12 +692,15 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -619,15 +710,16 @@ github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= -github.com/libp2p/go-addr-util v0.1.0 h1:acKsntI33w2bTU7tC9a0SaPimJGfSI0bFKC18ChxeVI= github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= @@ -641,8 +733,8 @@ github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5 github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-conn-security-multistream v0.3.0 h1:9UCIKlBL1hC9u7nkMXpD1nkc/T53PKMAn3/k9ivBAVc= github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= -github.com/libp2p/go-doh-resolver v0.3.1 h1:1wbVGkB4Tdj4WEvjAuYknOPyt4vSSDn9thnj13pKPaY= -github.com/libp2p/go-doh-resolver v0.3.1/go.mod h1:y5go1ZppAq9N2eppbX0xON01CyPBeUg2yS6BTssssog= +github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+0S7FQqw= +github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= @@ -659,14 +751,15 @@ github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniV github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= -github.com/libp2p/go-libp2p v0.14.0/go.mod h1:dsQrWLAoIn+GkHPN/U+yypizkHiB9tnv79Os+kSgQ4Q= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= github.com/libp2p/go-libp2p v0.14.4/go.mod h1:EIRU0Of4J5S8rkockZM7eJp2S0UrCyi55m2kJVru3rM= -github.com/libp2p/go-libp2p v0.15.0-rc.1.0.20211021081216-db8f9c6fddb5 h1:nE20CmFlCbwN56/3bADccjHEvbM9E9hFe7Y+0ebdpig= -github.com/libp2p/go-libp2p v0.15.0-rc.1.0.20211021081216-db8f9c6fddb5/go.mod h1:P+WgjkSS2d8eBj+NvkyKo0nb8fJAC04G+cCex0ZMcvI= +github.com/libp2p/go-libp2p v0.16.0/go.mod h1:ump42BsirwAWxKzsCiFnTtN1Yc+DuPu76fyMX364/O4= +github.com/libp2p/go-libp2p v0.19.1 h1:ysBA1vDxhvgy9WmXpDeuk082EakewbJAwfU+ApdTG6I= +github.com/libp2p/go-libp2p v0.19.1/go.mod h1:Ki9jJXLO2YqrTIFxofV7Twyd3INWPT97+r8hGt7XPjI= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= -github.com/libp2p/go-libp2p-asn-util v0.1.0 h1:rABPCO77SjdbJ/eJ/ynIo8vWICy1VEnL5JAxJbQLo1E= github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= @@ -675,19 +768,20 @@ github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRk github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= -github.com/libp2p/go-libp2p-autonat v0.5.0 h1:/+3+4NcQV47DQ/duvRyFDP8oxv6CQTvSKYD5iWoPcYs= -github.com/libp2p/go-libp2p-autonat v0.5.0/go.mod h1:085tmmuXn0nXgFwuF7a2tt4UxgTjuapbuml27v4htKY= +github.com/libp2p/go-libp2p-autonat v0.6.0/go.mod h1:bFC6kY8jwzNNWoqc8iGE57vsfwyJ/lP4O4DOV1e0B2o= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= -github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk= github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-blankhost v0.3.0 h1:kTnLArltMabZlzY63pgGDA4kkUcLkBFSM98zBssn/IY= +github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU= github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= -github.com/libp2p/go-libp2p-circuit v0.4.0 h1:eqQ3sEYkGTtybWgr6JLqJY6QLtPWRErvFjFDfAOO1wc= github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= +github.com/libp2p/go-libp2p-circuit v0.6.0 h1:rw/HlhmUB3OktS/Ygz6+2XABOmHKzZpPUuMNUMosj8w= +github.com/libp2p/go-libp2p-circuit v0.6.0/go.mod h1:kB8hY+zCpMeScyvFrKrGicRdid6vNXbunKE4rXATZ0M= github.com/libp2p/go-libp2p-connmgr v0.2.4 h1:TMS0vc0TCBomtQJyWr7fYxcVYYhx+q/2gF++G5Jkl/w= github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQiQfKhHCCs1++ufn0= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= @@ -718,8 +812,11 @@ github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8= github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= -github.com/libp2p/go-libp2p-core v0.11.0 h1:75jAgdA+IChNa+/mZXogfmrGkgwxkVvxmIC7pV+F6sI= github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.14.0/go.mod h1:tLasfcVdTXnixsLB0QYaT1syJOhsbrhG7q6pGrHtBg8= +github.com/libp2p/go-libp2p-core v0.15.1 h1:0RY+Mi/ARK9DgG1g9xVQLb8dDaaU8tCePMtGALEfBnM= +github.com/libp2p/go-libp2p-core v0.15.1/go.mod h1:agSaboYM4hzB1cWekgVReqV5M4g5M+2eNNejV+1EEhs= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= @@ -728,8 +825,8 @@ github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFT github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= -github.com/libp2p/go-libp2p-discovery v0.5.1 h1:CJylx+h2+4+s68GvrM4pGNyfNhOYviWBPtVv5PA7sfo= -github.com/libp2p/go-libp2p-discovery v0.5.1/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= +github.com/libp2p/go-libp2p-discovery v0.6.0 h1:1XdPmhMJr8Tmj/yUfkJMIi8mgwWrLUsCB3bMxdT+DSo= +github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= github.com/libp2p/go-libp2p-gostream v0.3.0/go.mod h1:pLBQu8db7vBMNINGsAwLL/ZCE8wng5V1FThoaE5rNjc= github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= @@ -738,9 +835,8 @@ github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= -github.com/libp2p/go-libp2p-kad-dht v0.11.1/go.mod h1:5ojtR2acDPqh/jXf5orWy8YGb8bHQDS+qeDcoscL/PI= -github.com/libp2p/go-libp2p-kad-dht v0.13.1 h1:wQgzOpoc+dcPVDb3h0HNWUjon5JiYEqsA4iNBUtIA7A= -github.com/libp2p/go-libp2p-kad-dht v0.13.1/go.mod h1:iVdxmsKHVPQSCGPP4V/A+tDFCLsxrREZUBX8ohOcKDw= +github.com/libp2p/go-libp2p-kad-dht v0.15.0 h1:Ke+Oj78gX5UDXnA6HBdrgvi+fStJxgYTDa51U0TsCLo= +github.com/libp2p/go-libp2p-kad-dht v0.15.0/go.mod h1:rZtPxYu1TnHHz6n1RggdGrxUX/tA1C2/Wiw3ZMUDrU0= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70= github.com/libp2p/go-libp2p-kbucket v0.4.7/go.mod h1:XyVo99AfQH0foSf176k4jY1xUJ2+jUJIZCSDm7r2YKk= @@ -755,8 +851,10 @@ github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= -github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-mplex v0.5.0/go.mod h1:eLImPJLkj3iG5t5lq68w3Vm5NAQ5BcKwrrb2VmOYb3M= +github.com/libp2p/go-libp2p-mplex v0.7.0 h1:ONTTvHIUaFCwyPO4FRkpe4OFQJq1bDkWQLbhWiD1A44= +github.com/libp2p/go-libp2p-mplex v0.7.0/go.mod h1:SeeXUXh7ZkfxnmsepnFgMPEhfEyACujuTM9k1TkErpc= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= @@ -769,8 +867,9 @@ github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLK github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= -github.com/libp2p/go-libp2p-noise v0.3.0 h1:NCVH7evhVt9njbTQshzT7N1S3Q6fjj9M11FCgfH5+cA= github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= +github.com/libp2p/go-libp2p-noise v0.4.0 h1:khcMsGhHNdGqKE5LDLrnHwZvdGVMsrnD4GTkTWkwmLU= +github.com/libp2p/go-libp2p-noise v0.4.0/go.mod h1:BzzY5pyzCYSyJbQy9oD8z5oP2idsafjt4/X42h9DjZU= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= @@ -785,28 +884,33 @@ github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.8/go.mod h1:gGiPlXdz7mIHd2vfAsHzBNAMqSDkt2UBFwgcITgw1lA= -github.com/libp2p/go-libp2p-peerstore v0.3.0 h1:wp/G0+37+GLr7tu+wE+4GWNrA3uxKg6IPRigIMSS5oQ= -github.com/libp2p/go-libp2p-peerstore v0.3.0/go.mod h1:fNX9WlOENMvdx/YD7YO/5Hkrn8+lQIk5A39BHa1HIrM= +github.com/libp2p/go-libp2p-peerstore v0.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= +github.com/libp2p/go-libp2p-peerstore v0.6.0 h1:HJminhQSGISBIRb93N6WK3t6Fa8OOTnHd/VBjL4mY5A= +github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= -github.com/libp2p/go-libp2p-pubsub v0.4.0/go.mod h1:izkeMLvz6Ht8yAISXjx60XUQZMq9ZMe5h2ih4dLIBIQ= -github.com/libp2p/go-libp2p-pubsub v0.5.4 h1:rHl9/Xok4zX3zgi0pg0XnUj9Xj2OeXO8oTu85q2+YA8= -github.com/libp2p/go-libp2p-pubsub v0.5.4/go.mod h1:gVOzwebXVdSMDQBTfH8ACO5EJ4SQrvsHqCmYsCZpD0E= -github.com/libp2p/go-libp2p-pubsub-router v0.4.0 h1:KjzTLIOBCt0+/4wH6epTxD/Qu4Up/IyeKHlj9MhWRJI= -github.com/libp2p/go-libp2p-pubsub-router v0.4.0/go.mod h1:hs0j0ugcBjMOMgJ6diOlZM2rZEId/w5Gg86E+ac4SmQ= +github.com/libp2p/go-libp2p-pubsub v0.6.0/go.mod h1:nJv87QM2cU0w45KPR1rZicq+FmFIOD16zmT+ep1nOmg= +github.com/libp2p/go-libp2p-pubsub v0.6.1 h1:wycbV+f4rreCoVY61Do6g/BUk0RIrbNRcYVbn+QkjGk= +github.com/libp2p/go-libp2p-pubsub v0.6.1/go.mod h1:nJv87QM2cU0w45KPR1rZicq+FmFIOD16zmT+ep1nOmg= +github.com/libp2p/go-libp2p-pubsub-router v0.5.0 h1:WuYdY42DVIJ+N0qMdq2du/E9poJH+xzsXL7Uptwj9tw= +github.com/libp2p/go-libp2p-pubsub-router v0.5.0/go.mod h1:TRJKskSem3C0aSb3CmRgPwq6IleVFzds6hS09fmZbGM= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= github.com/libp2p/go-libp2p-quic-transport v0.11.2/go.mod h1:wlanzKtIh6pHrq+0U3p3DY9PJfGqxMgPaGKaK5LifwQ= github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= -github.com/libp2p/go-libp2p-quic-transport v0.14.0 h1:sBjT/8zKv8otFZh3Uhdxl91BhwXwuHAOB5lJgbT2zyk= -github.com/libp2p/go-libp2p-quic-transport v0.14.0/go.mod h1:/W4njiXIRowKk62w6j4y4dVpBZvEk9WtGOtOYh2M6J8= +github.com/libp2p/go-libp2p-quic-transport v0.15.0/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-quic-transport v0.16.0/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= +github.com/libp2p/go-libp2p-quic-transport v0.17.0 h1:yFh4Gf5MlToAYLuw/dRvuzYd1EnE2pX3Lq1N6KDiWRQ= +github.com/libp2p/go-libp2p-quic-transport v0.17.0/go.mod h1:x4pw61P3/GRCcSLypcQJE/Q2+E9f4X+5aRcZLXf20LM= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= -github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= github.com/libp2p/go-libp2p-record v0.1.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk= github.com/libp2p/go-libp2p-record v0.1.3 h1:R27hoScIhQf/A8XJZ8lYpnqh9LatJ5YbHs28kCIfql0= github.com/libp2p/go-libp2p-record v0.1.3/go.mod h1:yNUff/adKIfPnYQXgp6FQmNu3gLJ6EMg7+/vv2+9pY4= +github.com/libp2p/go-libp2p-resource-manager v0.2.1/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= +github.com/libp2p/go-libp2p-resource-manager v0.3.0 h1:2+cYxUNi33tcydsVLt6K5Fv2E3OTiVeafltecAj15E0= +github.com/libp2p/go-libp2p-resource-manager v0.3.0/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= github.com/libp2p/go-libp2p-routing-helpers v0.2.3 h1:xY61alxJ6PurSi+MXbywZpelvuU4U4p/gPTxjqCqTzY= github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw= @@ -825,8 +929,10 @@ github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJeg github.com/libp2p/go-libp2p-swarm v0.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-swarm v0.5.3/go.mod h1:NBn7eNW2lu568L7Ns9wdFrOhgRlkRnIDg0FLKbuu3i8= -github.com/libp2p/go-libp2p-swarm v0.7.0 h1:ZohJ/XtPP0O73Y1BeCvRRfBcoBfZkqRiKmBwKQfnYGg= -github.com/libp2p/go-libp2p-swarm v0.7.0/go.mod h1:Ii3RNGBC+CMIO3BzK/hmzzriJUOkCVT7viOd+alyEPY= +github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= +github.com/libp2p/go-libp2p-swarm v0.10.0/go.mod h1:71ceMcV6Rg/0rIQ97rsZWMzto1l9LnNquef+efcRbmA= +github.com/libp2p/go-libp2p-swarm v0.10.2 h1:UaXf+CTq6Ns1N2V1EgqJ9Q3xaRsiN7ImVlDMpirMAWw= +github.com/libp2p/go-libp2p-swarm v0.10.2/go.mod h1:Pdkq0QU5a+qu+oyqIV3bknMsnzk9lnNyKvB9acJ5aZs= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -837,11 +943,16 @@ github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= -github.com/libp2p/go-libp2p-testing v0.5.0 h1:bTjC29TTQ/ODq0ld3+0KLq3irdA5cAH3OMbRi0/QsvE= github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= +github.com/libp2p/go-libp2p-testing v0.7.0/go.mod h1:OLbdn9DbgdMwv00v+tlp1l3oe2Cl+FAjoWIA2pa0X6E= +github.com/libp2p/go-libp2p-testing v0.9.0/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= +github.com/libp2p/go-libp2p-testing v0.9.2 h1:dCpODRtRaDZKF8HXT9qqqgON+OMEB423Knrgeod8j84= +github.com/libp2p/go-libp2p-testing v0.9.2/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= -github.com/libp2p/go-libp2p-tls v0.3.0 h1:8BgvUJiOTcj0Gp6XvEicF0rL5aUtRg/UzEdeZDmDlC8= github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.3.1/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.4.1 h1:1ByJUbyoMXvYXDoW6lLsMxqMViQNXmt+CfQqlnCpY+M= +github.com/libp2p/go-libp2p-tls v0.4.1/go.mod h1:EKCixHEysLNDlLUoKxv+3f/Lp90O2EXNjTr0UQDnrIw= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= @@ -852,8 +963,10 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= github.com/libp2p/go-libp2p-transport-upgrader v0.4.6/go.mod h1:JE0WQuQdy+uLZ5zOaI3Nw9dWGYJIA7mywEtP2lMvnyk= -github.com/libp2p/go-libp2p-transport-upgrader v0.5.0 h1:7SDl3O2+AYOgfE40Mis83ClpfGNkNA6m4FwhbOHs+iI= github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.0/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 h1:MSMe+tUfxpC9GArTz7a4G5zQKQgGh00Vio87d3j3xIg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db h1:EDoDKW8ZAHd6SIDeo+thU51PyQppqLYkBxx0ObvFj/w= github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= @@ -867,13 +980,15 @@ github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2Ez github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= -github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= -github.com/libp2p/go-libp2p-yamux v0.5.4 h1:/UOPtT/6DHPtr3TtKXBHa6g0Le0szYuI33Xc/Xpd7fQ= github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= +github.com/libp2p/go-libp2p-yamux v0.6.0/go.mod h1:MRhd6mAYnFRnSISp4M8i0ClV/j+mWHo2mYLifWGw33k= +github.com/libp2p/go-libp2p-yamux v0.8.0/go.mod h1:yTkPgN2ib8FHyU1ZcVD7aelzyAqXXwEPbyx+aSKm9h8= +github.com/libp2p/go-libp2p-yamux v0.8.1/go.mod h1:rUozF8Jah2dL9LLGyBaBeTQeARdwhefMCTQVQt6QobE= +github.com/libp2p/go-libp2p-yamux v0.9.1 h1:oplewiRix8s45SOrI30rCPZG5mM087YZp+VYhXAh4+c= +github.com/libp2p/go-libp2p-yamux v0.9.1/go.mod h1:wRc6wvyxQINFcKe7daL4BeQ02Iyp+wxyC8WCNfngBrA= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= -github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= @@ -881,14 +996,17 @@ github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6 github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= -github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.4.0/go.mod h1:y26Lx+wNVtMYMaPu300Cbot5LkEZ4tJaNYeHeT9dh6E= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.1.0 h1:8Q7g/528ivAlfXTFWvWhVjTE8XG8sDTkRUKPYh9+5Q8= github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE= +github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= @@ -897,8 +1015,9 @@ github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= -github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= +github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= +github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -917,15 +1036,15 @@ github.com/libp2p/go-reuseport-transport v0.1.0 h1:C3PHeHjmnz8m6f0uydObj02tMEoi7 github.com/libp2p/go-reuseport-transport v0.1.0/go.mod h1:vev0C0uMkzriDY59yFHD9v+ujJvYmDQVLowvAjEOmfw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-socket-activation v0.1.0/go.mod h1:gzda2dNkMG5Ti2OfWNNwW0FDIbj0g/aJJU320FcLfhk= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= -github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-stream-muxer-multistream v0.4.0 h1:HsM/9OdtqnIzjVXcxTXjmqKrj3gJ8kacaOJwJS1ipaY= +github.com/libp2p/go-stream-muxer-multistream v0.4.0/go.mod h1:nb+dGViZleRP4XcyHuZSVrJCBl55nRBOMmiSL/dyziw= github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= @@ -934,8 +1053,10 @@ github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1 github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.2.4/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.2.7/go.mod h1:lue9p1b3VmZj1MhhEGB/etmvF/nBQ0X9CW2DutBT3MM= -github.com/libp2p/go-tcp-transport v0.4.0 h1:VDyg4j6en3OuXf90gfDQh5Sy9KowO9udnd0OU8PP6zg= github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= +github.com/libp2p/go-tcp-transport v0.5.0/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= +github.com/libp2p/go-tcp-transport v0.5.1 h1:edOOs688VLZAozWC7Kj5/6HHXKNwi9M6wgRmmLa8M6Q= +github.com/libp2p/go-tcp-transport v0.5.1/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= @@ -944,8 +1065,9 @@ github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzl github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= -github.com/libp2p/go-ws-transport v0.5.0 h1:cO6x4P0v6PfxbKnxmf5cY2Ny4OPDGYkUqNvZzp/zdlo= github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xds1iamArLvl8kNg= +github.com/libp2p/go-ws-transport v0.6.0 h1:326XBL6Q+5CQ2KtjXz32+eGu02W/Kz2+Fm4SpXdr0q4= +github.com/libp2p/go-ws-transport v0.6.0/go.mod h1:dXqtI9e2JV9FtF1NOtWVZSKXh5zXvnuwPXfj8GPBbYU= github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= @@ -957,9 +1079,12 @@ github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= -github.com/libp2p/go-yamux/v2 v2.1.1/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= -github.com/libp2p/go-yamux/v2 v2.2.0 h1:RwtpYZ2/wVviZ5+3pjC8qdQ4TKnrak0/E01N1UWoAFU= github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= +github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= +github.com/libp2p/go-yamux/v3 v3.0.1/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.0.2/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.1.1 h1:X0qSVodCZciOu/f4KTp9V+O0LAqcqP2tdaUGB0+0lng= +github.com/libp2p/go-yamux/v3 v3.1.1/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= github.com/libp2p/zeroconf/v2 v2.1.1 h1:XAuSczA96MYkVwH+LqqqCUZb2yH3krobMJ1YE+0hG2s= github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -967,8 +1092,10 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lucas-clemente/quic-go v0.21.2/go.mod h1:vF5M1XqhBAHgbjKcJOXY3JZz3GP0T3FQhz/uyOUS38Q= github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= -github.com/lucas-clemente/quic-go v0.24.0 h1:ToR7SIIEdrgOhgVTHvPgdVRJfgVy+N0wQAagH7L4d5g= github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg= +github.com/lucas-clemente/quic-go v0.27.0 h1:v6WY87q9zD4dKASbG8hy/LpzAVNzEQzw8sEIeloJsc4= +github.com/lucas-clemente/quic-go v0.27.0/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -979,11 +1106,16 @@ github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0a github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/marten-seemann/qtls-go1-15 v0.1.5/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco= github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= +github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= -github.com/marten-seemann/qtls-go1-17 v0.1.0 h1:P9ggrs5xtwiqXv/FHNwntmuLMNq3KaSIG93AtAZ48xk= github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= +github.com/marten-seemann/qtls-go1-17 v0.1.1 h1:DQjHPq+aOzUeh9/lixAGunn6rIOQyWChPSI4+hgW7jc= +github.com/marten-seemann/qtls-go1-17 v0.1.1/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= +github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI= +github.com/marten-seemann/qtls-go1-18 v0.1.1 h1:qp7p7XXUFL7fpBvSS1sWD+uSqPvzNQK43DH+/qEkj0Y= +github.com/marten-seemann/qtls-go1-18 v0.1.1/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -995,8 +1127,9 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -1008,8 +1141,9 @@ github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -1038,14 +1172,16 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= +github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -1059,8 +1195,10 @@ github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= -github.com/multiformats/go-multiaddr v0.4.0 h1:hL/K4ZJhJ5PTw3nwylq9lGU5yArzcAroZmex1ghSEkQ= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= +github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= +github.com/multiformats/go-multiaddr v0.5.0 h1:i/JuOoVg4szYQ4YEzDGtb2h0o8M7CG/Yq6cGlcjWZpM= +github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= @@ -1082,8 +1220,11 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multicodec v0.2.0/go.mod h1:/y4YVwkfMyry5kFbMTbLJKErhycTIftytRV+llXdyS4= -github.com/multiformats/go-multicodec v0.3.0 h1:tstDwfIjiHbnIjeM5Lp+pMrSeN+LCMsEwOrkPmWm03A= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= +github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= +github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= +github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4= +github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -1091,16 +1232,19 @@ github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= +github.com/multiformats/go-multihash v0.0.16/go.mod h1:zhfEIgVnB/rPMfxgFw15ZmGoNaKyNUIE4IWHG/kC+Ag= +github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= +github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= -github.com/multiformats/go-multistream v0.2.2 h1:TCYu1BHTDr1F/Qm75qwYISQdzGcRdC21nFgQW7l7GBo= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= +github.com/multiformats/go-multistream v0.3.0 h1:yX1v4IWseLPmr0rmnDo148wWJbNx40JxBZGmQb5fUP4= +github.com/multiformats/go-multistream v0.3.0/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1130,17 +1274,21 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1152,13 +1300,20 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.4.0 h1:CtfRrOVZtbDj8rt1WXjklw0kqqJQwICrCKmlfUuBUUw= +github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= +github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -1178,12 +1333,12 @@ github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1196,33 +1351,42 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7q github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.33.0 h1:rHgav/0a6+uYgGdNt3jwz8FNSesO/Hsang3O0T9A5SE= +github.com/prometheus/common v0.33.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/statsd_exporter v0.20.0/go.mod h1:YL3FWCG8JBBtaUSxAg4Gz2ZYu22bS84XM89ZQXXTWmQ= github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ= +github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= +github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= +github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= +github.com/raulk/go-watchdog v1.2.0 h1:konN75pw2BMmZ+AfuAm5rtFsWcJpKF3m02rKituuXNo= +github.com/raulk/go-watchdog v1.2.0/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6RcA1i4mlqI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -1256,10 +1420,11 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -1288,36 +1453,51 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/tidwall/gjson v1.14.0 h1:6aeJ0bzojgWLa82gDQHcx3S0Lr/O51I9bJ5nv6JFx5w= +github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/wI2L/jsondiff v0.2.0 h1:dE00WemBa1uCjrzQUUTE/17I6m5qAaN0EMFOg2Ynr/k= +github.com/wI2L/jsondiff v0.2.0/go.mod h1:axTcwtBkY4TsKuV+RgoMhHyHKKFRI6nnjRLi8LLYQnA= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= -github.com/warpfork/go-testmark v0.3.0 h1:Q81c4u7hT+BR5kNfNQhEF0VT2pmL7+Kk0wD+ORYl7iA= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= +github.com/warpfork/go-testmark v0.9.0 h1:nc+uaCiv5lFQLYjhuC2LTYeJ7JaC+gdDmsz9r0ISy0Y= +github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= +github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= +github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= @@ -1339,6 +1519,9 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go. github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1346,6 +1529,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= @@ -1359,15 +1543,43 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.31.0/go.mod h1:PFmBsWbldL1kiWZk9+0LBZz2brhByaGsvp6pRICMlPE= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= +go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= +go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ= +go.opentelemetry.io/otel v1.6.1/go.mod h1:blzUabWHkX6LJewxvadmzafgh/wnvBSDBdOuwkAtrWQ= +go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= +go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= +go.opentelemetry.io/otel/exporters/jaeger v1.6.3 h1:7tvBU1Ydbzq080efuepYYqC1Pv3/vOFBgCSrxLb24d0= +go.opentelemetry.io/otel/exporters/jaeger v1.6.3/go.mod h1:YgX3eZWbJzgrNyNHCK0otGreAMBTIAcObtZS2VRi6sU= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.3 h1:nAmg1WgsUXoXf46dJG9eS/AzOcvkCTK4xJSUYpWyHYg= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.3/go.mod h1:NEu79Xo32iVb+0gVNV8PMd7GoWqnyDXRlj04yFjqz40= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.3 h1:4/UjHWMVVc5VwX/KAtqJOHErKigMCH8NexChMuanb/o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.3/go.mod h1:UJmXdiVVBaZ63umRUTwJuCMAV//GCMvDiQwn703/GoY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.3 h1:leYDq5psbM3K4QNcZ2juCj30LjUnvxjuYQj1mkGjXFM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.3/go.mod h1:ycItY/esVj8c0dKgYTOztTERXtPzcfDU/0o8EdwCjoA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.6.3 h1:ufVuVt/g16GZ/yDOyp+AcCGebGX8u4z7kDRuwEX0DkA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.6.3/go.mod h1:S18p8VK4KRHHyAg5rH3iUnJUcRvIUg9xwIWtq1MWibM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.6.3 h1:uSApZ0WGBOrEMNp0rtX1jtpYBh5CvktueAEHTWfLOtk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.6.3/go.mod h1:LhMjYbVawqjXUIRbAT2CFuWtuQVxTPL8WEtxB/Iyg5Y= +go.opentelemetry.io/otel/exporters/zipkin v1.6.3 h1:5BzTuSYCahVIsRlxZjJO23WUsJjq/q70TnmNZz5Klk8= +go.opentelemetry.io/otel/exporters/zipkin v1.6.3/go.mod h1:JRfrU4shvi54xFL5KA9ftJv7El3FMMpkz3V2S8aZ/q0= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= +go.opentelemetry.io/otel/metric v0.28.0/go.mod h1:TrzsfQAmQaB1PDcdhBauLMk7nyyg9hm+GoQq/ekE9Iw= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U= +go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= +go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= +go.opentelemetry.io/otel/trace v1.6.0/go.mod h1:qs7BrU5cZ8dXQHBGxHMOxwME/27YH2qEp4/+tZLLwJE= +go.opentelemetry.io/otel/trace v1.6.1/go.mod h1:RkFRM1m0puWIq10oxImnGEduNBzxiN7TXluRBtE+5j0= +go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= +go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0 h1:h0bKrvdrT/9sBwEJ6iWUqT/N/xPcS66bL4u3isneJ6w= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1375,21 +1587,24 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.10.0 h1:yLmDDj9/zuDjv3gz8GQGviXMs9TfysIUMUilCpgzUJY= -go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= -go.uber.org/fx v1.13.1 h1:CFNTr1oin5OJ0VCZ8EycL3wzF29Jz2g0xe55RFsf2a4= -go.uber.org/fx v1.13.1/go.mod h1:bREWhavnedxpJeTq9pQT53BbvwhUv7TcpsOqcH4a+3w= -go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= +go.uber.org/dig v1.12.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= +go.uber.org/dig v1.14.0 h1:VmGvIH45/aapXPQkaOrK5u4B5B7jxZB98HM/utx0eME= +go.uber.org/dig v1.14.0/go.mod h1:jHAn/z1Ld1luVVyGKOAIFYz/uBFqKjjEEdIqVAqfQ2o= +go.uber.org/fx v1.16.0 h1:N8i80+X1DCX+qMRiKzM+jPPZiIiyK/bVCysga3+B+1w= +go.uber.org/fx v1.16.0/go.mod h1:OMoT5BnXcOaiexlpjtpE4vcAmzyDKyRs9TRYXCzamx8= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -1397,8 +1612,10 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= @@ -1429,15 +1646,21 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e h1:VvfwVmMH40bpMeizC9/K7ipM5Qjucuu16RWfneFPyhQ= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1445,6 +1668,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20210615023648-acb5c1269671 h1:ddvpKwqE7dm58PoWjRCmaCiA3DANEW0zWGfNYQD212Y= +golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1458,19 +1683,19 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1524,9 +1749,17 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1535,6 +1768,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1548,6 +1783,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1594,13 +1830,13 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1614,6 +1850,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1621,21 +1858,30 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -1669,7 +1915,6 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1678,6 +1923,7 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1699,14 +1945,18 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1-0.20210225150353-54dc8c5edb56/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1770,6 +2020,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1794,8 +2046,11 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1808,8 +2063,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1822,6 +2078,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -1849,6 +2107,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= +pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/docs/examples/go-ipfs-as-a-library/main.go b/docs/examples/go-ipfs-as-a-library/main.go index 5b032e56a29..9150325f763 100644 --- a/docs/examples/go-ipfs-as-a-library/main.go +++ b/docs/examples/go-ipfs-as-a-library/main.go @@ -11,12 +11,12 @@ import ( "strings" "sync" - config "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" icore "github.com/ipfs/interface-go-ipfs-core" icorepath "github.com/ipfs/interface-go-ipfs-core/path" ma "github.com/multiformats/go-multiaddr" + "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" "github.com/ipfs/go-ipfs/core/node/libp2p" @@ -86,7 +86,7 @@ func createTempRepo() (string, error) { /// ------ Spawning the node // Creates an IPFS node and returns its coreAPI -func createNode(ctx context.Context, repoPath string) (icore.CoreAPI, error) { +func createNode(ctx context.Context, repoPath string) (*core.IpfsNode, error) { // Open the repo repo, err := fsrepo.Open(repoPath) if err != nil { @@ -102,48 +102,36 @@ func createNode(ctx context.Context, repoPath string) (icore.CoreAPI, error) { Repo: repo, } - node, err := core.NewNode(ctx, nodeOptions) - if err != nil { - return nil, err - } - - // Attach the Core API to the constructed node - return coreapi.NewCoreAPI(node) + return core.NewNode(ctx, nodeOptions) } -// Spawns a node on the default repo location, if the repo exists -func spawnDefault(ctx context.Context) (icore.CoreAPI, error) { - defaultPath, err := config.PathRoot() - if err != nil { - // shouldn't be possible - return nil, err - } - - if err := setupPlugins(defaultPath); err != nil { - return nil, err - - } - - return createNode(ctx, defaultPath) -} +var loadPluginsOnce sync.Once // Spawns a node to be used just for this run (i.e. creates a tmp repo) -func spawnEphemeral(ctx context.Context) (icore.CoreAPI, error) { - if err := setupPlugins(""); err != nil { - return nil, err +func spawnEphemeral(ctx context.Context) (icore.CoreAPI, *core.IpfsNode, error) { + var onceErr error + loadPluginsOnce.Do(func() { + onceErr = setupPlugins("") + }) + if onceErr != nil { + return nil, nil, onceErr } // Create a Temporary Repo repoPath, err := createTempRepo() if err != nil { - return nil, fmt.Errorf("failed to create temp repo: %s", err) + return nil, nil, fmt.Errorf("failed to create temp repo: %s", err) } - // Spawning an ephemeral IPFS node - return createNode(ctx, repoPath) -} + node, err := createNode(ctx, repoPath) + if err != nil { + return nil, nil, err + } -// + api, err := coreapi.NewCoreAPI(node) + + return api, node, err +} func connectToPeers(ctx context.Context, ipfs icore.CoreAPI, peers []string) error { var wg sync.WaitGroup @@ -179,26 +167,6 @@ func connectToPeers(ctx context.Context, ipfs icore.CoreAPI, peers []string) err return nil } -func getUnixfsFile(path string) (files.File, error) { - file, err := os.Open(path) - if err != nil { - return nil, err - } - defer file.Close() - - st, err := file.Stat() - if err != nil { - return nil, err - } - - f, err := files.NewReaderPathFile(path, file, st) - if err != nil { - return nil, err - } - - return f, nil -} - func getUnixfsNode(path string) (files.Node, error) { st, err := os.Stat(path) if err != nil { @@ -227,18 +195,23 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - /* - // Spawn a node using the default path (~/.ipfs), assuming that a repo exists there already - fmt.Println("Spawning node on default repo") - ipfs, err := spawnDefault(ctx) - if err != nil { - panic(fmt.Errorf("failed to spawnDefault node: %s", err)) - } - */ + // Spawn a local peer using a temporary path, for testing purposes + ipfsA, nodeA, err := spawnEphemeral(ctx) + if err != nil { + panic(fmt.Errorf("failed to spawn peer node: %s", err)) + } + + peerCidFile, err := ipfsA.Unixfs().Add(ctx, + files.NewBytesFile([]byte("hello from ipfs 101 in go-ipfs"))) + if err != nil { + panic(fmt.Errorf("could not add File: %s", err)) + } + + fmt.Printf("Added file to peer with CID %s\n", peerCidFile.String()) // Spawn a node using a temporary path, creating a temporary repo for the run fmt.Println("Spawning node on a temporary repo") - ipfs, err := spawnEphemeral(ctx) + ipfsB, _, err := spawnEphemeral(ctx) if err != nil { panic(fmt.Errorf("failed to spawn ephemeral node: %s", err)) } @@ -255,24 +228,24 @@ func main() { someFile, err := getUnixfsNode(inputPathFile) if err != nil { - panic(fmt.Errorf("Could not get File: %s", err)) + panic(fmt.Errorf("could not get File: %s", err)) } - cidFile, err := ipfs.Unixfs().Add(ctx, someFile) + cidFile, err := ipfsB.Unixfs().Add(ctx, someFile) if err != nil { - panic(fmt.Errorf("Could not add File: %s", err)) + panic(fmt.Errorf("could not add File: %s", err)) } fmt.Printf("Added file to IPFS with CID %s\n", cidFile.String()) someDirectory, err := getUnixfsNode(inputPathDirectory) if err != nil { - panic(fmt.Errorf("Could not get File: %s", err)) + panic(fmt.Errorf("could not get File: %s", err)) } - cidDirectory, err := ipfs.Unixfs().Add(ctx, someDirectory) + cidDirectory, err := ipfsB.Unixfs().Add(ctx, someDirectory) if err != nil { - panic(fmt.Errorf("Could not add Directory: %s", err)) + panic(fmt.Errorf("could not add Directory: %s", err)) } fmt.Printf("Added directory to IPFS with CID %s\n", cidDirectory.String()) @@ -287,26 +260,26 @@ func main() { outputPathFile := outputBasePath + strings.Split(cidFile.String(), "/")[2] outputPathDirectory := outputBasePath + strings.Split(cidDirectory.String(), "/")[2] - rootNodeFile, err := ipfs.Unixfs().Get(ctx, cidFile) + rootNodeFile, err := ipfsB.Unixfs().Get(ctx, cidFile) if err != nil { - panic(fmt.Errorf("Could not get file with CID: %s", err)) + panic(fmt.Errorf("could not get file with CID: %s", err)) } err = files.WriteTo(rootNodeFile, outputPathFile) if err != nil { - panic(fmt.Errorf("Could not write out the fetched CID: %s", err)) + panic(fmt.Errorf("could not write out the fetched CID: %s", err)) } - fmt.Printf("Got file back from IPFS (IPFS path: %s) and wrote it to %s\n", cidFile.String(), outputPathFile) + fmt.Printf("got file back from IPFS (IPFS path: %s) and wrote it to %s\n", cidFile.String(), outputPathFile) - rootNodeDirectory, err := ipfs.Unixfs().Get(ctx, cidDirectory) + rootNodeDirectory, err := ipfsB.Unixfs().Get(ctx, cidDirectory) if err != nil { - panic(fmt.Errorf("Could not get file with CID: %s", err)) + panic(fmt.Errorf("could not get file with CID: %s", err)) } err = files.WriteTo(rootNodeDirectory, outputPathDirectory) if err != nil { - panic(fmt.Errorf("Could not write out the fetched CID: %s", err)) + panic(fmt.Errorf("could not write out the fetched CID: %s", err)) } fmt.Printf("Got directory back from IPFS (IPFS path: %s) and wrote it to %s\n", cidDirectory.String(), outputPathDirectory) @@ -315,49 +288,52 @@ func main() { fmt.Println("\n-- Going to connect to a few nodes in the Network as bootstrappers --") + peerMa := fmt.Sprintf("/ip4/127.0.0.1/udp/4010/p2p/%s", nodeA.Identity.String()) + bootstrapNodes := []string{ // IPFS Bootstrapper nodes. - "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", - "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", - "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", - "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", + // "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", + // "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", + // "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", + // "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", // IPFS Cluster Pinning nodes - "/ip4/138.201.67.219/tcp/4001/p2p/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA", - "/ip4/138.201.67.219/udp/4001/quic/p2p/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA", - "/ip4/138.201.67.220/tcp/4001/p2p/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i", - "/ip4/138.201.67.220/udp/4001/quic/p2p/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i", - "/ip4/138.201.68.74/tcp/4001/p2p/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR", - "/ip4/138.201.68.74/udp/4001/quic/p2p/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR", - "/ip4/94.130.135.167/tcp/4001/p2p/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE", - "/ip4/94.130.135.167/udp/4001/quic/p2p/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE", + // "/ip4/138.201.67.219/tcp/4001/p2p/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA", + // "/ip4/138.201.67.219/udp/4001/quic/p2p/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA", + // "/ip4/138.201.67.220/tcp/4001/p2p/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i", + // "/ip4/138.201.67.220/udp/4001/quic/p2p/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i", + // "/ip4/138.201.68.74/tcp/4001/p2p/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR", + // "/ip4/138.201.68.74/udp/4001/quic/p2p/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR", + // "/ip4/94.130.135.167/tcp/4001/p2p/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE", + // "/ip4/94.130.135.167/udp/4001/quic/p2p/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE", // You can add more nodes here, for example, another IPFS node you might have running locally, mine was: // "/ip4/127.0.0.1/tcp/4010/p2p/QmZp2fhDLxjYue2RiUvLwT9MWdnbDxam32qYFnGmxZDh5L", // "/ip4/127.0.0.1/udp/4010/quic/p2p/QmZp2fhDLxjYue2RiUvLwT9MWdnbDxam32qYFnGmxZDh5L", + peerMa, } go func() { - err := connectToPeers(ctx, ipfs, bootstrapNodes) + err := connectToPeers(ctx, ipfsB, bootstrapNodes) if err != nil { log.Printf("failed connect to peers: %s", err) } }() - exampleCIDStr := "QmUaoioqU7bxezBQZkUcgcSyokatMY71sxsALxQmRRrHrj" + exampleCIDStr := peerCidFile.Cid().String() fmt.Printf("Fetching a file from the network with CID %s\n", exampleCIDStr) outputPath := outputBasePath + exampleCIDStr testCID := icorepath.New(exampleCIDStr) - rootNode, err := ipfs.Unixfs().Get(ctx, testCID) + rootNode, err := ipfsB.Unixfs().Get(ctx, testCID) if err != nil { - panic(fmt.Errorf("Could not get file with CID: %s", err)) + panic(fmt.Errorf("could not get file with CID: %s", err)) } err = files.WriteTo(rootNode, outputPath) if err != nil { - panic(fmt.Errorf("Could not write out the fetched CID: %s", err)) + panic(fmt.Errorf("could not write out the fetched CID: %s", err)) } fmt.Printf("Wrote the file to %s\n", outputPath) diff --git a/docs/experimental-features.md b/docs/experimental-features.md index 4d99f58c2e2..30343d48d7c 100644 --- a/docs/experimental-features.md +++ b/docs/experimental-features.md @@ -19,6 +19,7 @@ the above issue. - [Private Networks](#private-networks) - [ipfs p2p](#ipfs-p2p) - [p2p http proxy](#p2p-http-proxy) +- [FUSE](#fuse) - [Plugins](#plugins) - [Directory Sharding / HAMT](#directory-sharding--hamt) - [IPNS PubSub](#ipns-pubsub) @@ -386,6 +387,15 @@ We also support the use of protocol names of the form /x/$NAME/http where $NAME - [ ] More documentation - [ ] Need better integration with the subdomain gateway feature. +## FUSE + +FUSE makes it possible to mount `/ipfs` and `/ipns` namespaces in your OS, +allowing argitrary apps access to IPFS using a subset of filesystem abstractions. + +It is considered EXPERIMENTAL due to limited (and buggy) support on some platforms. + +See [fuse.md](./fuse.md) for more details. + ## Plugins ### In Version diff --git a/docs/fuse.md b/docs/fuse.md index a6399eeba44..8a229ead6ae 100644 --- a/docs/fuse.md +++ b/docs/fuse.md @@ -1,5 +1,7 @@ # FUSE +**EXPERIMENTAL:** FUSE support is limited, YMMV. + `go-ipfs` makes it possible to mount `/ipfs` and `/ipns` namespaces in your OS, allowing arbitrary apps access to IPFS. diff --git a/docs/gateway.md b/docs/gateway.md index dab41e09171..0abcb2c0005 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -2,19 +2,36 @@ An IPFS Gateway acts as a bridge between traditional web browsers and IPFS. Through the gateway, users can browse files and websites stored in IPFS as if -they were stored in a traditional web server. +they were stored in a traditional web server. -By default, go-ipfs nodes run a gateway at `http://127.0.0.1:8080/`. +[More about Gateways](https://docs.ipfs.io/concepts/ipfs-gateway/) and [addressing IPFS on the web](https://docs.ipfs.io/how-to/address-ipfs-on-web/). -We also provide a public gateway at `https://ipfs.io`. If you've ever seen a -link in the form `https://ipfs.io/ipfs/Qm...`, that's being served from *our* -gateway. +### Local gateway + +By default, go-ipfs nodes run +a [path gateway](https://docs.ipfs.io/how-to/address-ipfs-on-web/#path-gateway) at `http://127.0.0.1:8080/` +and a [subdomain gateway](https://docs.ipfs.io/how-to/address-ipfs-on-web/#subdomain-gateway) at `http://localhost:8080/` + +Additional listening addresses and gateway behaviors can be set in the [config](#configuration) file. + +### Public gateways + +Protocol Labs provides a public gateway at `https://ipfs.io` (path) and `https://dweb.link` (subdomain). +If you've ever seen a link in the form `https://ipfs.io/ipfs/Qm...`, that's being served from *our* gateway. + +There is a list of third-party public gateways provided by the IPFS community at https://ipfs.github.io/public-gateway-checker/ ## Configuration -The gateway's configuration options are (briefly) described in the +The `Gateway.*` configuration options are (briefly) described in the [config](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#gateway) -documentation. +documentation, including a list of common [gateway recipes](https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#gateway-recipes). + +### Debug +The gateway's log level can be changed with this command: +``` +> ipfs log level core/server debug +``` ## Directories @@ -34,7 +51,7 @@ for details ## Static Websites You can use an IPFS gateway to serve static websites at a custom domain using -[DNSLink](https://dnslink.io). See [Example: IPFS +[DNSLink](https://docs.ipfs.io/concepts/glossary#dnslink). See [Example: IPFS Gateway](https://dnslink.io/#example-ipfs-gateway) for instructions. ## Filenames @@ -59,17 +76,36 @@ images, audio, video, PDF) and trigger immediate "save as" dialog by appending > https://ipfs.io/ipfs/QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG?filename=hello_world.txt&download=true -## MIME-Types +## Response Format -TODO +An explicit response format can be requested using `?format=raw|car|..` URL parameter, +or by sending `Accept: application/vnd.ipld.{format}` HTTP header with one of supported content types. -## Read-Only API +## Content-Types -For convenience, the gateway exposes a read-only API. This read-only API exposes -a read-only, "safe" subset of the normal API. +### `application/vnd.ipld.raw` -For example, you use this to download a block: +Returns a byte array for a single `raw` block. -``` -> curl https://ipfs.io/api/v0/block/get/bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4 -``` +Sending such requests for `/ipfs/{cid}` allows for efficient fetch of blocks with data +encoded in custom format, without the need for deserialization and traversal on the gateway. + +This is equivalent of `ipfs block get`. + +### `application/vnd.ipld.car` + +Returns a [CAR](https://ipld.io/specs/transport/car/) stream for specific DAG and selector. + +Right now only 'full DAG' implicit selector is implemented. +Support for user-provided IPLD selectors is tracked in https://github.com/ipfs/go-ipfs/issues/8769. + +This is a rough equivalent of `ipfs dag export`. + +## Deprecated Subset of RPC API + +For legacy reasons, the gateway port exposes a small subset of RPC API under `/api/v0/`. +While this read-only API exposes a read-only, "safe" subset of the normal API, +it is deprecated and should not be used for greenfield projects. + +Where possible, leverage `/ipfs/` and `/ipns/` endpoints. +along with `application/vnd.ipld.*` Content-Types instead. diff --git a/docs/implement-api-bindings.md b/docs/implement-api-bindings.md index 364f3265e2e..c7bf9bdf0df 100644 --- a/docs/implement-api-bindings.md +++ b/docs/implement-api-bindings.md @@ -63,7 +63,7 @@ In HTTP, our API layering uses a REST-like mapping, where: There is a "standard IPFS API" which is currently defined as "all the commands exposed by the go-ipfs implementation". There are auto-generated [API Docs](https://ipfs.io/docs/api/). -You can Also see [a listing here](https://git.io/v5KG1), or get a list of +You can Also see [a listing here](https://github.com/ipfs/go-ipfs/blob/94b832df861728c65e912935641d08880c341e0a/core/commands/root.go#L96-L130), or get a list of commands by running `ipfs commands` locally. ## Implementing bindings for the HTTP API @@ -80,8 +80,8 @@ To date, we have two different HTTP API clients: - [js-ipfs-api](https://github.com/ipfs/js-ipfs-api) - simple javascript wrapper -- best to look at -- [go-ipfs/commands/http](https://git.io/v5KnB) - - generalized transport based on the [command definitions](https://git.io/v5KnE) +- [go-ipfs/commands/http](https://github.com/ipfs/go-ipfs/tree/916f987de2c35db71815b54bbb9a0a71df829838/commands/http) - + generalized transport based on the [command definitions](https://github.com/ipfs/go-ipfs/tree/916f987de2c35db71815b54bbb9a0a71df829838/core/commands) The Go implementation is good to answer harder questions, like how is multipart handled, or what headers should be set in edge conditions. But the javascript @@ -90,12 +90,12 @@ implementation is very concise, and easy to follow. #### Anatomy of node-ipfs-api Currently, node-ipfs-api has three main files -- [src/index.js](https://git.io/v5Kn2) defines the functions clients of the API +- [src/index.js](https://github.com/ipfs-inactive/js-ipfs-http-client/blob/66d1462bd02181d46e8baf4cd9d476b213426ad8/src/index.js) defines the functions clients of the API module will use. uses `RequestAPI`, and translates function call parameters to the API almost directly. -- [src/get-files-stream.js](https://git.io/v5Knr) implements the hardest part: +- [src/get-files-stream.js](https://github.com/ipfs-inactive/js-ipfs-http-client/blob/66d1462bd02181d46e8baf4cd9d476b213426ad8/src/get-files-stream.js) implements the hardest part: file streaming. This one uses multipart. -- [src/request-api.js](https://git.io/v5KnP) generic function call to perform +- [src/request-api.js](https://github.com/ipfs-inactive/js-ipfs-http-client/blob/66d1462bd02181d46e8baf4cd9d476b213426ad8/src/request-api.js) generic function call to perform the actual HTTP requests ## Note on multipart + inspecting requests diff --git a/docs/windows.md b/docs/windows.md index 4487e64ffe9..c23698384f3 100644 --- a/docs/windows.md +++ b/docs/windows.md @@ -114,20 +114,36 @@ You can use whichever version of `git` you wish but we recommend the Windows bui Clone and change directory to the source code, if you haven't already: -``` +CMD: +```bat git clone https://github.com/ipfs/go-ipfs %GOPATH%/src/github.com/ipfs/go-ipfs cd %GOPATH%/src/github.com/ipfs/go-ipfs/cmd/ipfs ``` +PowerShell: +```powershell +git clone https://github.com/ipfs/go-ipfs $env:GOPATH/src/github.com/ipfs/go-ipfs +cd $env:GOPATH/src/github.com/ipfs/go-ipfs/cmd/ipfs +``` + We need the `git` commit hash to be included in our build so that in the extremely rare event a bug is found, we have a reference point later for tracking it. We'll ask `git` for it and store it in a variable. The syntax for the next command is different depending on whether you're using the interactive command line or writing a batch file. Use the one that applies to you. - interactive: `FOR /F %V IN ('git rev-parse --short HEAD') do set SHA=%V` - interpreter: `FOR /F %%V IN ('git rev-parse --short HEAD') do set SHA=%%V` Finally, we'll build and test `ipfs` itself. -``` + +CMD: +```bat go install -ldflags="-X "github.com/ipfs/go-ipfs".CurrentCommit=%SHA%" %GOPATH%\bin\ipfs.exe version --all ``` + +PowerShell: +```powershell +go install -ldflags="-X "github.com/ipfs/go-ipfs".CurrentCommit=$env:SHA" +cp ./ipfs.exe $env:GOPATH/bin/ipfs.exe -force +. $env:GOPATH/bin/ipfs.exe version --all +``` You can check that the ipfs output versions match with `go version` and `git rev-parse --short HEAD`. If `ipfs.exe` executes and everything matches, then building was successful. diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index e9fce165403..cc725d8cb12 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -1,3 +1,4 @@ +//go:build !nofuse && !openbsd && !netbsd && !plan9 // +build !nofuse,!openbsd,!netbsd,!plan9 package ipns diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index b8caf0ca2fe..413999b9e9b 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -1,3 +1,4 @@ +//go:build !nofuse && !openbsd && !netbsd && !plan9 // +build !nofuse,!openbsd,!netbsd,!plan9 // package fuse/ipns implements a fuse filesystem that interfaces diff --git a/fuse/ipns/link_unix.go b/fuse/ipns/link_unix.go index 3be52da99b2..355787b3c5e 100644 --- a/fuse/ipns/link_unix.go +++ b/fuse/ipns/link_unix.go @@ -1,3 +1,4 @@ +//go:build !nofuse && !openbsd && !netbsd && !plan9 // +build !nofuse,!openbsd,!netbsd,!plan9 package ipns diff --git a/fuse/ipns/mount_unix.go b/fuse/ipns/mount_unix.go index 7c24e53beff..c59701146fb 100644 --- a/fuse/ipns/mount_unix.go +++ b/fuse/ipns/mount_unix.go @@ -1,3 +1,4 @@ +//go:build (linux || darwin || freebsd || netbsd || openbsd) && !nofuse // +build linux darwin freebsd netbsd openbsd // +build !nofuse diff --git a/fuse/mount/fuse.go b/fuse/mount/fuse.go index 7fd29e33df2..99f374043d2 100644 --- a/fuse/mount/fuse.go +++ b/fuse/mount/fuse.go @@ -1,3 +1,4 @@ +//go:build !nofuse && !windows && !openbsd && !netbsd && !plan9 // +build !nofuse,!windows,!openbsd,!netbsd,!plan9 package mount diff --git a/fuse/node/mount_darwin.go b/fuse/node/mount_darwin.go index a27d64ccd0a..382f575e2cf 100644 --- a/fuse/node/mount_darwin.go +++ b/fuse/node/mount_darwin.go @@ -1,3 +1,4 @@ +//go:build !nofuse // +build !nofuse package node diff --git a/fuse/node/mount_nofuse.go b/fuse/node/mount_nofuse.go index 7f824ef3e12..a5433c8c39e 100644 --- a/fuse/node/mount_nofuse.go +++ b/fuse/node/mount_nofuse.go @@ -1,3 +1,4 @@ +//go:build !windows && nofuse // +build !windows,nofuse package node diff --git a/fuse/node/mount_notsupp.go b/fuse/node/mount_notsupp.go index 929cdf7df90..d0db6f6b483 100644 --- a/fuse/node/mount_notsupp.go +++ b/fuse/node/mount_notsupp.go @@ -1,3 +1,4 @@ +//go:build (!nofuse && openbsd) || (!nofuse && netbsd) || (!nofuse && plan9) // +build !nofuse,openbsd !nofuse,netbsd !nofuse,plan9 package node @@ -9,5 +10,5 @@ import ( ) func Mount(node *core.IpfsNode, fsdir, nsdir string) error { - return errors.New("FUSE not supported on OpenBSD or NetBSD. See #5334 (https://git.io/fjMuC).") + return errors.New("FUSE not supported on OpenBSD or NetBSD. See #5334 (https://github.com/ipfs/go-ipfs/issues/5334).") } diff --git a/fuse/node/mount_test.go b/fuse/node/mount_test.go index 2d1642cb9f4..23eba3bc3f5 100644 --- a/fuse/node/mount_test.go +++ b/fuse/node/mount_test.go @@ -1,3 +1,4 @@ +//go:build !openbsd && !nofuse && !netbsd && !plan9 // +build !openbsd,!nofuse,!netbsd,!plan9 package node diff --git a/fuse/node/mount_unix.go b/fuse/node/mount_unix.go index 5388333ac78..85228435796 100644 --- a/fuse/node/mount_unix.go +++ b/fuse/node/mount_unix.go @@ -1,3 +1,4 @@ +//go:build !windows && !openbsd && !netbsd && !plan9 && !nofuse // +build !windows,!openbsd,!netbsd,!plan9,!nofuse package node diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index feb2d4ec454..d869e3d5da4 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -1,3 +1,4 @@ +//go:build !nofuse && !openbsd && !netbsd && !plan9 // +build !nofuse,!openbsd,!netbsd,!plan9 package readonly diff --git a/fuse/readonly/mount_unix.go b/fuse/readonly/mount_unix.go index e1065a2a1cd..719cb5ef295 100644 --- a/fuse/readonly/mount_unix.go +++ b/fuse/readonly/mount_unix.go @@ -1,3 +1,4 @@ +//go:build (linux || darwin || freebsd) && !nofuse // +build linux darwin freebsd // +build !nofuse diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 1fbb473106d..af961221ca7 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -188,13 +188,9 @@ func (s *Node) Lookup(ctx context.Context, name string) (fs.Node, error) { } nd, err := s.Ipfs.DAG.Get(ctx, link.Cid) - switch err { - case ipld.ErrNotFound: - default: + if err != nil && !ipld.IsNotFound(err) { log.Errorf("fuse lookup %q: %s", name, err) return nil, err - case nil: - // noop } return &Node{Ipfs: s.Ipfs, Nd: nd}, nil diff --git a/gc/gc.go b/gc/gc.go index a77142e103a..e3b0fda68f9 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -233,7 +233,7 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo bestEffortGetLinks := func(ctx context.Context, cid cid.Cid) ([]*ipld.Link, error) { links, err := ipld.GetLinks(ctx, ng, cid) - if err != nil && err != ipld.ErrNotFound { + if err != nil && !ipld.IsNotFound(err) { errors = true select { case output <- Result{Error: &CannotFetchLinksError{cid, err}}: diff --git a/go.mod b/go.mod index 817d80ef365..bcdd9069ec7 100644 --- a/go.mod +++ b/go.mod @@ -4,20 +4,22 @@ require ( bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc contrib.go.opencensus.io/exporter/prometheus v0.4.0 github.com/blang/semver/v4 v4.0.0 + github.com/cenkalti/backoff/v4 v4.1.3 github.com/ceramicnetwork/go-dag-jose v0.1.0 + github.com/cespare/xxhash v1.1.0 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-systemd/v22 v22.3.2 github.com/dustin/go-humanize v1.0.0 github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 + github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 github.com/fsnotify/fsnotify v1.5.1 github.com/gabriel-vasile/mimetype v1.4.0 - github.com/go-bindata/go-bindata/v3 v3.1.3 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/go-bitswap v0.5.1 + github.com/ipfs/go-bitswap v0.6.0 github.com/ipfs/go-block-format v0.0.3 - github.com/ipfs/go-blockservice v0.2.1 - github.com/ipfs/go-cid v0.1.0 - github.com/ipfs/go-cidutil v0.0.2 + github.com/ipfs/go-blockservice v0.3.0 + github.com/ipfs/go-cid v0.2.0 + github.com/ipfs/go-cidutil v0.1.0 github.com/ipfs/go-datastore v0.5.1 github.com/ipfs/go-detect-race v0.0.1 github.com/ipfs/go-ds-badger v0.3.0 @@ -25,16 +27,15 @@ require ( github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-measure v0.2.0 github.com/ipfs/go-fetcher v1.6.1 - github.com/ipfs/go-filestore v1.1.0 + github.com/ipfs/go-filestore v1.2.0 github.com/ipfs/go-fs-lock v0.0.7 - github.com/ipfs/go-graphsync v0.11.0 - github.com/ipfs/go-ipfs-blockstore v1.1.2 + github.com/ipfs/go-graphsync v0.13.1 + github.com/ipfs/go-ipfs-blockstore v1.2.0 github.com/ipfs/go-ipfs-chunker v0.0.5 - github.com/ipfs/go-ipfs-cmds v0.6.0 - github.com/ipfs/go-ipfs-config v0.18.0 + github.com/ipfs/go-ipfs-cmds v0.8.1 github.com/ipfs/go-ipfs-exchange-interface v0.1.0 - github.com/ipfs/go-ipfs-exchange-offline v0.1.1 - github.com/ipfs/go-ipfs-files v0.0.9 + github.com/ipfs/go-ipfs-exchange-offline v0.2.0 + github.com/ipfs/go-ipfs-files v0.1.1 github.com/ipfs/go-ipfs-keystore v0.0.2 github.com/ipfs/go-ipfs-pinner v0.2.1 github.com/ipfs/go-ipfs-posinfo v0.0.1 @@ -42,73 +43,235 @@ require ( github.com/ipfs/go-ipfs-routing v0.2.1 github.com/ipfs/go-ipfs-util v0.0.2 github.com/ipfs/go-ipld-cbor v0.0.5 - github.com/ipfs/go-ipld-format v0.2.0 + github.com/ipfs/go-ipld-format v0.4.0 github.com/ipfs/go-ipld-git v0.1.1 - github.com/ipfs/go-ipld-legacy v0.1.0 + github.com/ipfs/go-ipld-legacy v0.1.1 github.com/ipfs/go-ipns v0.1.2 github.com/ipfs/go-log v1.0.5 - github.com/ipfs/go-merkledag v0.5.1 + github.com/ipfs/go-merkledag v0.6.0 github.com/ipfs/go-metrics-interface v0.0.1 github.com/ipfs/go-metrics-prometheus v0.0.2 github.com/ipfs/go-mfs v0.2.1 - github.com/ipfs/go-namesys v0.4.0 - github.com/ipfs/go-path v0.2.1 - github.com/ipfs/go-pinning-service-http-client v0.1.0 + github.com/ipfs/go-namesys v0.5.0 + github.com/ipfs/go-path v0.3.0 + github.com/ipfs/go-pinning-service-http-client v0.1.1 github.com/ipfs/go-unixfs v0.3.1 - github.com/ipfs/go-unixfsnode v1.1.3 + github.com/ipfs/go-unixfsnode v1.4.0 github.com/ipfs/go-verifcid v0.0.1 - github.com/ipfs/interface-go-ipfs-core v0.5.2 + github.com/ipfs/interface-go-ipfs-core v0.7.0 github.com/ipfs/tar-utils v0.0.2 github.com/ipld/go-car v0.3.2 - github.com/ipld/go-codec-dagpb v1.3.2 - github.com/ipld/go-ipld-prime v0.14.2 + github.com/ipld/go-car/v2 v2.1.1 + github.com/ipld/go-codec-dagpb v1.4.0 + github.com/ipld/go-ipld-prime v0.16.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-temp-err-catcher v0.1.0 github.com/jbenet/goprocess v0.1.4 - github.com/libp2p/go-doh-resolver v0.3.1 - github.com/libp2p/go-libp2p v0.16.0 - github.com/libp2p/go-libp2p-connmgr v0.2.4 - github.com/libp2p/go-libp2p-core v0.11.0 + github.com/libp2p/go-doh-resolver v0.4.0 + github.com/libp2p/go-libp2p v0.19.4 + github.com/libp2p/go-libp2p-core v0.15.1 github.com/libp2p/go-libp2p-discovery v0.6.0 github.com/libp2p/go-libp2p-http v0.2.1 - github.com/libp2p/go-libp2p-kad-dht v0.15.0 + github.com/libp2p/go-libp2p-kad-dht v0.16.0 github.com/libp2p/go-libp2p-kbucket v0.4.7 github.com/libp2p/go-libp2p-loggables v0.1.0 - github.com/libp2p/go-libp2p-mplex v0.4.1 - github.com/libp2p/go-libp2p-noise v0.3.0 - github.com/libp2p/go-libp2p-peerstore v0.4.0 - github.com/libp2p/go-libp2p-pubsub v0.6.0 + github.com/libp2p/go-libp2p-mplex v0.7.0 + github.com/libp2p/go-libp2p-noise v0.4.0 + github.com/libp2p/go-libp2p-peerstore v0.6.0 + github.com/libp2p/go-libp2p-pubsub v0.6.1 github.com/libp2p/go-libp2p-pubsub-router v0.5.0 - github.com/libp2p/go-libp2p-quic-transport v0.15.0 + github.com/libp2p/go-libp2p-quic-transport v0.17.0 github.com/libp2p/go-libp2p-record v0.1.3 + github.com/libp2p/go-libp2p-resource-manager v0.3.0 github.com/libp2p/go-libp2p-routing-helpers v0.2.3 - github.com/libp2p/go-libp2p-swarm v0.8.0 - github.com/libp2p/go-libp2p-testing v0.5.0 - github.com/libp2p/go-libp2p-tls v0.3.1 - github.com/libp2p/go-libp2p-yamux v0.6.0 + github.com/libp2p/go-libp2p-swarm v0.10.2 + github.com/libp2p/go-libp2p-testing v0.9.2 + github.com/libp2p/go-libp2p-tls v0.4.1 + github.com/libp2p/go-libp2p-yamux v0.9.1 github.com/libp2p/go-socket-activation v0.1.0 - github.com/libp2p/go-tcp-transport v0.4.0 - github.com/libp2p/go-ws-transport v0.5.0 - github.com/miekg/dns v1.1.43 + github.com/libp2p/go-tcp-transport v0.5.1 + github.com/libp2p/go-ws-transport v0.6.0 + github.com/miekg/dns v1.1.48 github.com/mitchellh/go-homedir v1.1.0 - github.com/multiformats/go-multiaddr v0.4.1 + github.com/multiformats/go-multiaddr v0.5.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.0.3 - github.com/multiformats/go-multicodec v0.3.0 + github.com/multiformats/go-multicodec v0.4.1 github.com/multiformats/go-multihash v0.1.0 github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.11.0 - github.com/stretchr/testify v1.7.0 + github.com/prometheus/client_golang v1.12.1 + github.com/prometheus/common v0.33.0 // indirect + github.com/stretchr/testify v1.7.1 github.com/syndtr/goleveldb v1.0.0 + github.com/wI2L/jsondiff v0.2.0 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 go.opencensus.io v0.23.0 - go.uber.org/fx v1.15.0 - go.uber.org/zap v1.19.1 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 + go.opentelemetry.io/otel v1.7.0 + go.opentelemetry.io/otel/exporters/jaeger v1.7.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 + go.opentelemetry.io/otel/exporters/zipkin v1.7.0 + go.opentelemetry.io/otel/sdk v1.7.0 + go.opentelemetry.io/otel/trace v1.7.0 + go.uber.org/dig v1.14.0 + go.uber.org/fx v1.16.0 + go.uber.org/zap v1.21.0 + golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20211025112917-711f33c9992c + golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e ) -go 1.16 +require ( + github.com/benbjohnson/clock v1.3.0 + github.com/ipfs/go-log/v2 v2.5.1 +) + +require ( + github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect + github.com/Kubuxu/go-os-helper v0.0.1 // indirect + github.com/Stebalien/go-bitfield v0.0.1 // indirect + github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/btcsuite/btcd v0.22.1 // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cheekybits/genny v1.0.0 // indirect + github.com/containerd/cgroups v1.0.3 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect + github.com/cskr/pubsub v1.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/dgraph-io/badger v1.6.2 // indirect + github.com/dgraph-io/ristretto v0.0.2 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/elastic/gosigar v0.14.2 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/go-kit/log v0.2.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/huin/goupnp v1.0.3 // indirect + github.com/ipfs/bbloom v0.0.4 // indirect + github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-ipfs-delay v0.0.1 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-peertaskqueue v0.7.1 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/cpuid/v2 v2.0.12 // indirect + github.com/koron/go-ssdp v0.0.2 // indirect + github.com/libp2p/go-buffer-pool v0.0.2 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-conn-security-multistream v0.3.0 // indirect + github.com/libp2p/go-eventbus v0.2.1 // indirect + github.com/libp2p/go-flow-metrics v0.0.3 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-blankhost v0.3.0 // indirect + github.com/libp2p/go-libp2p-gostream v0.3.0 // indirect + github.com/libp2p/go-libp2p-nat v0.1.0 // indirect + github.com/libp2p/go-libp2p-pnet v0.2.0 // indirect + github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 // indirect + github.com/libp2p/go-libp2p-xor v0.1.0 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect + github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.0 // indirect + github.com/libp2p/go-openssl v0.0.7 // indirect + github.com/libp2p/go-reuseport v0.1.0 // indirect + github.com/libp2p/go-reuseport-transport v0.1.0 // indirect + github.com/libp2p/go-stream-muxer-multistream v0.4.0 // indirect + github.com/libp2p/go-yamux/v3 v3.1.2 // indirect + github.com/libp2p/zeroconf/v2 v2.1.1 // indirect + github.com/lucas-clemente/quic-go v0.27.1 // indirect + github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect + github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.0.4 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multistream v0.3.0 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/openzipkin/zipkin-go v0.4.0 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/statsd_exporter v0.21.0 // indirect + github.com/raulk/clock v1.1.0 // indirect + github.com/raulk/go-watchdog v1.2.0 // indirect + github.com/rs/cors v1.7.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e // indirect + github.com/tidwall/gjson v1.14.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect + github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect + github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 // indirect + github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect + go.opentelemetry.io/otel/metric v0.30.0 // indirect + go.opentelemetry.io/proto/otlp v0.16.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go4.org v0.0.0-20200411211856-f5505b9728dd // indirect + golang.org/x/exp v0.0.0-20210615023648-acb5c1269671 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect + golang.org/x/net v0.0.0-20220517181318-183a9ca12b87 // indirect + golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.10 // indirect + golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + google.golang.org/appengine v1.6.6 // indirect + google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect + google.golang.org/grpc v1.46.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + lukechampine.com/blake3 v1.1.7 // indirect +) + +go 1.17 diff --git a/go.sum b/go.sum index c6c8ad488db..09757be3eb4 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,7 @@ contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjI contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= @@ -54,7 +55,9 @@ github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETF github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -83,8 +86,9 @@ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -99,8 +103,11 @@ github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcug github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= +github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= +github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -117,13 +124,16 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= @@ -131,13 +141,23 @@ github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuP github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -145,14 +165,17 @@ github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelY github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -179,13 +202,19 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 h1:QV0ZrfBLpFc2KDk+a4LJefDczXnonRwrYrQJY/9L4dA= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWeVx9BjvqBsnC/8RUlAYpIFmPvgROcw0n1scE= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -194,23 +223,30 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe1ma7Lr6yG6/rjvM3emb6yoL7xLFzcVQ= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= +github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= @@ -219,8 +255,6 @@ github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0Fn github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-bindata/go-bindata/v3 v3.1.3 h1:F0nVttLC3ws0ojc7p60veTurcOm//D4QBODNM7EGrCI= -github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -229,19 +263,28 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/log v0.1.0 h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -251,6 +294,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -286,8 +331,9 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -297,11 +343,13 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -334,17 +382,24 @@ github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORR github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1/go.mod h1:jvfsLIxk0fY/2BKSQ1xf2406AKA5dwMmKKv0ADcOfN8= @@ -352,8 +407,9 @@ github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4n github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= @@ -366,6 +422,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -380,8 +437,9 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI= github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -396,8 +454,9 @@ github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSA github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM= github.com/ipfs/go-bitswap v0.3.4/go.mod h1:4T7fvNv/LmOys+21tnLzGKncMeeXUYUd1nUiJ2teMvI= -github.com/ipfs/go-bitswap v0.5.1 h1:721YAEDBnLIrvcIMkCHCdqp34hA8jwL9yKMkyJpSpco= github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= +github.com/ipfs/go-bitswap v0.6.0 h1:f2rc6GZtoSFhEIzQmddgGiel9xntj02Dg0ZNf2hSC+w= +github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= @@ -405,9 +464,9 @@ github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WW github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.1.4/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= -github.com/ipfs/go-blockservice v0.1.7/go.mod h1:GmS+BAt4hrwBKkzE11AFDQUrnvqjwFatGS2MY7wOjEM= -github.com/ipfs/go-blockservice v0.2.1 h1:NJ4j/cwEfIg60rzAWcCIxRtOwbf6ZPK49MewNxObCPQ= github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= +github.com/ipfs/go-blockservice v0.3.0 h1:cDgcZ+0P0Ih3sl8+qjFr2sVaMdysg/YZpLj5WJ8kiiw= +github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= @@ -415,10 +474,12 @@ github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= -github.com/ipfs/go-cidutil v0.0.2 h1:CNOboQf1t7Qp0nuNh8QMmhJs0+Q//bRL1axtCnIB1Yo= +github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= +github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= github.com/ipfs/go-cidutil v0.0.2/go.mod h1:ewllrvrxG6AMYStla3GD7Cqn+XYSLqjK0vc+086tB6s= +github.com/ipfs/go-cidutil v0.1.0 h1:RW5hO7Vcf16dplUU60Hs0AKDkQAVPVplr7lk97CFL+Q= +github.com/ipfs/go-cidutil v0.1.0/go.mod h1:e7OEVBMIv9JaOxt9zaGEmAoSlXW9jdFZ5lP/0PwcfpA= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -454,29 +515,26 @@ github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9 github.com/ipfs/go-fetcher v1.5.0/go.mod h1:5pDZ0393oRF/fHiLmtFZtpMNBQfHOYNPtryWedVuSWE= github.com/ipfs/go-fetcher v1.6.1 h1:UFuRVYX5AIllTiRhi5uK/iZkfhSpBCGX7L70nSZEmK8= github.com/ipfs/go-fetcher v1.6.1/go.mod h1:27d/xMV8bodjVs9pugh/RCjjK2OZ68UgAMspMdingNo= -github.com/ipfs/go-filestore v1.1.0 h1:Pu4tLBi1bucu6/HU9llaOmb9yLFk/sgP+pW764zNDoE= -github.com/ipfs/go-filestore v1.1.0/go.mod h1:6e1/5Y6NvLuCRdmda/KA4GUhXJQ3Uat6vcWm2DJfxc8= +github.com/ipfs/go-filestore v1.2.0 h1:O2wg7wdibwxkEDcl7xkuQsPvJFRBVgVSsOJ/GP6z3yU= +github.com/ipfs/go-filestore v1.2.0/go.mod h1:HLJrCxRXquTeEEpde4lTLMaE/MYJZD7WHLkp9z6+FF8= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-graphsync v0.11.0 h1:PiiD5CnoC3xEHMW8d6uBGqGcoTwiMB5d9CORIEyF6iA= -github.com/ipfs/go-graphsync v0.11.0/go.mod h1:wC+c8vGVjAHthsVIl8LKr37cUra2GOaMYcQNNmMxDqE= +github.com/ipfs/go-graphsync v0.13.1 h1:lWiP/WLycoPUYyj3IDEi1GJNP30kFuYOvimcfeuZyQs= +github.com/ipfs/go-graphsync v0.13.1/go.mod h1:y8e8G6CmZeL9Srvx1l15CtGiRdf3h5JdQuqPz/iYL0A= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ= -github.com/ipfs/go-ipfs-blockstore v0.1.6/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ= github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= -github.com/ipfs/go-ipfs-blockstore v1.1.1/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= -github.com/ipfs/go-ipfs-blockstore v1.1.2 h1:WCXoZcMYnvOTmlpX+RSSnhVN0uCmbWTeepTGX5lgiXw= github.com/ipfs/go-ipfs-blockstore v1.1.2/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY= +github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= +github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.6.0 h1:yAxdowQZzoFKjcLI08sXVNnqVj3jnABbf9smrPQmBsw= -github.com/ipfs/go-ipfs-cmds v0.6.0/go.mod h1:ZgYiWVnCk43ChwoH8hAmI1IRbuVtq3GSTHwtRB/Kqhk= -github.com/ipfs/go-ipfs-config v0.18.0 h1:Ta1aNGNEq6RIvzbw7dqzCVZJKb7j+Dd35JFnAOCpT8g= -github.com/ipfs/go-ipfs-config v0.18.0/go.mod h1:wz2lKzOjgJeYJa6zx8W9VT7mz+iSd0laBMqS/9wmX6A= +github.com/ipfs/go-ipfs-cmds v0.8.1 h1:El661DBWqdqwgz7B9xwKyUpigwqk6BBBHb5B8DfJP00= +github.com/ipfs/go-ipfs-cmds v0.8.1/go.mod h1:y0bflH6m4g6ary4HniYt98UqbrVnRxmRarzeMdLIUn0= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -488,12 +546,13 @@ github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFq github.com/ipfs/go-ipfs-exchange-interface v0.1.0 h1:TiMekCrOGQuWYtZO3mf4YJXDIdNgnKWZ9IE3fGlnWfo= github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= -github.com/ipfs/go-ipfs-exchange-offline v0.1.1 h1:mEiXWdbMN6C7vtDG21Fphx8TGCbZPpQnz/496w/PL4g= github.com/ipfs/go-ipfs-exchange-offline v0.1.1/go.mod h1:vTiBRIbzSwDD0OWm+i3xeT0mO7jG2cbJYatp3HPk5XY= +github.com/ipfs/go-ipfs-exchange-offline v0.2.0 h1:2PF4o4A7W656rC0RxuhUace997FTcDTcIQ6NoEtyjAI= +github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= -github.com/ipfs/go-ipfs-files v0.0.9 h1:OFyOfmuVDu9c5YtjSDORmwXzE6fmZikzZpzsnNkgFEg= -github.com/ipfs/go-ipfs-files v0.0.9/go.mod h1:aFv2uQ/qxWpL/6lidWvnSQmaVqCrf0TBGoUr+C1Fo84= +github.com/ipfs/go-ipfs-files v0.1.1 h1:/MbEowmpLo9PJTEQk16m9rKzUHjeP4KRU9nWJyJO324= +github.com/ipfs/go-ipfs-files v0.1.1/go.mod h1:8xkIrMWH+Y5P7HvJ4Yc5XWwIW2e52dyXUiC0tZyjDbM= github.com/ipfs/go-ipfs-keystore v0.0.2 h1:Fa9xg9IFD1VbiZtrNLzsD0GuELVHUFXCWF64kCPfEXU= github.com/ipfs/go-ipfs-keystore v0.0.2/go.mod h1:H49tRmibOEs7gLMgbOsjC4dqh1u5e0R/SWuc2ScfgSo= github.com/ipfs/go-ipfs-pinner v0.2.1 h1:kw9hiqh2p8TatILYZ3WAfQQABby7SQARdrdA+5Z5QfY= @@ -519,12 +578,15 @@ github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5 github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= -github.com/ipfs/go-ipld-format v0.2.0 h1:xGlJKkArkmBvowr+GMCX0FEZtkro71K1AwiKnL37mwA= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= +github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= +github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= github.com/ipfs/go-ipld-git v0.1.1/go.mod h1:+VyMqF5lMcJh4rwEppV0e6g4nCCHXThLYYDpKUkJubI= -github.com/ipfs/go-ipld-legacy v0.1.0 h1:wxkkc4k8cnvIGIjPO0waJCe7SHEyFgl+yQdafdjGrpA= github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= +github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2cdcc= +github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg= github.com/ipfs/go-ipns v0.1.2 h1:O/s/0ht+4Jl9+VoxoUo0zaHjnZUS+aBQIKTuzdZ/ucI= github.com/ipfs/go-ipns v0.1.2/go.mod h1:ioQ0j02o6jdIVW+bmi18f4k2gRf0AV3kZ9KeHYHICnQ= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= @@ -538,61 +600,71 @@ github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.3.0 h1:31Re/cPqFHpsRHgyVwjWADPoF0otB1WrjTy8ZFYwEZU= github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= +github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= -github.com/ipfs/go-merkledag v0.4.0/go.mod h1:XshXBkhyeS63YNGisLL1uDSfuTyrQIxVUOg3ojR5MOE= -github.com/ipfs/go-merkledag v0.5.1 h1:tr17GPP5XtPhvPPiWtu20tSGZiZDuTaJRXBLcr79Umk= github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= +github.com/ipfs/go-merkledag v0.6.0 h1:oV5WT2321tS4YQVOPgIrWHvJ0lJobRTerU+i9nmUCuA= +github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-metrics-prometheus v0.0.2 h1:9i2iljLg12S78OhC6UAiXi176xvQGiZaGVF1CUVdE+s= github.com/ipfs/go-metrics-prometheus v0.0.2/go.mod h1:ELLU99AQQNi+zX6GCGm2lAgnzdSH3u5UVlCdqSXnEks= github.com/ipfs/go-mfs v0.2.1 h1:5jz8+ukAg/z6jTkollzxGzhkl3yxm022Za9f2nL5ab8= github.com/ipfs/go-mfs v0.2.1/go.mod h1:Woj80iuw4ajDnIP6+seRaoHpPsc9hmL0pk/nDNDWP88= -github.com/ipfs/go-namesys v0.4.0 h1:Gxg4kEWxVcHuUJl60KMNs1k8AiVB3luXbz8ZJkSGacs= -github.com/ipfs/go-namesys v0.4.0/go.mod h1:jpJwzodyP8DZdWN6DShRjVZw6gaqMr4nQLBSxU5cR6E= +github.com/ipfs/go-namesys v0.5.0 h1:vZEkdqxRiSnxBBJrvYTkwHYBFgibGUSpNtg9BHRyN+o= +github.com/ipfs/go-namesys v0.5.0/go.mod h1:zZOme8KDAUYDl4f5MnWSiTRhoxcM7kLkZIyps/HV/S0= github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= github.com/ipfs/go-path v0.0.9/go.mod h1:VpDkSBKQ9EFQOUgi54Tq/O/tGi8n1RfYNks13M3DEs8= github.com/ipfs/go-path v0.1.1/go.mod h1:vC8q4AKOtrjJz2NnllIrmr2ZbGlF5fW2OKKyhV9ggb0= -github.com/ipfs/go-path v0.2.1 h1:R0JYCu0JBnfa6A3C42nzsNPxtKU5/fnUPhWSuzcJHws= github.com/ipfs/go-path v0.2.1/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= +github.com/ipfs/go-path v0.3.0 h1:tkjga3MtpXyM5v+3EbRvOHEoo+frwi4oumw5K+KYWyA= +github.com/ipfs/go-path v0.3.0/go.mod h1:NOScsVgxfC/eIw4nz6OiGwK42PjaSJ4Y/ZFPn1Xe07I= github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY= -github.com/ipfs/go-peertaskqueue v0.7.0 h1:VyO6G4sbzX80K58N60cCaHsSsypbUNs1GjO5seGNsQ0= github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= -github.com/ipfs/go-pinning-service-http-client v0.1.0 h1:Au0P4NglL5JfzhNSZHlZ1qra+IcJyO3RWMd9EYCwqSY= -github.com/ipfs/go-pinning-service-http-client v0.1.0/go.mod h1:tcCKmlkWWH9JUUkKs8CrOZBanacNc1dmKLfjlyXAMu4= +github.com/ipfs/go-peertaskqueue v0.7.1 h1:7PLjon3RZwRQMgOTvYccZ+mjzkmds/7YzSWKFlBAypE= +github.com/ipfs/go-peertaskqueue v0.7.1/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= +github.com/ipfs/go-pinning-service-http-client v0.1.1 h1:Bar+Vi60A0zI8GSSrumVqnbFg6qkUgZSQTX9sV5jWrA= +github.com/ipfs/go-pinning-service-http-client v0.1.1/go.mod h1:i6tC2nWOnJbZZUQPgxOlrg4CX8bhQZMh4II09FxvD58= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= github.com/ipfs/go-unixfs v0.3.1 h1:LrfED0OGfG98ZEegO4/xiprx2O+yS+krCMQSp7zLVv8= github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= github.com/ipfs/go-unixfsnode v1.1.2/go.mod h1:5dcE2x03pyjHk4JjamXmunTMzz+VUtqvPwZjIEkfV6s= -github.com/ipfs/go-unixfsnode v1.1.3 h1:IyqJBGIEvcHvll1wDDVIHOEVXnE+IH6tjzTWpZ6kGiI= -github.com/ipfs/go-unixfsnode v1.1.3/go.mod h1:ZZxUM5wXBC+G0Co9FjrYTOm+UlhZTjxLfRYdWY9veZ4= +github.com/ipfs/go-unixfsnode v1.4.0 h1:9BUxHBXrbNi8mWHc6j+5C580WJqtVw9uoeEKn4tMhwA= +github.com/ipfs/go-unixfsnode v1.4.0/go.mod h1:qc7YFFZ8tABc58p62HnIYbUMwj9chhUuFWmxSokfePo= github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/interface-go-ipfs-core v0.4.0/go.mod h1:UJBcU6iNennuI05amq3FQ7g0JHUkibHFAfhfUIy927o= -github.com/ipfs/interface-go-ipfs-core v0.5.2 h1:m1/5U+WpOK2ZE7Qzs5iIu80QM1ZA3aWYi2Ilwpi+tdg= -github.com/ipfs/interface-go-ipfs-core v0.5.2/go.mod h1:lNBJrdXHtWS46evMPBdWtDQMDsrKcGbxCOGoKLkztOE= +github.com/ipfs/interface-go-ipfs-core v0.7.0 h1:7tb+2upz8oCcjIyjo1atdMk+P+u7wPmI+GksBlLE8js= +github.com/ipfs/interface-go-ipfs-core v0.7.0/go.mod h1:lF27E/nnSPbylPqKVXGZghal2hzifs3MmjyiEjnc9FY= github.com/ipfs/tar-utils v0.0.2 h1:UNgHB4x/PPzbMkmJi+7EqC9LNMPDztOVSnx1HAqSNg4= github.com/ipfs/tar-utils v0.0.2/go.mod h1:4qlnRWgTVljIMhSG2SqRYn66NT+3wrv/kZt9V+eqxDM= github.com/ipld/go-car v0.3.2 h1:V9wt/80FNfbMRWSD98W5br6fyjUAyVgI2lDOTZX16Lg= github.com/ipld/go-car v0.3.2/go.mod h1:WEjynkVt04dr0GwJhry0KlaTeSDEiEYyMPOxDBQ17KE= +github.com/ipld/go-car/v2 v2.1.1 h1:saaKz4nC0AdfCGHLYKeXLGn8ivoPC54fyS55uyOLKwA= +github.com/ipld/go-car/v2 v2.1.1/go.mod h1:+2Yvf0Z3wzkv7NeI69i8tuZ+ft7jyjPYIWZzeVNeFcI= github.com/ipld/go-codec-dagpb v1.2.0/go.mod h1:6nBN7X7h8EOsEejZGqC7tej5drsdBAXbMHyBT+Fne5s= github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= -github.com/ipld/go-codec-dagpb v1.3.2 h1:MZQUIjanHXXfDuYmtWYT8nFbqfFsZuyHClj6VDmSXr4= -github.com/ipld/go-codec-dagpb v1.3.2/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= +github.com/ipld/go-codec-dagpb v1.3.1/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= +github.com/ipld/go-codec-dagpb v1.4.0 h1:VqADPIFng8G4vz5EQytmmcx/2gEgOHfBuw/kIuCgDAY= +github.com/ipld/go-codec-dagpb v1.4.0/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= github.com/ipld/go-ipld-prime v0.12.3/go.mod h1:PaeLYq8k6dJLmDUSLrzkEpoGV4PEfe/1OtFN/eALOc8= +github.com/ipld/go-ipld-prime v0.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= -github.com/ipld/go-ipld-prime v0.14.2 h1:P5fO2usnisXwrN/1sR5exCgEvINg/w/27EuYPKB/zx8= -github.com/ipld/go-ipld-prime v0.14.2/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= +github.com/ipld/go-ipld-prime v0.16.0 h1:RS5hhjB/mcpeEPJvfyj0qbOj/QL+/j05heZ0qa97dVo= +github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73 h1:TsyATB2ZRRQGTwafJdgEUQkmjOExRV0DNokcihZxbnQ= +github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -609,6 +681,12 @@ github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsj github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -621,6 +699,7 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -631,16 +710,18 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -660,7 +741,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= -github.com/libp2p/go-addr-util v0.1.0 h1:acKsntI33w2bTU7tC9a0SaPimJGfSI0bFKC18ChxeVI= github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= @@ -674,8 +754,8 @@ github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5 github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-conn-security-multistream v0.3.0 h1:9UCIKlBL1hC9u7nkMXpD1nkc/T53PKMAn3/k9ivBAVc= github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= -github.com/libp2p/go-doh-resolver v0.3.1 h1:1wbVGkB4Tdj4WEvjAuYknOPyt4vSSDn9thnj13pKPaY= -github.com/libp2p/go-doh-resolver v0.3.1/go.mod h1:y5go1ZppAq9N2eppbX0xON01CyPBeUg2yS6BTssssog= +github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+0S7FQqw= +github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= @@ -692,14 +772,16 @@ github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniV github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.12.0/go.mod h1:FpHZrfC1q7nA8jitvdjKBDF31hguaC676g/nT9PgQM0= github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= -github.com/libp2p/go-libp2p v0.14.0/go.mod h1:dsQrWLAoIn+GkHPN/U+yypizkHiB9tnv79Os+kSgQ4Q= github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= github.com/libp2p/go-libp2p v0.14.4/go.mod h1:EIRU0Of4J5S8rkockZM7eJp2S0UrCyi55m2kJVru3rM= -github.com/libp2p/go-libp2p v0.16.0 h1:aTxzQPllnW+nyC9mY8xaS20BbcrSYMt1HCkjZRHvdGY= github.com/libp2p/go-libp2p v0.16.0/go.mod h1:ump42BsirwAWxKzsCiFnTtN1Yc+DuPu76fyMX364/O4= +github.com/libp2p/go-libp2p v0.18.0/go.mod h1:+veaZ9z1SZQhmc5PW78jvnnxZ89Mgvmh4cggO11ETmw= +github.com/libp2p/go-libp2p v0.19.4 h1:50YL0YwPhWKDd+qbZQDEdnsmVAAkaCQrWUjpdHv4hNA= +github.com/libp2p/go-libp2p v0.19.4/go.mod h1:MIt8y481VDhUe4ErWi1a4bvt/CjjFfOq6kZTothWIXY= github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052/go.mod h1:nRMRTab+kZuk0LnKZpxhOVH/ndsdr2Nr//Zltc/vwgo= -github.com/libp2p/go-libp2p-asn-util v0.1.0 h1:rABPCO77SjdbJ/eJ/ynIo8vWICy1VEnL5JAxJbQLo1E= github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= @@ -708,19 +790,20 @@ github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRk github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= github.com/libp2p/go-libp2p-autonat v0.4.0/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= -github.com/libp2p/go-libp2p-autonat v0.6.0 h1:+vbQ1pMzMGjE/RJopiQKK2FRjdCKHPNPrkPm8u+luQU= github.com/libp2p/go-libp2p-autonat v0.6.0/go.mod h1:bFC6kY8jwzNNWoqc8iGE57vsfwyJ/lP4O4DOV1e0B2o= github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= -github.com/libp2p/go-libp2p-blankhost v0.2.0 h1:3EsGAi0CBGcZ33GwRuXEYJLLPoVWyXJ1bcJzAJjINkk= github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-blankhost v0.3.0 h1:kTnLArltMabZlzY63pgGDA4kkUcLkBFSM98zBssn/IY= +github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU= github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= -github.com/libp2p/go-libp2p-circuit v0.4.0 h1:eqQ3sEYkGTtybWgr6JLqJY6QLtPWRErvFjFDfAOO1wc= github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= +github.com/libp2p/go-libp2p-circuit v0.6.0 h1:rw/HlhmUB3OktS/Ygz6+2XABOmHKzZpPUuMNUMosj8w= +github.com/libp2p/go-libp2p-circuit v0.6.0/go.mod h1:kB8hY+zCpMeScyvFrKrGicRdid6vNXbunKE4rXATZ0M= github.com/libp2p/go-libp2p-connmgr v0.2.4 h1:TMS0vc0TCBomtQJyWr7fYxcVYYhx+q/2gF++G5Jkl/w= github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQiQfKhHCCs1++ufn0= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= @@ -751,8 +834,11 @@ github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJB github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8= github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= -github.com/libp2p/go-libp2p-core v0.11.0 h1:75jAgdA+IChNa+/mZXogfmrGkgwxkVvxmIC7pV+F6sI= github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.14.0/go.mod h1:tLasfcVdTXnixsLB0QYaT1syJOhsbrhG7q6pGrHtBg8= +github.com/libp2p/go-libp2p-core v0.15.1 h1:0RY+Mi/ARK9DgG1g9xVQLb8dDaaU8tCePMtGALEfBnM= +github.com/libp2p/go-libp2p-core v0.15.1/go.mod h1:agSaboYM4hzB1cWekgVReqV5M4g5M+2eNNejV+1EEhs= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= @@ -773,8 +859,9 @@ github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= -github.com/libp2p/go-libp2p-kad-dht v0.15.0 h1:Ke+Oj78gX5UDXnA6HBdrgvi+fStJxgYTDa51U0TsCLo= github.com/libp2p/go-libp2p-kad-dht v0.15.0/go.mod h1:rZtPxYu1TnHHz6n1RggdGrxUX/tA1C2/Wiw3ZMUDrU0= +github.com/libp2p/go-libp2p-kad-dht v0.16.0 h1:epVRYl3O8dn47uV3wVD2+IobEvBPapEMVj4sWlvwQHU= +github.com/libp2p/go-libp2p-kad-dht v0.16.0/go.mod h1:YYLlG8AbpWVGbI/zFeSbiGT0n0lluH7IG0sHeounyWA= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= github.com/libp2p/go-libp2p-kbucket v0.4.7 h1:spZAcgxifvFZHBD8tErvppbnNiKA5uokDu3CV7axu70= github.com/libp2p/go-libp2p-kbucket v0.4.7/go.mod h1:XyVo99AfQH0foSf176k4jY1xUJ2+jUJIZCSDm7r2YKk= @@ -789,8 +876,11 @@ github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= github.com/libp2p/go-libp2p-mplex v0.3.0/go.mod h1:l9QWxRbbb5/hQMECEb908GbS9Sm2UAR2KFZKUJEynEs= github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= -github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-mplex v0.5.0/go.mod h1:eLImPJLkj3iG5t5lq68w3Vm5NAQ5BcKwrrb2VmOYb3M= +github.com/libp2p/go-libp2p-mplex v0.6.0/go.mod h1:i3usuPrBbh9FD2fLZjGpotyNkwr42KStYZQY7BeTiu4= +github.com/libp2p/go-libp2p-mplex v0.7.0 h1:ONTTvHIUaFCwyPO4FRkpe4OFQJq1bDkWQLbhWiD1A44= +github.com/libp2p/go-libp2p-mplex v0.7.0/go.mod h1:SeeXUXh7ZkfxnmsepnFgMPEhfEyACujuTM9k1TkErpc= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= @@ -803,8 +893,9 @@ github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLK github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= github.com/libp2p/go-libp2p-noise v0.1.1/go.mod h1:QDFLdKX7nluB7DEnlVPbz7xlLHdwHFA9HiohJRr3vwM= github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= -github.com/libp2p/go-libp2p-noise v0.3.0 h1:NCVH7evhVt9njbTQshzT7N1S3Q6fjj9M11FCgfH5+cA= github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= +github.com/libp2p/go-libp2p-noise v0.4.0 h1:khcMsGhHNdGqKE5LDLrnHwZvdGVMsrnD4GTkTWkwmLU= +github.com/libp2p/go-libp2p-noise v0.4.0/go.mod h1:BzzY5pyzCYSyJbQy9oD8z5oP2idsafjt4/X42h9DjZU= github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= @@ -819,26 +910,35 @@ github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRj github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= github.com/libp2p/go-libp2p-peerstore v0.2.8/go.mod h1:gGiPlXdz7mIHd2vfAsHzBNAMqSDkt2UBFwgcITgw1lA= -github.com/libp2p/go-libp2p-peerstore v0.4.0 h1:DOhRJLnM9Dc9lIXi3rPDZBf789LXy1BrzwIs7Tj0cKA= github.com/libp2p/go-libp2p-peerstore v0.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= +github.com/libp2p/go-libp2p-peerstore v0.6.0 h1:HJminhQSGISBIRb93N6WK3t6Fa8OOTnHd/VBjL4mY5A= +github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= -github.com/libp2p/go-libp2p-pubsub v0.6.0 h1:98+RXuEWW17U6cAijK1yaTf6mw/B+n5yPA421z+dlo0= github.com/libp2p/go-libp2p-pubsub v0.6.0/go.mod h1:nJv87QM2cU0w45KPR1rZicq+FmFIOD16zmT+ep1nOmg= +github.com/libp2p/go-libp2p-pubsub v0.6.1 h1:wycbV+f4rreCoVY61Do6g/BUk0RIrbNRcYVbn+QkjGk= +github.com/libp2p/go-libp2p-pubsub v0.6.1/go.mod h1:nJv87QM2cU0w45KPR1rZicq+FmFIOD16zmT+ep1nOmg= github.com/libp2p/go-libp2p-pubsub-router v0.5.0 h1:WuYdY42DVIJ+N0qMdq2du/E9poJH+xzsXL7Uptwj9tw= github.com/libp2p/go-libp2p-pubsub-router v0.5.0/go.mod h1:TRJKskSem3C0aSb3CmRgPwq6IleVFzds6hS09fmZbGM= github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= github.com/libp2p/go-libp2p-quic-transport v0.11.2/go.mod h1:wlanzKtIh6pHrq+0U3p3DY9PJfGqxMgPaGKaK5LifwQ= github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= -github.com/libp2p/go-libp2p-quic-transport v0.15.0 h1:DR0mP6kcieowikBprWkcNtbquRKOPWb5dLZ4ahDZujk= github.com/libp2p/go-libp2p-quic-transport v0.15.0/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-quic-transport v0.16.0/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= +github.com/libp2p/go-libp2p-quic-transport v0.16.1/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= +github.com/libp2p/go-libp2p-quic-transport v0.17.0 h1:yFh4Gf5MlToAYLuw/dRvuzYd1EnE2pX3Lq1N6KDiWRQ= +github.com/libp2p/go-libp2p-quic-transport v0.17.0/go.mod h1:x4pw61P3/GRCcSLypcQJE/Q2+E9f4X+5aRcZLXf20LM= github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= github.com/libp2p/go-libp2p-record v0.1.2/go.mod h1:pal0eNcT5nqZaTV7UGhqeGqxFgGdsU/9W//C8dqjQDk= github.com/libp2p/go-libp2p-record v0.1.3 h1:R27hoScIhQf/A8XJZ8lYpnqh9LatJ5YbHs28kCIfql0= github.com/libp2p/go-libp2p-record v0.1.3/go.mod h1:yNUff/adKIfPnYQXgp6FQmNu3gLJ6EMg7+/vv2+9pY4= +github.com/libp2p/go-libp2p-resource-manager v0.1.5/go.mod h1:wJPNjeE4XQlxeidwqVY5G6DLOKqFK33u2n8blpl0I6Y= +github.com/libp2p/go-libp2p-resource-manager v0.2.1/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= +github.com/libp2p/go-libp2p-resource-manager v0.3.0 h1:2+cYxUNi33tcydsVLt6K5Fv2E3OTiVeafltecAj15E0= +github.com/libp2p/go-libp2p-resource-manager v0.3.0/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= github.com/libp2p/go-libp2p-routing-helpers v0.2.3 h1:xY61alxJ6PurSi+MXbywZpelvuU4U4p/gPTxjqCqTzY= github.com/libp2p/go-libp2p-routing-helpers v0.2.3/go.mod h1:795bh+9YeoFl99rMASoiVgHdi5bjack0N1+AFAdbvBw= @@ -857,8 +957,10 @@ github.com/libp2p/go-libp2p-swarm v0.3.1/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJeg github.com/libp2p/go-libp2p-swarm v0.4.0/go.mod h1:XVFcO52VoLoo0eitSxNQWYq4D6sydGOweTOAjJNraCw= github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= github.com/libp2p/go-libp2p-swarm v0.5.3/go.mod h1:NBn7eNW2lu568L7Ns9wdFrOhgRlkRnIDg0FLKbuu3i8= -github.com/libp2p/go-libp2p-swarm v0.8.0 h1:nRHNRhi86L7jhka02N4MoV+PSFFPoJFkHNQwCTFxNhw= github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= +github.com/libp2p/go-libp2p-swarm v0.10.0/go.mod h1:71ceMcV6Rg/0rIQ97rsZWMzto1l9LnNquef+efcRbmA= +github.com/libp2p/go-libp2p-swarm v0.10.2 h1:UaXf+CTq6Ns1N2V1EgqJ9Q3xaRsiN7ImVlDMpirMAWw= +github.com/libp2p/go-libp2p-swarm v0.10.2/go.mod h1:Pdkq0QU5a+qu+oyqIV3bknMsnzk9lnNyKvB9acJ5aZs= github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= @@ -869,12 +971,17 @@ github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= -github.com/libp2p/go-libp2p-testing v0.5.0 h1:bTjC29TTQ/ODq0ld3+0KLq3irdA5cAH3OMbRi0/QsvE= github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= +github.com/libp2p/go-libp2p-testing v0.7.0/go.mod h1:OLbdn9DbgdMwv00v+tlp1l3oe2Cl+FAjoWIA2pa0X6E= +github.com/libp2p/go-libp2p-testing v0.8.0/go.mod h1:gRdsNxQSxAZowTgcLY7CC33xPmleZzoBpqSYbWenqPc= +github.com/libp2p/go-libp2p-testing v0.9.0/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= +github.com/libp2p/go-libp2p-testing v0.9.2 h1:dCpODRtRaDZKF8HXT9qqqgON+OMEB423Knrgeod8j84= +github.com/libp2p/go-libp2p-testing v0.9.2/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= -github.com/libp2p/go-libp2p-tls v0.3.1 h1:lsE2zYte+rZCEOHF72J1Fg3XK3dGQyKvI6i5ehJfEp0= github.com/libp2p/go-libp2p-tls v0.3.1/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.4.1 h1:1ByJUbyoMXvYXDoW6lLsMxqMViQNXmt+CfQqlnCpY+M= +github.com/libp2p/go-libp2p-tls v0.4.1/go.mod h1:EKCixHEysLNDlLUoKxv+3f/Lp90O2EXNjTr0UQDnrIw= github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= @@ -885,10 +992,13 @@ github.com/libp2p/go-libp2p-transport-upgrader v0.4.0/go.mod h1:J4ko0ObtZSmgn5BX github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= github.com/libp2p/go-libp2p-transport-upgrader v0.4.6/go.mod h1:JE0WQuQdy+uLZ5zOaI3Nw9dWGYJIA7mywEtP2lMvnyk= -github.com/libp2p/go-libp2p-transport-upgrader v0.5.0 h1:7SDl3O2+AYOgfE40Mis83ClpfGNkNA6m4FwhbOHs+iI= github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= -github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db h1:EDoDKW8ZAHd6SIDeo+thU51PyQppqLYkBxx0ObvFj/w= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.0/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 h1:MSMe+tUfxpC9GArTz7a4G5zQKQgGh00Vio87d3j3xIg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= +github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= +github.com/libp2p/go-libp2p-xor v0.1.0/go.mod h1:LSTM5yRnjGZbWNTA/hRwq2gGFrvRIbQJscoIL/u6InY= github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= @@ -900,14 +1010,16 @@ github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2Ez github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-libp2p-yamux v0.5.1/go.mod h1:dowuvDu8CRWmr0iqySMiSxK+W0iL5cMVO9S94Y6gkv4= -github.com/libp2p/go-libp2p-yamux v0.5.3/go.mod h1:Vy3TMonBAfTMXHWopsMc8iX/XGRYrRlpUaMzaeuHV/s= github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= -github.com/libp2p/go-libp2p-yamux v0.6.0 h1:TKayW983n92JhCGdCo7ej7eEb+DQ0VYfKNOxlN/1kNQ= github.com/libp2p/go-libp2p-yamux v0.6.0/go.mod h1:MRhd6mAYnFRnSISp4M8i0ClV/j+mWHo2mYLifWGw33k= +github.com/libp2p/go-libp2p-yamux v0.8.0/go.mod h1:yTkPgN2ib8FHyU1ZcVD7aelzyAqXXwEPbyx+aSKm9h8= +github.com/libp2p/go-libp2p-yamux v0.8.1/go.mod h1:rUozF8Jah2dL9LLGyBaBeTQeARdwhefMCTQVQt6QobE= +github.com/libp2p/go-libp2p-yamux v0.8.2/go.mod h1:rUozF8Jah2dL9LLGyBaBeTQeARdwhefMCTQVQt6QobE= +github.com/libp2p/go-libp2p-yamux v0.9.1 h1:oplewiRix8s45SOrI30rCPZG5mM087YZp+VYhXAh4+c= +github.com/libp2p/go-libp2p-yamux v0.9.1/go.mod h1:wRc6wvyxQINFcKe7daL4BeQ02Iyp+wxyC8WCNfngBrA= github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= -github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= @@ -915,14 +1027,18 @@ github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6 github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= -github.com/libp2p/go-mplex v0.3.0 h1:U1T+vmCYJaEoDJPV1aq31N56hS+lJgb397GsylNSgrU= github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.4.0/go.mod h1:y26Lx+wNVtMYMaPu300Cbot5LkEZ4tJaNYeHeT9dh6E= +github.com/libp2p/go-mplex v0.6.0/go.mod h1:y26Lx+wNVtMYMaPu300Cbot5LkEZ4tJaNYeHeT9dh6E= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= -github.com/libp2p/go-msgio v0.1.0 h1:8Q7g/528ivAlfXTFWvWhVjTE8XG8sDTkRUKPYh9+5Q8= github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE= +github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= @@ -931,8 +1047,9 @@ github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= -github.com/libp2p/go-netroute v0.1.6 h1:ruPJStbYyXVYGQ81uzEDzuvbYRLKRrLvTYd33yomC38= github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= +github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= +github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= @@ -951,7 +1068,6 @@ github.com/libp2p/go-reuseport-transport v0.1.0 h1:C3PHeHjmnz8m6f0uydObj02tMEoi7 github.com/libp2p/go-reuseport-transport v0.1.0/go.mod h1:vev0C0uMkzriDY59yFHD9v+ujJvYmDQVLowvAjEOmfw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.1 h1:yD80l2ZOdGksnOyHrhxDdTDFrf7Oy+v3FMVArIRgZxQ= github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-socket-activation v0.1.0 h1:OImQPhtbGlCNaF/KSTl6pBBy+chA5eBt5i9uMJNtEdY= github.com/libp2p/go-socket-activation v0.1.0/go.mod h1:gzda2dNkMG5Ti2OfWNNwW0FDIbj0g/aJJU320FcLfhk= @@ -959,8 +1075,9 @@ github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= -github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-stream-muxer-multistream v0.4.0 h1:HsM/9OdtqnIzjVXcxTXjmqKrj3gJ8kacaOJwJS1ipaY= +github.com/libp2p/go-stream-muxer-multistream v0.4.0/go.mod h1:nb+dGViZleRP4XcyHuZSVrJCBl55nRBOMmiSL/dyziw= github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= @@ -969,8 +1086,10 @@ github.com/libp2p/go-tcp-transport v0.2.1/go.mod h1:zskiJ70MEfWz2MKxvFB/Pv+tPIB1 github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.2.4/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= github.com/libp2p/go-tcp-transport v0.2.7/go.mod h1:lue9p1b3VmZj1MhhEGB/etmvF/nBQ0X9CW2DutBT3MM= -github.com/libp2p/go-tcp-transport v0.4.0 h1:VDyg4j6en3OuXf90gfDQh5Sy9KowO9udnd0OU8PP6zg= github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= +github.com/libp2p/go-tcp-transport v0.5.0/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= +github.com/libp2p/go-tcp-transport v0.5.1 h1:edOOs688VLZAozWC7Kj5/6HHXKNwi9M6wgRmmLa8M6Q= +github.com/libp2p/go-tcp-transport v0.5.1/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= @@ -979,8 +1098,9 @@ github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzl github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= -github.com/libp2p/go-ws-transport v0.5.0 h1:cO6x4P0v6PfxbKnxmf5cY2Ny4OPDGYkUqNvZzp/zdlo= github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xds1iamArLvl8kNg= +github.com/libp2p/go-ws-transport v0.6.0 h1:326XBL6Q+5CQ2KtjXz32+eGu02W/Kz2+Fm4SpXdr0q4= +github.com/libp2p/go-ws-transport v0.6.0/go.mod h1:dXqtI9e2JV9FtF1NOtWVZSKXh5zXvnuwPXfj8GPBbYU= github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= @@ -992,10 +1112,13 @@ github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawOJiflsAM+7U= -github.com/libp2p/go-yamux/v2 v2.1.1/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= -github.com/libp2p/go-yamux/v2 v2.3.0 h1:luRV68GS1vqqr6EFUjtu1kr51d+IbW0gSowu8emYWAI= github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= +github.com/libp2p/go-yamux/v3 v3.0.1/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.0.2/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.1.1/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= +github.com/libp2p/go-yamux/v3 v3.1.2 h1:lNEy28MBk1HavUAlzKgShp+F6mn/ea1nDYWftZhFW9Q= +github.com/libp2p/go-yamux/v3 v3.1.2/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= github.com/libp2p/zeroconf/v2 v2.1.1 h1:XAuSczA96MYkVwH+LqqqCUZb2yH3krobMJ1YE+0hG2s= github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -1003,8 +1126,11 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= github.com/lucas-clemente/quic-go v0.21.2/go.mod h1:vF5M1XqhBAHgbjKcJOXY3JZz3GP0T3FQhz/uyOUS38Q= github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= -github.com/lucas-clemente/quic-go v0.24.0 h1:ToR7SIIEdrgOhgVTHvPgdVRJfgVy+N0wQAagH7L4d5g= github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg= +github.com/lucas-clemente/quic-go v0.27.0/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI= +github.com/lucas-clemente/quic-go v0.27.1 h1:sOw+4kFSVrdWOYmUjufQ9GBVPqZ+tu+jMtXxXNmRJyk= +github.com/lucas-clemente/quic-go v0.27.1/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1015,11 +1141,16 @@ github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0a github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/marten-seemann/qtls-go1-15 v0.1.5/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/marten-seemann/qtls-go1-16 v0.1.4 h1:xbHbOGGhrenVtII6Co8akhLEdrawwB2iHl5yhJRpnco= github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= +github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= -github.com/marten-seemann/qtls-go1-17 v0.1.0 h1:P9ggrs5xtwiqXv/FHNwntmuLMNq3KaSIG93AtAZ48xk= github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= +github.com/marten-seemann/qtls-go1-17 v0.1.1 h1:DQjHPq+aOzUeh9/lixAGunn6rIOQyWChPSI4+hgW7jc= +github.com/marten-seemann/qtls-go1-17 v0.1.1/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= +github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI= +github.com/marten-seemann/qtls-go1-18 v0.1.1 h1:qp7p7XXUFL7fpBvSS1sWD+uSqPvzNQK43DH+/qEkj0Y= +github.com/marten-seemann/qtls-go1-18 v0.1.1/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1032,8 +1163,9 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1047,8 +1179,9 @@ github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -1077,14 +1210,16 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= +github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -1099,8 +1234,9 @@ github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4 github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= -github.com/multiformats/go-multiaddr v0.4.1 h1:Pq37uLx3hsyNlTDir7FZyU8+cFCTqd5y1KiM2IzOutI= github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= +github.com/multiformats/go-multiaddr v0.5.0 h1:i/JuOoVg4szYQ4YEzDGtb2h0o8M7CG/Yq6cGlcjWZpM= +github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= @@ -1122,8 +1258,11 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multicodec v0.2.0/go.mod h1:/y4YVwkfMyry5kFbMTbLJKErhycTIftytRV+llXdyS4= -github.com/multiformats/go-multicodec v0.3.0 h1:tstDwfIjiHbnIjeM5Lp+pMrSeN+LCMsEwOrkPmWm03A= github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= +github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= +github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= +github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4= +github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -1141,8 +1280,9 @@ github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wS github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= github.com/multiformats/go-multistream v0.2.0/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= -github.com/multiformats/go-multistream v0.2.2 h1:TCYu1BHTDr1F/Qm75qwYISQdzGcRdC21nFgQW7l7GBo= github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= +github.com/multiformats/go-multistream v0.3.0 h1:yX1v4IWseLPmr0rmnDo148wWJbNx40JxBZGmQb5fUP4= +github.com/multiformats/go-multistream v0.3.0/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1172,17 +1312,21 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1194,13 +1338,20 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.4.0 h1:CtfRrOVZtbDj8rt1WXjklw0kqqJQwICrCKmlfUuBUUw= +github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk= +github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -1223,8 +1374,9 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1242,8 +1394,10 @@ github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16 github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.33.0 h1:rHgav/0a6+uYgGdNt3jwz8FNSesO/Hsang3O0T9A5SE= +github.com/prometheus/common v0.33.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1257,7 +1411,13 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8= github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ= +github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= +github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= +github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= +github.com/raulk/go-watchdog v1.2.0 h1:konN75pw2BMmZ+AfuAm5rtFsWcJpKF3m02rKituuXNo= +github.com/raulk/go-watchdog v1.2.0/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6RcA1i4mlqI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1265,6 +1425,8 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= @@ -1298,6 +1460,8 @@ github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5k github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -1329,28 +1493,40 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/tidwall/gjson v1.14.0 h1:6aeJ0bzojgWLa82gDQHcx3S0Lr/O51I9bJ5nv6JFx5w= +github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/wI2L/jsondiff v0.2.0 h1:dE00WemBa1uCjrzQUUTE/17I6m5qAaN0EMFOg2Ynr/k= +github.com/wI2L/jsondiff v0.2.0/go.mod h1:axTcwtBkY4TsKuV+RgoMhHyHKKFRI6nnjRLi8LLYQnA= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.9.0 h1:nc+uaCiv5lFQLYjhuC2LTYeJ7JaC+gdDmsz9r0ISy0Y= @@ -1361,6 +1537,8 @@ github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= +github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= +github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= @@ -1383,6 +1561,9 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go. github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1390,6 +1571,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= @@ -1403,15 +1585,43 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 h1:mac9BKRqwaX6zxHPDe3pvmWpwuuIM0vuXv2juCnQevE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= +go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= +go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= +go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 h1:7Yxsak1q4XrJ5y7XBnNwqWx9amMZvoidCctv62XOQ6Y= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 h1:cMDtmgJ5FpRvqx9x2Aq+Mm0O6K/zcUkH73SFz20TuBw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 h1:MFAyzUPrTwLOwCi+cltN0ZVyy4phU41lwH+lyMyQTS4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 h1:pLP0MH4MAqeTEV0g/4flxw9O8Is48uAIauAnjznbW50= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0/go.mod h1:aFXT9Ng2seM9eizF+LfKiyPBGy8xIZKwhusC1gIu3hA= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6VWahRvjgLUrNl7rW2hffUEPKXVEM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= +go.opentelemetry.io/otel/exporters/zipkin v1.7.0 h1:X0FZj+kaIdLi29UiyrEGDhRTYsEXj9GdEW5Y39UQFEE= +go.opentelemetry.io/otel/exporters/zipkin v1.7.0/go.mod h1:9YBXeOMFLQGwNEjsxMRiWPGoJX83usGMhbCmxUbNe5I= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= +go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= +go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U= +go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= +go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= +go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E= +go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1419,21 +1629,24 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.12.0 h1:l1GQeZpEbss0/M4l/ZotuBndCrkMdjnygzgcuOjAdaY= go.uber.org/dig v1.12.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= -go.uber.org/fx v1.15.0 h1:kcfBpAm98n0ksanyyZLFE/Q3T7yPi13Ge2liu3TxR+A= -go.uber.org/fx v1.15.0/go.mod h1:jI3RazQUhGv5KkpZIRv+kuP4CcgX3fnc0qX8bLnzbx8= +go.uber.org/dig v1.14.0 h1:VmGvIH45/aapXPQkaOrK5u4B5B7jxZB98HM/utx0eME= +go.uber.org/dig v1.14.0/go.mod h1:jHAn/z1Ld1luVVyGKOAIFYz/uBFqKjjEEdIqVAqfQ2o= +go.uber.org/fx v1.16.0 h1:N8i80+X1DCX+qMRiKzM+jPPZiIiyK/bVCysga3+B+1w= +go.uber.org/fx v1.16.0/go.mod h1:OMoT5BnXcOaiexlpjtpE4vcAmzyDKyRs9TRYXCzamx8= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -1442,8 +1655,9 @@ go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd h1:BNJlw5kRTzdmyfh5U8F93HA2OwkP7ZGwA51eJ/0wKOU= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= @@ -1474,16 +1688,22 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1491,6 +1711,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20210615023648-acb5c1269671 h1:ddvpKwqE7dm58PoWjRCmaCiA3DANEW0zWGfNYQD212Y= +golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1503,18 +1725,20 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1570,8 +1794,16 @@ golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220517181318-183a9ca12b87 h1:cCR+9mKLOGyX4Zx+uBZDXEDAQsvKQ/XbW4vreG5v1jU= +golang.org/x/net v0.0.0-20220517181318-183a9ca12b87/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1579,8 +1811,10 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1594,6 +1828,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1640,6 +1875,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1659,6 +1895,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1666,6 +1903,7 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1675,16 +1913,22 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025112917-711f33c9992c h1:i4MLwL3EbCgobekQtkVW94UBSPLMadfEGtKq+CAFsEU= -golang.org/x/sys v0.0.0-20211025112917-711f33c9992c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e h1:w36l2Uw3dRan1K3TyXriXvY+6T56GNmlKGcqiQUJDfM= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -1726,6 +1970,7 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1747,14 +1992,18 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -1818,8 +2067,9 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1844,8 +2094,12 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1858,8 +2112,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1901,8 +2156,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/mk/golang.mk b/mk/golang.mk index 0b2a2c55ae2..93753e5c1b3 100644 --- a/mk/golang.mk +++ b/mk/golang.mk @@ -1,5 +1,5 @@ # golang utilities -GO_MIN_VERSION = 1.15.2 +GO_MIN_VERSION = 1.17 export GO111MODULE=on @@ -70,7 +70,7 @@ test_go_fmt: TEST_GO += test_go_fmt test_go_lint: test/bin/golangci-lint - golangci-lint run ./... + golangci-lint run --timeout=3m ./... .PHONY: test_go_lint test_go: $(TEST_GO) diff --git a/package-list.json b/package-list.json index 934e5e34515..7dfc5648cf0 100644 --- a/package-list.json +++ b/package-list.json @@ -42,7 +42,6 @@ ["ipfs/go-ipns", "go-ipns", "IPNS datastructures and validation logic"], "Repo", - ["ipfs/go-ipfs-config", "go-ipfs-config", "go-ipfs config file definitions"], ["ipfs/go-fs-lock", "go-fs-lock", "lockfile management functions"], ["ipfs/fs-repo-migrations", "fs-repo-migrations", "repo migrations"], diff --git a/peering/peering_test.go b/peering/peering_test.go index 27c9b717514..09a54f2ce1e 100644 --- a/peering/peering_test.go +++ b/peering/peering_test.go @@ -6,20 +6,22 @@ import ( "time" "github.com/libp2p/go-libp2p" - connmgr "github.com/libp2p/go-libp2p-connmgr" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/p2p/net/connmgr" "github.com/stretchr/testify/require" ) -func newNode(ctx context.Context, t *testing.T) host.Host { +func newNode(t *testing.T) host.Host { + cm, err := connmgr.NewConnManager(1, 100, connmgr.WithGracePeriod(0)) + require.NoError(t, err) h, err := libp2p.New( libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"), // We'd like to set the connection manager low water to 0, but // that would disable the connection manager. - libp2p.ConnectionManager(connmgr.NewConnManager(1, 100, 0)), + libp2p.ConnectionManager(cm), ) require.NoError(t, err) return h @@ -29,12 +31,12 @@ func TestPeeringService(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - h1 := newNode(ctx, t) + h1 := newNode(t) ps1 := NewPeeringService(h1) - h2 := newNode(ctx, t) - h3 := newNode(ctx, t) - h4 := newNode(ctx, t) + h2 := newNode(t) + h3 := newNode(t) + h4 := newNode(t) // peer 1 -> 2 ps1.AddPeer(peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}) diff --git a/plugin/loader/load_nocgo.go b/plugin/loader/load_nocgo.go index 3c73059e16c..26bb215f29c 100644 --- a/plugin/loader/load_nocgo.go +++ b/plugin/loader/load_nocgo.go @@ -1,4 +1,6 @@ -// +build !cgo,!noplugin +//go:build !cgo && !noplugin && (linux || darwin || freebsd) +// +build !cgo +// +build !noplugin // +build linux darwin freebsd package loader diff --git a/plugin/loader/load_noplugin.go b/plugin/loader/load_noplugin.go index dfe1e3cac35..25b1c0c3879 100644 --- a/plugin/loader/load_noplugin.go +++ b/plugin/loader/load_noplugin.go @@ -1,3 +1,4 @@ +//go:build noplugin // +build noplugin package loader diff --git a/plugin/loader/load_unix.go b/plugin/loader/load_unix.go index e7d744cbd97..19ca4988974 100644 --- a/plugin/loader/load_unix.go +++ b/plugin/loader/load_unix.go @@ -1,4 +1,6 @@ -// +build cgo,!noplugin +//go:build cgo && !noplugin && (linux || darwin || freebsd) +// +build cgo +// +build !noplugin // +build linux darwin freebsd package loader diff --git a/plugin/loader/loader.go b/plugin/loader/loader.go index 167e1b3090b..3c52a4105ad 100644 --- a/plugin/loader/loader.go +++ b/plugin/loader/loader.go @@ -8,8 +8,8 @@ import ( "runtime" "strings" - config "github.com/ipfs/go-ipfs-config" - cserialize "github.com/ipfs/go-ipfs-config/serialize" + config "github.com/ipfs/go-ipfs/config" + cserialize "github.com/ipfs/go-ipfs/config/serialize" "github.com/ipld/go-ipld-prime/multicodec" "github.com/ipfs/go-ipfs/core" @@ -241,6 +241,7 @@ func (loader *PluginLoader) Inject() error { for _, pl := range loader.plugins { if pl, ok := pl.(plugin.PluginIPLD); ok { + err := injectIPLDPlugin(pl) if err != nil { loader.state = loaderFailed @@ -338,6 +339,7 @@ func injectIPLDPlugin(pl plugin.PluginIPLD) error { } func injectTracerPlugin(pl plugin.PluginTracer) error { + log.Warn("Tracer plugins are deprecated, it's recommended to configure an OpenTelemetry collector instead.") tracer, err := pl.InitTracer() if err != nil { return err diff --git a/plugin/plugins/Rules.mk b/plugin/plugins/Rules.mk index 4a4ed816140..05b11e340ce 100644 --- a/plugin/plugins/Rules.mk +++ b/plugin/plugins/Rules.mk @@ -1,6 +1,6 @@ include mk/header.mk -$(d)_plugins:=$(d)/git $(d)/dagjose $(d)/badgerds $(d)/flatfs $(d)/levelds $(d)/peerlog +$(d)_plugins:= $(d)_plugins_so:=$(addsuffix .so,$($(d)_plugins)) $(d)_plugins_main:=$(addsuffix /main/main.go,$($(d)_plugins)) diff --git a/profile/goroutines.go b/profile/goroutines.go new file mode 100644 index 00000000000..be227af488d --- /dev/null +++ b/profile/goroutines.go @@ -0,0 +1,27 @@ +package profile + +import ( + "io" + "runtime" +) + +// WriteAllGoroutineStacks writes a stack trace to the given writer. +// This is distinct from the Go-provided method because it does not truncate after 64 MB. +func WriteAllGoroutineStacks(w io.Writer) error { + // this is based on pprof.writeGoroutineStacks, and removes the 64 MB limit + buf := make([]byte, 1<<20) + for i := 0; ; i++ { + n := runtime.Stack(buf, true) + if n < len(buf) { + buf = buf[:n] + break + } + // if len(buf) >= 64<<20 { + // // Filled 64 MB - stop there. + // break + // } + buf = make([]byte, 2*len(buf)) + } + _, err := w.Write(buf) + return err +} diff --git a/profile/profile.go b/profile/profile.go new file mode 100644 index 00000000000..06cd4a7ba33 --- /dev/null +++ b/profile/profile.go @@ -0,0 +1,268 @@ +package profile + +import ( + "archive/zip" + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "os" + "runtime" + "runtime/pprof" + "sync" + "time" + + version "github.com/ipfs/go-ipfs" + "github.com/ipfs/go-log" +) + +const ( + CollectorGoroutinesStack = "goroutines-stack" + CollectorGoroutinesPprof = "goroutines-pprof" + CollectorVersion = "version" + CollectorHeap = "heap" + CollectorBin = "bin" + CollectorCPU = "cpu" + CollectorMutex = "mutex" + CollectorBlock = "block" +) + +var ( + logger = log.Logger("profile") + goos = runtime.GOOS +) + +type collector struct { + outputFile string + isExecutable bool + collectFunc func(ctx context.Context, opts Options, writer io.Writer) error + enabledFunc func(opts Options) bool +} + +func (p *collector) outputFileName() string { + fName := p.outputFile + if p.isExecutable { + if goos == "windows" { + fName += ".exe" + } + } + return fName +} + +var collectors = map[string]collector{ + CollectorGoroutinesStack: { + outputFile: "goroutines.stacks", + collectFunc: goroutineStacksText, + enabledFunc: func(opts Options) bool { return true }, + }, + CollectorGoroutinesPprof: { + outputFile: "goroutines.pprof", + collectFunc: goroutineStacksProto, + enabledFunc: func(opts Options) bool { return true }, + }, + CollectorVersion: { + outputFile: "version.json", + collectFunc: versionInfo, + enabledFunc: func(opts Options) bool { return true }, + }, + CollectorHeap: { + outputFile: "heap.pprof", + collectFunc: heapProfile, + enabledFunc: func(opts Options) bool { return true }, + }, + CollectorBin: { + outputFile: "ipfs", + isExecutable: true, + collectFunc: binary, + enabledFunc: func(opts Options) bool { return true }, + }, + CollectorCPU: { + outputFile: "cpu.pprof", + collectFunc: profileCPU, + enabledFunc: func(opts Options) bool { return opts.ProfileDuration > 0 }, + }, + CollectorMutex: { + outputFile: "mutex.pprof", + collectFunc: mutexProfile, + enabledFunc: func(opts Options) bool { return opts.ProfileDuration > 0 && opts.MutexProfileFraction > 0 }, + }, + CollectorBlock: { + outputFile: "block.pprof", + collectFunc: blockProfile, + enabledFunc: func(opts Options) bool { return opts.ProfileDuration > 0 && opts.BlockProfileRate > 0 }, + }, +} + +type Options struct { + Collectors []string + ProfileDuration time.Duration + MutexProfileFraction int + BlockProfileRate time.Duration +} + +func WriteProfiles(ctx context.Context, archive *zip.Writer, opts Options) error { + p := profiler{ + archive: archive, + opts: opts, + } + return p.runProfile(ctx) +} + +// profiler runs the collectors concurrently and writes the results to the zip archive. +type profiler struct { + archive *zip.Writer + opts Options +} + +func (p *profiler) runProfile(ctx context.Context) error { + type profileResult struct { + fName string + buf *bytes.Buffer + err error + } + + ctx, cancelFn := context.WithCancel(ctx) + defer cancelFn() + + var collectorsToRun []collector + for _, name := range p.opts.Collectors { + c, ok := collectors[name] + if !ok { + return fmt.Errorf("unknown collector '%s'", name) + } + collectorsToRun = append(collectorsToRun, c) + } + + results := make(chan profileResult, len(p.opts.Collectors)) + wg := sync.WaitGroup{} + for _, c := range collectorsToRun { + if !c.enabledFunc(p.opts) { + continue + } + + fName := c.outputFileName() + + wg.Add(1) + go func(c collector) { + defer wg.Done() + logger.Infow("collecting profile", "File", fName) + defer logger.Infow("profile done", "File", fName) + b := bytes.Buffer{} + err := c.collectFunc(ctx, p.opts, &b) + if err != nil { + select { + case results <- profileResult{err: fmt.Errorf("generating profile data for %q: %w", fName, err)}: + case <-ctx.Done(): + return + } + } + select { + case results <- profileResult{buf: &b, fName: fName}: + case <-ctx.Done(): + } + }(c) + } + go func() { + wg.Wait() + close(results) + }() + + for res := range results { + if res.err != nil { + return res.err + } + out, err := p.archive.Create(res.fName) + if err != nil { + return fmt.Errorf("creating output file %q: %w", res.fName, err) + } + _, err = io.Copy(out, res.buf) + if err != nil { + return fmt.Errorf("compressing result %q: %w", res.fName, err) + } + } + + return nil +} + +func goroutineStacksText(ctx context.Context, _ Options, w io.Writer) error { + return WriteAllGoroutineStacks(w) +} + +func goroutineStacksProto(ctx context.Context, _ Options, w io.Writer) error { + return pprof.Lookup("goroutine").WriteTo(w, 0) +} + +func heapProfile(ctx context.Context, _ Options, w io.Writer) error { + return pprof.Lookup("heap").WriteTo(w, 0) +} + +func versionInfo(ctx context.Context, _ Options, w io.Writer) error { + return json.NewEncoder(w).Encode(version.GetVersionInfo()) +} + +func binary(ctx context.Context, _ Options, w io.Writer) error { + var ( + path string + err error + ) + if goos == "linux" { + pid := os.Getpid() + path = fmt.Sprintf("/proc/%d/exe", pid) + } else { + path, err = os.Executable() + if err != nil { + return fmt.Errorf("finding binary path: %w", err) + } + } + fi, err := os.Open(path) + if err != nil { + return fmt.Errorf("opening binary %q: %w", path, err) + } + _, err = io.Copy(w, fi) + _ = fi.Close() + if err != nil { + return fmt.Errorf("copying binary %q: %w", path, err) + } + return nil +} + +func mutexProfile(ctx context.Context, opts Options, w io.Writer) error { + prev := runtime.SetMutexProfileFraction(opts.MutexProfileFraction) + defer runtime.SetMutexProfileFraction(prev) + err := waitOrCancel(ctx, opts.ProfileDuration) + if err != nil { + return err + } + return pprof.Lookup("mutex").WriteTo(w, 2) +} + +func blockProfile(ctx context.Context, opts Options, w io.Writer) error { + runtime.SetBlockProfileRate(int(opts.BlockProfileRate.Nanoseconds())) + defer runtime.SetBlockProfileRate(0) + err := waitOrCancel(ctx, opts.ProfileDuration) + if err != nil { + return err + } + return pprof.Lookup("block").WriteTo(w, 2) +} + +func profileCPU(ctx context.Context, opts Options, w io.Writer) error { + err := pprof.StartCPUProfile(w) + if err != nil { + return err + } + defer pprof.StopCPUProfile() + return waitOrCancel(ctx, opts.ProfileDuration) +} + +func waitOrCancel(ctx context.Context, d time.Duration) error { + timer := time.NewTimer(d) + defer timer.Stop() + select { + case <-timer.C: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/profile/profile_test.go b/profile/profile_test.go new file mode 100644 index 00000000000..8da00d0181a --- /dev/null +++ b/profile/profile_test.go @@ -0,0 +1,172 @@ +package profile + +import ( + "archive/zip" + "bytes" + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestProfiler(t *testing.T) { + allCollectors := []string{ + CollectorGoroutinesStack, + CollectorGoroutinesPprof, + CollectorVersion, + CollectorHeap, + CollectorBin, + CollectorCPU, + CollectorMutex, + CollectorBlock, + } + + cases := []struct { + name string + opts Options + goos string + + expectFiles []string + }{ + { + name: "happy case", + opts: Options{ + Collectors: allCollectors, + ProfileDuration: 1 * time.Millisecond, + MutexProfileFraction: 4, + BlockProfileRate: 50 * time.Nanosecond, + }, + expectFiles: []string{ + "goroutines.stacks", + "goroutines.pprof", + "version.json", + "heap.pprof", + "ipfs", + "cpu.pprof", + "mutex.pprof", + "block.pprof", + }, + }, + { + name: "windows", + opts: Options{ + Collectors: allCollectors, + ProfileDuration: 1 * time.Millisecond, + MutexProfileFraction: 4, + BlockProfileRate: 50 * time.Nanosecond, + }, + goos: "windows", + expectFiles: []string{ + "goroutines.stacks", + "goroutines.pprof", + "version.json", + "heap.pprof", + "ipfs.exe", + "cpu.pprof", + "mutex.pprof", + "block.pprof", + }, + }, + { + name: "sampling profiling disabled", + opts: Options{ + Collectors: allCollectors, + MutexProfileFraction: 4, + BlockProfileRate: 50 * time.Nanosecond, + }, + expectFiles: []string{ + "goroutines.stacks", + "goroutines.pprof", + "version.json", + "heap.pprof", + "ipfs", + }, + }, + { + name: "Mutex profiling disabled", + opts: Options{ + Collectors: allCollectors, + ProfileDuration: 1 * time.Millisecond, + BlockProfileRate: 50 * time.Nanosecond, + }, + expectFiles: []string{ + "goroutines.stacks", + "goroutines.pprof", + "version.json", + "heap.pprof", + "ipfs", + "cpu.pprof", + "block.pprof", + }, + }, + { + name: "block profiling disabled", + opts: Options{ + Collectors: allCollectors, + ProfileDuration: 1 * time.Millisecond, + MutexProfileFraction: 4, + BlockProfileRate: 0, + }, + expectFiles: []string{ + "goroutines.stacks", + "goroutines.pprof", + "version.json", + "heap.pprof", + "ipfs", + "cpu.pprof", + "mutex.pprof", + }, + }, + { + name: "single collector", + opts: Options{ + Collectors: []string{CollectorVersion}, + ProfileDuration: 1 * time.Millisecond, + MutexProfileFraction: 4, + BlockProfileRate: 0, + }, + expectFiles: []string{ + "version.json", + }, + }, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + if c.goos != "" { + oldGOOS := goos + goos = c.goos + defer func() { goos = oldGOOS }() + } + + buf := &bytes.Buffer{} + archive := zip.NewWriter(buf) + err := WriteProfiles(context.Background(), archive, c.opts) + require.NoError(t, err) + + err = archive.Close() + require.NoError(t, err) + + zr, err := zip.NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len())) + require.NoError(t, err) + + for _, f := range zr.File { + logger.Info("zip file: ", f.Name) + } + + require.Equal(t, len(c.expectFiles), len(zr.File)) + + for _, expectedFile := range c.expectFiles { + func() { + f, err := zr.Open(expectedFile) + require.NoError(t, err) + defer f.Close() + fi, err := f.Stat() + require.NoError(t, err) + assert.NotZero(t, fi.Size()) + }() + } + }) + } +} diff --git a/repo/common/common.go b/repo/common/common.go index dc1e7c50360..e9c56e65ee3 100644 --- a/repo/common/common.go +++ b/repo/common/common.go @@ -21,7 +21,13 @@ func MapGetKV(v map[string]interface{}, key string) (interface{}, error) { cursor, ok = mcursor[part] if !ok { - return nil, fmt.Errorf("%s key has no attributes", sofar) + // Construct the current path traversed to print a nice error message + var path string + if len(sofar) > 0 { + path += sofar + "." + } + path += part + return nil, fmt.Errorf("%s not found", path) } } return cursor, nil @@ -54,3 +60,33 @@ func MapSetKV(v map[string]interface{}, key string, value interface{}) error { } return nil } + +// Merges the right map into the left map, recursively traversing child maps +// until a non-map value is found +func MapMergeDeep(left, right map[string]interface{}) map[string]interface{} { + // We want to alter a copy of the map, not the original + result := make(map[string]interface{}) + for k, v := range left { + result[k] = v + } + + for key, rightVal := range right { + // If right value is a map + if rightMap, ok := rightVal.(map[string]interface{}); ok { + // If key is in left + if leftVal, found := result[key]; found { + // If left value is also a map + if leftMap, ok := leftVal.(map[string]interface{}); ok { + // Merge nested map + result[key] = MapMergeDeep(leftMap, rightMap) + continue + } + } + } + + // Otherwise set new value to result + result[key] = rightVal + } + + return result +} diff --git a/repo/common/common_test.go b/repo/common/common_test.go new file mode 100644 index 00000000000..5f62b688c8f --- /dev/null +++ b/repo/common/common_test.go @@ -0,0 +1,132 @@ +package common + +import ( + "testing" + + "github.com/ipfs/go-ipfs/thirdparty/assert" +) + +func TestMapMergeDeepReturnsNew(t *testing.T) { + leftMap := make(map[string]interface{}) + leftMap["A"] = "Hello World" + + rightMap := make(map[string]interface{}) + rightMap["A"] = "Foo" + + MapMergeDeep(leftMap, rightMap) + + assert.True(leftMap["A"] == "Hello World", t, "MapMergeDeep should return a new map instance") +} + +func TestMapMergeDeepNewKey(t *testing.T) { + leftMap := make(map[string]interface{}) + leftMap["A"] = "Hello World" + /* + leftMap + { + A: "Hello World" + } + */ + + rightMap := make(map[string]interface{}) + rightMap["B"] = "Bar" + /* + rightMap + { + B: "Bar" + } + */ + + result := MapMergeDeep(leftMap, rightMap) + /* + expected + { + A: "Hello World" + B: "Bar" + } + */ + + assert.True(result["B"] == "Bar", t, "New keys in right map should exist in resulting map") +} + +func TestMapMergeDeepRecursesOnMaps(t *testing.T) { + leftMapA := make(map[string]interface{}) + leftMapA["B"] = "A value!" + leftMapA["C"] = "Another value!" + + leftMap := make(map[string]interface{}) + leftMap["A"] = leftMapA + /* + leftMap + { + A: { + B: "A value!" + C: "Another value!" + } + } + */ + + rightMapA := make(map[string]interface{}) + rightMapA["C"] = "A different value!" + + rightMap := make(map[string]interface{}) + rightMap["A"] = rightMapA + /* + rightMap + { + A: { + C: "A different value!" + } + } + */ + + result := MapMergeDeep(leftMap, rightMap) + /* + expected + { + A: { + B: "A value!" + C: "A different value!" + } + } + */ + + resultA := result["A"].(map[string]interface{}) + assert.True(resultA["B"] == "A value!", t, "Unaltered values should not change") + assert.True(resultA["C"] == "A different value!", t, "Nested values should be altered") +} + +func TestMapMergeDeepRightNotAMap(t *testing.T) { + leftMapA := make(map[string]interface{}) + leftMapA["B"] = "A value!" + + leftMap := make(map[string]interface{}) + leftMap["A"] = leftMapA + /* + origMap + { + A: { + B: "A value!" + } + } + */ + + rightMap := make(map[string]interface{}) + rightMap["A"] = "Not a map!" + /* + newMap + { + A: "Not a map!" + } + */ + + result := MapMergeDeep(leftMap, rightMap) + /* + expected + { + A: "Not a map!" + } + */ + + assert.True(result["A"] == "Not a map!", t, "Right values that are not a map should be set on the result") +} diff --git a/repo/fsrepo/config_test.go b/repo/fsrepo/config_test.go index f7c19c30765..0ffdababe27 100644 --- a/repo/fsrepo/config_test.go +++ b/repo/fsrepo/config_test.go @@ -10,7 +10,7 @@ import ( "github.com/ipfs/go-ipfs/plugin/loader" "github.com/ipfs/go-ipfs/repo/fsrepo" - "github.com/ipfs/go-ipfs-config" + "github.com/ipfs/go-ipfs/config" ) // note: to test sorting of the mountpoints in the disk spec they are diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 2aa4a5e46c8..c35d5458dc7 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -20,9 +20,9 @@ import ( ds "github.com/ipfs/go-datastore" measure "github.com/ipfs/go-ds-measure" lockfile "github.com/ipfs/go-fs-lock" - config "github.com/ipfs/go-ipfs-config" - serialize "github.com/ipfs/go-ipfs-config/serialize" util "github.com/ipfs/go-ipfs-util" + config "github.com/ipfs/go-ipfs/config" + serialize "github.com/ipfs/go-ipfs/config/serialize" "github.com/ipfs/go-ipfs/repo/fsrepo/migrations" logging "github.com/ipfs/go-log" homedir "github.com/mitchellh/go-homedir" @@ -50,7 +50,7 @@ See https://github.com/ipfs/fs-repo-migrations/blob/master/run.md for details.` var ( ErrNoVersion = errors.New("no version file found, please run 0-to-1 migration tool.\n" + migrationInstructions) ErrOldRepo = errors.New("ipfs repo found in old '~/.go-ipfs' location, please run migration tool.\n" + migrationInstructions) - ErrNeedMigration = errors.New("ipfs repo needs migration") + ErrNeedMigration = errors.New("ipfs repo needs migration, please run migration tool.\n" + migrationInstructions) ) type NoRepoError struct { @@ -96,6 +96,9 @@ type FSRepo struct { closed bool // path is the file-system path path string + // Path to the configuration file that may or may not be inside the FSRepo + // path (see config.Filename for more details). + configFilePath string // lockfile is the file system lock to prevent others from opening // the same fsrepo path concurrently lockfile io.Closer @@ -111,16 +114,25 @@ var _ repo.Repo = (*FSRepo)(nil) // initialized. func Open(repoPath string) (repo.Repo, error) { fn := func() (repo.Repo, error) { - return open(repoPath) + return open(repoPath, "") } return onlyOne.Open(repoPath, fn) } -func open(repoPath string) (repo.Repo, error) { +// OpenWithUserConfig is the equivalent to the Open function above but with the +// option to set the configuration file path instead of using the default. +func OpenWithUserConfig(repoPath string, userConfigFilePath string) (repo.Repo, error) { + fn := func() (repo.Repo, error) { + return open(repoPath, userConfigFilePath) + } + return onlyOne.Open(repoPath, fn) +} + +func open(repoPath string, userConfigFilePath string) (repo.Repo, error) { packageLock.Lock() defer packageLock.Unlock() - r, err := newFSRepo(repoPath) + r, err := newFSRepo(repoPath, userConfigFilePath) if err != nil { return nil, err } @@ -185,13 +197,19 @@ func open(repoPath string) (repo.Repo, error) { return r, nil } -func newFSRepo(rpath string) (*FSRepo, error) { +func newFSRepo(rpath string, userConfigFilePath string) (*FSRepo, error) { expPath, err := homedir.Expand(filepath.Clean(rpath)) if err != nil { return nil, err } - return &FSRepo{path: expPath}, nil + configFilePath, err := config.Filename(rpath, userConfigFilePath) + if err != nil { + // FIXME: Personalize this when the user config path is "". + return nil, fmt.Errorf("finding config filepath from repo %s and user config %s: %w", + rpath, userConfigFilePath, err) + } + return &FSRepo{path: expPath, configFilePath: configFilePath}, nil } func checkInitialized(path string) error { @@ -205,26 +223,10 @@ func checkInitialized(path string) error { return nil } -// ConfigAt returns an error if the FSRepo at the given path is not -// initialized. This function allows callers to read the config file even when -// another process is running and holding the lock. -func ConfigAt(repoPath string) (*config.Config, error) { - - // packageLock must be held to ensure that the Read is atomic. - packageLock.Lock() - defer packageLock.Unlock() - - configFilename, err := config.Filename(repoPath) - if err != nil { - return nil, err - } - return serialize.Load(configFilename) -} - // configIsInitialized returns true if the repo is initialized at // provided |path|. func configIsInitialized(path string) bool { - configFilename, err := config.Filename(path) + configFilename, err := config.Filename(path, "") if err != nil { return false } @@ -238,7 +240,7 @@ func initConfig(path string, conf *config.Config) error { if configIsInitialized(path) { return nil } - configFilename, err := config.Filename(path) + configFilename, err := config.Filename(path, "") if err != nil { return err } @@ -388,11 +390,7 @@ func (r *FSRepo) SetAPIAddr(addr ma.Multiaddr) error { // openConfig returns an error if the config file is not present. func (r *FSRepo) openConfig() error { - configFilename, err := config.Filename(r.path) - if err != nil { - return err - } - conf, err := serialize.Load(configFilename) + conf, err := serialize.Load(r.configFilePath) if err != nil { return err } @@ -523,12 +521,7 @@ func (r *FSRepo) BackupConfig(prefix string) (string, error) { } defer temp.Close() - configFilename, err := config.Filename(r.path) - if err != nil { - return "", err - } - - orig, err := os.OpenFile(configFilename, os.O_RDONLY, 0600) + orig, err := os.OpenFile(r.configFilePath, os.O_RDONLY, 0600) if err != nil { return "", err } @@ -542,27 +535,39 @@ func (r *FSRepo) BackupConfig(prefix string) (string, error) { return orig.Name(), nil } -// setConfigUnsynced is for private use. -func (r *FSRepo) setConfigUnsynced(updated *config.Config) error { - configFilename, err := config.Filename(r.path) - if err != nil { - return err - } +// SetConfig updates the FSRepo's config. The user must not modify the config +// object after calling this method. +// FIXME: There is an inherent contradiction with storing non-user-generated +// Go config.Config structures as user-generated JSON nested maps. This is +// evidenced by the issue of `omitempty` property of fields that aren't defined +// by the user and Go still needs to initialize them to its default (which +// is not reflected in the repo's config file, see +// https://github.com/ipfs/go-ipfs/issues/8088 for more details). +// In general we should call this API with a JSON nested maps as argument +// (`map[string]interface{}`). Many calls to this function are forced to +// synthesize the config.Config struct from their available JSON map just to +// satisfy this (causing incompatibilities like the `omitempty` one above). +// We need to comb SetConfig calls and replace them when possible with a +// JSON map variant. +func (r *FSRepo) SetConfig(updated *config.Config) error { + + // packageLock is held to provide thread-safety. + packageLock.Lock() + defer packageLock.Unlock() + // to avoid clobbering user-provided keys, must read the config from disk // as a map, write the updated struct values to the map and write the map // to disk. var mapconf map[string]interface{} - if err := serialize.ReadConfigFile(configFilename, &mapconf); err != nil { + if err := serialize.ReadConfigFile(r.configFilePath, &mapconf); err != nil { return err } m, err := config.ToMap(updated) if err != nil { return err } - for k, v := range m { - mapconf[k] = v - } - if err := serialize.WriteConfigFile(configFilename, mapconf); err != nil { + mergedMap := common.MapMergeDeep(mapconf, m) + if err := serialize.WriteConfigFile(r.configFilePath, mergedMap); err != nil { return err } // Do not use `*r.config = ...`. This will modify the *shared* config @@ -571,17 +576,6 @@ func (r *FSRepo) setConfigUnsynced(updated *config.Config) error { return nil } -// SetConfig updates the FSRepo's config. The user must not modify the config -// object after calling this method. -func (r *FSRepo) SetConfig(updated *config.Config) error { - - // packageLock is held to provide thread-safety. - packageLock.Lock() - defer packageLock.Unlock() - - return r.setConfigUnsynced(updated) -} - // GetConfigKey retrieves only the value of a particular key. func (r *FSRepo) GetConfigKey(key string) (interface{}, error) { packageLock.Lock() @@ -591,12 +585,8 @@ func (r *FSRepo) GetConfigKey(key string) (interface{}, error) { return nil, errors.New("repo is closed") } - filename, err := config.Filename(r.path) - if err != nil { - return nil, err - } var cfg map[string]interface{} - if err := serialize.ReadConfigFile(filename, &cfg); err != nil { + if err := serialize.ReadConfigFile(r.configFilePath, &cfg); err != nil { return nil, err } return common.MapGetKV(cfg, key) @@ -611,13 +601,9 @@ func (r *FSRepo) SetConfigKey(key string, value interface{}) error { return errors.New("repo is closed") } - filename, err := config.Filename(r.path) - if err != nil { - return err - } // Load into a map so we don't end up writing any additional defaults to the config file. var mapconf map[string]interface{} - if err := serialize.ReadConfigFile(filename, &mapconf); err != nil { + if err := serialize.ReadConfigFile(r.configFilePath, &mapconf); err != nil { return err } @@ -645,10 +631,13 @@ func (r *FSRepo) SetConfigKey(key string, value interface{}) error { if err != nil { return err } - if err := serialize.WriteConfigFile(filename, mapconf); err != nil { + r.config = conf + + if err := serialize.WriteConfigFile(r.configFilePath, mapconf); err != nil { return err } - return r.setConfigUnsynced(conf) // TODO roll this into this method + + return nil } // Datastore returns a repo-owned datastore. If FSRepo is Closed, return value diff --git a/repo/fsrepo/fsrepo_test.go b/repo/fsrepo/fsrepo_test.go index cd2d66618a5..cf9aeabec0e 100644 --- a/repo/fsrepo/fsrepo_test.go +++ b/repo/fsrepo/fsrepo_test.go @@ -11,7 +11,7 @@ import ( "github.com/ipfs/go-ipfs/thirdparty/assert" datastore "github.com/ipfs/go-datastore" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ) // swap arg order diff --git a/repo/fsrepo/migrations/fetcher.go b/repo/fsrepo/migrations/fetcher.go index ef605153a46..6cdceffb1e6 100644 --- a/repo/fsrepo/migrations/fetcher.go +++ b/repo/fsrepo/migrations/fetcher.go @@ -38,7 +38,7 @@ type limitReadCloser struct { } // NewMultiFetcher creates a MultiFetcher with the given Fetchers. The -// Fetchers are tried in order ther passed to this function. +// Fetchers are tried in order, then passed to this function. func NewMultiFetcher(f ...Fetcher) *MultiFetcher { mf := &MultiFetcher{ diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go index 11203ed5a05..da8f83ac034 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher.go @@ -12,8 +12,8 @@ import ( "strings" "sync" - "github.com/ipfs/go-ipfs-config" files "github.com/ipfs/go-ipfs-files" + "github.com/ipfs/go-ipfs/config" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" "github.com/ipfs/go-ipfs/core/node/libp2p" @@ -33,9 +33,10 @@ const ( ) type IpfsFetcher struct { - distPath string - limit int64 - repoRoot *string + distPath string + limit int64 + repoRoot *string + userConfigFile string openOnce sync.Once openErr error @@ -62,11 +63,12 @@ var _ migrations.Fetcher = (*IpfsFetcher)(nil) // Bootstrap and peer information in read from the IPFS config file in // repoRoot, unless repoRoot is nil. If repoRoot is empty (""), then read the // config from the default IPFS directory. -func NewIpfsFetcher(distPath string, fetchLimit int64, repoRoot *string) *IpfsFetcher { +func NewIpfsFetcher(distPath string, fetchLimit int64, repoRoot *string, userConfigFile string) *IpfsFetcher { f := &IpfsFetcher{ - limit: defaultFetchLimit, - distPath: migrations.LatestIpfsDist, - repoRoot: repoRoot, + limit: defaultFetchLimit, + distPath: migrations.LatestIpfsDist, + repoRoot: repoRoot, + userConfigFile: userConfigFile, } if distPath != "" { @@ -92,7 +94,7 @@ func (f *IpfsFetcher) Fetch(ctx context.Context, filePath string) ([]byte, error // Initialize and start IPFS node on first call to Fetch, since the fetcher // may be created by not used. f.openOnce.Do(func() { - bootstrap, peers := readIpfsConfig(f.repoRoot) + bootstrap, peers := readIpfsConfig(f.repoRoot, f.userConfigFile) f.ipfsTmpDir, f.openErr = initTempNode(ctx, bootstrap, peers) if f.openErr != nil { return @@ -288,12 +290,12 @@ func parsePath(fetchPath string) (ipath.Path, error) { return ipfsPath, ipfsPath.IsValid() } -func readIpfsConfig(repoRoot *string) (bootstrap []string, peers []peer.AddrInfo) { +func readIpfsConfig(repoRoot *string, userConfigFile string) (bootstrap []string, peers []peer.AddrInfo) { if repoRoot == nil { return } - cfgPath, err := config.Filename(*repoRoot) + cfgPath, err := config.Filename(*repoRoot, userConfigFile) if err != nil { fmt.Fprintln(os.Stderr, err) return diff --git a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go index e300371a679..4e882b7ad83 100644 --- a/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go +++ b/repo/fsrepo/migrations/ipfsfetcher/ipfsfetcher_test.go @@ -26,7 +26,7 @@ func TestIpfsFetcher(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - fetcher := NewIpfsFetcher("", 0, nil) + fetcher := NewIpfsFetcher("", 0, nil, "") defer fetcher.Close() out, err := fetcher.Fetch(ctx, "go-ipfs/versions") @@ -62,7 +62,7 @@ func TestInitIpfsFetcher(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - f := NewIpfsFetcher("", 0, nil) + f := NewIpfsFetcher("", 0, nil, "") defer f.Close() // Init ipfs repo @@ -132,7 +132,7 @@ func TestReadIpfsConfig(t *testing.T) { ` noSuchDir := "no_such_dir-5953aa51-1145-4efd-afd1-a069075fcf76" - bootstrap, peers := readIpfsConfig(&noSuchDir) + bootstrap, peers := readIpfsConfig(&noSuchDir, "") if bootstrap != nil { t.Error("expected nil bootstrap") } @@ -142,12 +142,12 @@ func TestReadIpfsConfig(t *testing.T) { tmpDir := makeConfig(t, testConfig) - bootstrap, peers = readIpfsConfig(nil) + bootstrap, peers = readIpfsConfig(nil, "") if bootstrap != nil || peers != nil { t.Fatal("expected nil ipfs config items") } - bootstrap, peers = readIpfsConfig(&tmpDir) + bootstrap, peers = readIpfsConfig(&tmpDir, "") if len(bootstrap) != 2 { t.Fatal("wrong number of bootstrap addresses") } @@ -189,7 +189,7 @@ func TestBadBootstrappingIpfsConfig(t *testing.T) { tmpDir := makeConfig(t, configBadBootstrap) - bootstrap, peers := readIpfsConfig(&tmpDir) + bootstrap, peers := readIpfsConfig(&tmpDir, "") if bootstrap != nil { t.Fatal("expected nil bootstrap") } @@ -219,7 +219,7 @@ func TestBadPeersIpfsConfig(t *testing.T) { tmpDir := makeConfig(t, configBadPeers) - bootstrap, peers := readIpfsConfig(&tmpDir) + bootstrap, peers := readIpfsConfig(&tmpDir, "") if peers != nil { t.Fatal("expected nil peers") } diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index 5eac91b2932..02738483e29 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -15,7 +15,7 @@ import ( "strings" "sync" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ) const ( @@ -115,12 +115,12 @@ func ExeName(name string) string { // ReadMigrationConfig reads the Migration section of the IPFS config, avoiding // reading anything other than the Migration section. That way, we're free to // make arbitrary changes to all _other_ sections in migrations. -func ReadMigrationConfig(repoRoot string) (*config.Migration, error) { +func ReadMigrationConfig(repoRoot string, userConfigFile string) (*config.Migration, error) { var cfg struct { Migration config.Migration } - cfgPath, err := config.Filename(repoRoot) + cfgPath, err := config.Filename(repoRoot, userConfigFile) if err != nil { return nil, err } diff --git a/repo/fsrepo/migrations/migrations_test.go b/repo/fsrepo/migrations/migrations_test.go index 0e52b3a65ed..4fb75774793 100644 --- a/repo/fsrepo/migrations/migrations_test.go +++ b/repo/fsrepo/migrations/migrations_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ) func TestFindMigrations(t *testing.T) { @@ -221,7 +221,7 @@ var testConfig = ` func TestReadMigrationConfigDefaults(t *testing.T) { tmpDir := makeConfig(t, "{}") - cfg, err := ReadMigrationConfig(tmpDir) + cfg, err := ReadMigrationConfig(tmpDir, "") if err != nil { t.Fatal(err) } @@ -243,7 +243,7 @@ func TestReadMigrationConfigDefaults(t *testing.T) { func TestReadMigrationConfigErrors(t *testing.T) { tmpDir := makeConfig(t, `{"Migration": {"Keep": "badvalue"}}`) - _, err := ReadMigrationConfig(tmpDir) + _, err := ReadMigrationConfig(tmpDir, "") if err == nil { t.Fatal("expected error") } @@ -252,13 +252,13 @@ func TestReadMigrationConfigErrors(t *testing.T) { } os.RemoveAll(tmpDir) - _, err = ReadMigrationConfig(tmpDir) + _, err = ReadMigrationConfig(tmpDir, "") if err == nil { t.Fatal("expected error") } tmpDir = makeConfig(t, `}{`) - _, err = ReadMigrationConfig(tmpDir) + _, err = ReadMigrationConfig(tmpDir, "") if err == nil { t.Fatal("expected error") } @@ -267,7 +267,7 @@ func TestReadMigrationConfigErrors(t *testing.T) { func TestReadMigrationConfig(t *testing.T) { tmpDir := makeConfig(t, testConfig) - cfg, err := ReadMigrationConfig(tmpDir) + cfg, err := ReadMigrationConfig(tmpDir, "") if err != nil { t.Fatal(err) } diff --git a/repo/fsrepo/misc.go b/repo/fsrepo/misc.go index 7f0c01640a2..71b640331d4 100644 --- a/repo/fsrepo/misc.go +++ b/repo/fsrepo/misc.go @@ -3,7 +3,7 @@ package fsrepo import ( "os" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" homedir "github.com/mitchellh/go-homedir" ) diff --git a/repo/mock.go b/repo/mock.go index 0576498716a..15313ab373c 100644 --- a/repo/mock.go +++ b/repo/mock.go @@ -7,7 +7,7 @@ import ( filestore "github.com/ipfs/go-filestore" keystore "github.com/ipfs/go-ipfs-keystore" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ma "github.com/multiformats/go-multiaddr" ) diff --git a/repo/repo.go b/repo/repo.go index 744bfdf5d57..00735eb94ee 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -9,7 +9,7 @@ import ( keystore "github.com/ipfs/go-ipfs-keystore" ds "github.com/ipfs/go-datastore" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" ma "github.com/multiformats/go-multiaddr" ) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 3ebe0440969..c9d73395f61 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -29,7 +29,7 @@ parts: source-tag: master plugin: go # keep me up to date with the go version that go-ipfs expects to be built with. - go-channel: 1.16/stable + go-channel: 1.18/stable go-importpath: github.com/ipfs/go-ipfs build-packages: - build-essential diff --git a/test/bench/bench_cli_ipfs_add/main.go b/test/bench/bench_cli_ipfs_add/main.go index 727a87aea2f..b11b5f83c7d 100644 --- a/test/bench/bench_cli_ipfs_add/main.go +++ b/test/bench/bench_cli_ipfs_add/main.go @@ -12,7 +12,7 @@ import ( "github.com/ipfs/go-ipfs/thirdparty/unit" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" random "github.com/jbenet/go-random" ) diff --git a/test/bench/offline_add/main.go b/test/bench/offline_add/main.go index 94e8cac23ba..5d3f27fed1a 100644 --- a/test/bench/offline_add/main.go +++ b/test/bench/offline_add/main.go @@ -11,7 +11,7 @@ import ( "github.com/ipfs/go-ipfs/thirdparty/unit" - config "github.com/ipfs/go-ipfs-config" + config "github.com/ipfs/go-ipfs/config" random "github.com/jbenet/go-random" ) diff --git a/test/dependencies/dependencies.go b/test/dependencies/dependencies.go index 9dc48969801..0d56cd5a7c5 100644 --- a/test/dependencies/dependencies.go +++ b/test/dependencies/dependencies.go @@ -1,3 +1,4 @@ +//go:build tools // +build tools package tools diff --git a/test/dependencies/go.mod b/test/dependencies/go.mod index a742030a73a..b81021b3056 100644 --- a/test/dependencies/go.mod +++ b/test/dependencies/go.mod @@ -1,30 +1,300 @@ module github.com/ipfs/go-ipfs/test/dependencies -go 1.13 +go 1.17 require ( github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd - github.com/golangci/golangci-lint v1.26.0 - github.com/ipfs/go-blockservice v0.1.3 - github.com/ipfs/go-cid v0.0.6 + github.com/golangci/golangci-lint v1.45.2 + github.com/ipfs/go-blockservice v0.3.0 + github.com/ipfs/go-cid v0.1.0 github.com/ipfs/go-cidutil v0.0.2 - github.com/ipfs/go-datastore v0.4.4 - github.com/ipfs/go-graphsync v0.1.1 - github.com/ipfs/go-ipfs-blockstore v1.0.0 - github.com/ipfs/go-ipfs-exchange-offline v0.0.1 - github.com/ipfs/go-log v1.0.4 - github.com/ipfs/go-merkledag v0.3.2 - github.com/ipfs/go-unixfs v0.2.4 - github.com/ipfs/hang-fds v0.0.2 + github.com/ipfs/go-datastore v0.5.1 + github.com/ipfs/go-graphsync v0.11.0 + github.com/ipfs/go-ipfs-blockstore v1.2.0 + github.com/ipfs/go-ipfs-exchange-offline v0.2.0 + github.com/ipfs/go-log v1.0.5 + github.com/ipfs/go-merkledag v0.6.0 + github.com/ipfs/go-unixfs v0.3.1 + github.com/ipfs/hang-fds v0.1.0 github.com/ipfs/iptb v1.4.0 github.com/ipfs/iptb-plugins v0.3.0 - github.com/ipld/go-ipld-prime v0.0.4-0.20200503082126-7e0619f3a984 + github.com/ipld/go-ipld-prime v0.16.0 github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded - github.com/libp2p/go-libp2p v0.9.6 - github.com/libp2p/go-libp2p-core v0.5.7 - github.com/multiformats/go-multiaddr v0.2.2 - github.com/multiformats/go-multiaddr-net v0.1.5 - github.com/multiformats/go-multihash v0.0.13 + github.com/libp2p/go-libp2p v0.19.0 + github.com/libp2p/go-libp2p-core v0.15.1 + github.com/multiformats/go-multiaddr v0.5.0 + github.com/multiformats/go-multihash v0.1.0 gotest.tools/gotestsum v0.4.2 ) + +require ( + 4d63.com/gochecknoglobals v0.1.0 // indirect + github.com/Antonboom/errname v0.1.5 // indirect + github.com/Antonboom/nilnil v0.1.0 // indirect + github.com/BurntSushi/toml v1.0.0 // indirect + github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/OpenPeeDeeP/depguard v1.1.0 // indirect + github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/alexkohler/prealloc v1.0.0 // indirect + github.com/ashanbrown/forbidigo v1.3.0 // indirect + github.com/ashanbrown/makezero v1.1.1 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bkielbasa/cyclop v1.2.0 // indirect + github.com/blizzy78/varnamelen v0.6.1 // indirect + github.com/bombsimon/wsl/v3 v3.3.0 // indirect + github.com/breml/bidichk v0.2.2 // indirect + github.com/breml/errchkjson v0.2.3 // indirect + github.com/btcsuite/btcd v0.22.0-beta // indirect + github.com/butuzov/ireturn v0.1.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/charithe/durationcheck v0.0.9 // indirect + github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect + github.com/cheekybits/genny v1.0.0 // indirect + github.com/containerd/cgroups v1.0.3 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect + github.com/daixiang0/gci v0.3.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/denis-tingaikin/go-header v0.4.3 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/elastic/gosigar v0.14.2 // indirect + github.com/esimonov/ifshort v1.0.4 // indirect + github.com/ettle/strcase v0.1.1 // indirect + github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/fzipp/gocyclo v0.4.0 // indirect + github.com/go-critic/go-critic v0.6.2 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-toolsmith/astcast v1.0.0 // indirect + github.com/go-toolsmith/astcopy v1.0.0 // indirect + github.com/go-toolsmith/astequal v1.0.1 // indirect + github.com/go-toolsmith/astfmt v1.0.0 // indirect + github.com/go-toolsmith/astp v1.0.0 // indirect + github.com/go-toolsmith/strparse v1.0.0 // indirect + github.com/go-toolsmith/typep v1.0.2 // indirect + github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect + github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect + github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 // indirect + github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect + github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect + github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect + github.com/golangci/misspell v0.3.5 // indirect + github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 // indirect + github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect + github.com/google/go-cmp v0.5.7 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/gostaticanalysis/analysisutil v0.7.1 // indirect + github.com/gostaticanalysis/comment v1.4.2 // indirect + github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect + github.com/gostaticanalysis/nilerr v0.1.1 // indirect + github.com/gxed/go-shellwords v1.0.3 // indirect + github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-version v1.4.0 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/huin/goupnp v1.0.3 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/ipfs/bbloom v0.0.4 // indirect + github.com/ipfs/go-bitfield v1.0.0 // indirect + github.com/ipfs/go-block-format v0.0.3 // indirect + github.com/ipfs/go-ipfs-config v0.19.0 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.1.0 // indirect + github.com/ipfs/go-ipfs-pq v0.0.2 // indirect + github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-ipld-cbor v0.0.5 // indirect + github.com/ipfs/go-ipld-format v0.4.0 // indirect + github.com/ipfs/go-ipld-legacy v0.1.0 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/ipfs/go-metrics-interface v0.0.1 // indirect + github.com/ipfs/go-peertaskqueue v0.7.0 // indirect + github.com/ipfs/go-verifcid v0.0.1 // indirect + github.com/ipfs/interface-go-ipfs-core v0.4.0 // indirect + github.com/ipld/go-codec-dagpb v1.4.0 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/jbenet/goprocess v0.1.4 // indirect + github.com/jgautheron/goconst v1.5.1 // indirect + github.com/jingyugao/rowserrcheck v1.1.1 // indirect + github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect + github.com/jonboulle/clockwork v0.2.0 // indirect + github.com/julz/importas v0.1.0 // indirect + github.com/kisielk/errcheck v1.6.0 // indirect + github.com/kisielk/gotool v1.0.0 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/cpuid/v2 v2.0.12 // indirect + github.com/koron/go-ssdp v0.0.2 // indirect + github.com/kulti/thelper v0.5.1 // indirect + github.com/kunwardeep/paralleltest v1.0.3 // indirect + github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/ldez/gomoddirectives v0.2.2 // indirect + github.com/ldez/tagliatelle v0.3.1 // indirect + github.com/leonklingele/grouper v1.1.0 // indirect + github.com/libp2p/go-buffer-pool v0.0.2 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-conn-security-multistream v0.3.0 // indirect + github.com/libp2p/go-eventbus v0.2.1 // indirect + github.com/libp2p/go-flow-metrics v0.0.3 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-blankhost v0.3.0 // indirect + github.com/libp2p/go-libp2p-mplex v0.7.0 // indirect + github.com/libp2p/go-libp2p-nat v0.1.0 // indirect + github.com/libp2p/go-libp2p-noise v0.4.0 // indirect + github.com/libp2p/go-libp2p-peerstore v0.6.0 // indirect + github.com/libp2p/go-libp2p-pnet v0.2.0 // indirect + github.com/libp2p/go-libp2p-quic-transport v0.17.0 // indirect + github.com/libp2p/go-libp2p-record v0.1.3 // indirect + github.com/libp2p/go-libp2p-resource-manager v0.3.0 // indirect + github.com/libp2p/go-libp2p-swarm v0.10.2 // indirect + github.com/libp2p/go-libp2p-tls v0.4.1 // indirect + github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 // indirect + github.com/libp2p/go-libp2p-yamux v0.9.1 // indirect + github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.0 // indirect + github.com/libp2p/go-openssl v0.0.7 // indirect + github.com/libp2p/go-reuseport v0.1.0 // indirect + github.com/libp2p/go-reuseport-transport v0.1.0 // indirect + github.com/libp2p/go-stream-muxer-multistream v0.4.0 // indirect + github.com/libp2p/go-tcp-transport v0.5.1 // indirect + github.com/libp2p/go-ws-transport v0.6.0 // indirect + github.com/libp2p/go-yamux/v3 v3.1.1 // indirect + github.com/lucas-clemente/quic-go v0.27.0 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/maratori/testpackage v1.0.1 // indirect + github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect + github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mbilski/exhaustivestruct v1.2.0 // indirect + github.com/mgechev/revive v1.1.4 // indirect + github.com/miekg/dns v1.1.48 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/moricho/tparallel v0.2.1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.0.4 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multibase v0.0.3 // indirect + github.com/multiformats/go-multicodec v0.4.1 // indirect + github.com/multiformats/go-multistream v0.3.0 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect + github.com/nakabonne/nestif v0.3.1 // indirect + github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect + github.com/nishanths/exhaustive v0.7.11 // indirect + github.com/nishanths/predeclared v0.2.1 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect + github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect + github.com/polyfloyd/go-errorlint v0.0.0-20211125173453-6d6d39c5bb8b // indirect + github.com/prometheus/client_golang v1.12.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.33.0 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/quasilyte/go-ruleguard v0.3.15 // indirect + github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect + github.com/raulk/clock v1.1.0 // indirect + github.com/raulk/go-watchdog v1.2.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/ryancurrah/gomodguard v1.2.3 // indirect + github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect + github.com/securego/gosec/v2 v2.10.0 // indirect + github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sivchari/containedctx v1.0.2 // indirect + github.com/sivchari/tenv v1.4.7 // indirect + github.com/sonatard/noctx v0.0.1 // indirect + github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.4.1 // indirect + github.com/spf13/cobra v1.4.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.10.1 // indirect + github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect + github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/testify v1.7.1 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + github.com/sylvia7788/contextcheck v1.0.4 // indirect + github.com/tdakkota/asciicheck v0.1.1 // indirect + github.com/tetafro/godot v1.4.11 // indirect + github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect + github.com/tomarrell/wrapcheck/v2 v2.5.0 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect + github.com/ultraware/funlen v0.0.3 // indirect + github.com/ultraware/whitespace v0.0.5 // indirect + github.com/urfave/cli v1.22.2 // indirect + github.com/uudashr/gocognit v1.0.5 // indirect + github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect + github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect + github.com/yagipy/maintidx v1.0.0 // indirect + github.com/yeya24/promlinter v0.1.1-0.20210918184747-d757024714a1 // indirect + gitlab.com/bosi/decorder v0.2.1 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.21.0 // indirect + golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect + golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.10 // indirect + golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + honnef.co/go/tools v0.2.2 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + mvdan.cc/gofumpt v0.3.0 // indirect + mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect + mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect + mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 // indirect +) diff --git a/test/dependencies/go.sum b/test/dependencies/go.sum index e54b00cddec..5671560dd29 100644 --- a/test/dependencies/go.sum +++ b/test/dependencies/go.sum @@ -1,236 +1,581 @@ +4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= +4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w= +cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Antonboom/errname v0.1.5 h1:IM+A/gz0pDhKmlt5KSNTVAvfLMb+65RxavBXpRtCUEg= +github.com/Antonboom/errname v0.1.5/go.mod h1:DugbBstvPFQbv/5uLcRRzfrNqKE9tVdVCqWCLp6Cifo= +github.com/Antonboom/nilnil v0.1.0 h1:DLDavmg0a6G/F4Lt9t7Enrbgb3Oph6LnDE6YVsmTt74= +github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157 h1:hY39LwQHh+1kaovmIjOrlqnXNX6tygSRfLkkK33IkZU= -github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= +github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd h1:HNhzThEtZW714v8Eda8sWWRcu9WSzJC+oCyjRjvZgRA= github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= -github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= +github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= +github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 h1:3ILjVyslFbc4jl1w5TWuvvslFD/nDfR2H8tVaMVLrEY= -github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5KPJz66Kt9G0n+7Sn41Fy1wv9/jHOrc= +github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.0.1/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= +github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bombsimon/wsl/v3 v3.0.0 h1:w9f49xQatuaeTJFaNP4SpiWSR5vfT6IstPtM62JjcqA= -github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= +github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/blizzy78/varnamelen v0.6.1 h1:kttPCLzXFa+0nt++Cw9fb7GrSSM4KkyIAoX/vXsbuqA= +github.com/blizzy78/varnamelen v0.6.1/go.mod h1:zy2Eic4qWqjrxa60jG34cfL0VXcSwzUrIx68eJPb4Q8= +github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= +github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/breml/bidichk v0.2.2 h1:w7QXnpH0eCBJm55zGCTJveZEkQBt6Fs5zThIdA6qQ9Y= +github.com/breml/bidichk v0.2.2/go.mod h1:zbfeitpevDUGI7V91Uzzuwrn4Vls8MoBMrwtt78jmso= +github.com/breml/errchkjson v0.2.3 h1:97eGTmR/w0paL2SwfRPI1jaAZHaH/fXnxWTw2eEIqE0= +github.com/breml/errchkjson v0.2.3/go.mod h1:jZEATw/jF69cL1iy7//Yih8yp/mXp2CBoBr9GJwCAsY= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= +github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= +github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= +github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= +github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI= +github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21aspRGoBuCNV6V2fFJBF+pm1J6OY8Lys= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/daixiang0/gci v0.3.3 h1:55xJKH7Gl9Vk6oQ1cMkwrDWjAkT1D+D1G9kNmRcAIY4= +github.com/daixiang0/gci v0.3.3/go.mod h1:1Xr2bxnQbDxCqqulUOv8qpGqkgRw9RSCGGjEC2LjF8o= +github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= -github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f h1:BOaYiTvg8p9vBUXpklC22XSK/mifLF7lG9jtmYYi3Tc= -github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= +github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= +github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= +github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= +github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= +github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A= github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5/go.mod h1:JpoxHjuQauoxiFMl1ie8Xc/7TfLuMZ5eOCONd1sUBHg= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= +github.com/fzipp/gocyclo v0.4.0 h1:IykTnjwh2YLyYkGa0y92iTTEQcnyAz0r9zOo15EbJ7k= +github.com/fzipp/gocyclo v0.4.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-critic/go-critic v0.4.1 h1:4DTQfT1wWwLg/hzxwD9bkdhDQrdJtxe6DUTadPlrIeE= -github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= +github.com/go-critic/go-critic v0.6.2 h1:L5SDut1N4ZfsWZY0sH4DCrsHLHnhuuWak2wa165t9gs= +github.com/go-critic/go-critic v0.6.2/go.mod h1:td1s27kfmLpe5G/DPjlnFI7o1UCzePptwU7Az0V5iCM= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= -github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= +github.com/go-toolsmith/astequal v1.0.1 h1:JbSszi42Jiqu36Gnf363HWS9MTEAz67vTQLponh3Moc= +github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= -github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= -github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o= +github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= -github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.26.0 h1:CLLGRSA9BLMiNvsWPXHioYAdfIx9tkgdVWyA6bIdYCo= -github.com/golangci/golangci-lint v1.26.0/go.mod h1:tefbO6RcigFzvTnDC+Y51kntVGgkuCAVsC+mnfbPruc= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/golangci-lint v1.45.2 h1:9I3PzkvscJkFAQpTQi5Ga0V4qWdJERajX1UZ7QqkW+I= +github.com/golangci/golangci-lint v1.45.2/go.mod h1:f20dpzMmUTRp+oYnX0OGjV1Au3Jm2JeI9yLqHq1/xsI= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 h1:SgM7GDZTxtTTQPU84heOxy34iG5Du7F2jcoZnvp+fXI= +github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= +github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= -github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= +github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= +github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gxed/go-shellwords v1.0.3 h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38= github.com/gxed/go-shellwords v1.0.3/go.mod h1:N7paucT91ByIjmVJHhvoarjoQnmsi3Jd3vH7VqgtMxQ= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1/go.mod h1:jvfsLIxk0fY/2BKSQ1xf2406AKA5dwMmKKv0ADcOfN8= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e h1:3YKHER4nmd7b5qy5t0GWDTwSn4OyRgfAXSmo6VnryBY= github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e/go.mod h1:I8h3MITA53gN9OnWGCgaMa0JWVRdXthWw4M3CPM54OY= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -238,33 +583,64 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo= +github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/go-bitfield v1.0.0 h1:y/XHm2GEmD9wKngheWNNCNL0pzrWXZwCdQGv1ikXknQ= +github.com/ipfs/go-bitfield v1.0.0/go.mod h1:N/UiujQy+K+ceU1EF5EkVd1TNqevLrCQMIcAEPrdtus= +github.com/ipfs/go-bitswap v0.0.9/go.mod h1:kAPf5qgn2W2DrgAcscZ3HrM9qh4pH+X8Fkk3UPrwvis= github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= -github.com/ipfs/go-bitswap v0.1.8 h1:38X1mKXkiU6Nzw4TOSWD8eTVY5eX3slQunv3QEWfXKg= -github.com/ipfs/go-bitswap v0.1.8/go.mod h1:TOWoxllhccevbWFUR2N7B1MTSVVge1s6XSMiCSA4MzM= +github.com/ipfs/go-bitswap v0.5.1/go.mod h1:P+ckC87ri1xFLvk74NlXdP0Kj9RmWAh4+H78sC6Qopo= +github.com/ipfs/go-bitswap v0.6.0 h1:f2rc6GZtoSFhEIzQmddgGiel9xntj02Dg0ZNf2hSC+w= +github.com/ipfs/go-bitswap v0.6.0/go.mod h1:Hj3ZXdOC5wBJvENtdqsixmzzRukqd8EHLxZLZc3mzRA= github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= -github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= +github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= +github.com/ipfs/go-blockservice v0.0.7/go.mod h1:EOfb9k/Y878ZTRY/CH0x5+ATtaipfbRhbvNSdgc/7So= github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= -github.com/ipfs/go-blockservice v0.1.3 h1:9XgsPMwwWJSC9uVr2pMDsW2qFTBSkxpGMhmna8mIjPM= -github.com/ipfs/go-blockservice v0.1.3/go.mod h1:OTZhFpkgY48kNzbgyvcexW9cHrpjBYIjSR0KoDOFOLU= +github.com/ipfs/go-blockservice v0.2.1/go.mod h1:k6SiwmgyYgs4M/qt+ww6amPeUH9EISLRBnvUurKJhi8= +github.com/ipfs/go-blockservice v0.3.0 h1:cDgcZ+0P0Ih3sl8+qjFr2sVaMdysg/YZpLj5WJ8kiiw= +github.com/ipfs/go-blockservice v0.3.0/go.mod h1:P5ppi8IHDC7O+pA0AlGTF09jruB2h+oP3wVVaZl8sfk= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= -github.com/ipfs/go-cid v0.0.6 h1:go0y+GcDOGeJIV01FeBsta4FHngoA4Wz7KMeLkXAhMs= github.com/ipfs/go-cid v0.0.6/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0= +github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o= github.com/ipfs/go-cidutil v0.0.2 h1:CNOboQf1t7Qp0nuNh8QMmhJs0+Q//bRL1axtCnIB1Yo= github.com/ipfs/go-cidutil v0.0.2/go.mod h1:ewllrvrxG6AMYStla3GD7Cqn+XYSLqjK0vc+086tB6s= github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= @@ -274,42 +650,51 @@ github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRV github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= github.com/ipfs/go-datastore v0.4.0/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= -github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8= github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.5/go.mod h1:eXTcaaiN6uOlVCLS9GjJUJtlvJfM3xk23w3fyfrmmJs= +github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= +github.com/ipfs/go-datastore v0.5.1 h1:WkRhLuISI+XPD0uk3OskB0fYFSyqK8Ob5ZYew9Qa1nQ= +github.com/ipfs/go-datastore v0.5.1/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaHzfGTzuE3s= github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE= github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= -github.com/ipfs/go-graphsync v0.1.1 h1:bFDAYS0Z48yd8ROPI6f/zIVmJxaDLA6m8cVuJPKC5fE= -github.com/ipfs/go-graphsync v0.1.1/go.mod h1:jMXfqIEDFukLPZHqDPp8tJMbHO9Rmeb9CEGevngQbmE= +github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= +github.com/ipfs/go-graphsync v0.11.0 h1:PiiD5CnoC3xEHMW8d6uBGqGcoTwiMB5d9CORIEyF6iA= +github.com/ipfs/go-graphsync v0.11.0/go.mod h1:wC+c8vGVjAHthsVIl8LKr37cUra2GOaMYcQNNmMxDqE= github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= -github.com/ipfs/go-ipfs-blockstore v0.1.4/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ= -github.com/ipfs/go-ipfs-blockstore v1.0.0 h1:pmFp5sFYsYVvMOp9X01AK3s85usVcLvkBTRsN6SnfUA= -github.com/ipfs/go-ipfs-blockstore v1.0.0/go.mod h1:knLVdhVU9L7CC4T+T4nvGdeUIPAXlnd9zmXfp+9MIjU= +github.com/ipfs/go-ipfs-blockstore v0.2.1/go.mod h1:jGesd8EtCM3/zPgx+qr0/feTXGUeRai6adgwC+Q+JvE= +github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= +github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-config v0.5.3 h1:3GpI/xR9FoJNTjU6YvCMRbYyEi0dBVY5UtlUTcNRlSA= github.com/ipfs/go-ipfs-config v0.5.3/go.mod h1:nSLCFtlaL+2rbl3F+9D4gQZQbT1LjRKx7TJg/IHz6oM= +github.com/ipfs/go-ipfs-config v0.19.0 h1:OuKIL+BkOZgJ+hb4Wg/9ynCtE/BaZBWcGy8hgdMepAo= +github.com/ipfs/go-ipfs-config v0.19.0/go.mod h1:wz2lKzOjgJeYJa6zx8W9VT7mz+iSd0laBMqS/9wmX6A= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs= -github.com/ipfs/go-ipfs-ds-help v1.0.0 h1:bEQ8hMGs80h0sR8O4tfDgV6B01aaF9qeTrujrTLYV3g= -github.com/ipfs/go-ipfs-ds-help v1.0.0/go.mod h1:ujAbkeIgkKAWtxxNkoZHWLCyk5JpPoKnGyCcsoF6ueE= -github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= +github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= -github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-interface v0.1.0 h1:TiMekCrOGQuWYtZO3mf4YJXDIdNgnKWZ9IE3fGlnWfo= +github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI= github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-exchange-offline v0.1.1/go.mod h1:vTiBRIbzSwDD0OWm+i3xeT0mO7jG2cbJYatp3HPk5XY= +github.com/ipfs/go-ipfs-exchange-offline v0.2.0 h1:2PF4o4A7W656rC0RxuhUace997FTcDTcIQ6NoEtyjAI= +github.com/ipfs/go-ipfs-exchange-offline v0.2.0/go.mod h1:HjwBeW0dvZvfOMwDP0TSKXIHf2s+ksdP4E3MLDRtLKY= github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-files v0.0.8 h1:8o0oFJkJ8UkO/ABl8T6ac6tKF3+NIpj67aAB6ZpusRg= github.com/ipfs/go-ipfs-files v0.0.8/go.mod h1:wiN/jSG8FKyk7N0WyctKSvq3ljIa2NNTiZB55kpTdOs= @@ -318,60 +703,81 @@ github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqt github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY= github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= -github.com/ipfs/go-ipfs-routing v0.1.0 h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ= +github.com/ipfs/go-ipfs-routing v0.0.1/go.mod h1:k76lf20iKFxQTjcJokbPM9iBXVXVZhcOwc360N4nuKs= github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-routing v0.2.1 h1:E+whHWhJkdN9YeoHZNj5itzc+OR292AJ2uE9FFiW0BY= +github.com/ipfs/go-ipfs-routing v0.2.1/go.mod h1:xiNNiwgjmLqPS1cimvAw6EyB9rkVDbiocA4yY+wRNLM= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= -github.com/ipfs/go-ipld-cbor v0.0.4 h1:Aw3KPOKXjvrm6VjwJvFf1F1ekR/BH3jdof3Bk7OTiSA= github.com/ipfs/go-ipld-cbor v0.0.4/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= +github.com/ipfs/go-ipld-cbor v0.0.5 h1:ovz4CHKogtG2KB/h1zUp5U0c/IzZrL435rCh5+K/5G8= +github.com/ipfs/go-ipld-cbor v0.0.5/go.mod h1:BkCduEx3XBCO6t2Sfo5BaHzuok7hbhdMm9Oh8B2Ftq4= github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= -github.com/ipfs/go-ipld-format v0.2.0 h1:xGlJKkArkmBvowr+GMCX0FEZtkro71K1AwiKnL37mwA= github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= +github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= +github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-legacy v0.1.0 h1:wxkkc4k8cnvIGIjPO0waJCe7SHEyFgl+yQdafdjGrpA= +github.com/ipfs/go-ipld-legacy v0.1.0/go.mod h1:86f5P/srAmh9GcIcWQR9lfFLZPrIyyXQeVlOWeeWEuI= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= -github.com/ipfs/go-log v1.0.4 h1:6nLQdX4W8P9yZZFH7mO+X/PzjN8Laozm/lMJ6esdgzY= github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= +github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= -github.com/ipfs/go-log/v2 v2.0.5 h1:fL4YI+1g5V/b1Yxr1qAiXTMg1H8z9vx/VmJxBuQMHvU= github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= +github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= +github.com/ipfs/go-log/v2 v2.5.0/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= +github.com/ipfs/go-merkledag v0.0.6/go.mod h1:QYPdnlvkOg7GnQRofu9XZimC5ZW5Wi3bKys/4GQQfto= github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= -github.com/ipfs/go-merkledag v0.3.1/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= -github.com/ipfs/go-merkledag v0.3.2 h1:MRqj40QkrWkvPswXs4EfSslhZ4RVPRbxwX11js0t1xY= github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= +github.com/ipfs/go-merkledag v0.5.1/go.mod h1:cLMZXx8J08idkp5+id62iVftUQV+HlYJ3PIhDfZsjA4= +github.com/ipfs/go-merkledag v0.6.0 h1:oV5WT2321tS4YQVOPgIrWHvJ0lJobRTerU+i9nmUCuA= +github.com/ipfs/go-merkledag v0.6.0/go.mod h1:9HSEwRd5sV+lbykiYP+2NC/3o6MZbKNaa4hfNcH5iH0= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-path v0.0.7/go.mod h1:6KTKmeRnBXgqrTvzFrPV3CamxcgvXX/4z79tfAd2Sno= +github.com/ipfs/go-peertaskqueue v0.0.4/go.mod h1:03H8fhyeMfKNFWqzYEVyMbcPUeYrqP1MX6Kd+aN+rMQ= github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= -github.com/ipfs/go-peertaskqueue v0.1.1/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= -github.com/ipfs/go-peertaskqueue v0.2.0 h1:2cSr7exUGKYyDeUyQ7P/nHPs9P7Ht/B+ROrpN1EJOjc= -github.com/ipfs/go-peertaskqueue v0.2.0/go.mod h1:5/eNrBEbtSKWCG+kQK8K8fGNixoYUnr+P7jivavs9lY= +github.com/ipfs/go-peertaskqueue v0.7.0 h1:VyO6G4sbzX80K58N60cCaHsSsypbUNs1GjO5seGNsQ0= +github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU= github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4= -github.com/ipfs/go-unixfs v0.2.4 h1:6NwppOXefWIyysZ4LR/qUBPvXd5//8J3jiMdvpbw6Lo= github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= +github.com/ipfs/go-unixfs v0.3.1 h1:LrfED0OGfG98ZEegO4/xiprx2O+yS+krCMQSp7zLVv8= +github.com/ipfs/go-unixfs v0.3.1/go.mod h1:h4qfQYzghiIc8ZNFKiLMFWOTzrWIAtzYQ59W/pCFf1o= github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= -github.com/ipfs/hang-fds v0.0.2 h1:ffZPd+OFbKpfjNAoBCI+G7okTQKd7oS1jCEDm2Kzm4c= -github.com/ipfs/hang-fds v0.0.2/go.mod h1:Ajpp/qR2orKbv5LsZmotGRASTcH38MwcIG5vTlZ9y8k= +github.com/ipfs/hang-fds v0.1.0 h1:deBiFlWHsVGzJ0ZMaqscEqRM1r2O1rFZ59UiQXb1Xko= +github.com/ipfs/hang-fds v0.1.0/go.mod h1:29VLWOn3ftAgNNgXg/al7b11UzuQ+w7AwtCGcTaWkbM= +github.com/ipfs/interface-go-ipfs-core v0.4.0 h1:+mUiamyHIwedqP8ZgbCIwpy40oX7QcXUbo4CZOeJVJg= +github.com/ipfs/interface-go-ipfs-core v0.4.0/go.mod h1:UJBcU6iNennuI05amq3FQ7g0JHUkibHFAfhfUIy927o= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= github.com/ipfs/iptb-plugins v0.3.0 h1:C1rpq1o5lUZtaAOkLIox5akh6ba4uk/3RwWc6ttVxw0= github.com/ipfs/iptb-plugins v0.3.0/go.mod h1:5QtOvckeIw4bY86gSH4fgh3p3gCSMn3FmIKr4gaBncA= -github.com/ipld/go-ipld-prime v0.0.2-0.20200428162820-8b59dc292b8e/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8= -github.com/ipld/go-ipld-prime v0.0.4-0.20200503082126-7e0619f3a984 h1:IZS2f6O/JchRZ9B/hVOClRqJW3a0bJFovhfhCUj/a8o= -github.com/ipld/go-ipld-prime v0.0.4-0.20200503082126-7e0619f3a984/go.mod h1:uVIwe/u0H4VdKv3kaN1ck7uCb6yD9cFLS9/ELyXbsw8= -github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1 h1:K1Ysr7kgIlo7YQkPqdkA6H7BVdIugvuAz7OQUTJxLdE= -github.com/ipld/go-ipld-prime-proto v0.0.0-20200428191222-c1ffdadc01e1/go.mod h1:OAV6xBmuTLsPZ+epzKkPB1e25FHk/vCtyatkdHcArLs= +github.com/ipld/go-codec-dagpb v1.3.0/go.mod h1:ga4JTU3abYApDC3pZ00BC2RSvC3qfBb9MSJkMLSwnhA= +github.com/ipld/go-codec-dagpb v1.4.0 h1:VqADPIFng8G4vz5EQytmmcx/2gEgOHfBuw/kIuCgDAY= +github.com/ipld/go-codec-dagpb v1.4.0/go.mod h1:ErNNglIi5KMur/MfFE/svtgQthzVvf+43MrzLbpcIZY= +github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= +github.com/ipld/go-ipld-prime v0.12.3/go.mod h1:PaeLYq8k6dJLmDUSLrzkEpoGV4PEfe/1OtFN/eALOc8= +github.com/ipld/go-ipld-prime v0.16.0 h1:RS5hhjB/mcpeEPJvfyj0qbOj/QL+/j05heZ0qa97dVo= +github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= -github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c h1:uUx61FiAa1GI6ZmVd2wf2vULeQZIKG66eybjNXKYCz4= github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c/go.mod h1:sdx1xVM9UuLw1tXnhJWN3piypTUO3vCIHYmG15KE/dU= @@ -387,56 +793,112 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= -github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3 h1:jNYPNLe3d8smommaoQlK7LOA5ESyUJJ+Wf79ZtA7Vp4= -github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= +github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs= +github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= +github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d h1:68u9r4wEvL3gYg2jvAOgROwZ3H+Y3hIDk4tbbmIjcYQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/koron/go-ssdp v0.0.2 h1:fL3wAoyT6hXHQlORyXUW4Q23kkQpJRgEAYcZB5BR71o= +github.com/koron/go-ssdp v0.0.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.5.1 h1:Uf4CUekH0OvzQTFPrWkstJvXgm6pnNEtQu3HiqEkpB0= +github.com/kulti/thelper v0.5.1/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kunwardeep/paralleltest v1.0.3 h1:UdKIkImEAXjR1chUWLn+PNXqWUGs//7tzMeWuP7NhmI= +github.com/kunwardeep/paralleltest v1.0.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/ldez/gomoddirectives v0.2.2 h1:p9/sXuNFArS2RLc+UpYZSI4KQwGMEDWC/LbtF5OPFVg= +github.com/ldez/gomoddirectives v0.2.2/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= +github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= +github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= +github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= -github.com/libp2p/go-addr-util v0.0.2 h1:7cWK5cdA5x72jX0g8iLrQWm5TRJZ6CzGdPEhWj7plWU= github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= +github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= +github.com/libp2p/go-conn-security v0.0.1/go.mod h1:bGmu51N0KU9IEjX7kl2PQjgZa40JQWnayTvNMgD/vyk= +github.com/libp2p/go-conn-security-multistream v0.0.2/go.mod h1:nc9vud7inQ+d6SO0I/6dSWrdMnHnzZNHeyUQqrAJulE= github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= -github.com/libp2p/go-conn-security-multistream v0.2.0 h1:uNiDjS58vrvJTg9jO6bySd1rMKejieG7v45ekqHbZ1M= github.com/libp2p/go-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= +github.com/libp2p/go-conn-security-multistream v0.3.0 h1:9UCIKlBL1hC9u7nkMXpD1nkc/T53PKMAn3/k9ivBAVc= +github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= github.com/libp2p/go-eventbus v0.0.2/go.mod h1:Hr/yGlwxA/stuLnpMiu82lpNKpvRy3EaJxPu40XYOwk= github.com/libp2p/go-eventbus v0.1.0/go.mod h1:vROgu5cs5T7cv7POWlWxBaVLxfSegC5UGQf8A2eEmx4= github.com/libp2p/go-eventbus v0.2.1 h1:VanAdErQnpTioN2TowqNcOijf6YwhuODe4pPKSDpxGc= @@ -444,40 +906,48 @@ github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVh github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-libp2p v0.0.30/go.mod h1:XWT8FGHlhptAv1+3V/+J5mEpzyui/5bvFsNuWYs611A= github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= github.com/libp2p/go-libp2p v0.3.1/go.mod h1:e6bwxbdYH1HqWTz8faTChKGR0BjPc8p+6SyP8GTTR7Y= github.com/libp2p/go-libp2p v0.4.0/go.mod h1:9EsEIf9p2UDuwtPd0DwJsAl0qXVxgAnuDGRvHbfATfI= -github.com/libp2p/go-libp2p v0.6.0/go.mod h1:mfKWI7Soz3ABX+XEBR61lGbg+ewyMtJHVt043oWeqwg= github.com/libp2p/go-libp2p v0.6.1/go.mod h1:CTFnWXogryAHjXAKEbOf1OWY+VeAP3lDMZkfEI5sT54= github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xSU1ivxn0k= github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= -github.com/libp2p/go-libp2p v0.8.3/go.mod h1:EsH1A+8yoWK+L4iKcbPYu6MPluZ+CHWI9El8cTaefiM= -github.com/libp2p/go-libp2p v0.9.6 h1:sDiuVhuLpWQOjSFmxOJEXVM9RHKIUTKgi8ArSS9nBtE= -github.com/libp2p/go-libp2p v0.9.6/go.mod h1:EA24aHpFs3BscMWvO286AiaKs3a7efQdLo+tbZ2tUSk= +github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= +github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0= +github.com/libp2p/go-libp2p v0.16.0/go.mod h1:ump42BsirwAWxKzsCiFnTtN1Yc+DuPu76fyMX364/O4= +github.com/libp2p/go-libp2p v0.19.0 h1:zosskMbaobL7UDCVLEe1m5CGs1TaFNFoN/M5XLiKg0U= +github.com/libp2p/go-libp2p v0.19.0/go.mod h1:Ki9jJXLO2YqrTIFxofV7Twyd3INWPT97+r8hGt7XPjI= +github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p-autonat v0.0.6/go.mod h1:uZneLdOkZHro35xIhpbtTzLlgYturpu4J5+0cZK3MqE= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= github.com/libp2p/go-libp2p-autonat v0.1.1/go.mod h1:OXqkeGOY2xJVWKAGV2inNF5aKN/djNA3fdpCWloIudE= github.com/libp2p/go-libp2p-autonat v0.2.0/go.mod h1:DX+9teU4pEEoZUqR1PiMlqliONQdNbfzE1C718tcViI= github.com/libp2p/go-libp2p-autonat v0.2.1/go.mod h1:MWtAhV5Ko1l6QBsHQNSuM6b1sRkXrpk0/LqCr+vCVxI= github.com/libp2p/go-libp2p-autonat v0.2.2/go.mod h1:HsM62HkqZmHR2k1xgX34WuWDzk/nBwNHoeyyT4IWV6A= -github.com/libp2p/go-libp2p-autonat v0.2.3 h1:w46bKK3KTOUWDe5mDYMRjJu1uryqBp8HCNDp/TWMqKw= -github.com/libp2p/go-libp2p-autonat v0.2.3/go.mod h1:2U6bNWCNsAG9LEbwccBDQbjzQ8Krdjge1jLTE9rdoMM= +github.com/libp2p/go-libp2p-autonat v0.4.2/go.mod h1:YxaJlpr81FhdOv3W3BTconZPfhaYivRdf53g+S2wobk= +github.com/libp2p/go-libp2p-autonat v0.6.0/go.mod h1:bFC6kY8jwzNNWoqc8iGE57vsfwyJ/lP4O4DOV1e0B2o= github.com/libp2p/go-libp2p-autonat-svc v0.1.0/go.mod h1:fqi8Obl/z3R4PFVLm8xFtZ6PBL9MlV/xumymRFkKq5A= +github.com/libp2p/go-libp2p-blankhost v0.0.1/go.mod h1:Ibpbw/7cPPYwFb7PACIWdvxxv0t0XCCI10t7czjAjTc= github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= github.com/libp2p/go-libp2p-blankhost v0.1.3/go.mod h1:KML1//wiKR8vuuJO0y3LUd1uLv+tlkGTAr3jC0S5cLg= github.com/libp2p/go-libp2p-blankhost v0.1.4/go.mod h1:oJF0saYsAXQCSfDq254GMNmLNz6ZTHTOvtF4ZydUvwU= -github.com/libp2p/go-libp2p-blankhost v0.1.6 h1:CkPp1/zaCrCnBo0AdsQA0O1VkUYoUOtyHOnoa8gKIcE= -github.com/libp2p/go-libp2p-blankhost v0.1.6/go.mod h1:jONCAJqEP+Z8T6EQviGL4JsQcLx1LgTGtVqFNY8EMfQ= +github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-blankhost v0.3.0 h1:kTnLArltMabZlzY63pgGDA4kkUcLkBFSM98zBssn/IY= +github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU= +github.com/libp2p/go-libp2p-circuit v0.0.9/go.mod h1:uU+IBvEQzCu953/ps7bYzC/D/R0Ho2A9LfKVVCatlqU= github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.1/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= github.com/libp2p/go-libp2p-circuit v0.1.3/go.mod h1:Xqh2TjSy8DD5iV2cCOMzdynd6h8OTBGoV1AWbWor3qM= github.com/libp2p/go-libp2p-circuit v0.1.4/go.mod h1:CY67BrEjKNDhdTk8UgBX1Y/H5c3xkAcs3gnksxY7osU= github.com/libp2p/go-libp2p-circuit v0.2.1/go.mod h1:BXPwYDN5A8z4OEY9sOfr2DUQMLQvKt/6oku45YUmjIo= -github.com/libp2p/go-libp2p-circuit v0.2.2/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4= -github.com/libp2p/go-libp2p-circuit v0.2.3 h1:3Uw1fPHWrp1tgIhBz0vSOxRUmnKL8L/NGUyEd5WfSGM= -github.com/libp2p/go-libp2p-circuit v0.2.3/go.mod h1:nkG3iE01tR3FoQ2nMm06IUrCpCyJp1Eo4A1xYdpjfs4= +github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= +github.com/libp2p/go-libp2p-circuit v0.6.0 h1:rw/HlhmUB3OktS/Ygz6+2XABOmHKzZpPUuMNUMosj8w= +github.com/libp2p/go-libp2p-circuit v0.6.0/go.mod h1:kB8hY+zCpMeScyvFrKrGicRdid6vNXbunKE4rXATZ0M= github.com/libp2p/go-libp2p-connmgr v0.1.1/go.mod h1:wZxh8veAmU5qdrfJ0ZBLcU8oJe9L82ciVP/fl1VHjXk= -github.com/libp2p/go-libp2p-connmgr v0.2.3/go.mod h1:Gqjg29zI8CwXX21zRxy6gOg8VYu3zVerJRt2KyktzH4= github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= @@ -497,195 +967,401 @@ github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= -github.com/libp2p/go-libp2p-core v0.5.7 h1:QK3xRwFxqd0Xd9bSZL+8yZ8ncZZbl6Zngd/+Y+A6sgQ= github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.6.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.5/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= +github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8= +github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.14.0/go.mod h1:tLasfcVdTXnixsLB0QYaT1syJOhsbrhG7q6pGrHtBg8= +github.com/libp2p/go-libp2p-core v0.15.1 h1:0RY+Mi/ARK9DgG1g9xVQLb8dDaaU8tCePMtGALEfBnM= +github.com/libp2p/go-libp2p-core v0.15.1/go.mod h1:agSaboYM4hzB1cWekgVReqV5M4g5M+2eNNejV+1EEhs= +github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-crypto v0.0.2/go.mod h1:eETI5OUfBnvARGOHrJz2eWNyTUxEGZnBxMcbUjfIj4I= github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= github.com/libp2p/go-libp2p-daemon v0.2.2/go.mod h1:kyrpsLB2JeNYR2rvXSVWyY0iZuRIMhqzWR3im9BV6NQ= +github.com/libp2p/go-libp2p-discovery v0.0.5/go.mod h1:YtF20GUxjgoKZ4zmXj8j3Nb2TUSBHFlOCetzYdbZL5I= github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= github.com/libp2p/go-libp2p-discovery v0.2.0/go.mod h1:s4VGaxYMbw4+4+tsoQTqh7wfxg97AEdo4GYBt6BadWg= github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQOu38Fu7LJGEOK2gQltw= -github.com/libp2p/go-libp2p-discovery v0.4.0 h1:dK78UhopBk48mlHtRCzbdLm3q/81g77FahEBTjcqQT8= -github.com/libp2p/go-libp2p-discovery v0.4.0/go.mod h1:bZ0aJSrFc/eX2llP0ryhb1kpgkPyTo23SJ5b7UQCMh4= +github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug= +github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= +github.com/libp2p/go-libp2p-host v0.0.1/go.mod h1:qWd+H1yuU0m5CwzAkvbSjqKairayEHdR5MMl7Cwa7Go= +github.com/libp2p/go-libp2p-host v0.0.3/go.mod h1:Y/qPyA6C8j2coYyos1dfRm0I8+nvd4TGrDGt4tA7JR8= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.4/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-connmgr v0.0.5/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= +github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= github.com/libp2p/go-libp2p-kad-dht v0.2.1/go.mod h1:k7ONOlup7HKzQ68dE6lSnp07cdxdkmnRa+6B4Fh9/w0= github.com/libp2p/go-libp2p-kbucket v0.2.1/go.mod h1:/Rtu8tqbJ4WQ2KTCOMJhggMukOLNLNPY1EtEWWLxUvc= +github.com/libp2p/go-libp2p-loggables v0.0.1/go.mod h1:lDipDlBNYbpyqyPX/KcoO+eq0sJYEVR2JgOexcivchg= github.com/libp2p/go-libp2p-loggables v0.1.0 h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8= github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-metrics v0.0.1/go.mod h1:jQJ95SXXA/K1VZi13h52WZMa9ja78zjyy5rspMsC/08= +github.com/libp2p/go-libp2p-mplex v0.1.1/go.mod h1:KUQWpGkCzfV7UIpi8SKsAVxyBgz1c9R5EvxgnwLsb/I= github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= github.com/libp2p/go-libp2p-mplex v0.2.2/go.mod h1:74S9eum0tVQdAfFiKxAyKzNdSuLqw5oadDq7+L/FELo= -github.com/libp2p/go-libp2p-mplex v0.2.3 h1:2zijwaJvpdesST2MXpI5w9wWFRgYtMcpRX7rrw0jmOo= github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= +github.com/libp2p/go-libp2p-mplex v0.4.0/go.mod h1:yCyWJE2sc6TBTnFpjvLuEJgTSw/u+MamvzILKdX7asw= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-mplex v0.5.0/go.mod h1:eLImPJLkj3iG5t5lq68w3Vm5NAQ5BcKwrrb2VmOYb3M= +github.com/libp2p/go-libp2p-mplex v0.7.0 h1:ONTTvHIUaFCwyPO4FRkpe4OFQJq1bDkWQLbhWiD1A44= +github.com/libp2p/go-libp2p-mplex v0.7.0/go.mod h1:SeeXUXh7ZkfxnmsepnFgMPEhfEyACujuTM9k1TkErpc= github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= github.com/libp2p/go-libp2p-nat v0.0.5/go.mod h1:1qubaE5bTZMJE+E/uu2URroMbzdubFz1ChgiN79yKPE= -github.com/libp2p/go-libp2p-nat v0.0.6 h1:wMWis3kYynCbHoyKLPBEMu4YRLltbm8Mk08HGSfvTkU= github.com/libp2p/go-libp2p-nat v0.0.6/go.mod h1:iV59LVhB3IkFvS6S6sauVTSOrNEANnINbI/fkaLimiw= +github.com/libp2p/go-libp2p-nat v0.1.0 h1:vigUi2MEN+fwghe5ijpScxtbbDz+L/6y8XwlzYOJgSY= +github.com/libp2p/go-libp2p-nat v0.1.0/go.mod h1:DQzAG+QbDYjN1/C3B6vXucLtz3u9rEonLVPtZVzQqks= +github.com/libp2p/go-libp2p-net v0.0.1/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-net v0.0.2/go.mod h1:Yt3zgmlsHOgUWSXmt5V/Jpz9upuJBE8EgNU9DrCcR8c= +github.com/libp2p/go-libp2p-netutil v0.0.1/go.mod h1:GdusFvujWZI9Vt0X5BKqwWWmZFxecf9Gt03cKxm2f/Q= github.com/libp2p/go-libp2p-netutil v0.1.0 h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ= github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-noise v0.2.0/go.mod h1:IEbYhBBzGyvdLBoxxULL/SGbJARhUeqlO8lVSREYu2Q= +github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= +github.com/libp2p/go-libp2p-noise v0.4.0 h1:khcMsGhHNdGqKE5LDLrnHwZvdGVMsrnD4GTkTWkwmLU= +github.com/libp2p/go-libp2p-noise v0.4.0/go.mod h1:BzzY5pyzCYSyJbQy9oD8z5oP2idsafjt4/X42h9DjZU= +github.com/libp2p/go-libp2p-peer v0.0.1/go.mod h1:nXQvOBbwVqoP+T5Y5nCjeH4sP9IX/J0AMzcDUVruVoo= +github.com/libp2p/go-libp2p-peer v0.1.1/go.mod h1:jkF12jGB4Gk/IOo+yomm+7oLWxF278F7UnrYUQ1Q8es= github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.0.1/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= +github.com/libp2p/go-libp2p-peerstore v0.0.6/go.mod h1:RabLyPVJLuNQ+GFyoEkfi8H4Ti6k/HtZJ7YKgtSq+20= github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= github.com/libp2p/go-libp2p-peerstore v0.1.3/go.mod h1:BJ9sHlm59/80oSkpWgr1MyY1ciXAXV397W6h1GH/uKI= github.com/libp2p/go-libp2p-peerstore v0.2.0/go.mod h1:N2l3eVIeAitSg3Pi2ipSrJYnqhVnMNQZo9nkSCuAbnQ= github.com/libp2p/go-libp2p-peerstore v0.2.1/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= github.com/libp2p/go-libp2p-peerstore v0.2.2/go.mod h1:NQxhNjWxf1d4w6PihR8btWIRjwRLBr4TYKfNgrUkOPA= -github.com/libp2p/go-libp2p-peerstore v0.2.3/go.mod h1:K8ljLdFn590GMttg/luh4caB/3g0vKuY01psze0upRw= -github.com/libp2p/go-libp2p-peerstore v0.2.4/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= -github.com/libp2p/go-libp2p-peerstore v0.2.6 h1:2ACefBX23iMdJU9Ke+dcXt3w86MIryes9v7In4+Qq3U= github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.2.7/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= +github.com/libp2p/go-libp2p-peerstore v0.6.0 h1:HJminhQSGISBIRb93N6WK3t6Fa8OOTnHd/VBjL4mY5A= +github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= +github.com/libp2p/go-libp2p-protocol v0.0.1/go.mod h1:Af9n4PiruirSDjHycM1QuiMi/1VZNHYcK8cLgFJLZ4s= +github.com/libp2p/go-libp2p-protocol v0.1.0/go.mod h1:KQPHpAabB57XQxGrXCNvbL6UEXfQqUgC/1adR2Xtflk= github.com/libp2p/go-libp2p-pubsub v0.1.1/go.mod h1:ZwlKzRSe1eGvSIdU5bD7+8RZN/Uzw0t1Bp9R1znpR/Q= -github.com/libp2p/go-libp2p-pubsub v0.3.1/go.mod h1:TxPOBuo1FPdsTjFnv+FGZbNbWYsp74Culx+4ViQpato= github.com/libp2p/go-libp2p-quic-transport v0.1.1/go.mod h1:wqG/jzhF3Pu2NrhJEvE+IE0NTHNXslOPn9JQzyCAxzU= -github.com/libp2p/go-libp2p-quic-transport v0.3.7 h1:F9hxonkJvMipNim8swrvRk2uL9s8pqzHz0M6eMf8L58= -github.com/libp2p/go-libp2p-quic-transport v0.3.7/go.mod h1:Kr4aDtnfHHNeENn5J+sZIVc+t8HpQn9W6BOxhVGHbgI= +github.com/libp2p/go-libp2p-quic-transport v0.10.0/go.mod h1:RfJbZ8IqXIhxBRm5hqUEJqjiiY8xmEuq3HUDS993MkA= +github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= +github.com/libp2p/go-libp2p-quic-transport v0.15.0/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-quic-transport v0.16.0/go.mod h1:1BXjVMzr+w7EkPfiHkKnwsWjPjtfaNT0q8RS3tGDvEQ= +github.com/libp2p/go-libp2p-quic-transport v0.17.0 h1:yFh4Gf5MlToAYLuw/dRvuzYd1EnE2pX3Lq1N6KDiWRQ= +github.com/libp2p/go-libp2p-quic-transport v0.17.0/go.mod h1:x4pw61P3/GRCcSLypcQJE/Q2+E9f4X+5aRcZLXf20LM= +github.com/libp2p/go-libp2p-record v0.0.1/go.mod h1:grzqg263Rug/sRex85QrDOLntdFAymLDLm7lxMgU79Q= github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= -github.com/libp2p/go-libp2p-record v0.1.1 h1:ZJK2bHXYUBqObHX+rHLSNrM3M8fmJUlUHrodDPPATmY= github.com/libp2p/go-libp2p-record v0.1.1/go.mod h1:VRgKajOyMVgP/F0L5g3kH7SVskp17vFi2xheb5uMJtg= +github.com/libp2p/go-libp2p-record v0.1.3 h1:R27hoScIhQf/A8XJZ8lYpnqh9LatJ5YbHs28kCIfql0= +github.com/libp2p/go-libp2p-record v0.1.3/go.mod h1:yNUff/adKIfPnYQXgp6FQmNu3gLJ6EMg7+/vv2+9pY4= +github.com/libp2p/go-libp2p-resource-manager v0.2.1/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= +github.com/libp2p/go-libp2p-resource-manager v0.3.0 h1:2+cYxUNi33tcydsVLt6K5Fv2E3OTiVeafltecAj15E0= +github.com/libp2p/go-libp2p-resource-manager v0.3.0/go.mod h1:K+eCkiapf+ey/LADO4TaMpMTP9/Qde/uLlrnRqV4PLQ= +github.com/libp2p/go-libp2p-routing v0.0.1/go.mod h1:N51q3yTr4Zdr7V8Jt2JIktVU+3xBBylx1MZeVA6t1Ys= github.com/libp2p/go-libp2p-routing v0.1.0/go.mod h1:zfLhI1RI8RLEzmEaaPwzonRvXeeSHddONWkcTcB54nE= +github.com/libp2p/go-libp2p-secio v0.0.3/go.mod h1:hS7HQ00MgLhRO/Wyu1bTX6ctJKhVpm+j2/S2A5UqYb0= github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= github.com/libp2p/go-libp2p-secio v0.2.0/go.mod h1:2JdZepB8J5V9mBp79BmwsaPQhRPNN2NrnB2lKQcdy6g= github.com/libp2p/go-libp2p-secio v0.2.1/go.mod h1:cWtZpILJqkqrSkiYcDBh5lA3wbT2Q+hz3rJQq3iftD8= -github.com/libp2p/go-libp2p-secio v0.2.2 h1:rLLPvShPQAcY6eNurKNZq3eZjPWfU9kXF2eI9jIYdrg= github.com/libp2p/go-libp2p-secio v0.2.2/go.mod h1:wP3bS+m5AUnFA+OFO7Er03uO1mncHG0uVwGrwvjYlNY= +github.com/libp2p/go-libp2p-swarm v0.0.6/go.mod h1:s5GZvzg9xXe8sbeESuFpjt8CJPTCa8mhEusweJqyFy8= github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= github.com/libp2p/go-libp2p-swarm v0.2.1/go.mod h1:x07b4zkMFo2EvgPV2bMTlNmdQc8i+74Jjio7xGvsTgU= github.com/libp2p/go-libp2p-swarm v0.2.2/go.mod h1:fvmtQ0T1nErXym1/aa1uJEyN7JzaTNyBcHImCxRpPKU= github.com/libp2p/go-libp2p-swarm v0.2.3/go.mod h1:P2VO/EpxRyDxtChXz/VPVXyTnszHvokHKRhfkEgFKNM= -github.com/libp2p/go-libp2p-swarm v0.2.4/go.mod h1:/xIpHFPPh3wmSthtxdGbkHZ0OET1h/GGZes8Wku/M5Y= -github.com/libp2p/go-libp2p-swarm v0.2.6 h1:UhMXIa+yCOALQyceENEIStMlbTCzOM6aWo6vw8QW17Q= -github.com/libp2p/go-libp2p-swarm v0.2.6/go.mod h1:F9hrkZjO7dDbcEiYii/fAB1QdpLuU6h1pa4P5VNsEgc= +github.com/libp2p/go-libp2p-swarm v0.2.8/go.mod h1:JQKMGSth4SMqonruY0a8yjlPVIkb0mdNSwckW7OYziM= +github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.5.0/go.mod h1:sU9i6BoHE0Ve5SKz3y9WfKrh8dUat6JknzUehFx8xW4= +github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= +github.com/libp2p/go-libp2p-swarm v0.10.0/go.mod h1:71ceMcV6Rg/0rIQ97rsZWMzto1l9LnNquef+efcRbmA= +github.com/libp2p/go-libp2p-swarm v0.10.2 h1:UaXf+CTq6Ns1N2V1EgqJ9Q3xaRsiN7ImVlDMpirMAWw= +github.com/libp2p/go-libp2p-swarm v0.10.2/go.mod h1:Pdkq0QU5a+qu+oyqIV3bknMsnzk9lnNyKvB9acJ5aZs= +github.com/libp2p/go-libp2p-testing v0.0.1/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= github.com/libp2p/go-libp2p-testing v0.1.0/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-testing v0.1.1 h1:U03z3HnGI7Ni8Xx6ONVZvUFOAzWYmolWf5W5jAOPNmU= github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= -github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM= +github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= +github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= +github.com/libp2p/go-libp2p-testing v0.7.0/go.mod h1:OLbdn9DbgdMwv00v+tlp1l3oe2Cl+FAjoWIA2pa0X6E= +github.com/libp2p/go-libp2p-testing v0.9.0/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= +github.com/libp2p/go-libp2p-testing v0.9.2 h1:dCpODRtRaDZKF8HXT9qqqgON+OMEB423Knrgeod8j84= +github.com/libp2p/go-libp2p-testing v0.9.2/go.mod h1:Td7kbdkWqYTJYQGTwzlgXwaqldraIanyjuRiAbK/XQU= github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M= +github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.3.1/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.4.1 h1:1ByJUbyoMXvYXDoW6lLsMxqMViQNXmt+CfQqlnCpY+M= +github.com/libp2p/go-libp2p-tls v0.4.1/go.mod h1:EKCixHEysLNDlLUoKxv+3f/Lp90O2EXNjTr0UQDnrIw= +github.com/libp2p/go-libp2p-transport v0.0.1/go.mod h1:UzbUs9X+PHOSw7S3ZmeOxfnwaQY5vGDzZmKPod3N3tk= +github.com/libp2p/go-libp2p-transport v0.0.5/go.mod h1:StoY3sx6IqsP6XKoabsPnHCwqKXWUMWU7Rfcsubee/A= +github.com/libp2p/go-libp2p-transport-upgrader v0.0.4/go.mod h1:RGq+tupk+oj7PzL2kn/m1w6YXxcIAYJYeI90h6BGgUc= github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= -github.com/libp2p/go-libp2p-transport-upgrader v0.3.0 h1:q3ULhsknEQ34eVDhv4YwKS8iet69ffs9+Fir6a7weN4= github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.2/go.mod h1:NR8ne1VwfreD5VIWIU62Agt/J18ekORFU/j1i2y8zvk= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= +github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.0/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1 h1:MSMe+tUfxpC9GArTz7a4G5zQKQgGh00Vio87d3j3xIg= +github.com/libp2p/go-libp2p-transport-upgrader v0.7.1/go.mod h1:GIR2aTRp1J5yjVlkUoFqMkdobfob6RnAwYg/RZPhrzg= +github.com/libp2p/go-libp2p-yamux v0.1.2/go.mod h1:xUoV/RmYkg6BW/qGxA9XJyg+HzXFYkeXbnhjmnYzKp8= +github.com/libp2p/go-libp2p-yamux v0.1.3/go.mod h1:VGSQVrqkh6y4nm0189qqxMtvyBft44MOYYPpYKXiVt4= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= github.com/libp2p/go-libp2p-yamux v0.2.2/go.mod h1:lIohaR0pT6mOt0AZ0L2dFze9hds9Req3OfS+B+dv4qw= github.com/libp2p/go-libp2p-yamux v0.2.5/go.mod h1:Zpgj6arbyQrmZ3wxSZxfBmbdnWtbZ48OpsfmQVTErwA= github.com/libp2p/go-libp2p-yamux v0.2.7/go.mod h1:X28ENrBMU/nm4I3Nx4sZ4dgjZ6VhLEn0XhIoZ5viCwU= -github.com/libp2p/go-libp2p-yamux v0.2.8 h1:0s3ELSLu2O7hWKfX1YjzudBKCP0kZ+m9e2+0veXzkn4= github.com/libp2p/go-libp2p-yamux v0.2.8/go.mod h1:/t6tDqeuZf0INZMTgd0WxIRbtK2EzI2h7HbFm9eAKI4= +github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= +github.com/libp2p/go-libp2p-yamux v0.5.4/go.mod h1:tfrXbyaTqqSU654GTvK3ocnSZL3BuHoeTSqhcel1wsE= +github.com/libp2p/go-libp2p-yamux v0.6.0/go.mod h1:MRhd6mAYnFRnSISp4M8i0ClV/j+mWHo2mYLifWGw33k= +github.com/libp2p/go-libp2p-yamux v0.8.0/go.mod h1:yTkPgN2ib8FHyU1ZcVD7aelzyAqXXwEPbyx+aSKm9h8= +github.com/libp2p/go-libp2p-yamux v0.8.1/go.mod h1:rUozF8Jah2dL9LLGyBaBeTQeARdwhefMCTQVQt6QobE= +github.com/libp2p/go-libp2p-yamux v0.9.1 h1:oplewiRix8s45SOrI30rCPZG5mM087YZp+VYhXAh4+c= +github.com/libp2p/go-libp2p-yamux v0.9.1/go.mod h1:wRc6wvyxQINFcKe7daL4BeQ02Iyp+wxyC8WCNfngBrA= +github.com/libp2p/go-maddr-filter v0.0.1/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= -github.com/libp2p/go-maddr-filter v0.0.5 h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg= github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= +github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.0.4/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-mplex v0.1.1/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= -github.com/libp2p/go-mplex v0.1.2 h1:qOg1s+WdGLlpkrczDqmhYzyk3vCfsQ8+RxRTQjOZWwI= github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.2.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= +github.com/libp2p/go-mplex v0.4.0/go.mod h1:y26Lx+wNVtMYMaPu300Cbot5LkEZ4tJaNYeHeT9dh6E= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= -github.com/libp2p/go-msgio v0.0.4 h1:agEFehY3zWJFUHK6SEMR7UYmk2z6kC3oeCM7ybLhguA= github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= +github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE= +github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo= -github.com/libp2p/go-nat v0.0.5 h1:qxnwkco8RLKqVh1NmjQ+tJ8p8khNLFxuElYG/TwqW4Q= github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU= -github.com/libp2p/go-netroute v0.1.2 h1:UHhB35chwgvcRI392znJA3RCBtZ3MpE3ahNCN5MR4Xg= +github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= +github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= +github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= +github.com/libp2p/go-netroute v0.2.0 h1:0FpsbsvuSnAhXFnCY0VLFbJOzaK0VnP0r1QT/o4nWRE= +github.com/libp2p/go-netroute v0.2.0/go.mod h1:Vio7LTzZ+6hoT4CMZi5/6CpY3Snzh2vgZhWgxMNwlQI= github.com/libp2p/go-openssl v0.0.2/go.mod h1:v8Zw2ijCSWBQi8Pq5GAixw6DbFfa9u6VIYDXnvOXkc0= github.com/libp2p/go-openssl v0.0.3/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-openssl v0.0.5 h1:pQkejVhF0xp08D4CQUcw8t+BFJeXowja6RVcb5p++EA= github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= -github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw= +github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= +github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ= +github.com/libp2p/go-reuseport v0.1.0 h1:0ooKOx2iwyIkf339WCZ2HN3ujTDbkK0PjC7JVoP1AiM= +github.com/libp2p/go-reuseport v0.1.0/go.mod h1:bQVn9hmfcTaoo0c9v5pBhOarsU1eNOBZdaAd2hzXRKU= github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= -github.com/libp2p/go-reuseport-transport v0.0.3 h1:zzOeXnTooCkRvoH+bSXEfXhn76+LAiwoneM0gnXjF2M= github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= +github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw= +github.com/libp2p/go-reuseport-transport v0.1.0 h1:C3PHeHjmnz8m6f0uydObj02tMEoi7CyD1zuN7xQT8gc= +github.com/libp2p/go-reuseport-transport v0.1.0/go.mod h1:vev0C0uMkzriDY59yFHD9v+ujJvYmDQVLowvAjEOmfw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= -github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0= github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer v0.1.0/go.mod h1:8JAVsjeRBCWwPoZeH0W1imLOcriqXJyFvB0mR4A04sQ= +github.com/libp2p/go-stream-muxer-multistream v0.1.1/go.mod h1:zmGdfkQ1AzOECIAcccoL8L//laqawOsO03zX8Sa+eGw= github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= -github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-stream-muxer-multistream v0.4.0 h1:HsM/9OdtqnIzjVXcxTXjmqKrj3gJ8kacaOJwJS1ipaY= +github.com/libp2p/go-stream-muxer-multistream v0.4.0/go.mod h1:nb+dGViZleRP4XcyHuZSVrJCBl55nRBOMmiSL/dyziw= +github.com/libp2p/go-tcp-transport v0.0.4/go.mod h1:+E8HvC8ezEVOxIo3V5vCK9l1y/19K427vCzQ+xHKH/o= github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= github.com/libp2p/go-tcp-transport v0.1.1/go.mod h1:3HzGvLbx6etZjnFlERyakbaYPdfjg2pWP97dFZworkY= -github.com/libp2p/go-tcp-transport v0.2.0 h1:YoThc549fzmNJIh7XjHVtMIFaEDRtIrtWciG5LyYAPo= github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-tcp-transport v0.2.3/go.mod h1:9dvr03yqrPyYGIEN6Dy5UvdJZjyPFvl1S/igQ5QD1SU= +github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= +github.com/libp2p/go-tcp-transport v0.5.0/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= +github.com/libp2p/go-tcp-transport v0.5.1 h1:edOOs688VLZAozWC7Kj5/6HHXKNwi9M6wgRmmLa8M6Q= +github.com/libp2p/go-tcp-transport v0.5.1/go.mod h1:UPPL0DIjQqiWRwVAb+CEQlaAG0rp/mCqJfIhFcLHc4Y= +github.com/libp2p/go-testutil v0.0.1/go.mod h1:iAcJc/DKJQanJ5ws2V+u5ywdL2n12X1WbbEG+Jjy69I= github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= +github.com/libp2p/go-ws-transport v0.0.5/go.mod h1:Qbl4BxPfXXhhd/o0wcrgoaItHqA9tnZjoFZnxykuaXU= github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= github.com/libp2p/go-ws-transport v0.1.2/go.mod h1:dsh2Ld8F+XNmzpkaAijmg5Is+e9l6/1tK/6VFOdN69Y= github.com/libp2p/go-ws-transport v0.2.0/go.mod h1:9BHJz/4Q5A9ludYWKoGCFC5gUElzlHoKzu0yY9p/klM= github.com/libp2p/go-ws-transport v0.3.0/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= -github.com/libp2p/go-ws-transport v0.3.1 h1:ZX5rWB8nhRRJVaPO6tmkGI/Xx8XNboYX20PW5hXIscw= -github.com/libp2p/go-ws-transport v0.3.1/go.mod h1:bpgTJmRZAvVHrgHybCVyqoBmyLQ1fiZuEaBYusP5zsk= +github.com/libp2p/go-ws-transport v0.4.0/go.mod h1:EcIEKqf/7GDjth6ksuS/6p7R49V4CBY6/E7R/iyhYUA= +github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xds1iamArLvl8kNg= +github.com/libp2p/go-ws-transport v0.6.0 h1:326XBL6Q+5CQ2KtjXz32+eGu02W/Kz2+Fm4SpXdr0q4= +github.com/libp2p/go-ws-transport v0.6.0/go.mod h1:dXqtI9e2JV9FtF1NOtWVZSKXh5zXvnuwPXfj8GPBbYU= +github.com/libp2p/go-yamux v1.2.1/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.3.0/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.3.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= -github.com/libp2p/go-yamux v1.3.7 h1:v40A1eSPJDIZwz2AvrV3cxpTZEGDP11QJbukmEhYyQI= github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= +github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ= +github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= +github.com/libp2p/go-yamux/v3 v3.0.1/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.0.2/go.mod h1:s2LsDhHbh+RfCsQoICSYt58U2f8ijtPANFD8BmE74Bo= +github.com/libp2p/go-yamux/v3 v3.1.1 h1:X0qSVodCZciOu/f4KTp9V+O0LAqcqP2tdaUGB0+0lng= +github.com/libp2p/go-yamux/v3 v3.1.1/go.mod h1:jeLEQgLXqE2YqX1ilAClIfCMDY+0uXQUKmmb/qp0gT4= +github.com/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= -github.com/lucas-clemente/quic-go v0.15.7 h1:Pu7To5/G9JoP1mwlrcIvfV8ByPBlCzif3MCl8+1W83I= -github.com/lucas-clemente/quic-go v0.15.7/go.mod h1:Myi1OyS0FOjL3not4BxT7KN29bRkcMUV5JVVFLKtDp8= +github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= +github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.25.0/go.mod h1:YtzP8bxRVCBlO77yRanE264+fY/T2U9ZlW1AaHOsMOg= +github.com/lucas-clemente/quic-go v0.27.0 h1:v6WY87q9zD4dKASbG8hy/LpzAVNzEQzw8sEIeloJsc4= +github.com/lucas-clemente/quic-go v0.27.0/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= -github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk= -github.com/marten-seemann/qtls v0.9.1 h1:O0YKQxNVPaiFgMng0suWEOY2Sb4LT2sRn9Qimq3Z1IQ= -github.com/marten-seemann/qtls v0.9.1/go.mod h1:T1MmAdDPyISzxlK6kjRr0pcZFBVd1OZbBb/j3cvzHhk= -github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= -github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= +github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= +github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= +github.com/marten-seemann/qtls-go1-17 v0.1.1 h1:DQjHPq+aOzUeh9/lixAGunn6rIOQyWChPSI4+hgW7jc= +github.com/marten-seemann/qtls-go1-17 v0.1.1/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= +github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1/go.mod h1:PUhIQk19LoFt2174H4+an8TYvWOGjb/hHwphBeaDHwI= +github.com/marten-seemann/qtls-go1-18 v0.1.1 h1:qp7p7XXUFL7fpBvSS1sWD+uSqPvzNQK43DH+/qEkj0Y= +github.com/marten-seemann/qtls-go1-18 v0.1.1/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= +github.com/mgechev/revive v1.1.4 h1:sZOjY6GU35Kr9jKa/wsKSHgrFz8eASIB5i3tqWZMp0A= +github.com/mgechev/revive v1.1.4/go.mod h1:ZZq2bmyssGh8MSPz3VVziqRNIMYTJXzP8MUKG90vZ9A= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mozilla/tls-observatory v0.0.0-20200220173314-aae45faa4006/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= +github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= +github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= @@ -695,14 +1371,21 @@ github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= -github.com/multiformats/go-multiaddr v0.2.2 h1:XZLDTszBIJe6m0zF6ITBrEcZR73OPUhCBBS9rYAuUzI= github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= +github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= +github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= +github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= +github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= +github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= +github.com/multiformats/go-multiaddr v0.5.0 h1:i/JuOoVg4szYQ4YEzDGtb2h0o8M7CG/Yq6cGlcjWZpM= +github.com/multiformats/go-multiaddr v0.5.0/go.mod h1:3KAxNkUqLTJ20AAwN4XVX4kZar+bR+gh4zgbfr3SNug= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.0.3/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= github.com/multiformats/go-multiaddr-dns v0.1.0/go.mod h1:01k2RAqtoXIuPa3DCavAE9/6jc6nM0H3EgZyfUhN2oY= -github.com/multiformats/go-multiaddr-dns v0.2.0 h1:YWJoIDwLePniH7OU5hBnDZV6SWuvJqJ0YtN6pLeH9zA= github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= @@ -712,101 +1395,248 @@ github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJV github.com/multiformats/go-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= -github.com/multiformats/go-multiaddr-net v0.1.5 h1:QoRKvu0xHN1FCFJcMQLbG/yQE2z441L5urvG3+qyz7g= github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= -github.com/multiformats/go-multibase v0.0.2/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= +github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4= +github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= -github.com/multiformats/go-multihash v0.0.13 h1:06x+mk/zj1FoMsgNejLpy6QTvJqlSt/BhLEy87zidlc= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= +github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= +github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= +github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= +github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= -github.com/multiformats/go-multistream v0.1.1 h1:JlAdpIFhBhGRLxe9W6Om0w++Gd6KMWoFPZL/dEnm9nI= github.com/multiformats/go-multistream v0.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= +github.com/multiformats/go-multistream v0.3.0 h1:yX1v4IWseLPmr0rmnDo148wWJbNx40JxBZGmQb5fUP4= +github.com/multiformats/go-multistream v0.3.0/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= -github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= +github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/nishanths/exhaustive v0.7.11 h1:xV/WU3Vdwh5BUH4N06JNUznb6d5zhRPOnlgCrpNYNKA= +github.com/nishanths/exhaustive v0.7.11/go.mod h1:gX+MP7DWMKJmNa1HfMozK+u04hQd3na9i0hyqf3/dOI= +github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= +github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= +github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a h1:hjZfReYVLbqFkAtr2us7vdy04YWz3LVAirzP7reh8+M= -github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= +github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polyfloyd/go-errorlint v0.0.0-20211125173453-6d6d39c5bb8b h1:/BDyEJWLnDUYKGWdlNx/82qSaVu2bUok/EvPUtIGuvw= +github.com/polyfloyd/go-errorlint v0.0.0-20211125173453-6d6d39c5bb8b/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.33.0 h1:rHgav/0a6+uYgGdNt3jwz8FNSesO/Hsang3O0T9A5SE= +github.com/prometheus/common v0.33.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= +github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= +github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= +github.com/quasilyte/go-ruleguard v0.3.15 h1:iWYzp1z72IlXTioET0+XI6SjQdPfMGfuAiZiKznOt7g= +github.com/quasilyte/go-ruleguard v0.3.15/go.mod h1:NhuWhnlVEM1gT1A4VJHYfy9MuYSxxwHgxWoPsn9llB4= +github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.12-0.20220101150716-969a394a9451/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.12/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.17/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3 h1:P4QPNn+TK49zJjXKERt/vyPbv/mCHB/zQ4flDYOMN+M= +github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= +github.com/raulk/clock v1.1.0/go.mod h1:3MpVxdZ/ODBQDxbN+kzshf5OSZwPjtMDx6BBXBmOeY0= +github.com/raulk/go-watchdog v1.2.0 h1:konN75pw2BMmZ+AfuAm5rtFsWcJpKF3m02rKituuXNo= +github.com/raulk/go-watchdog v1.2.0/go.mod h1:lzSbAl5sh4rtI8tYHU01BWIDzgzqaQLj6RcA1i4mlqI= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/ryancurrah/gomodguard v1.0.4 h1:oCreMAt9GuFXDe9jW4HBpc3GjdX3R/sUEcLAGh1zPx8= -github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE= -github.com/securego/gosec v0.0.0-20200316084457-7da9f46445fd h1:qB+l4fYZsH78xORC1aqVS0zNmgkQp4rkj2rvfxQMtzc= -github.com/securego/gosec v0.0.0-20200316084457-7da9f46445fd/go.mod h1:NurAFZsWJAEZjogSwdVPlHkOZB3DOAU7gsPP8VFZCHc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.2.3 h1:ww2fsjqocGCAFamzvv/b8IsRduuHHeK2MHTcTxZTQX8= +github.com/ryancurrah/gomodguard v1.2.3/go.mod h1:rYbA/4Tg5c54mV1sv4sQTP5WOPBcoLtnBZ7/TEhXAbg= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= +github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= +github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= +github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/securego/gosec/v2 v2.10.0 h1:l6BET4EzWtyUXCpY2v7N92v0DDCas0L7ngg3bpqbr8g= +github.com/securego/gosec/v2 v2.10.0/go.mod h1:PVq8Ewh/nCN8l/kKC6zrGXSr7m2NmEK6ITIAWMtIaA0= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil/v3 v3.22.2/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= @@ -823,26 +1653,35 @@ github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= +github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sivchari/tenv v1.4.7 h1:FdTpgRlTue5eb5nXIYgS/lyVXSjugU8UUVDwhP1NLU8= +github.com/sivchari/tenv v1.4.7/go.mod h1:5nF+bITvkebQVanjU6IuMbvIot/7ReNsUV7I5NbprB0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= -github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= -github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= @@ -850,68 +1689,107 @@ github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= -github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= +github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= +github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk= +github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/sylvia7788/contextcheck v1.0.4 h1:MsiVqROAdr0efZc/fOCt0c235qm9XJqHtWwM+2h2B04= +github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2 h1:Xr9gkxfOP0KQWXKNqmwe8vEeSUiUj4Rlee9CMVX2ZUQ= -github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tetafro/godot v0.3.3 h1:uJjg8N+Ee10rAnaqJGet1WeI0YW4fiX9pKbwqnsqH6k= -github.com/tetafro/godot v0.3.3/go.mod h1:pT6/T8+h6//L/LwQcFc4C0xpfy1euZwzS1sHdrFCms0= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= +github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= +github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= +github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= +github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa h1:RC4maTWLKKwb7p1cnoygsbKIgNlJqSYBeAFON3Ar8As= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomarrell/wrapcheck/v2 v2.5.0 h1:g27SGGHNoQdvHz4KZA9o4v09RcWzylR+b1yueE5ECiw= +github.com/tomarrell/wrapcheck/v2 v2.5.0/go.mod h1:68bQ/eJg55BROaRTbMjC7vuhL2OgfoG8bLp9ZyoBfyY= +github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= +github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= +github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo= -github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= -github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= +github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= -github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4= +github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= -github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= +github.com/warpfork/go-testmark v0.3.0 h1:Q81c4u7hT+BR5kNfNQhEF0VT2pmL7+Kk0wD+ORYl7iA= +github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor-gen v0.0.0-20200123233031-1cdf64d27158/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= -github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105 h1:Sh6UG5dW5xW8Ek2CtRGq4ipdEvvx9hOyBJjEGyTYDl0= -github.com/whyrusleeping/cbor-gen v0.0.0-20200402171437-3d27c146c105/go.mod h1:Xj/M2wWU+QdTdRbu/L/1dIZY8/Wb2K9pAhtroQuxJJI= +github.com/whyrusleeping/cbor-gen v0.0.0-20200710004633-5379fc63235d/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= +github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 h1:bsUlNhdmbtlfdLVXAVfuvKQ01RnWAM09TVrJkI7NZs4= +github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95/go.mod h1:SJqKCCPXRfBFCwXjfNT/skfsceF7+MBFLI2OrvuRA7g= @@ -927,36 +1805,86 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go. github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= +github.com/yeya24/promlinter v0.1.1-0.20210918184747-d757024714a1 h1:YAaOqqMTstELMMGblt6yJ/fcOt4owSYuw3IttMnKfAM= +github.com/yeya24/promlinter v0.1.1-0.20210918184747-d757024714a1/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +gitlab.com/bosi/decorder v0.2.1 h1:ehqZe8hI4w7O4b1vgsDZw1YU1PE7iJXrQWFMsocbQ1w= +gitlab.com/bosi/decorder v0.2.1/go.mod h1:6C/nhLSbF6qZbYD8bRmISBwc6vcWdNsiIBkRvjJFrH0= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= +go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -968,189 +1896,640 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU= -golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200228224639-71482053b885/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e h1:3Dzrrxi54Io7Aoyb0PYLsI47K2TxkRQg+cqUn+m04do= golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/gotestsum v0.4.2 h1:QOdtb6bnnPUuHKkR9+/QQa8e6qjpTTP7cDi7G9/10C4= gotest.tools/gotestsum v0.4.2/go.mod h1:a32lmn/7xfm0+QHj8K5NyQY1NNNNhZoAp+/OHkLs77Y= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= @@ -1159,16 +2538,28 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.2.2 h1:MNh1AVMyVX23VUHE2O27jm6lNj3vjO5DexS4A1xvnzk= +honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= +lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +mvdan.cc/gofumpt v0.3.0 h1:kTojdZo9AcEYbQYhGuLf/zszYthRdhDNDUi2JKTxas4= +mvdan.cc/gofumpt v0.3.0/go.mod h1:0+VyGZWleeIj5oostkOex+nDBA0eyavuDnDusAJ8ylo= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= -mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= +mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 h1:Jh3LAeMt1eGpxomyu3jVkmVZWW2MxZ1qIIV2TZ/nRio= +mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5/go.mod h1:b8RRCBm0eeiWR8cfN88xeq2G5SG3VKGO+5UPWi5FSOY= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/test/dependencies/graphsync-get/graphsync-get.go b/test/dependencies/graphsync-get/graphsync-get.go index e15522116f2..169647260ca 100644 --- a/test/dependencies/graphsync-get/graphsync-get.go +++ b/test/dependencies/graphsync-get/graphsync-get.go @@ -11,7 +11,7 @@ import ( "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" - "github.com/ipfs/go-graphsync" + graphsync "github.com/ipfs/go-graphsync" gsimpl "github.com/ipfs/go-graphsync/impl" "github.com/ipfs/go-graphsync/network" "github.com/ipfs/go-graphsync/storeutil" @@ -21,7 +21,7 @@ import ( uio "github.com/ipfs/go-unixfs/io" "github.com/ipld/go-ipld-prime" cidlink "github.com/ipld/go-ipld-prime/linking/cid" - basicnode "github.com/ipld/go-ipld-prime/node/basic" + basicnode "github.com/ipld/go-ipld-prime/node/basicnode" ipldselector "github.com/ipld/go-ipld-prime/traversal/selector" "github.com/ipld/go-ipld-prime/traversal/selector/builder" "github.com/libp2p/go-libp2p" @@ -34,13 +34,12 @@ func newGraphsync(ctx context.Context, p2p host.Host, bs blockstore.Blockstore) network := network.NewFromLibp2pHost(p2p) return gsimpl.New(ctx, network, - storeutil.LoaderForBlockstore(bs), - storeutil.StorerForBlockstore(bs), + storeutil.LinkSystemForBlockstore(bs), ), nil } var selectAll ipld.Node = func() ipld.Node { - ssb := builder.NewSelectorSpecBuilder(basicnode.Style.Any) + ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any) return ssb.ExploreRecursive( ipldselector.RecursionLimitDepth(100), // default max ssb.ExploreAll(ssb.ExploreRecursiveEdge()), @@ -90,13 +89,14 @@ func main() { log.Fatalf("failed to decode CID '%q': %s", os.Args[2], err) } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - p2p, err := libp2p.New(ctx, libp2p.NoListenAddrs) + p2p, err := libp2p.New(libp2p.NoListenAddrs) if err != nil { log.Fatal(err) } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = p2p.Connect(ctx, *ai) if err != nil { log.Fatal(err) diff --git a/test/dependencies/ma-pipe-unidir/main.go b/test/dependencies/ma-pipe-unidir/main.go index db77f5fbae4..3cf10b4de17 100644 --- a/test/dependencies/ma-pipe-unidir/main.go +++ b/test/dependencies/ma-pipe-unidir/main.go @@ -9,7 +9,7 @@ import ( "strconv" ma "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr-net" + manet "github.com/multiformats/go-multiaddr/net" ) const USAGE = "ma-pipe-unidir [-l|--listen] [--pidFile=path] [-h|--help] \n" diff --git a/test/dependencies/pollEndpoint/main.go b/test/dependencies/pollEndpoint/main.go index 7eadcd3f702..0c548d8c9f2 100644 --- a/test/dependencies/pollEndpoint/main.go +++ b/test/dependencies/pollEndpoint/main.go @@ -2,19 +2,25 @@ package main import ( + "context" "flag" + "io" + "net" + "net/http" "os" "time" logging "github.com/ipfs/go-log" ma "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr-net" + manet "github.com/multiformats/go-multiaddr/net" ) var ( host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on") tries = flag.Int("tries", 10, "how many tries to make before failing") timeout = flag.Duration("tout", time.Second, "how long to wait between attempts") + httpURL = flag.String("http-url", "", "HTTP URL to fetch") + httpOut = flag.Bool("http-out", false, "Print the HTTP response body to stdout") verbose = flag.Bool("v", false, "verbose logging") ) @@ -37,18 +43,76 @@ func main() { start := time.Now() log.Debugf("starting at %s, tries: %d, timeout: %s, addr: %s", start, *tries, *timeout, addr) - for *tries > 0 { + connTries := *tries + for connTries > 0 { c, err := manet.Dial(addr) if err == nil { log.Debugf("ok - endpoint reachable with %d tries remaining, took %s", *tries, time.Since(start)) c.Close() - os.Exit(0) + break } log.Debug("connect failed: ", err) time.Sleep(*timeout) - *tries-- + connTries-- } - log.Error("failed.") + if err != nil { + goto Fail + } + + if *httpURL != "" { + dialer := &connDialer{addr: addr} + httpClient := http.Client{Transport: &http.Transport{ + DialContext: dialer.DialContext, + }} + reqTries := *tries + for reqTries > 0 { + try := (*tries - reqTries) + 1 + log.Debugf("trying HTTP req %d: '%s'", try, *httpURL) + if tryHTTPGet(&httpClient, *httpURL) { + log.Debugf("HTTP req %d to '%s' succeeded", try, *httpURL) + goto Success + } + log.Debugf("HTTP req %d to '%s' failed", try, *httpURL) + time.Sleep(*timeout) + reqTries-- + } + goto Fail + } + +Success: + os.Exit(0) + +Fail: + log.Error("failed") os.Exit(1) } + +func tryHTTPGet(client *http.Client, url string) bool { + resp, err := client.Get(*httpURL) + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } + if err != nil { + return false + } + if resp.StatusCode != http.StatusOK { + return false + } + if *httpOut { + _, err := io.Copy(os.Stdout, resp.Body) + if err != nil { + panic(err) + } + } + + return true +} + +type connDialer struct { + addr ma.Multiaddr +} + +func (d connDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + return (&manet.Dialer{}).DialContext(ctx, d.addr) +} diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index eebc1f63f76..f564ee5ee3e 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -18,8 +18,8 @@ import ( mock "github.com/ipfs/go-ipfs/core/mock" "github.com/ipfs/go-ipfs/thirdparty/unit" logging "github.com/ipfs/go-log" - random "github.com/jbenet/go-random" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/jbenet/go-random" + "github.com/libp2p/go-libp2p-core/peer" testutil "github.com/libp2p/go-libp2p-testing/net" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -97,7 +97,7 @@ func DirectAddCat(data []byte, conf testutil.LatencyConfig) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, // TODO add to conf. This is tricky because we want 0 values to be functional. diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index 6115b5b54dd..45b3b9f3e28 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -14,7 +14,7 @@ import ( "github.com/ipfs/go-ipfs/core/coreapi" mock "github.com/ipfs/go-ipfs/core/mock" "github.com/ipfs/go-ipfs/thirdparty/unit" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" testutil "github.com/libp2p/go-libp2p-testing/net" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -40,7 +40,7 @@ func benchCat(b *testing.B, data []byte, conf testutil.LatencyConfig) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, // TODO add to conf. This is tricky because we want 0 values to be functional. diff --git a/test/integration/bitswap_wo_routing_test.go b/test/integration/bitswap_wo_routing_test.go index ec0c2f11a83..9caa78c38c5 100644 --- a/test/integration/bitswap_wo_routing_test.go +++ b/test/integration/bitswap_wo_routing_test.go @@ -19,7 +19,7 @@ func TestBitswapWithoutRouting(t *testing.T) { const numPeers = 4 // create network - mn := mocknet.New(ctx) + mn := mocknet.New() var nodes []*core.IpfsNode for i := 0; i < numPeers; i++ { diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index eb82d00083a..009d1af32d6 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -15,7 +15,7 @@ import ( "github.com/ipfs/go-ipfs/thirdparty/unit" files "github.com/ipfs/go-ipfs-files" - peer "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/peer" testutil "github.com/libp2p/go-libp2p-testing/net" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ) @@ -68,7 +68,7 @@ func RunThreeLeggedCat(data []byte, conf testutil.LatencyConfig) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, // TODO add to conf. This is tricky because we want 0 values to be functional. diff --git a/test/integration/wan_lan_dht_test.go b/test/integration/wan_lan_dht_test.go index da2468d5a1e..44305e05174 100644 --- a/test/integration/wan_lan_dht_test.go +++ b/test/integration/wan_lan_dht_test.go @@ -72,7 +72,7 @@ func RunDHTConnectivity(conf testutil.LatencyConfig, numPeers int) error { defer cancel() // create network - mn := mocknet.New(ctx) + mn := mocknet.New() mn.SetLinkDefaults(mocknet.LinkOptions{ Latency: conf.NetworkLatency, Bandwidth: math.MaxInt32, @@ -209,9 +209,9 @@ WanStartupWait: for { select { case err := <-testPeer.DHT.WAN.RefreshRoutingTable(): - //if err != nil { + // if err != nil { // fmt.Printf("Error refreshing routing table: %v\n", err) - //} + // } if testPeer.DHT.WAN.RoutingTable() == nil || testPeer.DHT.WAN.RoutingTable().Size() == 0 || err != nil { diff --git a/test/ipfs-test-lib.sh b/test/ipfs-test-lib.sh index 38c62d33177..eabf17020d2 100644 --- a/test/ipfs-test-lib.sh +++ b/test/ipfs-test-lib.sh @@ -62,12 +62,7 @@ docker_run() { # This takes a docker ID and a command as arguments docker_exec() { - if test "$CIRCLE" = 1 - then - sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' $1)" -- /bin/bash -c "$2" - else - docker exec -t "$1" /bin/bash -c "$2" - fi + docker exec -t "$1" /bin/sh -c "$2" } # This takes a docker ID as argument @@ -75,6 +70,16 @@ docker_stop() { docker stop "$1" } +# This takes a docker ID as argument +docker_rm() { + docker rm -f -v "$1" > /dev/null +} + +# This takes a docker image name as argument +docker_rmi() { + docker rmi -f "$1" > /dev/null +} + # Test whether all the expected lines are included in a file. The file # can have extra lines. # diff --git a/test/sharness/.gitignore b/test/sharness/.gitignore index 06ceccc7567..c7ab08146c5 100644 --- a/test/sharness/.gitignore +++ b/test/sharness/.gitignore @@ -2,3 +2,4 @@ lib/sharness/ test-results/ trash directory.*.sh/ plugins +*.DS_Store diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index a68c5d9737b..0757c323cf9 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -388,6 +388,15 @@ test_should_contain() { fi } +test_should_not_contain() { + test "$#" = 2 || error "bug in the test script: not 2 parameters to test_should_not_contain" + if grep -q "$1" "$2" + then + echo "'$2' contains undesired value '$1'" + return 1 + fi +} + test_str_contains() { find=$1 shift @@ -520,3 +529,16 @@ findprovs_expect() { test_cmp findprovsOut expected ' } + +purge_blockstore() { + ipfs pin ls --quiet --type=recursive | ipfs pin rm &>/dev/null + ipfs repo gc --silent &>/dev/null + + test_expect_success "pinlist empty" ' + [[ -z "$( ipfs pin ls )" ]] + ' + test_expect_success "nothing left to gc" ' + [[ -z "$( ipfs repo gc )" ]] + ' +} + diff --git a/test/sharness/t0020-init.sh b/test/sharness/t0020-init.sh index 55ae34eadb9..c1eb209a84c 100755 --- a/test/sharness/t0020-init.sh +++ b/test/sharness/t0020-init.sh @@ -8,23 +8,23 @@ test_description="Test init command" . lib/test-lib.sh -# test that ipfs fails to init if IPFS_PATH isn't writeable +# test that ipfs fails to init with BAD_IPFS_DIR that isn't writeable test_expect_success "create dir and change perms succeeds" ' - export IPFS_PATH="$(pwd)/.badipfs" && - mkdir "$IPFS_PATH" && - chmod 000 "$IPFS_PATH" + export BAD_IPFS_DIR="$(pwd)/.badipfs" && + mkdir "$BAD_IPFS_DIR" && + chmod 000 "$BAD_IPFS_DIR" ' test_expect_success "ipfs init fails" ' - test_must_fail ipfs init 2> init_fail_out + test_must_fail ipfs init --repo-dir "$BAD_IPFS_DIR" 2> init_fail_out ' # Under Windows/Cygwin the error message is different, # so we use the STD_ERR_MSG prereq. if test_have_prereq STD_ERR_MSG; then - init_err_msg="Error: error loading plugins: open $IPFS_PATH/config: permission denied" + init_err_msg="Error: error loading plugins: open $BAD_IPFS_DIR/config: permission denied" else - init_err_msg="Error: error loading plugins: open $IPFS_PATH/config: The system cannot find the path specified." + init_err_msg="Error: error loading plugins: open $BAD_IPFS_DIR/config: The system cannot find the path specified." fi test_expect_success "ipfs init output looks good" ' @@ -33,19 +33,19 @@ test_expect_success "ipfs init output looks good" ' ' test_expect_success "cleanup dir with bad perms" ' - chmod 775 "$IPFS_PATH" && - rmdir "$IPFS_PATH" + chmod 775 "$BAD_IPFS_DIR" && + rmdir "$BAD_IPFS_DIR" ' # test no repo error message # this applies to `ipfs add sth`, `ipfs refs ` test_expect_success "ipfs cat fails" ' - export IPFS_PATH="$(pwd)/.ipfs" && - test_must_fail ipfs cat Qmaa4Rw81a3a1VEx4LxB7HADUAXvZFhCoRdBzsMZyZmqHD 2> cat_fail_out + export IPFS_DIR="$(pwd)/.ipfs" && + test_must_fail ipfs cat --repo-dir "$IPFS_DIR" Qmaa4Rw81a3a1VEx4LxB7HADUAXvZFhCoRdBzsMZyZmqHD 2> cat_fail_out ' test_expect_success "ipfs cat no repo message looks good" ' - echo "Error: no IPFS repo found in $IPFS_PATH." > cat_fail_exp && + echo "Error: no IPFS repo found in $IPFS_DIR." > cat_fail_exp && echo "please run: '"'"'ipfs init'"'"'" >> cat_fail_exp && test_path_cmp cat_fail_exp cat_fail_out ' @@ -56,39 +56,39 @@ test_ipfs_init_flags() { # test that init succeeds test_expect_success "ipfs init succeeds" ' - export IPFS_PATH="$(pwd)/.ipfs" && - echo "IPFS_PATH: \"$IPFS_PATH\"" && + export IPFS_DIR="$(pwd)/.ipfs" && + echo "IPFS_DIR: \"$IPFS_DIR\"" && RSA_BITS="2048" && case $TEST_ALG in "rsa") - ipfs init --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init + ipfs init --repo-dir "$IPFS_DIR" --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init ;; "ed25519") - ipfs init --algorithm=ed25519 >actual_init || test_fsh cat actual_init + ipfs init --repo-dir "$IPFS_DIR" --algorithm=ed25519 >actual_init || test_fsh cat actual_init ;; *) - ipfs init --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init + ipfs init --repo-dir "$IPFS_DIR" --algorithm=rsa --bits="$RSA_BITS" >actual_init || test_fsh cat actual_init ;; esac ' test_expect_success ".ipfs/ has been created" ' - test -d ".ipfs" && - test -f ".ipfs/config" && - test -d ".ipfs/datastore" && - test -d ".ipfs/blocks" && + test -d "$IPFS_DIR" && + test -f "$IPFS_DIR/config" && + test -d "$IPFS_DIR/datastore" && + test -d "$IPFS_DIR/blocks" && test ! -f ._check_writeable || - test_fsh ls -al .ipfs + test_fsh ls -al $IPFS_DIR ' test_expect_success "ipfs config succeeds" ' echo /ipfs >expected_config && - ipfs config Mounts.IPFS >actual_config && + ipfs config --repo-dir "$IPFS_DIR" Mounts.IPFS >actual_config && test_cmp expected_config actual_config ' test_expect_success "ipfs peer id looks good" ' - PEERID=$(ipfs config Identity.PeerID) && + PEERID=$(ipfs config --repo-dir "$IPFS_DIR" Identity.PeerID) && test_check_peerid "$PEERID" ' @@ -97,13 +97,13 @@ test_ipfs_init_flags() { echo "generating $RSA_BITS-bit RSA keypair...done" >rsa_expected && echo "peer identity: $PEERID" >>rsa_expected && - echo "initializing IPFS node at $IPFS_PATH" >>rsa_expected && + echo "initializing IPFS node at $IPFS_DIR" >>rsa_expected && echo "to get started, enter:" >>rsa_expected && printf "\\n\\t$STARTFILE\\n\\n" >>rsa_expected && echo "generating ED25519 keypair...done" >ed25519_expected && echo "peer identity: $PEERID" >>ed25519_expected && - echo "initializing IPFS node at $IPFS_PATH" >>ed25519_expected && + echo "initializing IPFS node at $IPFS_DIR" >>ed25519_expected && echo "to get started, enter:" >>ed25519_expected && printf "\\n\\t$STARTFILE\\n\\n" >>ed25519_expected && @@ -125,26 +125,26 @@ test_ipfs_init_flags() { ' test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" + rm -rf "$IPFS_DIR" ' test_expect_success "'ipfs init --empty-repo' succeeds" ' RSA_BITS="2048" && case $TEST_ALG in rsa) - ipfs init --algorithm=rsa --bits="$RSA_BITS" --empty-repo >actual_init + ipfs init --repo-dir "$IPFS_DIR" --algorithm=rsa --bits="$RSA_BITS" --empty-repo >actual_init ;; ed25519) - ipfs init --algorithm=ed25519 --empty-repo >actual_init + ipfs init --repo-dir "$IPFS_DIR" --algorithm=ed25519 --empty-repo >actual_init ;; *) - ipfs init --empty-repo >actual_init + ipfs init --repo-dir "$IPFS_DIR" --empty-repo >actual_init ;; esac ' test_expect_success "ipfs peer id looks good" ' - PEERID=$(ipfs config Identity.PeerID) && + PEERID=$(ipfs config --repo-dir "$IPFS_DIR" Identity.PeerID) && test_check_peerid "$PEERID" ' @@ -152,11 +152,11 @@ test_ipfs_init_flags() { echo "generating $RSA_BITS-bit RSA keypair...done" >rsa_expected && echo "peer identity: $PEERID" >>rsa_expected && - echo "initializing IPFS node at $IPFS_PATH" >>rsa_expected && + echo "initializing IPFS node at $IPFS_DIR" >>rsa_expected && echo "generating ED25519 keypair...done" >ed25519_expected && echo "peer identity: $PEERID" >>ed25519_expected && - echo "initializing IPFS node at $IPFS_PATH" >>ed25519_expected && + echo "initializing IPFS node at $IPFS_DIR" >>ed25519_expected && case $TEST_ALG in rsa) @@ -180,7 +180,7 @@ test_ipfs_init_flags() { ' test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" + rm -rf "$IPFS_DIR" ' } test_ipfs_init_flags 'ed25519' @@ -190,70 +190,70 @@ test_ipfs_init_flags '' # test init profiles test_expect_success "'ipfs init --profile' with invalid profile fails" ' RSA_BITS="2048" && - test_must_fail ipfs init --profile=nonexistent_profile 2> invalid_profile_out + test_must_fail ipfs init --repo-dir "$IPFS_DIR" --profile=nonexistent_profile 2> invalid_profile_out EXPECT="Error: invalid configuration profile: nonexistent_profile" && grep "$EXPECT" invalid_profile_out ' test_expect_success "'ipfs init --profile' succeeds" ' RSA_BITS="2048" && - ipfs init --profile=server + ipfs init --repo-dir "$IPFS_DIR" --profile=server ' test_expect_success "'ipfs config Swarm.AddrFilters' looks good" ' - ipfs config Swarm.AddrFilters > actual_config && + ipfs config --repo-dir "$IPFS_DIR" Swarm.AddrFilters > actual_config && test $(cat actual_config | wc -l) = 18 ' test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" + rm -rf "$IPFS_DIR" ' test_expect_success "'ipfs init --profile=test' succeeds" ' RSA_BITS="2048" && - ipfs init --profile=test + ipfs init --repo-dir "$IPFS_DIR" --profile=test ' test_expect_success "'ipfs config Bootstrap' looks good" ' - ipfs config Bootstrap > actual_config && + ipfs config --repo-dir "$IPFS_DIR" Bootstrap > actual_config && test $(cat actual_config) = "[]" ' test_expect_success "'ipfs config Addresses.API' looks good" ' - ipfs config Addresses.API > actual_config && + ipfs config --repo-dir "$IPFS_DIR" Addresses.API > actual_config && test $(cat actual_config) = "/ip4/127.0.0.1/tcp/0" ' test_expect_success "ipfs init from existing config succeeds" ' - export ORIG_PATH=$IPFS_PATH - export IPFS_PATH=$(pwd)/.ipfs-clone + export ORIG_PATH=$IPFS_DIR + export IPFS_DIR=$(pwd)/.ipfs-clone - ipfs init "$ORIG_PATH/config" && - ipfs config Addresses.API > actual_config && + ipfs init --repo-dir "$IPFS_DIR" "$ORIG_PATH/config" && + ipfs config --repo-dir "$IPFS_DIR" Addresses.API > actual_config && test $(cat actual_config) = "/ip4/127.0.0.1/tcp/0" ' -test_expect_success "clean up ipfs clone dir and reset IPFS_PATH" ' - rm -rf "$IPFS_PATH" && - export IPFS_PATH=$ORIG_PATH +test_expect_success "clean up ipfs clone dir and reset IPFS_DIR" ' + rm -rf "$IPFS_DIR" && + export IPFS_DIR=$ORIG_PATH ' test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" + rm -rf "$IPFS_DIR" ' test_expect_success "'ipfs init --profile=lowpower' succeeds" ' RSA_BITS="2048" && - ipfs init --profile=lowpower + ipfs init --repo-dir "$IPFS_DIR" --profile=lowpower ' test_expect_success "'ipfs config Discovery.Routing' looks good" ' - ipfs config Routing.Type > actual_config && + ipfs config --repo-dir "$IPFS_DIR" Routing.Type > actual_config && test $(cat actual_config) = "dhtclient" ' test_expect_success "clean up ipfs dir" ' - rm -rf "$IPFS_PATH" + rm -rf "$IPFS_DIR" ' test_init_ipfs @@ -261,7 +261,7 @@ test_init_ipfs test_launch_ipfs_daemon test_expect_success "ipfs init should not run while daemon is running" ' - test_must_fail ipfs init 2> daemon_running_err && + test_must_fail ipfs init --repo-dir "$IPFS_DIR" 2> daemon_running_err && EXPECT="Error: ipfs daemon is running. please stop it to run this command" && grep "$EXPECT" daemon_running_err ' diff --git a/test/sharness/t0021-config.sh b/test/sharness/t0021-config.sh index ee0e81988dd..5264908c73f 100755 --- a/test/sharness/t0021-config.sh +++ b/test/sharness/t0021-config.sh @@ -110,6 +110,13 @@ test_config_cmd() { grep "\"beep3\": false," actual ' + test_expect_success "'ipfs config show --config-file' works" ' + mv "$IPFS_PATH/config" "$IPFS_PATH/config-moved" && + ipfs config --config-file "$IPFS_PATH/config-moved" show >moved && + test_cmp moved actual && + mv "$IPFS_PATH/config-moved" "$IPFS_PATH/config" + ' + test_expect_success "setup for config replace test" ' cp "$IPFS_PATH/config" newconfig.json && sed -i"~" -e /PrivKey/d -e s/10GB/11GB/ newconfig.json && diff --git a/test/sharness/t0026-id.sh b/test/sharness/t0026-id.sh index 8e02fac3711..6f37120e059 100755 --- a/test/sharness/t0026-id.sh +++ b/test/sharness/t0026-id.sh @@ -48,10 +48,17 @@ test_expect_success "checking ProtocolVersion" ' test_cmp expected-protocol-version actual-protocol-version ' -test_expect_success "checking ID" ' +test_expect_success "checking ID of self" ' ipfs config Identity.PeerID > expected-id && ipfs id -f "\n" > actual-id && test_cmp expected-id actual-id ' +test_expect_success "checking and converting ID of a random peer while offline" ' + # Peer ID taken from `t0140-swarm.sh` test. + echo k2k4r8ncs1yoluq95unsd7x2vfhgve0ncjoggwqx9vyh3vl8warrcp15 > expected-id && + ipfs id -f "\n" --peerid-base base36 --offline QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N > actual-id && + test_cmp expected-id actual-id +' + test_done diff --git a/test/sharness/t0040-add-and-cat.sh b/test/sharness/t0040-add-and-cat.sh index 635b97453a9..833d6043e2e 100755 --- a/test/sharness/t0040-add-and-cat.sh +++ b/test/sharness/t0040-add-and-cat.sh @@ -345,6 +345,23 @@ test_add_cat_file() { echo "added Qmf35k66MZNW2GijohUmXQEWKZU4cCGTCwK6idfnt152wJ hello2.txt" >> expected && test_cmp expected actual ' + + test_expect_success "ipfs add with multiple files of same name and import dir succeeds" ' + ipfs add mountdir/hello.txt mountdir/hello.txt >actual + ' + + test_expect_success "ipfs add with multiple files of same name output looks good" ' + echo "added QmVr26fY1tKyspEJBniVhqxQeEjhF78XerGiqWAwraVLQH hello.txt" >expected && + test_cmp expected actual + ' + + test_must_fail "ipfs add with multiple files of same name but different dirs fails" ' + mkdir -p mountdir/same-file/ && + cp mountdir/hello.txt mountdir/same-file/hello.txt && + ipfs add mountdir/hello.txt mountdir/same-file/hello.txt >actual && + rm mountdir/same-file/hello.txt && + rmdir mountdir/same-file + ' } test_add_cat_5MB() { diff --git a/test/sharness/t0050-block.sh b/test/sharness/t0050-block.sh index 70639f623e9..9ecf2087596 100755 --- a/test/sharness/t0050-block.sh +++ b/test/sharness/t0050-block.sh @@ -10,16 +10,18 @@ test_description="Test block command" test_init_ipfs -HASH="QmRKqGMAM6EZngbpjSqrvYzq5Qd8b1bSWymjSUY9zQSNDk" -HASHB="QmdnpnsaEj69isdw5sNzp3h3HkaDz7xKq7BmvFFBzNr5e7" +HASH="bafkreibmlvvgdyihetgocpof6xk64kjjzdeq2e4c7hqs3krdheosk4tgj4" +HASHB="bafkreihfsphazrk2ilejpekyltjeh5k4yvwgjuwg26ueafohqioeo3sdca" + +HASHV0="QmRKqGMAM6EZngbpjSqrvYzq5Qd8b1bSWymjSUY9zQSNDk" +HASHBV0="QmdnpnsaEj69isdw5sNzp3h3HkaDz7xKq7BmvFFBzNr5e7" -# # "block put tests" # test_expect_success "'ipfs block put' succeeds" ' echo "Hello Mars!" >expected_in && - ipfs block put actual_out + ipfs block put a && echo "Hello Venus!" > b && - ipfs block put a b >actual_out + ipfs block put a b | tee actual_out ' test_expect_success "'ipfs block put' output looks good" ' @@ -39,6 +41,15 @@ test_expect_success "'ipfs block put' output looks good" ' test_cmp expected_out actual_out ' +test_expect_success "can set cid codec on block put" ' + CODEC_HASH=$(ipfs block put --cid-codec=dag-pb ../t0051-object-data/testPut.pb) +' + +test_expect_success "block get output looks right" ' + ipfs block get $CODEC_HASH > pb_block_out && + test_cmp pb_block_out ../t0051-object-data/testPut.pb +' + # # "block get" tests # @@ -134,9 +145,9 @@ test_expect_success "multi-block 'ipfs block rm '" ' ' test_expect_success "multi-block 'ipfs block rm ' output looks good" ' - echo "cannot remove $RANDOMHASH: blockstore: block not found" >> expect_mixed_rm && + echo "cannot remove $RANDOMHASH: ipld: could not find $RANDOMHASH" >> expect_mixed_rm && echo "removed $TESTHASH" >> expect_mixed_rm && - echo "cannot remove $RANDOMHASH: blockstore: block not found" >> expect_mixed_rm && + echo "cannot remove $RANDOMHASH: ipld: could not find $RANDOMHASH" >> expect_mixed_rm && echo "Error: some blocks not removed" >> expect_mixed_rm test_cmp actual_mixed_rm expect_mixed_rm ' @@ -196,7 +207,9 @@ test_expect_success "multi-block 'ipfs block rm -q' produces no output" ' test ! -s block_rm_out ' -test_expect_success "can set cid format on block put" ' +# --format used 'protobuf' for 'dag-pb' which was invalid, but we keep +# for backward-compatibility +test_expect_success "can set deprecated --format=protobuf on block put" ' HASH=$(ipfs block put --format=protobuf ../t0051-object-data/testPut.pb) ' @@ -211,7 +224,22 @@ test_expect_success "block get output looks right" ' test_cmp pb_block_out ../t0051-object-data/testPut.pb ' -test_expect_success "can set multihash type and length on block put" ' +test_expect_success "can set --cid-codec=dag-pb on block put" ' + HASH=$(ipfs block put --cid-codec=dag-pb ../t0051-object-data/testPut.pb) +' + +test_expect_success "created an object correctly!" ' + ipfs object get $HASH > obj_out && + echo "{\"Links\":[],\"Data\":\"test json for sharness test\"}" > obj_exp && + test_cmp obj_out obj_exp +' + +test_expect_success "block get output looks right" ' + ipfs block get $HASH > pb_block_out && + test_cmp pb_block_out ../t0051-object-data/testPut.pb +' + +test_expect_success "can set multihash type and length on block put with --format=raw (deprecated)" ' HASH=$(echo "foooo" | ipfs block put --format=raw --mhtype=sha3 --mhlen=20) ' @@ -219,6 +247,11 @@ test_expect_success "output looks good" ' test "bafkrifctrq4xazzixy2v4ezymjcvzpskqdwlxra" = "$HASH" ' +test_expect_success "can't use both legacy format and custom cid-codec at the same time" ' + test_expect_code 1 ipfs block put --format=dag-cbor --cid-codec=dag-json < ../t0051-object-data/testPut.pb 2> output && + test_should_contain "unable to use \"format\" (deprecated) and a custom \"cid-codec\" at the same time" output +' + test_expect_success "can read block with different hash" ' ipfs block get $HASH > blk_get_out && echo "foooo" > blk_get_exp && @@ -232,14 +265,23 @@ test_expect_success "'ipfs block stat' with nothing from stdin doesn't crash" ' test_expect_code 1 ipfs block stat < /dev/null 2> stat_out ' +# lol test_expect_success "no panic in output" ' test_expect_code 1 grep "panic" stat_out ' -test_expect_success "can set multihash type and length on block put without format" ' +test_expect_success "can set multihash type and length on block put without format or cid-codec" ' HASH=$(echo "foooo" | ipfs block put --mhtype=sha3 --mhlen=20) ' +test_expect_success "output looks good" ' + test "bafkrifctrq4xazzixy2v4ezymjcvzpskqdwlxra" = "$HASH" +' + +test_expect_success "can set multihash type and length on block put with cid-codec=dag-pb" ' + HASH=$(echo "foooo" | ipfs block put --mhtype=sha3 --mhlen=20 --cid-codec=dag-pb) +' + test_expect_success "output looks good" ' test "bafybifctrq4xazzixy2v4ezymjcvzpskqdwlxra" = "$HASH" ' @@ -248,4 +290,18 @@ test_expect_success "put with sha3 and cidv0 fails" ' echo "foooo" | test_must_fail ipfs block put --mhtype=sha3 --mhlen=20 --format=v0 ' +test_expect_success "'ipfs block put' check block size" ' + dd if=/dev/zero bs=2MB count=1 > 2-MB-file && + test_expect_code 1 ipfs block put 2-MB-file >block_put_out 2>&1 + ' + + test_expect_success "ipfs block put output has the correct error" ' + grep "produced block is over 1MiB" block_put_out + ' + + test_expect_success "ipfs block put --allow-big-block=true works" ' + test_expect_code 0 ipfs block put 2-MB-file --allow-big-block=true && + rm 2-MB-file + ' + test_done diff --git a/test/sharness/t0051-object.sh b/test/sharness/t0051-object.sh index 875548411b4..316c220abd5 100755 --- a/test/sharness/t0051-object.sh +++ b/test/sharness/t0051-object.sh @@ -229,12 +229,12 @@ test_object_cmd() { do DIR=$(ipfs object patch "$DIR" add-link "$DIR.jpg" "$DIR") done - # Fail when new block goes over the BS limit of 1MB, but allow manual override + # Fail when new block goes over the BS limit of 1MiB, but allow manual override test_expect_code 1 ipfs object patch "$DIR" add-link "$DIR.jpg" "$DIR" >patch_out 2>&1 ' test_expect_success "ipfs object patch add-link output has the correct error" ' - grep "produced block is over 1MB, object API is deprecated and does not support HAMT-sharding: to create big directories, please use the files API (MFS)" patch_out + grep "produced block is over 1MiB" patch_out ' test_expect_success "ipfs object patch --allow-big-block=true add-link works" ' diff --git a/test/sharness/t0053-dag.sh b/test/sharness/t0053-dag.sh index c46dcc8c19a..7514476be6e 100755 --- a/test/sharness/t0053-dag.sh +++ b/test/sharness/t0053-dag.sh @@ -44,6 +44,20 @@ test_dag_cmd() { test $EXPHASH = $IPLDHASH ' +test_expect_success "'ipfs dag put' check block size" ' + dd if=/dev/zero bs=2MB count=1 > 2-MB-file && + test_expect_code 1 ipfs dag put --input-codec=raw --store-codec=raw 2-MB-file >dag_put_out 2>&1 + ' + + test_expect_success "ipfs dag put output has the correct error" ' + grep "produced block is over 1MiB" dag_put_out + ' + + test_expect_success "ipfs dag put --allow-big-block=true works" ' + test_expect_code 0 ipfs dag put --input-codec=raw --store-codec=raw 2-MB-file --allow-big-block=true && + rm 2-MB-file + ' + test_expect_success "can add an ipld object using dag-json to dag-json" ' IPLDHASH=$(cat ipld_object | ipfs dag put --input-codec dag-json --store-codec dag-json) ' diff --git a/test/sharness/t0054-dag-car-import-export-data/README.md b/test/sharness/t0054-dag-car-import-export-data/README.md index 77679af390f..2b6b5c00f24 100644 --- a/test/sharness/t0054-dag-car-import-export-data/README.md +++ b/test/sharness/t0054-dag-car-import-export-data/README.md @@ -22,3 +22,7 @@ - combined_naked_roots_genesis_and_128.car - only the roots of `lotus_devnet_genesis.car` and `lotus_testnet_export_128.car`, to to be used in combination with the root-less parts to validate "transactional" pinning +- lotus_testnet_export_128_v2.car +- lotus_devnet_genesis_v2.car + - generated with `car index lotus_testnet_export_128.car > lotus_testnet_export_128_v2.car` + - install `go-car` CLI from https://github.com/ipld/go-car diff --git a/test/sharness/t0054-dag-car-import-export-data/test_dataset_car.tar.xz b/test/sharness/t0054-dag-car-import-export-data/test_dataset_car.tar.xz new file mode 100644 index 00000000000..f64f2411d65 Binary files /dev/null and b/test/sharness/t0054-dag-car-import-export-data/test_dataset_car.tar.xz differ diff --git a/test/sharness/t0054-dag-car-import-export-data/test_dataset_car_v0.tar.xz b/test/sharness/t0054-dag-car-import-export-data/test_dataset_car_v0.tar.xz deleted file mode 100644 index 34eb36dd1ca..00000000000 Binary files a/test/sharness/t0054-dag-car-import-export-data/test_dataset_car_v0.tar.xz and /dev/null differ diff --git a/test/sharness/t0054-dag-car-import-export.sh b/test/sharness/t0054-dag-car-import-export.sh index 311833748f0..6f32cf27775 100755 --- a/test/sharness/t0054-dag-car-import-export.sh +++ b/test/sharness/t0054-dag-car-import-export.sh @@ -8,7 +8,7 @@ export -f ipfsi set -o pipefail -tar -C ../t0054-dag-car-import-export-data/ --strip-components=1 -Jxf ../t0054-dag-car-import-export-data/test_dataset_car_v0.tar.xz +tar -C ../t0054-dag-car-import-export-data/ --strip-components=1 -Jxf ../t0054-dag-car-import-export-data/test_dataset_car.tar.xz tab=$'\t' test_cmp_sorted() { @@ -67,7 +67,7 @@ EOE # Explainer: # naked_root_import_json_expected output is produced by dag import of combined_naked_roots_genesis_and_128.car # executed when roots are already present in the repo - thus the BlockCount=0 - # (if blocks were not present in the repo, blockstore: block not found would be returned) + # (if blocks were not present in the repo, ipld: could not find would be returned) cat >naked_root_import_json_expected < offline_fetch_error_expected +echo "Error: block was not found locally (offline): ipld: could not find QmYwAPJXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (currently offline, perhaps retry after attaching to the network)" > offline_fetch_error_expected test_expect_success "basic offline export of nonexistent cid" ' ! ipfs dag export QmYwAPJXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2> offline_fetch_error_actual >/dev/null ' @@ -233,4 +233,34 @@ test_expect_success "naked root import expected output" ' test_cmp_sorted naked_root_import_json_expected naked_root_import_json_actual ' +test_expect_success "'ipfs dag import' check block size" ' + BIG_CID=$(dd if=/dev/zero bs=2MB count=1 | ipfs dag put --input-codec=raw --store-codec=raw --allow-big-block) && + ipfs dag export $BIG_CID > 2-MB-block.car && + test_expect_code 1 ipfs dag import 2-MB-block.car >dag_import_out 2>&1 +' +test_expect_success "ipfs dag import output has the correct error" ' + grep "block is over 1MiB" dag_import_out +' + +test_expect_success "ipfs dag import --allow-big-block works" ' + test_expect_code 0 ipfs dag import --allow-big-block 2-MB-block.car +' + +cat > version_2_import_expected << EOE +{"Root":{"Cid":{"/":"bafy2bzaceaxm23epjsmh75yvzcecsrbavlmkcxnva66bkdebdcnyw3bjrc74u"},"PinErrorMsg":""}} +{"Root":{"Cid":{"/":"bafy2bzaced4ueelaegfs5fqu4tzsh6ywbbpfk3cxppupmxfdhbpbhzawfw5oy"},"PinErrorMsg":""}} +{"Stats":{"BlockCount":1198,"BlockBytesCount":468513}} +EOE + +test_expect_success "version 2 import" ' + ipfs dag import --stats --enc=json \ + ../t0054-dag-car-import-export-data/lotus_testnet_export_128_v2.car \ + ../t0054-dag-car-import-export-data/lotus_devnet_genesis_v2.car \ + > version_2_import_actual +' + +test_expect_success "version 2 import output as expected" ' + test_cmp_sorted version_2_import_expected version_2_import_actual +' + test_done diff --git a/test/sharness/t0060-daemon.sh b/test/sharness/t0060-daemon.sh index e04060e45c8..d448e035b46 100755 --- a/test/sharness/t0060-daemon.sh +++ b/test/sharness/t0060-daemon.sh @@ -125,11 +125,26 @@ test_expect_success "ipfs help output looks good" ' test_fsh cat help.txt ' -# check transport is encrypted -test_expect_success SOCAT "transport should be encrypted ( needs socat )" ' - socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-ls && +# check transport is encrypted by default and no plaintext is allowed + +test_expect_success SOCAT "default transport should support encryption (TLS, needs socat )" ' + socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-tls && grep -q "/tls" swarmnc && - test_must_fail grep -q "/plaintext/1.0.0" swarmnc || + test_must_fail grep -q "na" swarmnc || + test_fsh cat swarmnc +' + +test_expect_success SOCAT "default transport should support encryption (Noise, needs socat )" ' + socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-noise && + grep -q "/noise" swarmnc && + test_must_fail grep -q "na" swarmnc || + test_fsh cat swarmnc +' + +test_expect_success SOCAT "default transport should not support plaintext (needs socat )" ' + socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-plaintext && + grep -q "na" swarmnc && + test_must_fail grep -q "/plaintext" swarmnc || test_fsh cat swarmnc ' diff --git a/test/sharness/t0060-data/mss-ls b/test/sharness/t0060-data/mss-noise similarity index 71% rename from test/sharness/t0060-data/mss-ls rename to test/sharness/t0060-data/mss-noise index ce39aa9990a..f9d349802e6 100644 --- a/test/sharness/t0060-data/mss-ls +++ b/test/sharness/t0060-data/mss-noise @@ -1,2 +1,2 @@ /multistream/1.0.0 -ls +/noise diff --git a/test/sharness/t0060-data/mss-plaintext b/test/sharness/t0060-data/mss-plaintext new file mode 100644 index 00000000000..e6057b493ef --- /dev/null +++ b/test/sharness/t0060-data/mss-plaintext @@ -0,0 +1,2 @@ +/multistream/1.0.0 +/plaintext/2.0.0 diff --git a/test/sharness/t0060-data/mss-tls b/test/sharness/t0060-data/mss-tls new file mode 100644 index 00000000000..92294bb5b01 --- /dev/null +++ b/test/sharness/t0060-data/mss-tls @@ -0,0 +1,2 @@ +/multistream/1.0.0 + /tls/1.0.0 diff --git a/test/sharness/t0061-daemon-opts.sh b/test/sharness/t0061-daemon-opts.sh index 108fe75abce..531d2d247a5 100755 --- a/test/sharness/t0061-daemon-opts.sh +++ b/test/sharness/t0061-daemon-opts.sh @@ -18,8 +18,9 @@ apiaddr=$API_ADDR # Odd. this fails here, but the inverse works on t0060-daemon. test_expect_success SOCAT 'transport should be unencrypted ( needs socat )' ' - socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-ls && - grep -q "/plaintext" swarmnc || + socat - tcp:localhost:$SWARM_PORT,connect-timeout=1 > swarmnc < ../t0060-data/mss-plaintext && + grep -q "/plaintext" swarmnc && + test_must_fail grep -q "na" swarmnc || test_fsh cat swarmnc ' diff --git a/test/sharness/t0080-repo.sh b/test/sharness/t0080-repo.sh index a6631b53cfc..2cdaac474b1 100755 --- a/test/sharness/t0080-repo.sh +++ b/test/sharness/t0080-repo.sh @@ -55,6 +55,17 @@ test_expect_success "ipfs repo gc fully reverse ipfs add (part 1)" ' ipfs pin rm -r $hash && ipfs repo gc ' +test_expect_success "'ipfs repo gc --silent' succeeds (no output)" ' + echo "should be empty" >bfile && + HASH2=`ipfs add -q bfile` && + ipfs cat "$HASH2" >expected11 && + test_cmp expected11 bfile && + ipfs pin rm -r "$HASH2" && + ipfs repo gc --silent >gc_out_empty && + test_cmp /dev/null gc_out_empty && + test_must_fail ipfs cat "$HASH2" 2>err_expected1 && + grep "Error: ipld: could not find $HASH2" err_expected1 +' test_kill_ipfs_daemon diff --git a/test/sharness/t0081-repo-pinning.sh b/test/sharness/t0081-repo-pinning.sh index 121051ee18a..030f3fa3d06 100755 --- a/test/sharness/t0081-repo-pinning.sh +++ b/test/sharness/t0081-repo-pinning.sh @@ -238,7 +238,7 @@ test_expect_success "some are no longer there" ' test_launch_ipfs_daemon_without_network test_expect_success "recursive pin fails without objects" ' test_must_fail ipfs pin add -r "$HASH_DIR1" 2>err_expected8 && - grep "pin: merkledag: not found" err_expected8 || + grep "ipld: could not find" err_expected8 || test_fsh cat err_expected8 ' diff --git a/test/sharness/t0085-pins.sh b/test/sharness/t0085-pins.sh index 90f3b0d8acd..c83c513682b 100755 --- a/test/sharness/t0085-pins.sh +++ b/test/sharness/t0085-pins.sh @@ -115,7 +115,7 @@ test_pins_error_reporting() { test_expect_success "'ipfs pin add $PIN_ARGS' on non-existent hash should fail" ' test_must_fail ipfs pin add $PIN_ARGS $RANDOM_HASH 2> err && - grep -q "not found" err + grep -q "ipld: could not find" err ' } @@ -147,7 +147,7 @@ test_pin_dag() { test_expect_success "pin file, should fail" ' test_must_fail ipfs pin add --recursive=true $HASH 2> err && cat err && - grep -q "not found" err + grep -q "ipld: could not find" err ' } diff --git a/test/sharness/t0087-repo-robust-gc.sh b/test/sharness/t0087-repo-robust-gc.sh index ca00d591ffc..884de5774e0 100755 --- a/test/sharness/t0087-repo-robust-gc.sh +++ b/test/sharness/t0087-repo-robust-gc.sh @@ -10,7 +10,7 @@ test_description="Test robustness of garbage collector" set -e to_raw_cid() { - ipfs cid format -b b --codec raw -v 1 "$1" + ipfs cid format -b b --mc raw -v 1 "$1" } test_gc_robust_part1() { @@ -73,7 +73,7 @@ test_gc_robust_part1() { grep -q "permission denied" block_rm_err ' - # repo gc outputs raw multihashes. We chech HASH1 with block stat rather than + # repo gc outputs raw multihashes. We check HASH1 with block stat rather than # grepping the output since it's not a raw multihash test_expect_success "'ipfs repo gc' should still run and remove as much as possible" ' test_must_fail ipfs repo gc 2>&1 | tee repo_gc_out && diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 276c90b2228..11220347819 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -163,6 +163,19 @@ test_expect_success "test failure conditions of mutex pprof endpoint" ' test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-mutex/?fraction=-1" ' +curl_pprofblock() { + curl -f -X POST "http://127.0.0.1:$apiport/debug/pprof-block/?rate=$1" +} + +test_expect_success "set blocking profiler rate for pprof (0 so it doesn't enable)" ' + curl_pprofblock 0 +' + +test_expect_success "test failure conditions of mutex block endpoint" ' + test_must_fail curl_pprofblock && + test_must_fail curl_pprofblock that_is_string && + test_must_fail curl -f -X GET "http://127.0.0.1:$apiport/debug/pprof-block/?rate=0" +' test_expect_success "setup index hash" ' mkdir index && @@ -249,7 +262,7 @@ test_expect_success "try fetching it from gateway" ' test_expect_success "Add compact blocks" ' ipfs block put ../t0110-gateway-data/foo.block && - FOO2_HASH=$(ipfs block put ../t0110-gateway-data/foofoo.block) && + FOO2_HASH=$(ipfs block put --cid-codec=dag-pb ../t0110-gateway-data/foofoo.block) && printf "foofoo" > expected ' diff --git a/test/sharness/t0112-gateway-cors.sh b/test/sharness/t0112-gateway-cors.sh index 9670b7ffa16..4bb2a509029 100755 --- a/test/sharness/t0112-gateway-cors.sh +++ b/test/sharness/t0112-gateway-cors.sh @@ -26,7 +26,10 @@ test_expect_success "GET response for Gateway resource looks good" ' grep "< Access-Control-Allow-Origin: \*" curl_output && grep "< Access-Control-Allow-Methods: GET" curl_output && grep "< Access-Control-Allow-Headers: Range" curl_output && - grep "< Access-Control-Expose-Headers: Content-Range" curl_output + grep "< Access-Control-Expose-Headers: Content-Range" curl_output && + grep "< Access-Control-Expose-Headers: Content-Length" curl_output && + grep "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && + grep "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output ' # HTTP OPTIONS Request @@ -40,7 +43,10 @@ test_expect_success "OPTIONS response for Gateway resource looks good" ' grep "< Access-Control-Allow-Origin: \*" curl_output && grep "< Access-Control-Allow-Methods: GET" curl_output && grep "< Access-Control-Allow-Headers: Range" curl_output && - grep "< Access-Control-Expose-Headers: Content-Range" curl_output + grep "< Access-Control-Expose-Headers: Content-Range" curl_output && + grep "< Access-Control-Expose-Headers: Content-Length" curl_output && + grep "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && + grep "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output ' test_kill_ipfs_daemon @@ -63,6 +69,9 @@ test_expect_success "Access-Control-Allow-Headers extends" ' grep "< Access-Control-Allow-Headers: Range" curl_output && grep "< Access-Control-Allow-Headers: X-Custom1" curl_output && grep "< Access-Control-Expose-Headers: Content-Range" curl_output && + grep "< Access-Control-Expose-Headers: Content-Length" curl_output && + grep "< Access-Control-Expose-Headers: X-Ipfs-Path" curl_output && + grep "< Access-Control-Expose-Headers: X-Ipfs-Roots" curl_output && grep "< Access-Control-Expose-Headers: X-Custom2" curl_output ' @@ -77,8 +86,8 @@ test_expect_success "GET to API succeeds" ' curl -svX GET "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" >/dev/null 2>curl_output ' # GET Response from the API should NOT contain CORS headers -# Blacklisting: https://git.io/vzaj2 -# Rationale: https://git.io/vzajX +# Blacklisting: https://github.com/ipfs/go-ipfs/blob/5d9ee59908099df3f7e85679f7384c98d4ac8111/commands/http/handler.go#L71-L82 +# Rationale: https://github.com/ipfs/go-ipfs/pull/1529#issuecomment-125702347 test_expect_success "OPTIONS response for API looks good" ' grep -q "Access-Control-Allow-" curl_output && false || true ' diff --git a/test/sharness/t0114-gateway-subdomains.sh b/test/sharness/t0114-gateway-subdomains.sh index 41abd4a8774..f9ab0d82427 100755 --- a/test/sharness/t0114-gateway-subdomains.sh +++ b/test/sharness/t0114-gateway-subdomains.sh @@ -116,7 +116,7 @@ test_expect_success "Add the test directory" ' test_expect_success "Publish test text file to IPNS using RSA keys" ' RSA_KEY=$(ipfs key gen --ipns-base=b58mh --type=rsa --size=2048 test_key_rsa | head -n1 | tr -d "\n") RSA_IPNS_IDv0=$(echo "$RSA_KEY" | ipfs cid format -v 0) - RSA_IPNS_IDv1=$(echo "$RSA_KEY" | ipfs cid format -v 1 --codec libp2p-key -b base36) + RSA_IPNS_IDv1=$(echo "$RSA_KEY" | ipfs cid format -v 1 --mc libp2p-key -b base36) RSA_IPNS_IDv1_DAGPB=$(echo "$RSA_IPNS_IDv0" | ipfs cid format -v 1 -b base36) test_check_peerid "${RSA_KEY}" && ipfs name publish --key test_key_rsa --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out && @@ -129,7 +129,7 @@ test_expect_success "Publish test text file to IPNS using ED25519 keys" ' ED25519_KEY=$(ipfs key gen --ipns-base=b58mh --type=ed25519 test_key_ed25519 | head -n1 | tr -d "\n") ED25519_IPNS_IDv0=$ED25519_KEY ED25519_IPNS_IDv1=$(ipfs key list -l --ipns-base=base36 | grep test_key_ed25519 | cut -d " " -f1 | tr -d "\n") - ED25519_IPNS_IDv1_DAGPB=$(echo "$ED25519_IPNS_IDv1" | ipfs cid format -v 1 -b base36 --codec protobuf) + ED25519_IPNS_IDv1_DAGPB=$(echo "$ED25519_IPNS_IDv1" | ipfs cid format -v 1 -b base36 --mc dag-pb) test_check_peerid "${ED25519_KEY}" && ipfs name publish --key test_key_ed25519 --allow-offline -Q "/ipfs/$CIDv1" > name_publish_out && ipfs name resolve "$ED25519_KEY" > output && diff --git a/test/sharness/t0115-gateway-dir-listing.sh b/test/sharness/t0115-gateway-dir-listing.sh index 0fc86ed7904..91ab8afe1fa 100755 --- a/test/sharness/t0115-gateway-dir-listing.sh +++ b/test/sharness/t0115-gateway-dir-listing.sh @@ -28,7 +28,9 @@ test_expect_success "Add the test directory" ' echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt && echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt && DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) && - FILE_CID=$(ipfs files stat /ipfs/$DIR_CID/ฤ…/ฤ™/file-ลบล‚.txt | head -1) + FILE_CID=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ฤ…/ฤ™/file-ลบล‚.txt | jq -r .Hash) && + FILE_SIZE=$(ipfs files stat --enc=json /ipfs/$DIR_CID/ฤ…/ฤ™/file-ลบล‚.txt | jq -r .Size) + echo "$FILE_CID / $FILE_SIZE" ' ## ============================================================================ @@ -135,6 +137,28 @@ test_expect_success "dnslink gw: hash column should be a CID link to cid.ipfs.io test_should_contain "" list_response ' +## ============================================================================ +## Test dir listing of a big directory +## ============================================================================ + +test_expect_success "dir listing should resolve child sizes if under Gateway.FastDirIndexThreshold" ' + curl -sD - http://127.0.0.1:$GWAY_PORT/ipfs/${DIR_CID}/ฤ…/ฤ™/ | tee list_response && + test_should_contain "/ipfs/${FILE_CID}?filename" list_response && + test_should_contain ">${FILE_SIZE} B" list_response +' + +# force fast dir index for all responses +ipfs config --json Gateway.FastDirIndexThreshold 0 +# restart daemon to apply config changes +test_kill_ipfs_daemon +test_launch_ipfs_daemon + +test_expect_success "dir listing should not resolve child sizes beyond Gateway.FastDirIndexThreshold" ' + curl -sD - http://127.0.0.1:$GWAY_PORT/ipfs/${DIR_CID}/ฤ…/ฤ™/ | tee list_response && + test_should_contain "/ipfs/${FILE_CID}?filename" list_response && + test_should_not_contain ">${FILE_SIZE} B" list_response +' + ## ============================================================================ ## End of tests, cleanup ## ============================================================================ diff --git a/test/sharness/t0116-gateway-cache.sh b/test/sharness/t0116-gateway-cache.sh new file mode 100755 index 00000000000..e5471088e2d --- /dev/null +++ b/test/sharness/t0116-gateway-cache.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env bash + +test_description="Test HTTP Gateway Cache Control Support" + +. lib/test-lib.sh + +test_init_ipfs +test_launch_ipfs_daemon_without_network + +# Cache control support is based on logical roots (each path segment == one logical root). +# To maximize the test surface, we want to test: +# - /ipfs/ content path +# - /ipns/ content path +# - at least 3 levels +# - separate tests for a directory listing and a file +# - have implicit index.html for a good measure +# /ipns/root1/root2/root3/ (/ipns/root1/root2/root3/index.html) + +# Note: we cover important edge case here: +# ROOT3_CID - dir listing (dir-index-html response) +# ROOT4_CID - index.html returned as a root response (dir/), instead of generated dir-index-html +# FILE_CID - index.html returned directly, as a file + +test_expect_success "Add the test directory" ' + mkdir -p root2/root3/root4 && + echo "hello" > root2/root3/root4/index.html && + ROOT1_CID=$(ipfs add -Qrw --cid-version 1 root2) + ROOT2_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2 | cut -d "/" -f3) + ROOT3_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3 | cut -d "/" -f3) + ROOT4_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4 | cut -d "/" -f3) + FILE_CID=$(ipfs resolve -r /ipfs/$ROOT1_CID/root2/root3/root4/index.html | cut -d "/" -f3) +' + +test_expect_success "Prepare IPNS unixfs content path for testing" ' + TEST_IPNS_ID=$(ipfs key gen --ipns-base=base36 --type=ed25519 cache_test_key | head -n1 | tr -d "\n") + ipfs name publish --key cache_test_key --allow-offline -Q "/ipfs/$ROOT1_CID" > name_publish_out && + test_check_peerid "${TEST_IPNS_ID}" && + ipfs name resolve "${TEST_IPNS_ID}" > output && + printf "/ipfs/%s\n" "$ROOT1_CID" > expected && + test_cmp expected output +' + +# GET /ipfs/ + test_expect_success "GET for /ipfs/ unixfs dir listing succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/" >/dev/null 2>curl_ipfs_dir_listing_output && + cat curl_ipfs_dir_listing_output + ' + test_expect_success "GET for /ipfs/ unixfs dir with index.html succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/" >/dev/null 2>curl_ipfs_dir_index.html_output && + cat curl_ipfs_dir_index.html_output + ' + test_expect_success "GET for /ipfs/ unixfs file succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_ipfs_file_output && + cat curl_ipfs_file_output + ' +# GET /ipns/ + test_expect_success "GET for /ipns/ unixfs dir listing succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/" >/dev/null 2>curl_ipns_dir_listing_output && + cat curl_ipns_dir_listing_output + ' + test_expect_success "GET for /ipns/ unixfs dir with index.html succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/" >/dev/null 2>curl_ipns_dir_index.html_output && + cat curl_ipns_dir_index.html_output + ' + test_expect_success "GET for /ipns/ unixfs file succeeds" ' + curl -svX GET "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/index.html" >/dev/null 2>curl_ipns_file_output && + cat curl_ipns_file_output + ' + +# X-Ipfs-Path + + ## dir generated listing + test_expect_success "GET /ipfs/ dir listing response has original content path in X-Ipfs-Path" ' + grep "< X-Ipfs-Path: /ipfs/$ROOT1_CID/root2/root3" curl_ipfs_dir_listing_output + ' + test_expect_success "GET /ipns/ dir listing response has original content path in X-Ipfs-Path" ' + grep "< X-Ipfs-Path: /ipns/$TEST_IPNS_ID/root2/root3" curl_ipns_dir_listing_output + ' + + ## dir static index.html + test_expect_success "GET /ipfs/ dir index.html response has original content path in X-Ipfs-Path" ' + grep "< X-Ipfs-Path: /ipfs/$ROOT1_CID/root2/root3/root4/" curl_ipfs_dir_index.html_output + ' + test_expect_success "GET /ipns/ dir index.html response has original content path in X-Ipfs-Path" ' + grep "< X-Ipfs-Path: /ipns/$TEST_IPNS_ID/root2/root3/root4/" curl_ipns_dir_index.html_output + ' + + # file + test_expect_success "GET /ipfs/ file response has original content path in X-Ipfs-Path" ' + grep "< X-Ipfs-Path: /ipfs/$ROOT1_CID/root2/root3/root4/index.html" curl_ipfs_file_output + ' + test_expect_success "GET /ipns/ file response has original content path in X-Ipfs-Path" ' + grep "< X-Ipfs-Path: /ipns/$TEST_IPNS_ID/root2/root3/root4/index.html" curl_ipns_file_output + ' + +# X-Ipfs-Roots + + ## dir generated listing + test_expect_success "GET /ipfs/ dir listing response has logical CID roots in X-Ipfs-Roots" ' + grep "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID}" curl_ipfs_dir_listing_output + ' + test_expect_success "GET /ipns/ dir listing response has logical CID roots in X-Ipfs-Roots" ' + grep "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID}" curl_ipns_dir_listing_output + ' + + ## dir static index.html + test_expect_success "GET /ipfs/ dir index.html response has logical CID roots in X-Ipfs-Roots" ' + grep "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID}" curl_ipfs_dir_index.html_output + ' + test_expect_success "GET /ipns/ dir index.html response has logical CID roots in X-Ipfs-Roots" ' + grep "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID}" curl_ipns_dir_index.html_output + ' + + ## file + test_expect_success "GET /ipfs/ file response has logical CID roots in X-Ipfs-Roots" ' + grep "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID},${FILE_CID}" curl_ipfs_file_output + ' + test_expect_success "GET /ipns/ file response has logical CID roots in X-Ipfs-Roots" ' + grep "< X-Ipfs-Roots: ${ROOT1_CID},${ROOT2_CID},${ROOT3_CID},${ROOT4_CID},${FILE_CID}" curl_ipns_file_output + ' + +# Etag + + ## dir generated listing + test_expect_success "GET /ipfs/ dir response has special Etag for generated dir listing" ' + grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipfs_dir_listing_output + ' + test_expect_success "GET /ipns/ dir response has special Etag for generated dir listing" ' + grep -E "< Etag: \"DirIndex-.+_CID-${ROOT3_CID}\"" curl_ipns_dir_listing_output + ' + + ## dir static index.html should use CID of the index.html file for improved HTTP caching + test_expect_success "GET /ipfs/ dir index.html response has dir CID as Etag" ' + grep "< Etag: \"${ROOT4_CID}\"" curl_ipfs_dir_index.html_output + ' + test_expect_success "GET /ipns/ dir index.html response has dir CID as Etag" ' + grep "< Etag: \"${ROOT4_CID}\"" curl_ipns_dir_index.html_output + ' + + ## file + test_expect_success "GET /ipfs/ response has CID as Etag for a file" ' + grep "< Etag: \"${FILE_CID}\"" curl_ipfs_file_output + ' + test_expect_success "GET /ipns/ response has CID as Etag for a file" ' + grep "< Etag: \"${FILE_CID}\"" curl_ipns_file_output + ' + +# If-None-Match (return 304 Not Modified when client sends matching Etag they already have) + + test_expect_success "GET for /ipfs/ file with matching Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: \"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + test_expect_success "GET for /ipfs/ dir with index.html file with matching Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: \"$ROOT4_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + test_expect_success "GET for /ipfs/ file with matching third Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: \"fakeEtag1\", \"fakeEtag2\", \"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + test_expect_success "GET for /ipfs/ file with matching weak Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: W/\"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + test_expect_success "GET for /ipfs/ file with wildcard Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: *" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/root4/index.html" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + test_expect_success "GET for /ipns/ file with matching Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: \"$FILE_CID\"" "http://127.0.0.1:$GWAY_PORT/ipns/$TEST_IPNS_ID/root2/root3/root4/index.html" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + test_expect_success "GET for /ipfs/ dir listing with matching weak Etag in If-None-Match returns 304 Not Modified" ' + curl -svX GET -H "If-None-Match: W/\"$ROOT3_CID\"" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/" >/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + + # DirIndex etag is based on xxhash(./assets/dir-index-html), so we need to fetch it dynamically + test_expect_success "GET for /ipfs/ dir listing with matching strong Etag in If-None-Match returns 304 Not Modified" ' + curl -Is "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/"| grep -i Etag | cut -f2- -d: | tr -d "[:space:]\"" > dir_index_etag && + curl -svX GET -H "If-None-Match: \"$(/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + test_expect_success "GET for /ipfs/ dir listing with matching weak Etag in If-None-Match returns 304 Not Modified" ' + curl -Is "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT1_CID/root2/root3/"| grep -i Etag | cut -f2- -d: | tr -d "[:space:]\"" > dir_index_etag && + curl -svX GET -H "If-None-Match: W/\"$(/dev/null 2>curl_output && + test_should_contain "304 Not Modified" curl_output + ' + +test_kill_ipfs_daemon + +test_done diff --git a/test/sharness/t0116-prometheus-data/prometheus_metrics b/test/sharness/t0116-prometheus-data/prometheus_metrics index af41dc8a88d..dd358e82f4f 100644 --- a/test/sharness/t0116-prometheus-data/prometheus_metrics +++ b/test/sharness/t0116-prometheus-data/prometheus_metrics @@ -159,6 +159,9 @@ flatfs_datastore_sync_latency_seconds_bucket flatfs_datastore_sync_latency_seconds_count flatfs_datastore_sync_latency_seconds_sum flatfs_datastore_sync_total +go_gc_cycles_automatic_gc_cycles_total +go_gc_cycles_forced_gc_cycles_total +go_gc_cycles_total_gc_cycles_total go_gc_duration_seconds go_gc_duration_seconds go_gc_duration_seconds @@ -166,8 +169,70 @@ go_gc_duration_seconds go_gc_duration_seconds go_gc_duration_seconds_count go_gc_duration_seconds_sum +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_bucket +go_gc_heap_allocs_by_size_bytes_total_count +go_gc_heap_allocs_by_size_bytes_total_sum +go_gc_heap_allocs_bytes_total +go_gc_heap_allocs_objects_total +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_bucket +go_gc_heap_frees_by_size_bytes_total_count +go_gc_heap_frees_by_size_bytes_total_sum +go_gc_heap_frees_bytes_total +go_gc_heap_frees_objects_total +go_gc_heap_goal_bytes +go_gc_heap_objects_objects +go_gc_heap_tiny_allocs_objects_total +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_bucket +go_gc_pauses_seconds_total_count +go_gc_pauses_seconds_total_sum go_goroutines go_info +go_memory_classes_heap_free_bytes +go_memory_classes_heap_objects_bytes +go_memory_classes_heap_released_bytes +go_memory_classes_heap_stacks_bytes +go_memory_classes_heap_unused_bytes +go_memory_classes_metadata_mcache_free_bytes +go_memory_classes_metadata_mcache_inuse_bytes +go_memory_classes_metadata_mspan_free_bytes +go_memory_classes_metadata_mspan_inuse_bytes +go_memory_classes_metadata_other_bytes +go_memory_classes_os_stacks_bytes +go_memory_classes_other_bytes +go_memory_classes_profiling_buckets_bytes +go_memory_classes_total_bytes go_memstats_alloc_bytes go_memstats_alloc_bytes_total go_memstats_buck_hash_sys_bytes @@ -192,6 +257,20 @@ go_memstats_other_sys_bytes go_memstats_stack_inuse_bytes go_memstats_stack_sys_bytes go_memstats_sys_bytes +go_sched_goroutines_goroutines +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_bucket +go_sched_latencies_seconds_count +go_sched_latencies_seconds_sum go_threads ipfs_bitswap_active_block_tasks ipfs_bitswap_active_tasks diff --git a/test/sharness/t0117-gateway-block.sh b/test/sharness/t0117-gateway-block.sh new file mode 100755 index 00000000000..c9e3a4713c8 --- /dev/null +++ b/test/sharness/t0117-gateway-block.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +test_description="Test HTTP Gateway Raw Block (application/vnd.ipld.raw) Support" + +. lib/test-lib.sh + +test_init_ipfs +test_launch_ipfs_daemon_without_network + +test_expect_success "Create text fixtures" ' + mkdir -p dir && + echo "hello application/vnd.ipld.raw" > dir/ascii.txt && + ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 dir) && + FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/dir/ascii.txt | cut -d "/" -f3) +' + +# GET unixfs dir root block and compare it with `ipfs block get` output + + test_expect_success "GET with format=raw param returns a raw block" ' + ipfs block get "/ipfs/$ROOT_DIR_CID/dir" > expected && + curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir?format=raw" -o curl_ipfs_dir_block_param_output && + test_cmp expected curl_ipfs_dir_block_param_output + ' + + test_expect_success "GET for application/vnd.ipld.raw returns a raw block" ' + ipfs block get "/ipfs/$ROOT_DIR_CID/dir" > expected_block && + curl -sX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir" -o curl_ipfs_dir_block_accept_output && + test_cmp expected_block curl_ipfs_dir_block_accept_output + ' + +# Make sure expected HTTP headers are returned with the block bytes + + test_expect_success "GET response for application/vnd.ipld.raw has expected Content-Type" ' + curl -svX GET -H "Accept: application/vnd.ipld.raw" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/dir/ascii.txt" >/dev/null 2>curl_output && + cat curl_output && + grep "< Content-Type: application/vnd.ipld.raw" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.raw includes Content-Length" ' + BYTES=$(ipfs block get $FILE_CID | wc --bytes) + grep "< Content-Length: $BYTES" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.raw includes Content-Disposition" ' + grep "< Content-Disposition: attachment\; filename=\"${FILE_CID}.bin\"" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.raw includes nosniff hint" ' + grep "< X-Content-Type-Options: nosniff" curl_output + ' + +# Cache control HTTP headers +# (basic checks, detailed behavior is tested in t0116-gateway-cache.sh) + + test_expect_success "GET response for application/vnd.ipld.raw includes Etag" ' + grep "< Etag: \"${FILE_CID}.raw\"" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.raw includes X-Ipfs-Path and X-Ipfs-Roots" ' + grep "< X-Ipfs-Path" curl_output && + grep "< X-Ipfs-Roots" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.raw includes Cache-Control" ' + grep "< Cache-Control" curl_output + ' + +test_kill_ipfs_daemon + +test_done diff --git a/test/sharness/t0118-gateway-car.sh b/test/sharness/t0118-gateway-car.sh new file mode 100755 index 00000000000..796c3c33947 --- /dev/null +++ b/test/sharness/t0118-gateway-car.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +test_description="Test HTTP Gateway CAR (application/vnd.ipld.car) Support" + +. lib/test-lib.sh + +test_init_ipfs +test_launch_ipfs_daemon_without_network + +# CAR stream is not deterministic, as blocks can arrive in random order, +# but if we have a small file that fits into a single block, and export its CID +# we will get a CAR that is a deterministic array of bytes. + + test_expect_success "Create a deterministic CAR for testing" ' + mkdir -p subdir && + echo "hello application/vnd.ipld.car" > subdir/ascii.txt && + ROOT_DIR_CID=$(ipfs add -Qrw --cid-version 1 subdir) && + FILE_CID=$(ipfs resolve -r /ipfs/$ROOT_DIR_CID/subdir/ascii.txt | cut -d "/" -f3) && + ipfs dag export $ROOT_DIR_CID > test-dag.car && + ipfs dag export $FILE_CID > deterministic.car && + purge_blockstore + ' + +# GET a reference DAG with dag-cbor+dag-pb+raw blocks as CAR + + # This test uses official CARv1 fixture from https://ipld.io/specs/transport/car/fixture/carv1-basic/ + test_expect_success "GET for application/vnd.ipld.car with dag-cbor root returns a CARv1 stream with full DAG" ' + ipfs dag import ../t0118-gateway-car/carv1-basic.car && + DAG_CBOR_CID=bafyreihyrpefhacm6kkp4ql6j6udakdit7g3dmkzfriqfykhjw6cad5lrm && + curl -sX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$DAG_CBOR_CID" -o gateway-dag-cbor.car && + purge_blockstore && + ipfs dag import gateway-dag-cbor.car && + ipfs dag stat --offline $DAG_CBOR_CID + ' + +# GET unixfs file as CAR +# (by using a single file we ensure deterministic result that can be compared byte-for-byte) + + test_expect_success "GET with format=car param returns a CARv1 stream" ' + ipfs dag import test-dag.car && + curl -sX GET "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt?format=car" -o gateway-param.car && + test_cmp deterministic.car gateway-param.car + ' + + test_expect_success "GET for application/vnd.ipld.car returns a CARv1 stream" ' + ipfs dag import test-dag.car && + curl -sX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" -o gateway-header.car && + test_cmp deterministic.car gateway-header.car + ' + + # explicit version=1 + test_expect_success "GET for application/vnd.ipld.raw version=1 returns a CARv1 stream" ' + ipfs dag import test-dag.car && + curl -sX GET -H "Accept: application/vnd.ipld.car;version=1" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" -o gateway-header-v1.car && + test_cmp deterministic.car gateway-header-v1.car + ' + + # explicit version=1 with whitepace + test_expect_success "GET for application/vnd.ipld.raw version=1 returns a CARv1 stream (with whitespace)" ' + ipfs dag import test-dag.car && + curl -sX GET -H "Accept: application/vnd.ipld.car; version=1" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" -o gateway-header-v1.car && + test_cmp deterministic.car gateway-header-v1.car + ' + + # explicit version=2 + test_expect_success "GET for application/vnd.ipld.raw version=2 returns HTTP 400 Bad Request error" ' + curl -svX GET -H "Accept: application/vnd.ipld.car;version=2" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" > curl_output 2>&1 && + cat curl_output && + grep "400 Bad Request" curl_output && + grep "unsupported CAR version" curl_output + ' + +# GET unixfs directory as a CAR with DAG and some selector + + # TODO: this is basic test for "full" selector, we will add support for custom ones in https://github.com/ipfs/go-ipfs/issues/8769 + test_expect_success "GET for application/vnd.ipld.car with unixfs dir returns a CARv1 stream with full DAG" ' + ipfs dag import test-dag.car && + curl -sX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID" -o gateway-dir.car && + purge_blockstore && + ipfs dag import gateway-dir.car && + ipfs dag stat --offline $ROOT_DIR_CID + ' + +# Make sure expected HTTP headers are returned with the CAR bytes + + test_expect_success "GET response for application/vnd.ipld.car has expected Content-Type" ' + ipfs dag import test-dag.car && + curl -svX GET -H "Accept: application/vnd.ipld.car" "http://127.0.0.1:$GWAY_PORT/ipfs/$ROOT_DIR_CID/subdir/ascii.txt" >/dev/null 2>curl_output && + cat curl_output && + grep "< Content-Type: application/vnd.ipld.car; version=1" curl_output + ' + + # CAR is streamed, gateway may not have the entire thing, unable to calculate total size + test_expect_success "GET response for application/vnd.ipld.car includes no Content-Length" ' + grep -qv "< Content-Length:" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.car includes Content-Disposition" ' + grep "< Content-Disposition: attachment\; filename=\"${FILE_CID}.car\"" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.car includes nosniff hint" ' + grep "< X-Content-Type-Options: nosniff" curl_output + ' + + # CAR is streamed, gateway may not have the entire thing, unable to support range-requests + # Partial downloads and resumes should be handled using + # IPLD selectors: https://github.com/ipfs/go-ipfs/issues/8769 + test_expect_success "GET response for application/vnd.ipld.car includes Accept-Ranges header" ' + grep "< Accept-Ranges: none" curl_output + ' + +# Cache control HTTP headers + + test_expect_success "GET response for application/vnd.ipld.car includes a weak Etag" ' + grep "< Etag: W/\"${FILE_CID}.car\"" curl_output + ' + + # (basic checks, detailed behavior for some fields is tested in t0116-gateway-cache.sh) + test_expect_success "GET response for application/vnd.ipld.car includes X-Ipfs-Path and X-Ipfs-Roots" ' + grep "< X-Ipfs-Path" curl_output && + grep "< X-Ipfs-Roots" curl_output + ' + + test_expect_success "GET response for application/vnd.ipld.car includes expected Cache-Control" ' + grep "< Cache-Control: no-cache, no-transform" curl_output + ' + +test_kill_ipfs_daemon + +test_done diff --git a/test/sharness/t0118-gateway-car/README.md b/test/sharness/t0118-gateway-car/README.md new file mode 100644 index 00000000000..2efccc18544 --- /dev/null +++ b/test/sharness/t0118-gateway-car/README.md @@ -0,0 +1,10 @@ +# Dataset description/sources + +- carv1-basic.car + - raw CARv1 + - Source: https://ipld.io/specs/transport/car/fixture/carv1-basic/carv1-basic.car + +- carv1-basic.json + - description of the contents and layout of the raw CAR, encoded in DAG-JSON + - Source: https://ipld.io/specs/transport/car/fixture/carv1-basic/carv1-basic.json + diff --git a/test/sharness/t0118-gateway-car/carv1-basic.car b/test/sharness/t0118-gateway-car/carv1-basic.car new file mode 100644 index 00000000000..48c67a3d8dc Binary files /dev/null and b/test/sharness/t0118-gateway-car/carv1-basic.car differ diff --git a/test/sharness/t0118-gateway-car/carv1-basic.json b/test/sharness/t0118-gateway-car/carv1-basic.json new file mode 100644 index 00000000000..99a7eadab8b --- /dev/null +++ b/test/sharness/t0118-gateway-car/carv1-basic.json @@ -0,0 +1,159 @@ +{ + "blocks": [ + { + "blockLength": 55, + "blockOffset": 137, + "cid": { + "/": "bafyreihyrpefhacm6kkp4ql6j6udakdit7g3dmkzfriqfykhjw6cad5lrm" + }, + "content": { + "link": { + "/": "QmNX6Tffavsya4xgBi2VJQnSuqy9GsxongxZZ9uZBqp16d" + }, + "name": "blip" + }, + "length": 92, + "offset": 100 + }, + { + "blockLength": 97, + "blockOffset": 228, + "cid": { + "/": "QmNX6Tffavsya4xgBi2VJQnSuqy9GsxongxZZ9uZBqp16d" + }, + "content": { + "Links": [ + { + "Hash": { + "/": "bafkreifw7plhl6mofk6sfvhnfh64qmkq73oeqwl6sloru6rehaoujituke" + }, + "Name": "bear", + "Tsize": 4 + }, + { + "Hash": { + "/": "QmWXZxVQ9yZfhQxLD35eDR8LiMRsYtHxYqTFCBbJoiJVys" + }, + "Name": "second", + "Tsize": 149 + } + ] + }, + "length": 133, + "offset": 192 + }, + { + "blockLength": 4, + "blockOffset": 362, + "cid": { + "/": "bafkreifw7plhl6mofk6sfvhnfh64qmkq73oeqwl6sloru6rehaoujituke" + }, + "content": { + "/": { + "bytes": "Y2NjYw" + } + }, + "length": 41, + "offset": 325 + }, + { + "blockLength": 94, + "blockOffset": 402, + "cid": { + "/": "QmWXZxVQ9yZfhQxLD35eDR8LiMRsYtHxYqTFCBbJoiJVys" + }, + "content": { + "Links": [ + { + "Hash": { + "/": "bafkreiebzrnroamgos2adnbpgw5apo3z4iishhbdx77gldnbk57d4zdio4" + }, + "Name": "dog", + "Tsize": 4 + }, + { + "Hash": { + "/": "QmdwjhxpxzcMsR3qUuj7vUL8pbA7MgR3GAxWi2GLHjsKCT" + }, + "Name": "first", + "Tsize": 51 + } + ] + }, + "length": 130, + "offset": 366 + }, + { + "blockLength": 4, + "blockOffset": 533, + "cid": { + "/": "bafkreiebzrnroamgos2adnbpgw5apo3z4iishhbdx77gldnbk57d4zdio4" + }, + "content": { + "/": { + "bytes": "YmJiYg" + } + }, + "length": 41, + "offset": 496 + }, + { + "blockLength": 47, + "blockOffset": 572, + "cid": { + "/": "QmdwjhxpxzcMsR3qUuj7vUL8pbA7MgR3GAxWi2GLHjsKCT" + }, + "content": { + "Links": [ + { + "Hash": { + "/": "bafkreidbxzk2ryxwwtqxem4l3xyyjvw35yu4tcct4cqeqxwo47zhxgxqwq" + }, + "Name": "cat", + "Tsize": 4 + } + ] + }, + "length": 82, + "offset": 537 + }, + { + "blockLength": 4, + "blockOffset": 656, + "cid": { + "/": "bafkreidbxzk2ryxwwtqxem4l3xyyjvw35yu4tcct4cqeqxwo47zhxgxqwq" + }, + "content": { + "/": { + "bytes": "YWFhYQ" + } + }, + "length": 41, + "offset": 619 + }, + { + "blockLength": 18, + "blockOffset": 697, + "cid": { + "/": "bafyreidj5idub6mapiupjwjsyyxhyhedxycv4vihfsicm2vt46o7morwlm" + }, + "content": { + "link": null, + "name": "limbo" + }, + "length": 55, + "offset": 660 + } + ], + "header": { + "roots": [ + { + "/": "bafyreihyrpefhacm6kkp4ql6j6udakdit7g3dmkzfriqfykhjw6cad5lrm" + }, + { + "/": "bafyreidj5idub6mapiupjwjsyyxhyhedxycv4vihfsicm2vt46o7morwlm" + } + ], + "version": 1 + } +} diff --git a/test/sharness/t0116-prometheus.sh b/test/sharness/t0119-prometheus.sh similarity index 100% rename from test/sharness/t0116-prometheus.sh rename to test/sharness/t0119-prometheus.sh diff --git a/test/sharness/t0139-swarm-rcmgr.sh b/test/sharness/t0139-swarm-rcmgr.sh new file mode 100755 index 00000000000..24b9ebf6544 --- /dev/null +++ b/test/sharness/t0139-swarm-rcmgr.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +# +test_description="Test ipfs swarm ResourceMgr config and commands" + +. lib/test-lib.sh + +test_init_ipfs + +# test correct behavior when resource manager is disabled (default behavior) +test_launch_ipfs_daemon + +test_expect_success 'Swarm limit should fail since RM is disabled' ' + test_expect_code 1 ipfs swarm limit system 2> actual && + test_should_contain "missing ResourceMgr" actual +' + +test_expect_success 'Swarm stats should fail since RM is disabled' ' + test_expect_code 1 ipfs swarm stats all 2> actual && + test_should_contain "missing ResourceMgr" actual +' + +test_kill_ipfs_daemon + +test_expect_success 'Enable resource manager' ' + ipfs config --bool Swarm.ResourceMgr.Enabled true +' + +# swarm limit|stats should fail in offline mode + +test_expect_success 'disconnected: swarm limit requires running daemon' ' + test_expect_code 1 ipfs swarm limit system 2> actual && + test_should_contain "missing ResourceMgr" actual +' +test_expect_success 'disconnected: swarm stats requires running daemon' ' + test_expect_code 1 ipfs swarm stats all 2> actual && + test_should_contain "missing ResourceMgr" actual +' + +# swarm limit|stats should succeed in online mode by default +# because Resource Manager is opt-out +test_launch_ipfs_daemon + +# every scope has the same fields, so we only inspect System +test_expect_success 'ResourceMgr enabled: swarm limit' ' + ipfs swarm limit system --enc=json | tee json && + jq -e .Conns < json && + jq -e .ConnsInbound < json && + jq -e .ConnsOutbound < json && + jq -e .FD < json && + jq -e .Memory < json && + jq -e .Streams < json && + jq -e .StreamsInbound < json && + jq -e .StreamsOutbound < json +' + +# every scope has the same fields, so we only inspect System +test_expect_success 'ResourceMgr enabled: swarm stats' ' + ipfs swarm stats all --enc=json | tee json && + jq -e .System.Memory < json && + jq -e .System.NumConnsInbound < json && + jq -e .System.NumConnsOutbound < json && + jq -e .System.NumFD < json && + jq -e .System.NumStreamsInbound < json && + jq -e .System.NumStreamsOutbound < json && + jq -e .Transient.Memory < json +' + +# shut down the daemon, set a limit in the config, and verify that it's applied +test_kill_ipfs_daemon + +test_expect_success "Set system conns limit while daemon is not running" " + ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 99999 +" + +test_expect_success "Set an invalid limit, which should result in a failure" " + test_expect_code 1 ipfs config --json Swarm.ResourceMgr.Limits.System.Conns 'asdf' 2> actual && + test_should_contain 'failed to unmarshal' actual +" + +test_launch_ipfs_daemon + +test_expect_success 'Ensure the new system conns limit is applied' ' + ipfs swarm limit system --enc=json | tee json && + jq -e ".Conns == 99999" < json +' + +test_expect_success 'Set system memory limit while the daemon is running' ' + ipfs swarm limit system | jq ".Memory = 99998" > system.json && + ipfs swarm limit system system.json +' + +test_expect_success 'The new system limits were written to the config' ' + jq -e ".Swarm.ResourceMgr.Limits.System.Memory == 99998" < "$IPFS_PATH/config" +' + +test_expect_success 'The new system limits are in the swarm limit output' ' + ipfs swarm limit system --enc=json | jq -e ".Memory == 99998" +' + +# now test all the other scopes +test_expect_success 'Set limit on transient scope' ' + ipfs swarm limit transient | jq ".Memory = 88888" > transient.json && + ipfs swarm limit transient transient.json && + jq -e ".Swarm.ResourceMgr.Limits.Transient.Memory == 88888" < "$IPFS_PATH/config" && + ipfs swarm limit transient --enc=json | tee limits && + jq -e ".Memory == 88888" < limits +' + +test_expect_success 'Set limit on service scope' ' + ipfs swarm limit svc:foo | jq ".Memory = 77777" > service-foo.json && + ipfs swarm limit svc:foo service-foo.json --enc=json && + jq -e ".Swarm.ResourceMgr.Limits.Service.foo.Memory == 77777" < "$IPFS_PATH/config" && + ipfs swarm limit svc:foo --enc=json | tee limits && + jq -e ".Memory == 77777" < limits +' + +test_expect_success 'Set limit on protocol scope' ' + ipfs swarm limit proto:foo | jq ".Memory = 66666" > proto-foo.json && + ipfs swarm limit proto:foo proto-foo.json --enc=json && + jq -e ".Swarm.ResourceMgr.Limits.Protocol.foo.Memory == 66666" < "$IPFS_PATH/config" && + ipfs swarm limit proto:foo --enc=json | tee limits && + jq -e ".Memory == 66666" < limits +' + +# any valid peer id +PEER_ID=QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN + +test_expect_success 'Set limit on peer scope' ' + ipfs swarm limit peer:$PEER_ID | jq ".Memory = 66666" > peer-$PEER_ID.json && + ipfs swarm limit peer:$PEER_ID peer-$PEER_ID.json --enc=json && + jq -e ".Swarm.ResourceMgr.Limits.Peer.${PEER_ID}.Memory == 66666" < "$IPFS_PATH/config" && + ipfs swarm limit peer:$PEER_ID --enc=json | tee limits && + jq -e ".Memory == 66666" < limits +' + +test_expect_success 'Get limit for peer scope with an invalid peer ID' ' + test_expect_code 1 ipfs swarm limit peer:foo 2> actual && + test_should_contain "invalid peer ID" actual +' + +test_expect_success 'Set limit for peer scope with an invalid peer ID' ' + echo "{\"Memory\": 99}" > invalid-peer-id.json && + test_expect_code 1 ipfs swarm limit peer:foo invalid-peer-id.json 2> actual && + test_should_contain "invalid peer ID" actual +' + +test_kill_ipfs_daemon + +test_done diff --git a/test/sharness/t0152-profile.sh b/test/sharness/t0152-profile.sh index 6a45dbf167e..0bc328d2ed2 100755 --- a/test/sharness/t0152-profile.sh +++ b/test/sharness/t0152-profile.sh @@ -16,8 +16,8 @@ test_expect_success "profiling requires a running daemon" ' test_launch_ipfs_daemon -test_expect_success "test profiling (without CPU)" ' - ipfs diag profile --cpu-profile-time=0 > cmd_out +test_expect_success "test profiling (without sampling)" ' + ipfs diag profile --profile-time=0 > cmd_out ' test_expect_success "filename shows up in output" ' @@ -29,12 +29,17 @@ test_expect_success "profile file created" ' ' test_expect_success "test profiling with -o" ' - ipfs diag profile --cpu-profile-time=1s -o test-profile.zip + ipfs diag profile --profile-time=1s -o test-profile.zip ' test_expect_success "test that test-profile.zip exists" ' test -e test-profile.zip ' + +test_expect_success "test profiling with specific collectors" ' + ipfs diag profile --collectors version,goroutines-stack -o test-profile-small.zip +' + test_kill_ipfs_daemon if ! test_have_prereq UNZIP; then @@ -42,7 +47,8 @@ if ! test_have_prereq UNZIP; then fi test_expect_success "unpack profiles" ' - unzip -d profiles test-profile.zip + unzip -d profiles test-profile.zip && + unzip -d profiles-small test-profile-small.zip ' test_expect_success "cpu profile is valid" ' @@ -57,8 +63,22 @@ test_expect_success "goroutines profile is valid" ' go tool pprof -top profiles/ipfs "profiles/goroutines.pprof" | grep -q "Type: goroutine" ' +test_expect_success "mutex profile is valid" ' + go tool pprof -top profiles/ipfs "profiles/mutex.pprof" | grep -q "Type: delay" +' + +test_expect_success "block profile is valid" ' + go tool pprof -top profiles/ipfs "profiles/block.pprof" | grep -q "Type: delay" +' + test_expect_success "goroutines stacktrace is valid" ' grep -q "goroutine" "profiles/goroutines.stacks" ' +test_expect_success "the small profile only contains the requested data" ' + find profiles-small -type f | sort > actual && + echo -e "profiles-small/goroutines.stacks\nprofiles-small/version.json" > expected && + test_cmp expected actual +' + test_done diff --git a/test/sharness/t0160-resolve.sh b/test/sharness/t0160-resolve.sh index 600e4c07bba..ca11947b093 100755 --- a/test/sharness/t0160-resolve.sh +++ b/test/sharness/t0160-resolve.sh @@ -121,11 +121,11 @@ test_resolve_cmd_b32() { # peer ID represented as CIDv1 require libp2p-key multicodec # https://github.com/libp2p/specs/blob/master/RFC/0001-text-peerid-cid.md - local self_hash_b32protobuf=$(echo $self_hash | ipfs cid format -v 1 -b b --codec protobuf) - local self_hash_b32libp2pkey=$(echo $self_hash | ipfs cid format -v 1 -b b --codec libp2p-key) + local self_hash_b32protobuf=$(echo $self_hash | ipfs cid format -v 1 -b b --mc dag-pb) + local self_hash_b32libp2pkey=$(echo $self_hash | ipfs cid format -v 1 -b b --mc libp2p-key) test_expect_success "resolve of /ipns/{cidv1} with multicodec other than libp2p-key returns a meaningful error" ' test_expect_code 1 ipfs resolve /ipns/$self_hash_b32protobuf 2>cidcodec_error && - grep "Error: peer ID represented as CIDv1 require libp2p-key multicodec: retry with /ipns/$self_hash_b32libp2pkey" cidcodec_error + test_should_contain "Error: peer ID represented as CIDv1 require libp2p-key multicodec: retry with /ipns/$self_hash_b32libp2pkey" cidcodec_error ' } diff --git a/test/sharness/t0165-keystore-data/README.md b/test/sharness/t0165-keystore-data/README.md new file mode 100644 index 00000000000..4c0a68b5169 --- /dev/null +++ b/test/sharness/t0165-keystore-data/README.md @@ -0,0 +1,26 @@ +# OpenSSL generated keys for import/export tests + +Created with commands: + +```bash +openssl genpkey -algorithm ED25519 > openssl_ed25519.pem +openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 > openssl_rsa.pem +``` + +secp key used in the 'restrict import key' test. +From: https://www.openssl.org/docs/man1.1.1/man1/openssl-genpkey.html +```bash +openssl genpkey -genparam -algorithm EC -out ecp.pem \ + -pkeyopt ec_paramgen_curve:secp384r1 \ + -pkeyopt ec_param_enc:named_curve +openssl genpkey -paramfile ecp.pem -out openssl_secp384r1.pem +rm ecp.pem +``` +Note: The Bitcoin `secp256k1` curve which is what `go-libp2p-core/crypto` +actually generates and would be of interest to test against is not +recognized by the Go library: +``` +Error: parsing PKCS8 format: x509: failed to parse EC private key embedded + in PKCS#8: x509: unknown elliptic curve +``` +We keep the `secp384r1` type instead from the original openssl example. diff --git a/test/sharness/t0165-keystore-data/openssl_ed25519.pem b/test/sharness/t0165-keystore-data/openssl_ed25519.pem new file mode 100644 index 00000000000..387972c5265 --- /dev/null +++ b/test/sharness/t0165-keystore-data/openssl_ed25519.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIJ2M1na2f3dRm4b1FcAQvsn7q08+XfBZcr4MgH4yiBdz +-----END PRIVATE KEY----- diff --git a/test/sharness/t0165-keystore-data/openssl_rsa.pem b/test/sharness/t0165-keystore-data/openssl_rsa.pem new file mode 100644 index 00000000000..34d365bed2e --- /dev/null +++ b/test/sharness/t0165-keystore-data/openssl_rsa.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDSaJB9EKnShOs6 +sbGkB40crn72yNKXj5OBPS2wBDTHWwxyhTB0qJirOT2QYW2DmR/4lPfVk5/f4CJ7 +xIHUBJRoC+NTwqHit24DQBd00tNG4EnKn2Dad/arZ/nEVshkKiGXn0qXxiHHsaCn +X/pnVPU4+O7fdfUlz2EKf3Og/ocRCFrdMsULR2QwDc0YWsY8ngrcKegyFCbKjXjo +zvfbGevCDPlhKaZLxRy0PHnON00YC4KO6d77XpbECFvsE1aG1RxYQX0Zjr+i8UvD +UJp/YCoRNEX54/wKpGebMUrFse5K9hBsFen/wCsPnOsYPSb9g8qyoYRDBnr9sIe1 +9MxFTMy/AgMBAAECggEAKXu2KQI1CS1tlzfbdySJ/MKmg49afckv4sYmENLzeO6J +iLabtBRdbTyu151t0wlIlWEBb9lYJvJwuggnNJ7mh5D4c9YmxqU1imyDc2PxhcLI +qas8lDYcqvSn+L7HaYAo+VTNhxjoJg/uRbGVk/PbGS1zIxmFiLvXPROdv3sPNBsf +EYMDH9q7/8DI6dNBQPxtTKlTDLDsTezbkNFQ74znlXgQYcfY1mXljcRtbJqhQJT3 +uppktESPwLRmqtT9H+v9nCtQR6OLmAmLWNgMrSdGKBsSsgJwv2xfpNMffwd84dtT +uGrS2K+BY0TH2q+Xx04r18GLCst3U5MBSklyHQ/mwQKBgQDqnxNOnK41/n/Q8X4a +/TUnZBx/JHiCoQoa06AsMxFgOvV3ycR+Z9lwb5I5BsicH1GUcHIxSY3mCyd4fLwE +FC0QIyNhPJ5oFKh0Oynjm+79VE8v7kK2qqRL4zUpaCXEsSOrhRsCY0/WQdMUPVsh +okXDUIv37G9KUcjdrhNVpGK3oQKBgQDllK7augIhmlQZTdSLTgmuzhYsXdSGDML/ +Bx48q7OvPhvZIIOsygLGhtcBk2xG6PN1yP44cx9dvcTnzxU6TEblO5P8TWY0BSNj +ZuC5wdxLwc3KUdLd9JLR7qcbjqndDruE01rQFVQ3MDbyB1+VrJgiVHIEomJJrKGm +FQ+314moXwKBgQDL90sDlnZk/kED1k15DRN+kSus5HnXpkRwmfWvNx4t+FOZtdCa +y5Fei8Akz17rStbTIwZDDtzLVnsT5exV52xdkQ6a4+YaOYtQsHZ0JwWXOgo1cv6Q +ary2NGns+1uKKS0HWYnng4rOix8Dg2uMS9Q2PfnQqLz/cSYcgc7RLz2awQKBgQDd +HSaLYztKQeldtahPwwlwYuzYLkbSFNh559EnfffBgIAxzy8C7E1gB95sliBi61oQ +x1SR6c776hoLaVd4np5picgt6B3XXFuJETy/rAcQr8gUZFpDi5sctk4cLHtNfTL9 +6tI8N061GKrS0GcvMNwVtF9cN0mSy8GkxAQvfFgI4QKBgQC4NVimIPptfFckulAL +/t0vkdLhCRr1+UFNhgsQJhCZpfWZK4x8If6Jru/eiU7ywEsL6fHE2ENvyoTjV33g +b9yJ7SV4zkz4VhBxc3p26SIvBgLqtHwH8IkIonlbfQFoEAg1iOneLvimPy0YGHsG ++bTwwlAJJhctILkFtAbooeAQVQ== +-----END PRIVATE KEY----- diff --git a/test/sharness/t0165-keystore-data/openssl_secp384r1.pem b/test/sharness/t0165-keystore-data/openssl_secp384r1.pem new file mode 100644 index 00000000000..d9000993526 --- /dev/null +++ b/test/sharness/t0165-keystore-data/openssl_secp384r1.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8DksLZwPKGQS8tuWI +w+dNYiSHUyw30NkrK9YGmjgp84sVVa5NGrv0QniAnNWG1DqhZANiAATq0d5KV1MF +IIpF4beNX+YsmFdqB2oDLhznO/4xNsFCFKE39oGQmuMwnQhDNZZ2CQA8csfgZmuF +OSooe/Ru6ubyeGVKafcHJrOMBvl8hIg0tVWgIAhuXiTHq0UL0QTv9Vk= +-----END PRIVATE KEY----- diff --git a/test/sharness/t0165-keystore.sh b/test/sharness/t0165-keystore.sh index ad4b6a6c7c7..60089ecd7f2 100755 --- a/test/sharness/t0165-keystore.sh +++ b/test/sharness/t0165-keystore.sh @@ -63,23 +63,27 @@ ipfs key rm key_ed25519 echo $rsahash > rsa_key_id ' + test_key_import_export_all_formats rsa_key + test_expect_success "create a new ed25519 key" ' edhash=$(ipfs key gen generated_ed25519_key --type=ed25519) echo $edhash > ed25519_key_id ' - test_expect_success "export and import rsa key" ' - ipfs key export generated_rsa_key && - ipfs key rm generated_rsa_key && - ipfs key import generated_rsa_key generated_rsa_key.key > roundtrip_rsa_key_id && - test_cmp rsa_key_id roundtrip_rsa_key_id + test_key_import_export_all_formats ed25519_key + + test_openssl_compatibility_all_types + + INVALID_KEY=../t0165-keystore-data/openssl_secp384r1.pem + test_expect_success "import key type we don't generate fails" ' + test_must_fail ipfs key import restricted-type -f pem-pkcs8-cleartext $INVALID_KEY 2>&1 | tee key_exp_out && + grep -q "Error: key type \*crypto.ECDSAPrivateKey is not allowed to be imported" key_exp_out && + rm key_exp_out ' - test_expect_success "export and import ed25519 key" ' - ipfs key export generated_ed25519_key && - ipfs key rm generated_ed25519_key && - ipfs key import generated_ed25519_key generated_ed25519_key.key > roundtrip_ed25519_key_id && - test_cmp ed25519_key_id roundtrip_ed25519_key_id + test_expect_success "import key type we don't generate succeeds with flag" ' + ipfs key import restricted-type --allow-any-key-type -f pem-pkcs8-cleartext $INVALID_KEY > /dev/null && + ipfs key rm restricted-type ' test_expect_success "test export file option" ' @@ -176,15 +180,15 @@ ipfs key rm key_ed25519 ' # export works directly on the keystore present in IPFS_PATH - test_expect_success "export and import ed25519 key while daemon is running" ' - edhash=$(ipfs key gen exported_ed25519_key --type=ed25519) + test_expect_success "prepare ed25519 key while daemon is running" ' + edhash=$(ipfs key gen generated_ed25519_key --type=ed25519) echo $edhash > ed25519_key_id - ipfs key export exported_ed25519_key && - ipfs key rm exported_ed25519_key && - ipfs key import exported_ed25519_key exported_ed25519_key.key > roundtrip_ed25519_key_id && - test_cmp ed25519_key_id roundtrip_ed25519_key_id ' + test_key_import_export_all_formats ed25519_key + + test_openssl_compatibility_all_types + test_expect_success "key export over HTTP /api/v0/key/export is not possible" ' ipfs key gen nohttpexporttest_key --type=ed25519 && curl -X POST -sI "http://$API_ADDR/api/v0/key/export&arg=nohttpexporttest_key" | grep -q "^HTTP/1.1 404 Not Found" @@ -214,6 +218,64 @@ test_check_ed25519_sk() { } } +test_key_import_export_all_formats() { + KEY_NAME=$1 + test_key_import_export $KEY_NAME pem-pkcs8-cleartext + test_key_import_export $KEY_NAME libp2p-protobuf-cleartext +} + +test_key_import_export() { + local KEY_NAME FORMAT + KEY_NAME=$1 + FORMAT=$2 + ORIG_KEY="generated_$KEY_NAME" + if [ $FORMAT == "pem-pkcs8-cleartext" ]; then + FILE_EXT="pem" + else + FILE_EXT="key" + fi + + test_expect_success "export and import $KEY_NAME with format $FORMAT" ' + ipfs key export $ORIG_KEY --format=$FORMAT && + ipfs key rm $ORIG_KEY && + ipfs key import $ORIG_KEY $ORIG_KEY.$FILE_EXT --format=$FORMAT > imported_key_id && + test_cmp ${KEY_NAME}_id imported_key_id + ' +} + +# Test the entire import/export cycle with a openssl-generated key. +# 1. Import openssl key with PEM format. +# 2. Export key with libp2p format. +# 3. Reimport key. +# 4. Now exported with PEM format. +# 5. Compare with original openssl key. +# 6. Clean up. +test_openssl_compatibility() { + local KEY_NAME FORMAT + KEY_NAME=$1 + + test_expect_success "import and export $KEY_NAME with all formats" ' + ipfs key import test-openssl -f pem-pkcs8-cleartext $KEY_NAME > /dev/null && + ipfs key export test-openssl -f libp2p-protobuf-cleartext -o $KEY_NAME.libp2p.key && + ipfs key rm test-openssl && + + ipfs key import test-openssl -f libp2p-protobuf-cleartext $KEY_NAME.libp2p.key > /dev/null && + ipfs key export test-openssl -f pem-pkcs8-cleartext -o $KEY_NAME.ipfs-exported.pem && + ipfs key rm test-openssl && + + test_cmp $KEY_NAME $KEY_NAME.ipfs-exported.pem && + + rm $KEY_NAME.libp2p.key && + rm $KEY_NAME.ipfs-exported.pem + ' +} + +test_openssl_compatibility_all_types() { + test_openssl_compatibility ../t0165-keystore-data/openssl_ed25519.pem + test_openssl_compatibility ../t0165-keystore-data/openssl_rsa.pem +} + + test_key_cmd test_done diff --git a/test/sharness/t0171-peering.sh b/test/sharness/t0171-peering.sh index 9b775cb3cbe..207b279803a 100755 --- a/test/sharness/t0171-peering.sh +++ b/test/sharness/t0171-peering.sh @@ -33,7 +33,7 @@ peer_addrs() { peer() { PEER1="$1" && PEER2="$2" && - PEER_LIST="$(ipfsi "$PEER1" config Peering.Peers)" && + PEER_LIST="$(ipfsi "$PEER1" config Peering.Peers || true)" && { [[ "$PEER_LIST" == "null" ]] || PEER_LIST_INNER="${PEER_LIST:1:-1}"; } && ADDR_INFO="$(printf '[%s{"ID": "%s", "Addrs": %s}]' \ "${PEER_LIST_INNER:+${PEER_LIST_INNER},}" \ diff --git a/test/sharness/t0182-circuit-relay.sh b/test/sharness/t0182-circuit-relay.sh index 2b855844db0..d6e439ae318 100755 --- a/test/sharness/t0182-circuit-relay.sh +++ b/test/sharness/t0182-circuit-relay.sh @@ -31,8 +31,14 @@ test_expect_success 'configure the relay node as a static relay for node A' ' ' test_expect_success 'configure the relay node' ' - ipfsi 1 config --json Addresses.Swarm "$relayaddrs" && - ipfsi 1 config Internal.Libp2pForceReachability public + ipfsi 1 config Internal.Libp2pForceReachability public && + ipfsi 1 config --json Swarm.RelayService.Enabled true && + ipfsi 1 config --json Addresses.Swarm "$relayaddrs" +' + +test_expect_success 'configure the node B' ' + ipfsi 2 config Internal.Libp2pForceReachability private && + ipfsi 2 config --json Swarm.RelayClient.Enabled true ' test_expect_success 'restart nodes' ' @@ -50,7 +56,14 @@ test_expect_success 'connect B <-> Relay' ' ' test_expect_success 'wait until relay is ready to do work' ' - sleep 1 + while ! ipfsi 2 swarm connect /p2p/$PEERID_1/p2p-circuit/p2p/$PEERID_0; do + iptb stop && + iptb_wait_stop && + iptb start -wait -- --routing=none && + iptb connect 0 1 && + iptb connect 2 1 && + sleep 5 + done ' test_expect_success 'connect A <-Relay-> B' ' diff --git a/test/sharness/t0250-files-api.sh b/test/sharness/t0250-files-api.sh index c91dd123b33..382758a0551 100755 --- a/test/sharness/t0250-files-api.sh +++ b/test/sharness/t0250-files-api.sh @@ -875,8 +875,7 @@ test_expect_success "set up automatic sharding/unsharding data" ' done ' -# TODO: This does not need to report an error https://github.com/ipfs/go-ipfs/issues/8088 -test_expect_failure "reset automatic sharding" ' +test_expect_success "reset automatic sharding" ' ipfs config --json Internal.UnixFSShardingSizeThreshold null ' diff --git a/test/sharness/t0280-plugin-dag-jose.sh b/test/sharness/t0280-plugin-dag-jose.sh old mode 100644 new mode 100755 diff --git a/test/sharness/t0290-cid.sh b/test/sharness/t0290-cid.sh index 680e5308d91..7f0e0e1814d 100755 --- a/test/sharness/t0290-cid.sh +++ b/test/sharness/t0290-cid.sh @@ -13,6 +13,7 @@ CIDb32="bafybeibxm2nsadl3fnxv2sxcxmxaco2jl53wpeorjdzidjwf5aqdg7wa6u" CIDbase="QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6" CIDb32pb="bafybeievd6mwe6vcwnkwo3eizs3h7w3a34opszbyfxziqdxguhjw7imdve" CIDb32raw="bafkreievd6mwe6vcwnkwo3eizs3h7w3a34opszbyfxziqdxguhjw7imdve" +CIDb32dagcbor="bafyreievd6mwe6vcwnkwo3eizs3h7w3a34opszbyfxziqdxguhjw7imdve" test_expect_success "cid base32 works" ' echo $CIDb32 > expected && @@ -103,11 +104,19 @@ Z 90 base58flickr EOF cat < codecs_expect + 81 cbor 85 raw - 112 protobuf - 113 cbor + 112 dag-pb + 113 dag-cbor + 114 libp2p-key 120 git-raw + 123 torrent-info + 124 torrent-file + 129 leofcoin-block + 130 leofcoin-tx + 131 leofcoin-pr 133 dag-jose + 134 dag-cose 144 eth-block 145 eth-block-list 146 eth-tx-trie @@ -117,16 +126,36 @@ cat < codecs_expect 150 eth-state-trie 151 eth-account-snapshot 152 eth-storage-trie + 153 eth-receipt-log-trie + 154 eth-reciept-log 176 bitcoin-block 177 bitcoin-tx + 178 bitcoin-witness-commitment 192 zcash-block 193 zcash-tx + 208 stellar-block + 209 stellar-tx 224 decred-block 225 decred-tx 240 dash-block 241 dash-tx -61697 fil-commitment-unsealed -61698 fil-commitment-sealed + 250 swarm-manifest + 251 swarm-feed + 297 dag-json + 496 swhid-1-snp + 512 json +EOF + +cat < supported_codecs_expect + 81 cbor + 85 raw + 112 dag-pb + 113 dag-cbor + 114 libp2p-key + 120 git-raw + 133 dag-jose + 297 dag-json + 512 json EOF cat < hashes_expect @@ -232,6 +261,17 @@ test_expect_success "cid codecs --numeric" ' test_cmp codecs_expect actual ' +test_expect_success "cid codecs --supported" ' + cut -c 8- supported_codecs_expect > expect && + ipfs cid codecs --supported > actual + test_cmp expect actual +' + +test_expect_success "cid codecs --supported --numeric" ' + ipfs cid codecs --supported --numeric > actual && + test_cmp supported_codecs_expect actual +' + test_expect_success "cid hashes" ' cut -c 8- hashes_expect > expect && ipfs cid hashes > actual @@ -245,13 +285,28 @@ test_expect_success "cid hashes --numeric" ' test_expect_success "cid format -c raw" ' echo $CIDb32raw > expected && - ipfs cid format --codec raw -b base32 $CIDb32pb > actual && + ipfs cid format --mc raw -b base32 $CIDb32pb > actual && test_cmp actual expected ' -test_expect_success "cid format -c protobuf -v 0" ' +test_expect_success "cid format --mc dag-pb -v 0" ' echo $CIDbase > expected && - ipfs cid format --codec protobuf -v 0 $CIDb32raw > actual && + ipfs cid format --mc dag-pb -v 0 $CIDb32raw > actual && + test_cmp actual expected +' + +test_expect_success "cid format --mc dag-cbor" ' + echo $CIDb32dagcbor > expected && + ipfs cid format --mc dag-cbor $CIDb32pb > actual && + test_cmp actual expected +' + +# this was an old flag that we removed, explicitly to force an error +# so the user would read about the new multicodec names introduced +# by https://github.com/ipfs/go-cid/commit/b2064d74a8b098193b316689a715cdf4e4934805 +test_expect_success "cid format --codec fails" ' + echo "Error: unknown option \"codec\"" > expected && + test_expect_code 1 ipfs cid format --codec protobuf 2> actual && test_cmp actual expected ' diff --git a/test/sharness/t0300-docker-image.sh b/test/sharness/t0300-docker-image.sh index 3d8f573f2f5..a3a802b287f 100755 --- a/test/sharness/t0300-docker-image.sh +++ b/test/sharness/t0300-docker-image.sh @@ -29,30 +29,53 @@ TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR") APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR") test_expect_success "docker image build succeeds" ' - docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" >actual || + docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" | tee build-actual || test_fsh echo "TEST_TESTS_DIR: $TEST_TESTS_DIR" || test_fsh echo "APP_ROOT_DIR : $APP_ROOT_DIR" || - test_fsh cat actual + test_fsh cat build-actual ' test_expect_success "docker image build output looks good" ' - SUCCESS_LINE=$(egrep "^Successfully built" actual) && + SUCCESS_LINE=$(egrep "^Successfully built" build-actual) && IMAGE_ID=$(expr "$SUCCESS_LINE" : "^Successfully built \(.*\)") || - test_fsh cat actual + test_fsh cat build-actual +' + +test_expect_success "write init scripts" ' + echo "ipfs config Foo Bar" > 001.sh && + echo "ipfs config Baz Qux" > 002.sh && + chmod +x 002.sh ' test_expect_success "docker image runs" ' - DOC_ID=$(docker_run "$IMAGE_ID") + DOC_ID=$(docker run -d \ + -p 127.0.0.1:5001:5001 -p 127.0.0.1:8080:8080 \ + -v "$PWD/001.sh":/container-init.d/001.sh \ + -v "$PWD/002.sh":/container-init.d/002.sh \ + "$IMAGE_ID") +' + +test_expect_success "docker container gateway is up" ' + pollEndpoint -host=/ip4/127.0.0.1/tcp/8080 -http-url http://localhost:8080/api/v0/version -v -tries 30 -tout 1s ' -test_expect_success "docker image gateway is up" ' - docker_exec "$DOC_ID" "wget --retry-connrefused --waitretry=1 --timeout=30 -t 30 \ - -q -O - http://localhost:8080/version >/dev/null" +test_expect_success "docker container API is up" ' + pollEndpoint -host=/ip4/127.0.0.1/tcp/5001 -http-url http://localhost:5001/version -v -tries 30 -tout 1s ' -test_expect_success "docker image API is up" ' - docker_exec "$DOC_ID" "wget --retry-connrefused --waitretry=1 --timeout=30 -t 30 \ - -q -O - http://localhost:5001/api/v0/version >/dev/null" +test_expect_success "check that init scripts were run correctly and in the correct order" " + echo -e \"Sourcing '/container-init.d/001.sh'...\nExecuting '/container-init.d/002.sh'...\" > expected && + docker logs $DOC_ID 2>/dev/null | grep -e 001.sh -e 002.sh > actual && + test_cmp actual expected +" + +test_expect_success "check that init script configs were applied" ' + echo Bar > expected && + docker exec "$DOC_ID" ipfs config Foo > actual && + test_cmp actual expected && + echo Qux > expected && + docker exec "$DOC_ID" ipfs config Baz > actual && + test_cmp actual expected ' test_expect_success "simple ipfs add/cat can be run in docker container" ' @@ -63,8 +86,7 @@ test_expect_success "simple ipfs add/cat can be run in docker container" ' ' read testcode <actual ; \ + pollEndpoint -host=/ip4/127.0.0.1/tcp/5001 -http-url http://localhost:5001/version -http-out | grep Commit | cut -d" " -f2 >actual ; \ test -s actual ; \ docker exec -i "$DOC_ID" ipfs version --enc json \ | sed 's/^.*"Commit":"\\\([^"]*\\\)".*$/\\\1/g' >expected ; \ @@ -77,5 +99,7 @@ test_expect_success "stop docker container" ' docker_stop "$DOC_ID" ' +docker_rm "$DOC_ID" +docker_rmi "$IMAGE_ID" test_done diff --git a/test/sharness/t0301-docker-migrate.sh b/test/sharness/t0301-docker-migrate.sh index 4f47310d181..3f7d32f214b 100755 --- a/test/sharness/t0301-docker-migrate.sh +++ b/test/sharness/t0301-docker-migrate.sh @@ -32,6 +32,10 @@ test_expect_success "docker image build succeeds" ' test_init_ipfs +test_expect_success "configure migration sources" ' + ipfs config --json Migration.DownloadSources "[\"http://127.0.0.1:17233\"]" +' + test_expect_success "make repo be version 4" ' echo 4 > "$IPFS_PATH/version" ' @@ -43,17 +47,13 @@ test_expect_success "setup http response" ' echo "v1.1.1" >> vers_resp ' -pretend_server() { - socat tcp-listen:17233,fork,bind=127.0.0.1,reuseaddr 'SYSTEM:cat vers_resp'!!STDERR & -} - test_expect_success "startup fake dists server" ' - pretend_server > dist_serv_out & + ( socat tcp-listen:17233,fork,bind=127.0.0.1,reuseaddr "SYSTEM:cat vers_resp"!!STDERR 2> dist_serv_out ) & echo $! > netcat_pid ' test_expect_success "docker image runs" ' - DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host -e IPFS_DIST_PATH="http://localhost:17233" "$IMAGE_ID" --migrate) + DOC_ID=$(docker run -d -v "$IPFS_PATH":/data/ipfs --net=host "$IMAGE_ID") ' test_expect_success "docker container tries to pull migrations from netcat" ' @@ -74,8 +74,10 @@ test_expect_success "kill the net cat" ' ' test_expect_success "correct version was requested" ' - grep "/fs-repo-migrations/v1.1.1/fs-repo-migrations_v1.1.1_linux-amd64.tar.gz" dist_serv_out > /dev/null + grep "/fs-repo-6-to-7/v1.1.1/fs-repo-6-to-7_v1.1.1_linux-amd64.tar.gz" dist_serv_out > /dev/null ' +docker_rm "$DOC_ID" +docker_rmi "$IMAGE_ID" test_done diff --git a/test/sharness/t0310-tracing.sh b/test/sharness/t0310-tracing.sh new file mode 100755 index 00000000000..96d07ae8da2 --- /dev/null +++ b/test/sharness/t0310-tracing.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2022 Protocol Labs +# MIT/Apache-2.0 Licensed; see the LICENSE file in this repository. +# + +test_description="Test tracing" + +. lib/test-lib.sh + +test_init_ipfs + +export OTEL_TRACES_EXPORTER=otlp +export OTEL_EXPORTER_OTLP_PROTOCOL=grpc +export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 + +cat < collector-config.yaml +receivers: + otlp: + protocols: + grpc: + +processors: + batch: + +exporters: + file: + path: /traces/traces.json + +service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [file] +EOF + +# touch traces.json and give it 777 perms, in case docker runs as a different user +rm -rf traces.json && touch traces.json && chmod 777 traces.json + +test_expect_success "run opentelemetry collector" ' + docker run --rm -d -v "$PWD/collector-config.yaml":/config.yaml -v "$PWD":/traces --net=host --name=ipfs-test-otel-collector otel/opentelemetry-collector-contrib:0.52.0 --config /config.yaml +' + +test_launch_ipfs_daemon + +test_expect_success "check that a swarm span eventually appears in exported traces" ' + until cat traces.json | grep CoreAPI.SwarmAPI >/dev/null; do sleep 0.1; done +' + +test_expect_success "kill docker container" ' + docker kill ipfs-test-otel-collector +' + +test_kill_ipfs_daemon + +test_done diff --git a/test/sharness/t0401-api-browser-security.sh b/test/sharness/t0401-api-browser-security.sh index 1e36bcead32..f288259d5f6 100755 --- a/test/sharness/t0401-api-browser-security.sh +++ b/test/sharness/t0401-api-browser-security.sh @@ -39,6 +39,22 @@ test_expect_success "browser is able to access API if Origin is the API port on grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output ' +test_expect_success "Random browser extension is unable to access RPC API due to invalid Origin" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: chrome-extension://invalidextensionid" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 403 Forbidden" curl_output +' + +test_expect_success "Companion extension is able to access RPC API on localhost" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: chrome-extension://nibjojkomfdiaoajekhjakgkdhaomnch" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + cat curl_output && + grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output +' + +test_expect_success "Companion beta extension is able to access API on localhost" ' + curl -sD - -X POST -A "Mozilla" -H "Origin: chrome-extension://hjoieblefckbooibpepigmacodalfndh" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + grep "HTTP/1.1 200 OK" curl_output && grep "$PEERID" curl_output +' + test_kill_ipfs_daemon test_expect_success "setting CORS in API.HTTPHeaders works via CLI" " @@ -49,6 +65,14 @@ test_expect_success "setting CORS in API.HTTPHeaders works via CLI" " test_launch_ipfs_daemon +test_expect_success "Companion extension is able to access RPC API even when custom Access-Control-Allow-Origin is set" ' + ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin | grep -q valid.example.com && + curl -sD - -X POST -A "Mozilla" -H "Origin: chrome-extension://nibjojkomfdiaoajekhjakgkdhaomnch" "http://127.0.0.1:$API_PORT/api/v0/id" >curl_output && + cat curl_output && + grep "HTTP/1.1 200 OK" curl_output && + grep "$PEERID" curl_output +' + # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request test_expect_success "OPTIONS with preflight request to API with CORS allowlist succeeds" ' curl -svX OPTIONS -A "Mozilla" -H "Origin: https://valid.example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: origin, x-requested-with" "http://127.0.0.1:$API_PORT/api/v0/id" 2>curl_output && diff --git a/test/sharness/t0700-remotepin.sh b/test/sharness/t0700-remotepin.sh index 538375841c6..2566c06d899 100755 --- a/test/sharness/t0700-remotepin.sh +++ b/test/sharness/t0700-remotepin.sh @@ -319,6 +319,14 @@ test_remote_pins() { test_remote_pins "" test_kill_ipfs_daemon + +WARNINGMESSAGE="WARNING: the local node is offline and remote pinning may fail if there is no other provider for this CID" + +test_expect_success "'ipfs pin remote add' shows the warning message while offline" ' + test_expect_code 0 ipfs pin remote add --service=test_pin_svc --background $BASE_ARGS --name=name_a $HASH_A > actual && + test_expect_code 0 grep -q "$WARNINGMESSAGE" actual +' + test_done # vim: ts=2 sw=2 sts=2 et: diff --git a/tracing/doc.go b/tracing/doc.go new file mode 100644 index 00000000000..a7b43f0ce2a --- /dev/null +++ b/tracing/doc.go @@ -0,0 +1,77 @@ +// Package tracing contains the tracing logic for go-ipfs, including configuring the tracer and +// helping keep consistent naming conventions across the stack. +// +// NOTE: Tracing is currently experimental. Span names may change unexpectedly, spans may be removed, +// and backwards-incompatible changes may be made to tracing configuration, options, and defaults. +// +// Tracing is configured through environment variables, as consistent with the OpenTelemetry spec as possible: +// +// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md +// +// - OTEL_TRACES_EXPORTER: a comma-separated list of exporters +// - otlp +// - jaeger +// - zipkin +// - file +// +// Different exporters have their own set of environment variables, depending on the exporter. These are typically +// standard environment variables. Some common ones: +// +// Jaeger: +// +// - OTEL_EXPORTER_JAEGER_AGENT_HOST +// - OTEL_EXPORTER_JAEGER_AGENT_PORT +// - OTEL_EXPORTER_JAEGER_ENDPOINT +// - OTEL_EXPORTER_JAEGER_USER +// - OTEL_EXPORTER_JAEGER_PASSWORD +// +// OTLP HTTP/gRPC: +// +// - OTEL_EXPORTER_OTLP_PROTOCOL +// - one of [grpc, http/protobuf] +// - default: grpc +// - OTEL_EXPORTER_OTLP_ENDPOINT +// - OTEL_EXPORTER_OTLP_CERTIFICATE +// - OTEL_EXPORTER_OTLP_HEADERS +// - OTEL_EXPORTER_OTLP_COMPRESSION +// - OTEL_EXPORTER_OTLP_TIMEOUT +// +// Zipkin: +// +// - OTEL_EXPORTER_ZIPKIN_ENDPOINT +// +// File: +// +// - OTEL_EXPORTER_FILE_PATH +// - file path to write JSON traces +// - default: `$PWD/traces.json` +// +// For example, if you run a local IPFS daemon, you can use the jaegertracing/all-in-one Docker image to run +// a full Jaeger stack and configure go-ipfs to publish traces to it: +// +// docker run -d --name jaeger \ +// -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ +// -p 5775:5775/udp \ +// -p 6831:6831/udp \ +// -p 6832:6832/udp \ +// -p 5778:5778 \ +// -p 16686:16686 \ +// -p 14268:14268 \ +// -p 14269:14269 \ +// -p 14250:14250 \ +// -p 9411:9411 \ +// jaegertracing/all-in-one +// OTEL_TRACES_EXPORTER=jaeger ipfs daemon +// +// In this example the Jaeger UI is available at http://localhost:16686. +// +// +// Implementer Notes +// +// Span names follow a convention of ., some examples: +// +// - component=Gateway + span=Request -> Gateway.Request +// - component=CoreAPI.PinAPI + span=Verify.CheckPin -> CoreAPI.PinAPI.Verify.CheckPin +// +// We follow the OpenTelemetry convention of using whatever TracerProvider is registered globally. +package tracing diff --git a/tracing/file_exporter.go b/tracing/file_exporter.go new file mode 100644 index 00000000000..32ca20ee274 --- /dev/null +++ b/tracing/file_exporter.go @@ -0,0 +1,45 @@ +package tracing + +import ( + "context" + "fmt" + "os" + + "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + "go.opentelemetry.io/otel/sdk/trace" +) + +// fileExporter wraps a file-writing exporter and closes the file when the exporter is shutdown. +type fileExporter struct { + file *os.File + writerExporter *stdouttrace.Exporter +} + +func newFileExporter(file string) (*fileExporter, error) { + f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + return nil, fmt.Errorf("opening '%s' for OpenTelemetry file exporter: %w", file, err) + } + stdoutExporter, err := stdouttrace.New(stdouttrace.WithWriter(f)) + if err != nil { + return nil, err + } + return &fileExporter{ + writerExporter: stdoutExporter, + file: f, + }, nil +} + +func (e *fileExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { + return e.writerExporter.ExportSpans(ctx, spans) +} + +func (e *fileExporter) Shutdown(ctx context.Context) error { + if err := e.writerExporter.Shutdown(ctx); err != nil { + return err + } + if err := e.file.Close(); err != nil { + return fmt.Errorf("closing trace file: %w", err) + } + return nil +} diff --git a/tracing/tracing.go b/tracing/tracing.go new file mode 100644 index 00000000000..84eabc5e78e --- /dev/null +++ b/tracing/tracing.go @@ -0,0 +1,148 @@ +package tracing + +import ( + "context" + "fmt" + "os" + "path" + "strings" + + version "github.com/ipfs/go-ipfs" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/jaeger" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" + "go.opentelemetry.io/otel/exporters/zipkin" + "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + traceapi "go.opentelemetry.io/otel/trace" +) + +// shutdownTracerProvider adds a shutdown method for tracer providers. +// +// Note that this doesn't directly use the provided TracerProvider interface +// to avoid build breaking go-ipfs if new methods are added to it. +type shutdownTracerProvider interface { + Tracer(instrumentationName string, opts ...traceapi.TracerOption) traceapi.Tracer + Shutdown(ctx context.Context) error +} + +// noopShutdownTracerProvider adds a no-op Shutdown method to a TracerProvider. +type noopShutdownTracerProvider struct{ traceapi.TracerProvider } + +func (n *noopShutdownTracerProvider) Shutdown(ctx context.Context) error { return nil } + +func buildExporters(ctx context.Context) ([]trace.SpanExporter, error) { + // These env vars are standardized but not yet supported by opentelemetry-go. + // Once supported, we can remove most of this code. + // + // Specs: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#exporter-selection + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md + var exporters []trace.SpanExporter + for _, exporterStr := range strings.Split(os.Getenv("OTEL_TRACES_EXPORTER"), ",") { + switch exporterStr { + case "otlp": + protocol := "http/protobuf" + if v := os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL"); v != "" { + protocol = v + } + if v := os.Getenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"); v != "" { + protocol = v + } + + switch protocol { + case "http/protobuf": + exporter, err := otlptracehttp.New(ctx) + if err != nil { + return nil, fmt.Errorf("building OTLP HTTP exporter: %w", err) + } + exporters = append(exporters, exporter) + case "grpc": + exporter, err := otlptracegrpc.New(ctx) + if err != nil { + return nil, fmt.Errorf("building OTLP gRPC exporter: %w", err) + } + exporters = append(exporters, exporter) + default: + return nil, fmt.Errorf("unknown or unsupported OTLP exporter '%s'", exporterStr) + } + case "jaeger": + exporter, err := jaeger.New(jaeger.WithCollectorEndpoint()) + if err != nil { + return nil, fmt.Errorf("building Jaeger exporter: %w", err) + } + exporters = append(exporters, exporter) + case "zipkin": + exporter, err := zipkin.New("") + if err != nil { + return nil, fmt.Errorf("building Zipkin exporter: %w", err) + } + exporters = append(exporters, exporter) + case "file": + // This is not part of the spec, but provided for convenience + // so that you don't have to setup a collector, + // and because we don't support the stdout exporter. + filePath := os.Getenv("OTEL_EXPORTER_FILE_PATH") + if filePath == "" { + cwd, err := os.Getwd() + if err != nil { + return nil, fmt.Errorf("finding working directory for the OpenTelemetry file exporter: %w", err) + } + filePath = path.Join(cwd, "traces.json") + } + exporter, err := newFileExporter(filePath) + if err != nil { + return nil, err + } + exporters = append(exporters, exporter) + case "none": + continue + case "": + continue + case "stdout": + // stdout is already used for certain kinds of logging, so we don't support this + fallthrough + default: + return nil, fmt.Errorf("unknown or unsupported exporter '%s'", exporterStr) + } + } + return exporters, nil +} + +// NewTracerProvider creates and configures a TracerProvider. +func NewTracerProvider(ctx context.Context) (shutdownTracerProvider, error) { + exporters, err := buildExporters(ctx) + if err != nil { + return nil, err + } + if len(exporters) == 0 { + return &noopShutdownTracerProvider{TracerProvider: traceapi.NewNoopTracerProvider()}, nil + } + + options := []trace.TracerProviderOption{} + + for _, exporter := range exporters { + options = append(options, trace.WithBatcher(exporter)) + } + + r, err := resource.Merge( + resource.Default(), + resource.NewSchemaless( + semconv.ServiceNameKey.String("go-ipfs"), + semconv.ServiceVersionKey.String(version.CurrentVersionNumber), + ), + ) + if err != nil { + return nil, err + } + options = append(options, trace.WithResource(r)) + + return trace.NewTracerProvider(options...), nil +} + +// Span starts a new span using the standard IPFS tracing conventions. +func Span(ctx context.Context, componentName string, spanName string, opts ...traceapi.SpanStartOption) (context.Context, traceapi.Span) { + return otel.Tracer("go-ipfs").Start(ctx, fmt.Sprintf("%s.%s", componentName, spanName), opts...) +} diff --git a/version.go b/version.go index 79b1721a285..944af1c3898 100644 --- a/version.go +++ b/version.go @@ -1,10 +1,17 @@ package ipfs +import ( + "fmt" + "runtime" + + "github.com/ipfs/go-ipfs/repo/fsrepo" +) + // CurrentCommit is the current git commit, this is set as a ldflag in the Makefile var CurrentCommit string // CurrentVersionNumber is the current application's version literal -const CurrentVersionNumber = "0.12.2" +const CurrentVersionNumber = "0.13.0" const ApiVersion = "/go-ipfs/" + CurrentVersionNumber + "/" @@ -27,3 +34,21 @@ var userAgentSuffix string func SetUserAgentSuffix(suffix string) { userAgentSuffix = suffix } + +type VersionInfo struct { + Version string + Commit string + Repo string + System string + Golang string +} + +func GetVersionInfo() *VersionInfo { + return &VersionInfo{ + Version: CurrentVersionNumber, + Commit: CurrentCommit, + Repo: fmt.Sprint(fsrepo.RepoVersion), + System: runtime.GOARCH + "/" + runtime.GOOS, //TODO: Precise version here + Golang: runtime.Version(), + } +}